system.c revision 200150
1251881Speter/* 2251881Speter * Copyright (c) 1988, 1993 3251881Speter * The Regents of the University of California. All rights reserved. 4251881Speter * 5251881Speter * Redistribution and use in source and binary forms, with or without 6251881Speter * modification, are permitted provided that the following conditions 7251881Speter * are met: 8251881Speter * 1. Redistributions of source code must retain the above copyright 9251881Speter * notice, this list of conditions and the following disclaimer. 10251881Speter * 2. Redistributions in binary form must reproduce the above copyright 11251881Speter * notice, this list of conditions and the following disclaimer in the 12251881Speter * documentation and/or other materials provided with the distribution. 13251881Speter * 4. Neither the name of the University nor the names of its contributors 14251881Speter * may be used to endorse or promote products derived from this software 15251881Speter * without specific prior written permission. 16251881Speter * 17251881Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18251881Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19251881Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20251881Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21251881Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22251881Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23251881Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24251881Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25251881Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26251881Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27251881Speter * SUCH DAMAGE. 28251881Speter */ 29251881Speter 30251881Speter#if defined(LIBC_SCCS) && !defined(lint) 31251881Speterstatic char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; 32251881Speter#endif /* LIBC_SCCS and not lint */ 33251881Speter#include <sys/cdefs.h> 34251881Speter__FBSDID("$FreeBSD: head/lib/libc/stdlib/system.c 200150 2009-12-05 19:31:38Z ed $"); 35251881Speter 36251881Speter#include "namespace.h" 37251881Speter#include <sys/types.h> 38251881Speter#include <sys/wait.h> 39251881Speter#include <signal.h> 40251881Speter#include <stdlib.h> 41251881Speter#include <stddef.h> 42251881Speter#include <unistd.h> 43251881Speter#include <paths.h> 44251881Speter#include <errno.h> 45251881Speter#include "un-namespace.h" 46251881Speter#include "libc_private.h" 47251881Speter 48251881Speterint 49251881Speter__system(const char *command) 50251881Speter{ 51251881Speter pid_t pid, savedpid; 52251881Speter int pstat; 53251881Speter struct sigaction ign, intact, quitact; 54251881Speter sigset_t newsigblock, oldsigblock; 55251881Speter 56251881Speter if (!command) /* just checking... */ 57251881Speter return(1); 58251881Speter 59251881Speter /* 60251881Speter * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save 61251881Speter * existing signal dispositions. 62251881Speter */ 63251881Speter ign.sa_handler = SIG_IGN; 64251881Speter (void)sigemptyset(&ign.sa_mask); 65251881Speter ign.sa_flags = 0; 66251881Speter (void)_sigaction(SIGINT, &ign, &intact); 67251881Speter (void)_sigaction(SIGQUIT, &ign, &quitact); 68262253Speter (void)sigemptyset(&newsigblock); 69251881Speter (void)sigaddset(&newsigblock, SIGCHLD); 70262253Speter (void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock); 71251881Speter switch(pid = fork()) { 72251881Speter case -1: /* error */ 73251881Speter break; 74251881Speter case 0: /* child */ 75251881Speter /* 76251881Speter * Restore original signal dispositions and exec the command. 77251881Speter */ 78251881Speter (void)_sigaction(SIGINT, &intact, NULL); 79251881Speter (void)_sigaction(SIGQUIT, &quitact, NULL); 80251881Speter (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); 81251881Speter execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL); 82251881Speter _exit(127); 83251881Speter default: /* parent */ 84251881Speter savedpid = pid; 85251881Speter do { 86251881Speter pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0); 87251881Speter } while (pid == -1 && errno == EINTR); 88251881Speter break; 89251881Speter } 90251881Speter (void)_sigaction(SIGINT, &intact, NULL); 91251881Speter (void)_sigaction(SIGQUIT, &quitact, NULL); 92251881Speter (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL); 93251881Speter return(pid == -1 ? -1 : pstat); 94251881Speter} 95251881Speter 96251881Speter__weak_reference(__system, system); 97251881Speter__weak_reference(__system, _system); 98251881Speter