da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * spawnveg -- spawnve with process group or session control
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pgid <0 setsid() [session group leader]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 nothing [retain session and process group]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 1 setpgid(0,0) [process group leader]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * >1 setpgid(0,pgid) [join process group]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_spawnveg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNoN(spawnveg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_posix_spawn > 1 /* reports underlying exec() errors */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <spawn.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <wait.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin posix_spawnattr_t attr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (err = posix_spawnattr_init(&attr))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto nope;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid <= 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pgid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (err = posix_spawnattr_setpgroup(&attr, pgid))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (err = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (err = posix_spawn(&pid, path, NiL, &attr, argv, envv ? envv : environ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto bad;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin posix_spawnattr_destroy(&attr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_posix_spawn < 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (waitpid(pid, &err, WNOHANG|WNOWAIT) == pid && EXIT_STATUS(err) == 127)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!access(path, X_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOEXEC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bad:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz posix_spawnattr_destroy(&attr);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nope:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = err;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_spawn_mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <process.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef P_NOWAIT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define P_NOWAIT _P_NOWAIT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef P_DETACH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define P_DETACH _P_DETACH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return spawnve(pgid ? P_DETACH : P_NOWAIT, path, argv, envv ? envv : environ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_spawn && _hdr_spawn && _mem_pgroup_inheritance
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <spawn.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * open-edition/mvs/zos fork+exec+(setpgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct inheritance inherit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inherit.flags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inherit.flags |= SPAWN_SETGROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inherit.pgroup = (pgid > 1) ? pgid : SPAWN_NEWPGROUP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return spawn(path, 0, (int*)0, &inherit, (const char**)argv, (const char**)envv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <wait.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sig.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast_vfork.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef ENOSYS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ENOSYS EINVAL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_spawnve && _hdr_process
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <process.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(P_NOWAIT) || defined(_P_NOWAIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef _lib_spawnve
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_lib_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef _real_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * fork+exec+(setsid|setpgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpid_t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_fork || _lib_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid_t rid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _real_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin volatile int exec_errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin volatile int* volatile exec_errno_ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int err[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (access(path, X_OK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!envv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin envv = environ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_spawnve
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_fork || _lib_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!pgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return spawnve(path, argv, envv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_fork || _lib_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _real_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exec_errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exec_errno_ptr = &exec_errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pipe(err) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin err[0] = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(err[0], F_SETFD, FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(err[1], F_SETFD, FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigcritical(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _lib_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = vfork();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pid = fork();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigcritical(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (pid == -1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = errno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (!pid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setsid();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (pgid > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pgid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (setpgid(0, pgid) < 0 && pgid && errno == EPERM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setpgid(0, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin execve(path, argv, envv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _real_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *exec_errno_ptr = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (err[0] != -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(err[1], &n, sizeof(n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rid = pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if _real_vfork
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pid != -1 && (m = *exec_errno_ptr))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rid = pid = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (err[0] != -1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(err[1]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (pid != -1 && read(err[0], &m, sizeof(m)) == sizeof(m) && m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rid = pid = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(err[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pid != -1 && pgid > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * parent and child are in a race here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (pgid == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pgid = pid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (setpgid(pid, pgid) < 0 && pid != pgid && errno == EPERM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setpgid(pid, pid);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return rid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOSYS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif