diff options
author | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
---|---|---|
committer | Joe Hunkeler <jhunkeler@gmail.com> | 2015-08-11 16:51:37 -0400 |
commit | 40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch) | |
tree | 4464880c571602d54f6ae114729bf62a89518057 /unix/os/prwait.c | |
download | iraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz |
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'unix/os/prwait.c')
-rw-r--r-- | unix/os/prwait.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/unix/os/prwait.c b/unix/os/prwait.c new file mode 100644 index 00000000..381d87b1 --- /dev/null +++ b/unix/os/prwait.c @@ -0,0 +1,175 @@ +/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. + */ + +#include <stdio.h> +#include <sys/wait.h> + +#define import_kernel +#define import_knames +#define import_spp +#include <iraf.h> + +/* Process table code. The high level code assumes that it can open and close + * processes in any order. The UNIX "wait" primitive, called when a process is + * closed, returns the process status and pid of the first process to exit. + * Hence several calls to wait may be necessary to wait for a given process to + * exit. We hide all this behind the pr_wait call, which waits for a PARTICULAR + * process to exit and returns its exit status. + * + * NOT INTERFACE PROCEDURES. This code is only called internally by other + * kernel procedures. All primitives which execute subprocesses, i.e., ZOPCPR, + * ZOPDPR, ZOSCMD, etc. must call these routines. + */ + +struct proctable { + int pr_pid; /* process id */ + int pr_active; /* if YES, process is still active */ + int pr_inchan; /* input IPC channel */ + int pr_outchan; /* output IPC channel */ + int pr_exit_status; /* process exit_status */ +} prtable[MAXPROCS]; + +extern int errno; + +#ifdef MACOSX +#define POSIX +#endif + + +/* PR_ENTER -- Make a new entry in the process table. Something is very wrong + * if the table overflows. + */ +void +pr_enter (int pid, int inchan, int outchan) +{ + register struct proctable *pr; + struct proctable *pr_findpid(); + + extern int kernel_panic (char *msg); + + + if ((pr = pr_findpid (NULL)) == NULL) + kernel_panic ("iraf process table overflow"); + else { + pr->pr_pid = pid; + pr->pr_active = YES; + pr->pr_inchan = inchan; + pr->pr_outchan = outchan; + } +} + + +/* PR_WAIT -- Wait for the process associated with the given pid to terminate + * and return it's exit status. If there is no such process in the table + * return ERR. The table entry is cleared by this call. + */ +int +pr_wait (int pid) +{ + register struct proctable *pr; + int error_code; + pid_t waitpid; + struct proctable *pr_findpid(); +#ifdef POSIX + int exit_status; +#else + union wait exit_status; +#endif + + + /* Lookup process in table. Return ERR if there is no entry. + */ + if ((pr = pr_findpid (pid)) == NULL) + return (ERR); + + if (pr->pr_active == NO) { + /* Process has already terminated. Clear table entry and return + * exit status (set in a previous call). + */ + pr->pr_pid = (int) 0; + return (pr->pr_exit_status); + + } else { + /* Process is in table but has not yet terminated. Call wait until + * the process exits. If other processes exit in the meantime + * save their exit status in the table and mark them inactive. + * If an unknown process terminates ignore it; this will happen + * when a killed bkg process terminates after its process slot + * has been released. + */ + while ((waitpid = wait (&exit_status)) != ERR) { + if ((pr = pr_findpid (waitpid)) != NULL) { + pr->pr_active = NO; + + /* The integer argument to exit() is returned in the + * wait struct defined in <sys/wait.h>. + */ +#ifdef POSIX + error_code = WEXITSTATUS(exit_status); +#else + error_code = exit_status.w_T.w_Retcode; +#endif + pr->pr_exit_status = error_code ? error_code : XOK; + + if (waitpid == pid) { + pr->pr_pid = (int) 0; + return (pr->pr_exit_status); + } + } + } + return (ERR); + } +} + + +/* PR_GETIPC -- Get the codes for the IPC channels assigned to a process. + */ +int +pr_getipc (int pid, int *inchan, int *outchan) +{ + register struct proctable *pr; + struct proctable *pr_findpid(); + + + /* Lookup process in table. Return ERR if there is no entry. + */ + if ((pr = pr_findpid (pid)) == NULL) + return (ERR); + else { + *inchan = pr->pr_inchan; + *outchan = pr->pr_outchan; + return (pid); + } +} + + +/* PR_FINDPID -- Search the process table for a process. NULL is returned if + * the process cannot be found, otherwise a pointer to the table entry is + * returned. + */ +struct proctable * +pr_findpid (int pid) +{ + register int pr; + + + for (pr=0; pr < MAXPROCS; pr++) { + if (prtable[pr].pr_pid == pid) + return (&prtable[pr]); + } + + return (NULL); +} + + +/* PR_RELEASE -- Release the table entry for the process. Used when a process + * is killed and we do not wish to wait for process termination. + */ +void +pr_release (int pid) +{ + register struct proctable *pr; + + if ((pr = pr_findpid (pid)) != NULL) + pr->pr_pid = (int) 0; +} |