system.c revision 287292
159769Sgrog/*
259769Sgrog * Copyright (c) 1988, 1993
324424Swosch *	The Regents of the University of California.  All rights reserved.
424424Swosch *
524424Swosch * Redistribution and use in source and binary forms, with or without
624424Swosch * modification, are permitted provided that the following conditions
724424Swosch * are met:
824424Swosch * 1. Redistributions of source code must retain the above copyright
924424Swosch *    notice, this list of conditions and the following disclaimer.
1024424Swosch * 2. Redistributions in binary form must reproduce the above copyright
1124424Swosch *    notice, this list of conditions and the following disclaimer in the
1224424Swosch *    documentation and/or other materials provided with the distribution.
1324424Swosch * 3. Neither the name of the University nor the names of its contributors
1424424Swosch *    may be used to endorse or promote products derived from this software
1542704Swosch *    without specific prior written permission.
1642704Swosch *
1742704Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1824424Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1942704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2042704Swosch * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2142704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2242704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2342704Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2442704Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2542704Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2642704Swosch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2742704Swosch * SUCH DAMAGE.
2842704Swosch */
2942704Swosch
3059769Sgrog#if defined(LIBC_SCCS) && !defined(lint)
3159769Sgrogstatic char sccsid[] = "@(#)system.c	8.1 (Berkeley) 6/4/93";
3259769Sgrog#endif /* LIBC_SCCS and not lint */
3359769Sgrog#include <sys/cdefs.h>
3459769Sgrog__FBSDID("$FreeBSD: head/lib/libc/stdlib/system.c 287292 2015-08-29 14:25:01Z kib $");
3559769Sgrog
3659769Sgrog#include "namespace.h"
3759769Sgrog#include <sys/types.h>
3859769Sgrog#include <sys/wait.h>
3924424Swosch#include <signal.h>
4042704Swosch#include <stdlib.h>
4124424Swosch#include <stddef.h>
4242704Swosch#include <string.h>
4324424Swosch#include <unistd.h>
4442704Swosch#include <paths.h>
4524424Swosch#include <errno.h>
4624424Swosch#include "un-namespace.h"
4724424Swosch#include "libc_private.h"
4842704Swosch
4925031Swosch#pragma weak system
5059156Swoschint
5125031Swoschsystem(const char *command)
5225031Swosch{
5324424Swosch
5424424Swosch	return (((int (*)(const char *))
5524424Swosch	    __libc_interposing[INTERPOS_system])(command));
5624424Swosch}
5771231Sitojun
5824424Swoschint
5971231Sitojun__libc_system(const char *command)
6025031Swosch{
6171231Sitojun	pid_t pid, savedpid;
6224424Swosch	int pstat;
6325031Swosch	struct sigaction ign, intact, quitact;
6425031Swosch	sigset_t newsigblock, oldsigblock;
6571231Sitojun
6625031Swosch	if (!command)		/* just checking... */
6771231Sitojun		return(1);
6870110Swosch
6970110Swosch	(void)sigemptyset(&newsigblock);
7070110Swosch	(void)sigaddset(&newsigblock, SIGCHLD);
7170110Swosch	(void)sigaddset(&newsigblock, SIGINT);
7270110Swosch	(void)sigaddset(&newsigblock, SIGQUIT);
7370110Swosch	(void)__libc_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
7470110Swosch	switch(pid = vfork()) {
7570110Swosch	/*
7670110Swosch	 * In the child, use unwrapped syscalls.  libthr is in
7770110Swosch	 * undefined state after vfork().
7870110Swosch	 */
7980675Sasmodai	case -1:			/* error */
8080675Sasmodai		(void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
8180675Sasmodai		return (-1);
8280675Sasmodai	case 0:				/* child */
8380675Sasmodai		/*
8480675Sasmodai		 * Restore original signal dispositions and exec the command.
8580675Sasmodai		 */
8680675Sasmodai		(void)__sys_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
8780675Sasmodai		execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
8880675Sasmodai		_exit(127);
8980675Sasmodai	}
9080675Sasmodai	/*
9180675Sasmodai	 * If we are running means that the child has either completed
9280675Sasmodai	 * its execve, or has failed.
9380675Sasmodai	 * Block SIGINT/QUIT because sh -c handles it and wait for
9480675Sasmodai	 * it to clean up.
9580675Sasmodai	 */
9680675Sasmodai	memset(&ign, 0, sizeof(ign));
9780675Sasmodai	ign.sa_handler = SIG_IGN;
9880675Sasmodai	(void)sigemptyset(&ign.sa_mask);
9980675Sasmodai	(void)__libc_sigaction(SIGINT, &ign, &intact);
10080675Sasmodai	(void)__libc_sigaction(SIGQUIT, &ign, &quitact);
10180675Sasmodai	savedpid = pid;
10280675Sasmodai	do {
10380675Sasmodai		pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
10480675Sasmodai	} while (pid == -1 && errno == EINTR);
10580675Sasmodai	(void)__libc_sigaction(SIGINT, &intact, NULL);
10680675Sasmodai	(void)__libc_sigaction(SIGQUIT,  &quitact, NULL);
10780675Sasmodai	(void)__libc_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
10880675Sasmodai	return (pid == -1 ? -1 : pstat);
10980675Sasmodai}
11080675Sasmodai
11180675Sasmodai__weak_reference(__libc_system, __system);
11280675Sasmodai__weak_reference(__libc_system, _system);
11380675Sasmodai