|
|
1.1 ! root 1: /* iswait.c ! 2: Wait for a process to finish. ! 3: ! 4: Copyright (C) 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #include "uudefs.h" ! 29: #include "sysdep.h" ! 30: ! 31: #include <errno.h> ! 32: ! 33: #if HAVE_SYS_WAIT_H ! 34: #include <sys/wait.h> ! 35: #endif ! 36: ! 37: /* We use a typedef wait_status for wait (waitpid, wait4) to put ! 38: results into. We define the POSIX examination functions we need if ! 39: they are not already defined (if they aren't defined, I assume that ! 40: we have a standard wait status). */ ! 41: ! 42: #if HAVE_UNION_WAIT ! 43: typedef union wait wait_status; ! 44: #ifndef WIFEXITED ! 45: #define WIFEXITED(u) ((u).w_termsig == 0) ! 46: #endif ! 47: #ifndef WEXITSTATUS ! 48: #define WEXITSTATUS(u) ((u).w_retcode) ! 49: #endif ! 50: #ifndef WTERMSIG ! 51: #define WTERMSIG(u) ((u).w_termsig) ! 52: #endif ! 53: #else /* ! HAVE_UNION_WAIT */ ! 54: typedef int wait_status; ! 55: #ifndef WIFEXITED ! 56: #define WIFEXITED(i) (((i) & 0xff) == 0) ! 57: #endif ! 58: #ifndef WEXITSTATUS ! 59: #define WEXITSTATUS(i) (((i) >> 8) & 0xff) ! 60: #endif ! 61: #ifndef WTERMSIG ! 62: #define WTERMSIG(i) ((i) & 0x7f) ! 63: #endif ! 64: #endif /* ! HAVE_UNION_WAIT */ ! 65: ! 66: /* Wait for a particular process to finish. The ipid argument should ! 67: be pid_t, but then we couldn't have a prototype. If the zreport ! 68: argument is not NULL, then a wait error will be logged, and if the ! 69: exit status is non-zero it will be logged with zreport as the ! 70: header of the log message. If the zreport argument is NULL, no ! 71: errors will be logged. This function returns the exit status if ! 72: the process exited normally, or -1 on error or if the process was ! 73: killed by a signal (I don't just always return the exit status ! 74: because then the calling code would have to prepared to handle ! 75: union wait status vs. int status, and none of the callers care ! 76: which signal killed the program anyhow). ! 77: ! 78: This functions keeps waiting until the process finished, even if it ! 79: is interrupted by a signal. I think this is right for all uses. ! 80: The controversial one would be when called from uuxqt to wait for a ! 81: requested process. Hitting uuxqt with SIGKILL will approximate the ! 82: actions taken if we return from here with an error anyhow. If we ! 83: do get a signal, we call ulog with a NULL argument to get it in the ! 84: log file at about the right time. */ ! 85: ! 86: int ! 87: ixswait (ipid, zreport) ! 88: unsigned long ipid; ! 89: const char *zreport; ! 90: { ! 91: wait_status istat; ! 92: ! 93: #if HAVE_WAITPID ! 94: while (waitpid ((pid_t) ipid, (pointer) &istat, 0) < 0) ! 95: { ! 96: if (errno != EINTR) ! 97: { ! 98: if (zreport != NULL) ! 99: ulog (LOG_ERROR, "waitpid: %s", strerror (errno)); ! 100: return -1; ! 101: } ! 102: ulog (LOG_ERROR, (const char *) NULL); ! 103: } ! 104: #else /* ! HAVE_WAITPID */ ! 105: #if HAVE_WAIT4 ! 106: while (wait4 ((pid_t) ipid, (pointer) &istat, 0, ! 107: (struct rusage *) NULL) < 0) ! 108: { ! 109: if (errno != EINTR) ! 110: { ! 111: if (zreport != NULL) ! 112: ulog (LOG_ERROR, "wait4: %s", strerror (errno)); ! 113: return -1; ! 114: } ! 115: ulog (LOG_ERROR, (const char *) NULL); ! 116: } ! 117: #else /* ! HAVE_WAIT4 */ ! 118: pid_t igot; ! 119: ! 120: /* We could theoretically get the wrong child here if we're in some ! 121: kind of weird pipeline, so we don't give any error messages for ! 122: it. */ ! 123: while ((igot = wait ((pointer) &istat)) != (pid_t) ipid) ! 124: { ! 125: if (igot < 0) ! 126: { ! 127: if (errno != EINTR) ! 128: { ! 129: if (zreport != NULL) ! 130: ulog (LOG_ERROR, "wait: %s", strerror (errno)); ! 131: return -1; ! 132: } ! 133: ulog (LOG_ERROR, (const char *) NULL); ! 134: } ! 135: } ! 136: #endif /* ! HAVE_WAIT4 */ ! 137: #endif /* ! HAVE_WAITPID */ ! 138: ! 139: DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d", ! 140: WIFEXITED (istat) ? "Exit status" : "Signal", ! 141: WIFEXITED (istat) ? WEXITSTATUS (istat) : WTERMSIG (istat)); ! 142: ! 143: if (WIFEXITED (istat) && WEXITSTATUS (istat) == 0) ! 144: return 0; ! 145: ! 146: if (zreport != NULL) ! 147: { ! 148: if (! WIFEXITED (istat)) ! 149: ulog (LOG_ERROR, "%s: Got signal %d", zreport, WTERMSIG (istat)); ! 150: else ! 151: ulog (LOG_ERROR, "%s: Exit status %d", zreport, ! 152: WEXITSTATUS (istat)); ! 153: } ! 154: ! 155: if (WIFEXITED (istat)) ! 156: return WEXITSTATUS (istat); ! 157: else ! 158: return -1; ! 159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.