system.c revision 200150
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1988, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 4. Neither the name of the University nor the names of its contributors
141590Srgrimes *    may be used to endorse or promote products derived from this software
151590Srgrimes *    without specific prior written permission.
161590Srgrimes *
171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271590Srgrimes * SUCH DAMAGE.
281590Srgrimes */
291590Srgrimes
301590Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311590Srgrimesstatic char sccsid[] = "@(#)system.c	8.1 (Berkeley) 6/4/93";
321590Srgrimes#endif /* LIBC_SCCS and not lint */
331590Srgrimes#include <sys/cdefs.h>
341590Srgrimes__FBSDID("$FreeBSD: head/lib/libc/stdlib/system.c 200150 2009-12-05 19:31:38Z ed $");
3571725Swill
3671725Swill#include "namespace.h"
3771725Swill#include <sys/types.h>
381590Srgrimes#include <sys/wait.h>
391590Srgrimes#include <signal.h>
401590Srgrimes#include <stdlib.h>
4141568Sarchie#include <stddef.h>
421590Srgrimes#include <unistd.h>
431590Srgrimes#include <paths.h>
4441568Sarchie#include <errno.h>
4571725Swill#include "un-namespace.h"
4671725Swill#include "libc_private.h"
471590Srgrimes
481590Srgrimesint
491590Srgrimes__system(const char *command)
5027098Scharnier{
511590Srgrimes	pid_t pid, savedpid;
521590Srgrimes	int pstat;
5343531Seivind	struct sigaction ign, intact, quitact;
541590Srgrimes	sigset_t newsigblock, oldsigblock;
551590Srgrimes
561590Srgrimes	if (!command)		/* just checking... */
5723693Speter		return(1);
581590Srgrimes
591590Srgrimes	/*
601590Srgrimes	 * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save
611590Srgrimes	 * existing signal dispositions.
621590Srgrimes	 */
631590Srgrimes	ign.sa_handler = SIG_IGN;
641590Srgrimes	(void)sigemptyset(&ign.sa_mask);
6571726Swill	ign.sa_flags = 0;
6671726Swill	(void)_sigaction(SIGINT, &ign, &intact);
6771726Swill	(void)_sigaction(SIGQUIT, &ign, &quitact);
6871726Swill	(void)sigemptyset(&newsigblock);
6971726Swill	(void)sigaddset(&newsigblock, SIGCHLD);
701590Srgrimes	(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
711590Srgrimes	switch(pid = fork()) {
721590Srgrimes	case -1:			/* error */
731590Srgrimes		break;
741590Srgrimes	case 0:				/* child */
751590Srgrimes		/*
761590Srgrimes		 * Restore original signal dispositions and exec the command.
7771726Swill		 */
781590Srgrimes		(void)_sigaction(SIGINT, &intact, NULL);
791590Srgrimes		(void)_sigaction(SIGQUIT,  &quitact, NULL);
8043533Seivind		(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
8143531Seivind		execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
8243531Seivind		_exit(127);
831590Srgrimes	default:			/* parent */
841590Srgrimes		savedpid = pid;
8543531Seivind		do {
8643531Seivind			pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
8743532Seivind		} while (pid == -1 && errno == EINTR);
881590Srgrimes		break;
8943531Seivind	}
901590Srgrimes	(void)_sigaction(SIGINT, &intact, NULL);
911590Srgrimes	(void)_sigaction(SIGQUIT,  &quitact, NULL);
921590Srgrimes	(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
931590Srgrimes	return(pid == -1 ? -1 : pstat);
941590Srgrimes}
951590Srgrimes
961590Srgrimes__weak_reference(__system, system);
971590Srgrimes__weak_reference(__system, _system);
981590Srgrimes