summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/misc/procopen.c
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2020-12-27 17:47:37 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2021-01-30 17:13:33 +0000
commitb30d193948be5a7794d7ae3ba0ed9c2f72c88e0f (patch)
tree6a37e590faffb9bb9af66887de645c546445036c /usr/src/lib/libast/common/misc/procopen.c
parentdf36e06d12cbf655ddf22339ef8c39fa2b83ebf8 (diff)
downloadillumos-gate-b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f.tar.gz
13405 ksh93 update to 2012-08-01
13434 sh: mishandles backslash as last character of a block of input 11750 ksh mkdir builtin doesn't honor special file permissions 9199 ksh93 builtin *grep -v mishandles blank lines, blows up libgcrypt-config 6756 sh (and ksh) have issues with ${1+"$@"} 6520 ksh: sleep could wait forever 4860 ksh93: core in printf 3791 /bin/sh's builtin 'rm' busted: 'rm -f' without arguments returns error 1047 ksh overwrites child core files 880 ksh93 coredumps on 'unset' 499 "interrupted system call" when using "tee" builtin in ksh Reviewed by: Robert Mustacchi <rm@fingolfin.org> Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> Reviewed by: Dominik Hassler <hadfl@omnios.org> Approved by: Rich Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src/lib/libast/common/misc/procopen.c')
-rw-r--r--usr/src/lib/libast/common/misc/procopen.c869
1 files changed, 0 insertions, 869 deletions
diff --git a/usr/src/lib/libast/common/misc/procopen.c b/usr/src/lib/libast/common/misc/procopen.c
deleted file mode 100644
index 9f0194cf42..0000000000
--- a/usr/src/lib/libast/common/misc/procopen.c
+++ /dev/null
@@ -1,869 +0,0 @@
-/***********************************************************************
-* *
-* This software is part of the ast package *
-* Copyright (c) 1985-2010 AT&T Intellectual Property *
-* and is licensed under the *
-* Common Public License, Version 1.0 *
-* by AT&T Intellectual Property *
-* *
-* A copy of the License is available at *
-* http://www.opensource.org/licenses/cpl1.0.txt *
-* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
-* *
-* Information and Software Systems Research *
-* AT&T Research *
-* Florham Park NJ *
-* *
-* Glenn Fowler <gsf@research.att.com> *
-* David Korn <dgk@research.att.com> *
-* Phong Vo <kpv@research.att.com> *
-* *
-***********************************************************************/
-#pragma prototyped
-/*
- * Glenn Fowler
- * AT&T Research
- *
- * common process execution support with
- * proper sfio, signal and wait() syncronization
- *
- * _ contains the process path name and is
- * placed at the top of the environment
- */
-
-#include "proclib.h"
-
-#include <ls.h>
-
-/*
- * not quite ready for _use_spawnveg
- */
-
-#if _use_spawnveg && _lib_fork
-#undef _use_spawnveg
-#endif
-
-#ifndef DEBUG_PROC
-#define DEBUG_PROC 1
-#endif
-
-#if _lib_socketpair
-#if _sys_socket
-#include <sys/types.h>
-#include <sys/socket.h>
-#else
-#undef _lib_socketpair
-#endif
-#endif
-
-Proc_t proc_default = { -1 };
-
-#if DEBUG_PROC
-
-#include <namval.h>
-
-#define PROC_ENV_OPTIONS "PROC_OPTIONS"
-
-#define PROC_OPT_ENVIRONMENT (1<<0)
-#define PROC_OPT_EXEC (1<<1)
-#define PROC_OPT_TRACE (1<<2)
-#define PROC_OPT_VERBOSE (1<<3)
-
-static const Namval_t options[] =
-{
- "debug", PROC_OPT_VERBOSE,
- "environment", PROC_OPT_ENVIRONMENT,
- "exec", PROC_OPT_EXEC,
- "trace", PROC_OPT_TRACE,
- "verbose", PROC_OPT_VERBOSE,
- 0, 0
-};
-
-/*
- * called by stropt() to set options
- */
-
-static int
-setopt(register void* a, register const void* p, register int n, const char* v)
-{
- NoP(v);
- if (p)
- {
- if (n)
- *((int*)a) |= ((Namval_t*)p)->value;
- else
- *((int*)a) &= ~((Namval_t*)p)->value;
- }
- return 0;
-}
-
-#endif
-
-#if _use_spawnveg
-
-typedef struct Fd_s
-{
- short fd;
- short flag;
-} Fd_t;
-
-typedef struct Mod_s
-{
- struct Mod_s* next;
- short op;
- short save;
-
- union
- {
-
- struct
- {
- Fd_t parent;
- Fd_t child;
- } fd;
-
- Handler_t handler;
-
- } arg;
-
-} Modify_t;
-
-#endif
-
-#ifdef SIGPIPE
-
-/*
- * catch but ignore sig
- * avoids SIG_IGN being passed to children
- */
-
-static void
-ignoresig(int sig)
-{
- signal(sig, ignoresig);
-}
-
-#endif
-
-/*
- * do modification op and save previous state for restore()
- */
-
-static int
-modify(Proc_t* proc, int forked, int op, long arg1, long arg2)
-{
-#if _lib_fork
- if (forked)
- {
- switch (op)
- {
- case PROC_fd_dup:
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_CHILD:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- if (arg1 != arg2)
- {
- if (arg2 != PROC_ARG_NULL)
- {
- close(arg2);
- if (fcntl(arg1, F_DUPFD, arg2) != arg2)
- return -1;
- }
- if (op & PROC_FD_CHILD)
- close(arg1);
- }
- break;
- case PROC_sig_dfl:
- signal(arg1, SIG_DFL);
- break;
- case PROC_sig_ign:
- signal(arg1, SIG_IGN);
- break;
- case PROC_sys_pgrp:
- if (arg1 < 0)
- setsid();
- else if (arg1 > 0)
- {
- if (arg1 == 1)
- arg1 = 0;
- if (setpgid(0, arg1) < 0 && arg1 && errno == EPERM)
- setpgid(0, 0);
- }
- break;
- case PROC_sys_umask:
- umask(arg1);
- break;
- default:
- return -1;
- }
- }
-#if _use_spawnveg
- else
-#endif
-#else
- NoP(forked);
-#endif
-#if _use_spawnveg
- {
- register Modify_t* m;
-
- if (!(m = newof(NiL, Modify_t, 1, 0)))
- return -1;
- m->next = proc->mods;
- proc->mods = m;
- switch (m->op = op)
- {
- case PROC_fd_dup:
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_CHILD:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- m->arg.fd.parent.fd = (short)arg1;
- m->arg.fd.parent.flag = fcntl(arg1, F_GETFD, 0);
- if ((m->arg.fd.child.fd = (short)arg2) != arg1)
- {
- if (arg2 != PROC_ARG_NULL)
- {
- m->arg.fd.child.flag = fcntl(arg2, F_GETFD, 0);
- if ((m->save = fcntl(arg2, F_DUPFD, 3)) < 0)
- {
- m->op = 0;
- return -1;
- }
- fcntl(m->save, F_SETFD, FD_CLOEXEC);
- close(arg2);
- if (fcntl(arg1, F_DUPFD, arg2) != arg2)
- return -1;
- if (op & PROC_FD_CHILD)
- close(arg1);
- }
- else if (op & PROC_FD_CHILD)
- {
- if (m->arg.fd.parent.flag)
- break;
- fcntl(arg1, F_SETFD, FD_CLOEXEC);
- }
- else if (!m->arg.fd.parent.flag)
- break;
- else
- fcntl(arg1, F_SETFD, 0);
- return 0;
- }
- break;
- case PROC_sig_dfl:
- if ((m->arg.handler = signal(arg1, SIG_DFL)) == SIG_DFL)
- break;
- m->save = (short)arg1;
- return 0;
- case PROC_sig_ign:
- if ((m->arg.handler = signal(arg1, SIG_IGN)) == SIG_IGN)
- break;
- m->save = (short)arg1;
- return 0;
- case PROC_sys_pgrp:
- proc->pgrp = arg1;
- break;
- case PROC_sys_umask:
- if ((m->save = (short)umask(arg1)) == arg1)
- break;
- return 0;
- default:
- proc->mods = m->next;
- free(m);
- return -1;
- }
- proc->mods = m->next;
- free(m);
- }
-#else
- NoP(proc);
-#endif
- return 0;
-}
-
-#if _use_spawnveg
-
-/*
- * restore modifications
- */
-
-static void
-restore(Proc_t* proc)
-{
- register Modify_t* m;
- register Modify_t* p;
- int oerrno;
-
- NoP(proc);
- oerrno = errno;
- m = proc->mods;
- proc->mods = 0;
- while (m)
- {
- switch (m->op)
- {
- case PROC_fd_dup:
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_CHILD:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- if (m->op & PROC_FD_PARENT)
- close(m->arg.fd.parent.fd);
- if (m->arg.fd.child.fd != m->arg.fd.parent.fd && m->arg.fd.child.fd != PROC_ARG_NULL)
- {
- if (!(m->op & PROC_FD_PARENT))
- {
- if (m->op & PROC_FD_CHILD)
- {
- close(m->arg.fd.parent.fd);
- fcntl(m->arg.fd.child.fd, F_DUPFD, m->arg.fd.parent.fd);
- }
- fcntl(m->arg.fd.parent.fd, F_SETFD, m->arg.fd.parent.flag);
- }
- close(m->arg.fd.child.fd);
- fcntl(m->save, F_DUPFD, m->arg.fd.child.fd);
- close(m->save);
- if (m->arg.fd.child.flag)
- fcntl(m->arg.fd.child.fd, F_SETFD, FD_CLOEXEC);
- }
- else if ((m->op & (PROC_FD_PARENT|PROC_FD_CHILD)) == PROC_FD_CHILD)
- fcntl(m->arg.fd.parent.fd, F_SETFD, 0);
- break;
- case PROC_sig_dfl:
- case PROC_sig_ign:
- signal(m->save, m->arg.handler);
- break;
- case PROC_sys_umask:
- umask(m->save);
- break;
- }
- p = m;
- m = m->next;
- free(p);
- }
- errno = oerrno;
-}
-
-#else
-
-#define restore(p)
-
-#endif
-
-/*
- * fork and exec or spawn proc(argv) and return a Proc_t handle
- *
- * pipe not used when PROC_READ|PROC_WRITE omitted
- * argv==0 duplicates current process if possible
- * cmd==0 names the current shell
- * cmd=="" does error cleanup
- * envv is the child environment
- * modv is the child modification vector of PROC_*() ops
- */
-
-Proc_t*
-procopen(const char* cmd, char** argv, char** envv, long* modv, int flags)
-{
- register Proc_t* proc = 0;
- register int procfd;
- register char** p;
- char** v;
- int i;
- int forked = 0;
- int signalled = 0;
- long n;
- char path[PATH_MAX];
- char env[PATH_MAX + 2];
- int pio[2];
-#if !_pipe_rw && !_lib_socketpair
- int poi[2];
-#endif
-#if defined(SIGCHLD) && ( _lib_sigprocmask || _lib_sigsetmask )
- Sig_mask_t mask;
-#endif
-#if _use_spawnveg
- int newenv = 0;
-#endif
-#if DEBUG_PROC
- int debug = PROC_OPT_EXEC;
-#endif
-
-#if _lib_fork
- if (!argv && (flags & PROC_OVERLAY))
-#else
- if (!argv)
-#endif
- {
- errno = ENOEXEC;
- return 0;
- }
- pio[0] = pio[1] = -1;
-#if !_pipe_rw && !_lib_socketpair
- poi[0] = poi[1] = -1;
-#endif
- if (cmd && (!*cmd || !pathpath(path, cmd, NiL, PATH_REGULAR|PATH_EXECUTE)))
- goto bad;
- switch (flags & (PROC_READ|PROC_WRITE))
- {
- case 0:
- procfd = -1;
- break;
- case PROC_READ:
- procfd = 1;
- break;
- case PROC_WRITE:
- procfd = 0;
- break;
- case PROC_READ|PROC_WRITE:
- procfd = 2;
- break;
- }
- if (proc_default.pid == -1)
- proc = &proc_default;
- else if (!(proc = newof(0, Proc_t, 1, 0)))
- goto bad;
- proc->pid = -1;
- proc->pgrp = 0;
- proc->rfd = -1;
- proc->wfd = -1;
- proc->flags = flags;
- sfsync(NiL);
- if (environ && envv != (char**)environ && (envv || (flags & PROC_PARANOID) || argv && (environ[0][0] != '_' || environ[0][1] != '=')))
- {
- if (!setenviron(NiL))
- goto bad;
-#if _use_spawnveg
- newenv = 1;
-#endif
- }
- if (procfd >= 0)
- {
-#if _pipe_rw
- if (pipe(pio))
- goto bad;
-#else
- if (procfd > 1)
- {
-#if _lib_socketpair
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pio))
- goto bad;
-#else
- if (pipe(pio) || pipe(poi))
- goto bad;
-#endif
- }
- else if (pipe(pio))
- goto bad;
-#endif
- }
- if (flags & PROC_OVERLAY)
- {
- proc->pid = 0;
- forked = 1;
- }
-#if _use_spawnveg
- else if (argv)
- proc->pid = 0;
-#endif
-#if _lib_fork
- else
- {
- if (!(flags & PROC_FOREGROUND))
- sigcritical(SIG_REG_EXEC|SIG_REG_PROC);
- else
- {
- signalled = 1;
- proc->sigint = signal(SIGINT, SIG_IGN);
- proc->sigquit = signal(SIGQUIT, SIG_IGN);
-#if defined(SIGCHLD)
-#if _lib_sigprocmask
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &mask, &proc->mask);
-#else
-#if _lib_sigsetmask
- mask = sigmask(SIGCHLD);
- proc->mask = sigblock(mask);
-#else
- proc->sigchld = signal(SIGCHLD, SIG_DFL);
-#endif
-#endif
-#endif
- }
- proc->pid = fork();
- if (!(flags & PROC_FOREGROUND))
- sigcritical(0);
- else if (!proc->pid)
- {
- if (proc->sigint != SIG_IGN)
- {
- proc->sigint = SIG_DFL;
- signal(SIGINT, proc->sigint);
- }
- if (proc->sigquit != SIG_IGN)
- {
- proc->sigquit = SIG_DFL;
- signal(SIGQUIT, proc->sigquit);
- }
-#if defined(SIGCHLD)
-#if _lib_sigprocmask
- sigprocmask(SIG_SETMASK, &proc->mask, NiL);
-#else
-#if _lib_sigsetmask
- sigsetmask(proc->mask);
-#else
- if (proc->sigchld != SIG_IGN)
- signal(SIGCHLD, SIG_DFL);
-#endif
-#endif
-#endif
- }
- else if (proc->pid == -1)
- goto bad;
- forked = 1;
- }
-#endif
- if (!proc->pid)
- {
-#if _use_spawnveg
- char** oenviron = 0;
- char* oenviron0 = 0;
-
- v = 0;
-#endif
-#if DEBUG_PROC
- stropt(getenv(PROC_ENV_OPTIONS), options, sizeof(*options), setopt, &debug);
-#if _lib_fork
- if (debug & PROC_OPT_TRACE)
- {
- if (!fork())
- {
- sfsprintf(path, sizeof(path), "%d", getppid());
- execlp("trace", "trace", "-p", path, NiL);
- _exit(EXIT_NOTFOUND);
- }
- sleep(2);
- }
-#endif
-#endif
- if (flags & PROC_DAEMON)
- {
-#ifdef SIGHUP
- modify(proc, forked, PROC_sig_ign, SIGHUP, 0);
-#endif
- modify(proc, forked, PROC_sig_dfl, SIGTERM, 0);
-#ifdef SIGTSTP
- modify(proc, forked, PROC_sig_ign, SIGTSTP, 0);
-#endif
-#ifdef SIGTTIN
- modify(proc, forked, PROC_sig_ign, SIGTTIN, 0);
-#endif
-#ifdef SIGTTOU
- modify(proc, forked, PROC_sig_ign, SIGTTOU, 0);
-#endif
- }
- if (flags & (PROC_BACKGROUND|PROC_DAEMON))
- {
- modify(proc, forked, PROC_sig_ign, SIGINT, 0);
-#ifdef SIGQUIT
- modify(proc, forked, PROC_sig_ign, SIGQUIT, 0);
-#endif
- }
- if (flags & (PROC_DAEMON|PROC_SESSION))
- modify(proc, forked, PROC_sys_pgrp, -1, 0);
- if (forked || (flags & PROC_OVERLAY))
- {
- if ((flags & PROC_PRIVELEGED) && !geteuid())
- {
- setuid(geteuid());
- setgid(getegid());
- }
- if (flags & (PROC_PARANOID|PROC_GID))
- setgid(getgid());
- if (flags & (PROC_PARANOID|PROC_UID))
- setuid(getuid());
- }
- if (procfd > 1)
- {
- if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[0], PROC_ARG_NULL))
- goto cleanup;
- if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[1], 1))
- goto cleanup;
-#if _pipe_rw || _lib_socketpair
- if (modify(proc, forked, PROC_fd_dup, 1, 0))
- goto cleanup;
-#else
- if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, poi[0], 0))
- goto cleanup;
- if (poi[1] != 0 && modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, poi[1], PROC_ARG_NULL))
- goto cleanup;
-#endif
- }
- else if (procfd >= 0)
- {
- if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[!!procfd], !!procfd))
- goto cleanup;
- if (pio[!procfd] != !!procfd && modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[!procfd], PROC_ARG_NULL))
- goto cleanup;
- }
- if (modv)
- for (i = 0; n = modv[i]; i++)
- switch (PROC_OP(n))
- {
- case PROC_fd_dup:
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_CHILD:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- if (modify(proc, forked, PROC_OP(n), PROC_ARG(n, 1), PROC_ARG(n, 2)))
- goto cleanup;
- break;
- default:
- if (modify(proc, forked, PROC_OP(n), PROC_ARG(n, 1), 0))
- goto cleanup;
- break;
- }
-#if _lib_fork
- if (forked && (flags & PROC_ENVCLEAR))
- environ = 0;
-#if _use_spawnveg
- else
-#endif
-#endif
-#if _use_spawnveg
- if (newenv)
- {
- p = environ;
- while (*p++);
- if (!(oenviron = (char**)memdup(environ, (p - environ) * sizeof(char*))))
- goto cleanup;
- }
-#endif
- if (argv && envv != (char**)environ)
- {
-#if _use_spawnveg
- if (!newenv && environ[0][0] == '_' && environ[0][1] == '=')
- oenviron0 = environ[0];
-#endif
- env[0] = '_';
- env[1] = '=';
- env[2] = 0;
- if (!setenviron(env))
- goto cleanup;
- }
- if ((flags & PROC_PARANOID) && setenv("PATH", astconf("PATH", NiL, NiL), 1))
- goto cleanup;
- if ((p = envv) && p != (char**)environ)
- while (*p)
- if (!setenviron(*p++))
- goto cleanup;
- p = argv;
-#if _lib_fork
- if (forked && !p)
- return proc;
-#endif
-#if DEBUG_PROC
- if (!(debug & PROC_OPT_EXEC) || (debug & PROC_OPT_VERBOSE))
- {
- if ((debug & PROC_OPT_ENVIRONMENT) && (p = environ))
- while (*p)
- sfprintf(sfstderr, "%s\n", *p++);
- sfprintf(sfstderr, "+ %s", cmd ? path : "sh");
- if ((p = argv) && *p)
- while (*++p)
- sfprintf(sfstderr, " %s", *p);
- sfprintf(sfstderr, "\n");
-sfsync(sfstderr);
- if (!(debug & PROC_OPT_EXEC))
- _exit(0);
- p = argv;
- }
-#endif
- if (cmd)
- {
- strcpy(env + 2, path);
- if (forked || (flags & PROC_OVERLAY))
- execve(path, p, environ);
-#if _use_spawnveg
- else if ((proc->pid = spawnveg(path, p, environ, proc->pgrp)) != -1)
- goto cleanup;
-#endif
- if (errno != ENOEXEC)
- goto cleanup;
-
- /*
- * try cmd as a shell script
- */
-
- if (!(flags & PROC_ARGMOD))
- {
- while (*p++);
- if (!(v = newof(0, char*, p - argv + 2, 0)))
- goto cleanup;
- p = v + 2;
- if (*argv)
- argv++;
- while (*p++ = *argv++);
- p = v + 1;
- }
- *p = path;
- *--p = "sh";
- }
- strcpy(env + 2, (flags & PROC_PARANOID) ? astconf("SH", NiL, NiL) : pathshell());
- if (forked || (flags & PROC_OVERLAY))
- execve(env + 2, p, environ);
-#if _use_spawnveg
- else
- proc->pid = spawnveg(env + 2, p, environ, proc->pgrp);
-#endif
- cleanup:
- if (forked)
- {
- if (!(flags & PROC_OVERLAY))
- _exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
- goto bad;
- }
-#if _use_spawnveg
- if (v)
- free(v);
- if (p = oenviron)
- {
- environ = 0;
- while (*p)
- if (!setenviron(*p++))
- goto bad;
- free(oenviron);
- }
- else if (oenviron0)
- environ[0] = oenviron0;
- restore(proc);
- if (flags & PROC_OVERLAY)
- exit(0);
-#endif
- }
- if (proc->pid != -1)
- {
- if (!forked)
- {
- if (flags & PROC_FOREGROUND)
- {
- signalled = 1;
- proc->sigint = signal(SIGINT, SIG_IGN);
- proc->sigquit = signal(SIGQUIT, SIG_IGN);
-#if defined(SIGCHLD)
-#if _lib_sigprocmask
- sigemptyset(&mask);
- sigaddset(&mask, SIGCHLD);
- sigprocmask(SIG_BLOCK, &mask, &proc->mask);
-#else
-#if _lib_sigsetmask
- mask = sigmask(SIGCHLD);
- proc->mask = sigblock(mask);
-#else
- proc->sigchld = signal(SIGCHLD, SIG_DFL);
-#endif
-#endif
-#endif
- }
- }
- else if (modv)
- for (i = 0; n = modv[i]; i++)
- switch (PROC_OP(n))
- {
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- close(PROC_ARG(n, 1));
- break;
- case PROC_sys_pgrp:
- if (proc->pgrp < 0)
- proc->pgrp = proc->pid;
- else if (proc->pgrp > 0)
- {
- if (proc->pgrp == 1)
- proc->pgrp = proc->pid;
- if (setpgid(proc->pid, proc->pgrp) < 0 && proc->pid != proc->pgrp && errno == EPERM)
- setpgid(proc->pid, proc->pid);
- }
- break;
- }
- if (procfd >= 0)
- {
-#ifdef SIGPIPE
- if ((flags & (PROC_WRITE|PROC_IGNORE)) == (PROC_WRITE|PROC_IGNORE))
- {
- Handler_t handler;
-
- if ((handler = signal(SIGPIPE, ignoresig)) != SIG_DFL && handler != ignoresig)
- signal(SIGPIPE, handler);
- }
-#endif
- switch (procfd)
- {
- case 0:
- proc->wfd = pio[1];
- close(pio[0]);
- break;
- default:
-#if _pipe_rw || _lib_socketpair
- proc->wfd = pio[0];
-#else
- proc->wfd = poi[1];
- close(poi[0]);
-#endif
- /*FALLTHROUGH*/
- case 1:
- proc->rfd = pio[0];
- close(pio[1]);
- break;
- }
- if (proc->rfd > 2)
- fcntl(proc->rfd, F_SETFD, FD_CLOEXEC);
- if (proc->wfd > 2)
- fcntl(proc->wfd, F_SETFD, FD_CLOEXEC);
- }
- if (!proc->pid)
- proc->pid = getpid();
- return proc;
- }
- bad:
- if (signalled)
- {
- if (proc->sigint != SIG_IGN)
- signal(SIGINT, proc->sigint);
- if (proc->sigquit != SIG_IGN)
- signal(SIGQUIT, proc->sigquit);
-#if defined(SIGCHLD)
-#if _lib_sigprocmask
- sigprocmask(SIG_SETMASK, &proc->mask, NiL);
-#else
-#if _lib_sigsetmask
- sigsetmask(proc->mask);
-#else
- if (proc->sigchld != SIG_DFL)
- signal(SIGCHLD, proc->sigchld);
-#endif
-#endif
-#endif
- }
- if ((flags & PROC_CLEANUP) && modv)
- for (i = 0; n = modv[i]; i++)
- switch (PROC_OP(n))
- {
- case PROC_fd_dup:
- case PROC_fd_dup|PROC_FD_PARENT:
- case PROC_fd_dup|PROC_FD_CHILD:
- case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
- if (PROC_ARG(n, 2) != PROC_ARG_NULL)
- close(PROC_ARG(n, 1));
- break;
- }
- if (pio[0] >= 0)
- close(pio[0]);
- if (pio[1] >= 0)
- close(pio[1]);
-#if !_pipe_rw && !_lib_socketpair
- if (poi[0] >= 0)
- close(poi[0]);
- if (poi[1] >= 0)
- close(poi[1]);
-#endif
- procfree(proc);
- return 0;
-}