diff options
author | chin <none@none> | 2007-08-17 12:01:52 -0700 |
---|---|---|
committer | chin <none@none> | 2007-08-17 12:01:52 -0700 |
commit | da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968 (patch) | |
tree | 5280d3b78e289fe9551371ab6e7f15ef9944ea14 /usr/src/lib/libast/common/comp/waitpid.c | |
parent | 073dbf9103ef2a2b05d8a16e2d26db04e0374b0e (diff) | |
download | illumos-joyent-da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968.tar.gz |
6437624 RFE: Add ksh93 (as /usr/bin/ksh93) and libshell.so to OS/Net
6505835 AST tools and library (libpp) required for creating l10n messages for ksh93
PSARC/2006/550 Korn Shell 93 Integration
PSARC/2006/587 /etc/ksh.kshrc for ksh93
PSARC/2007/035 ksh93 Amendments
Contributed by Roland Mainz <roland.mainz@nrubsig.org>
--HG--
rename : usr/src/lib/libcmd/common/mapfile-vers => deleted_files/usr/src/lib/libcmd/common/mapfile-vers
rename : usr/src/lib/libcmd/common/placeholder.c => deleted_files/usr/src/lib/libcmd/common/placeholder.c
Diffstat (limited to 'usr/src/lib/libast/common/comp/waitpid.c')
-rw-r--r-- | usr/src/lib/libast/common/comp/waitpid.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/comp/waitpid.c b/usr/src/lib/libast/common/comp/waitpid.c new file mode 100644 index 0000000000..95b29abdab --- /dev/null +++ b/usr/src/lib/libast/common/comp/waitpid.c @@ -0,0 +1,199 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* 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 +/* + * POSIX waitpid() + * + * pid < -1 WUNTRACED may not be fully supported + * process group specifics ignored by non-{waitpid,wait4} + */ + +#include <ast.h> +#include <wait.h> + +#if _lib_waitpid + +NoN(waitpid) + +#else + +#if _lib_wait4 + +struct rusage; + +extern int wait4(int, int*, int, struct rusage*); + +pid_t +waitpid(pid_t pid, int* status, int flags) +{ + return(wait4(pid, status, flags, NiL)); +} + +#else + +#undef SIGCLD + +#if _lib_wait3 + +extern int wait3(int*, int, struct rusage*); + +#else + +#if _lib_wait2 + +#define wait3(s,f,u) wait2(s,f) + +extern int wait2(int*, int); + +#else + +#include <sig.h> + +#define wait3(s,f,u) wait(s) + +static int caught; + +static void +catch(sig) +int sig; +{ + NoP(sig); + caught = 1; +} + +#endif + +#endif + +#include <error.h> + +struct zombie +{ + struct zombie* next; + int status; + pid_t pid; +}; + +pid_t +waitpid(pid_t pid, int* status, int flags) +{ + register struct zombie* zp; + register struct zombie* pp; + register int p; + int s; +#if !_lib_wait2 && !_lib_wait3 +#if !defined(SIGCLD) + int n; + int oerrno; +#endif + Sig_handler_t handler; +#endif + + static struct zombie* zombies; + + pp = 0; + zp = zombies; + while (zp) + { + if (zp->pid >= 0 && (zp->pid == pid || pid <= 0)) + { + if (pp) pp->next = zp->next; + else zombies = zp->next; + if (status) *status = zp->status; + pid = zp->pid; + free(zp); + return(pid); + } + } + if (pid > 0 && kill(pid, 0) < 0) return(-1); + for (;;) + { +#if !_lib_wait2 && !_lib_wait3 +#if !defined(SIGCLD) + oerrno = errno; +#endif + if (flags & WNOHANG) + { + caught = 0; +#if defined(SIGCLD) + handler = signal(SIGCLD, catch); + if (!caught) + { + signal(SIGCLD, handler); + return(0); + } +#else +#if defined(SIGALRM) + handler = signal(SIGALRM, catch); + n = alarm(1); +#endif +#endif + } +#endif + p = wait3(&s, flags, NiL); +#if !_lib_wait3 +#if !_lib_wait2 +#if defined(SIGCLD) + if (flags & WNOHANG) signal(SIGCLD, handler); +#else +#if defined(SIGALRM) + if (flags & WNOHANG) + { + if (n == 0 && !caught || n == 1) alarm(n); + else if (n > 1) alarm(n - caught); + signal(SIGALRM, handler); + } + if (p == -1 && errno == EINTR) + { + errno = oerrno; + p = 0; + s = 0; + } +#endif +#endif +#else + if (p == -1 && errno == EINVAL && (flags & ~WNOHANG)) + p = wait3(&s, flags & WNOHANG, NiL); +#endif +#endif + if (p <= 0) + { + if (p == 0 && status) *status = s; + return(p); + } + if (pid <= 0 || p == pid) + { + if (status) *status = s; + return(p); + } + if (!(zp = newof(0, struct zombie, 1, 0))) return(-1); + zp->pid = p; + zp->status = s; + zp->next = zombies; + zombies = zp; + } + /*NOTREACHED*/ +} + +#endif + +#endif |