diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-06-24 22:28:35 +0000 |
commit | 3950ffe2a485479f6561c27364d3d7df5a21d124 (patch) | |
tree | 468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/misc/procclose.c | |
download | ksh-upstream.tar.gz |
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/misc/procclose.c')
-rw-r--r-- | src/lib/libast/misc/procclose.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/lib/libast/misc/procclose.c b/src/lib/libast/misc/procclose.c new file mode 100644 index 0000000..a492454 --- /dev/null +++ b/src/lib/libast/misc/procclose.c @@ -0,0 +1,98 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2011 AT&T Intellectual Property * +* and is licensed under the * +* Eclipse Public License, Version 1.0 * +* by AT&T Intellectual Property * +* * +* A copy of the License is available at * +* http://www.eclipse.org/org/documents/epl-v10.html * +* (with md5 checksum b35adb5213ca9657e911e9befb180842) * +* * +* 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 + * + * close a proc opened by procopen() + * otherwise exit() status of process is returned + */ + +#include "proclib.h" + +int +procclose(register Proc_t* p) +{ + int pid; + int flags = 0; + int status = -1; + + if (p) + { + if (p->rfd >= 0) + close(p->rfd); + if (p->wfd >= 0 && p->wfd != p->rfd) + close(p->wfd); + if (p->flags & PROC_ORPHAN) + status = 0; + else + { + if (p->flags & PROC_ZOMBIE) + { + /* + * process may leave a zombie behind + * give it a chance to do that but + * don't hang waiting for it + */ + + flags |= WNOHANG; + sleep(1); + } + if (!(p->flags & PROC_FOREGROUND)) + sigcritical(SIG_REG_EXEC|SIG_REG_PROC); + while ((pid = waitpid(p->pid, &status, flags)) == -1 && errno == EINTR); + if (pid != p->pid && (flags & WNOHANG)) + status = 0; + if (!(p->flags & PROC_FOREGROUND)) + sigcritical(0); + else + { + if (p->sigint != SIG_IGN) + signal(SIGINT, p->sigint); + if (p->sigquit != SIG_IGN) + signal(SIGQUIT, p->sigquit); +#if defined(SIGCHLD) +#if _lib_sigprocmask + sigprocmask(SIG_SETMASK, &p->mask, NiL); +#else +#if _lib_sigsetmask + sigsetmask(p->mask); +#else + if (p->sigchld != SIG_DFL) + signal(SIGCHLD, p->sigchld); +#endif +#endif +#endif + } + status = status == -1 ? + EXIT_QUIT : + WIFSIGNALED(status) ? + EXIT_TERM(WTERMSIG(status)) : + EXIT_CODE(WEXITSTATUS(status)); + } + procfree(p); + } + else + status = errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC; + return status; +} |