diff options
| author | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 | 
|---|---|---|
| committer | svn2git <svn2git@FreeBSD.org> | 1994-05-01 08:00:00 +0000 | 
| commit | a16f65c7d117419bd266c28a1901ef129a337569 (patch) | |
| tree | 2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /gnu/libexec/uucp/libunix/iswait.c | |
| parent | 8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff) | |
Diffstat (limited to 'gnu/libexec/uucp/libunix/iswait.c')
| -rw-r--r-- | gnu/libexec/uucp/libunix/iswait.c | 159 | 
1 files changed, 159 insertions, 0 deletions
| diff --git a/gnu/libexec/uucp/libunix/iswait.c b/gnu/libexec/uucp/libunix/iswait.c new file mode 100644 index 000000000000..d2610aa1f8bd --- /dev/null +++ b/gnu/libexec/uucp/libunix/iswait.c @@ -0,0 +1,159 @@ +/* iswait.c +   Wait for a process to finish. + +   Copyright (C) 1992 Ian Lance Taylor + +   This file is part of the Taylor UUCP package. + +   This program is free software; you can redistribute it and/or +   modify it under the terms of the GNU General Public License as +   published by the Free Software Foundation; either version 2 of the +   License, or (at your option) any later version. + +   This program is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program; if not, write to the Free Software +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +   The author of the program may be contacted at ian@airs.com or +   c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. +   */ + +#include "uucp.h" + +#include "uudefs.h" +#include "sysdep.h" + +#include <errno.h> + +#if HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +/* We use a typedef wait_status for wait (waitpid, wait4) to put +   results into.  We define the POSIX examination functions we need if +   they are not already defined (if they aren't defined, I assume that +   we have a standard wait status).  */ + +#if HAVE_UNION_WAIT +typedef union wait wait_status; +#ifndef WIFEXITED +#define WIFEXITED(u) ((u).w_termsig == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(u) ((u).w_retcode) +#endif +#ifndef WTERMSIG +#define WTERMSIG(u) ((u).w_termsig) +#endif +#else /* ! HAVE_UNION_WAIT */ +typedef int wait_status; +#ifndef WIFEXITED +#define WIFEXITED(i) (((i) & 0xff) == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(i) (((i) >> 8) & 0xff) +#endif +#ifndef WTERMSIG +#define WTERMSIG(i) ((i) & 0x7f) +#endif +#endif /* ! HAVE_UNION_WAIT */ + +/* Wait for a particular process to finish.  The ipid argument should +   be pid_t, but then we couldn't have a prototype.  If the zreport +   argument is not NULL, then a wait error will be logged, and if the +   exit status is non-zero it will be logged with zreport as the +   header of the log message.  If the zreport argument is NULL, no +   errors will be logged.  This function returns the exit status if +   the process exited normally, or -1 on error or if the process was +   killed by a signal (I don't just always return the exit status +   because then the calling code would have to prepared to handle +   union wait status vs. int status, and none of the callers care +   which signal killed the program anyhow). + +   This functions keeps waiting until the process finished, even if it +   is interrupted by a signal.  I think this is right for all uses. +   The controversial one would be when called from uuxqt to wait for a +   requested process.  Hitting uuxqt with SIGKILL will approximate the +   actions taken if we return from here with an error anyhow.  If we +   do get a signal, we call ulog with a NULL argument to get it in the +   log file at about the right time.  */ + +int +ixswait (ipid, zreport) +     unsigned long ipid; +     const char *zreport; +{ +  wait_status istat; + +#if HAVE_WAITPID +  while (waitpid ((pid_t) ipid, (pointer) &istat, 0) < 0) +    { +      if (errno != EINTR) +	{ +	  if (zreport != NULL) +	    ulog (LOG_ERROR, "waitpid: %s", strerror (errno)); +	  return -1; +	} +      ulog (LOG_ERROR, (const char *) NULL); +    } +#else /* ! HAVE_WAITPID */ +#if HAVE_WAIT4 +  while (wait4 ((pid_t) ipid, (pointer) &istat, 0, +		(struct rusage *) NULL) < 0) +    { +      if (errno != EINTR) +	{ +	  if (zreport != NULL) +	    ulog (LOG_ERROR, "wait4: %s", strerror (errno)); +	  return -1; +	} +      ulog (LOG_ERROR, (const char *) NULL); +    } +#else /* ! HAVE_WAIT4 */ +  pid_t igot; + +  /* We could theoretically get the wrong child here if we're in some +     kind of weird pipeline, so we don't give any error messages for +     it.  */ +  while ((igot = wait ((pointer) &istat)) != (pid_t) ipid) +    { +      if (igot < 0) +	{ +	  if (errno != EINTR) +	    { +	      if (zreport != NULL) +		ulog (LOG_ERROR, "wait: %s", strerror (errno)); +	      return -1; +	    } +	  ulog (LOG_ERROR, (const char *) NULL); +	} +    } +#endif /* ! HAVE_WAIT4 */ +#endif /* ! HAVE_WAITPID */   + +  DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d", +		  WIFEXITED (istat) ? "Exit status" : "Signal", +		  WIFEXITED (istat) ? WEXITSTATUS (istat) : WTERMSIG (istat)); + +  if (WIFEXITED (istat) && WEXITSTATUS (istat) == 0) +    return 0; + +  if (zreport != NULL) +    { +      if (! WIFEXITED (istat)) +	ulog (LOG_ERROR, "%s: Got signal %d", zreport, WTERMSIG (istat)); +      else +	ulog (LOG_ERROR, "%s: Exit status %d", zreport, +	      WEXITSTATUS (istat)); +    } + +  if (WIFEXITED (istat)) +    return WEXITSTATUS (istat); +  else +    return -1; +} | 
