1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
*/
#define import_spp
#define import_libc
#define import_xnames
#define import_stdio
#define import_prstat
#include <iraf.h>
/* CPRCON -- Connected subprocesses. A connected subprocess is an active filter
** which communicates with the parent process via an input stream and an output
** stream. A connected subprocess is logically equivalent to the user terminal.
** The set of useful operations thus far identified for connected subprocesses
** are open and close, read and write, and signal (interrupt). The read and
** write operations are provided by interfacing the IPC channels from the
** subprocess to FIO. The remaining operations are peculiar to connected
** subprocesses and are summarized below.
**
** pid = c_propen (process, in, out)
** stat = c_prclose (pid)
** stat = c_prstati (pid, param)
** c_prsignal (pid, signal)
** c_prredir (pid, stream, new_fd)
** c_prchdir (pid, newdir)
** c_prenvset (pid, envvar, valuestr)
**
** A connected subprocess must be opened either with c_propen or with the low
** level procedure PROPCPR (the latter does not require that the subprocess
** recognize the standard IPC protocol). An idle subprocess may be closed
** with c_prclose, which not only closes the process but releases important
** system resources. The c_prsignal procedure raises the X_INT (interrupt)
** exception in a subprocess, generally following receipt of a user interrupt
** by the parent process. Redirection of the child's standard i/o streams
** is provided by c_prredir. Finally, c_prchdir and c_prenvsets are used
** to update the current directory and environment in child processes.
*/
/* C_PROPEN -- Open a connected subprocess, i.e., spawn the subprocess and
** connect the two IPC channels connecting the child and parent to FIO.
** The FIO streams may subsequently be opened for C style STDIO by calling
** FDOPEN, if desired. The C_PROPEN procedure sends the current environment
** and working directory to the child as part of process startup. The process
** id (PID) of the child process is returned as the function value. This
** magic integer value uniquely identifies the process to the system.
**
** N.B.: opening a child process leaves the child in the IRAF Main interpreter
** loop, with the child waiting for a command from the parent. A child process
** is capabable of performing an arbitrary number of "tasks". To get the child
** to run a task, the parent must write the name of the task to the OUT stream,
** then read from the IN stream, responding to all queries from the child until
** "bye" or "error" is received.
*/
unsigned int
c_propen (
char *process, /* filename of executable process */
int *in, /* FD for reading from child */
int *out /* FD for writing to child */
)
{
register unsigned int pid;
XINT x_in = *in, x_out = *out;
iferr (pid = (unsigned int) PROPEN (c_sppstr(process), &x_in, &x_out))
return (0);
else {
*in = (int) x_in;
*out = (int) x_out;
FDTOFP(*in)->_fflags |= _FIPC;
return (pid);
}
}
/* C_PRCLOSE -- Close a connected subprocess. The "bye" command is sent to
** the child, commanding it to shut down, and when the task terminates the
** exit status is returned as the function value. The C_PRCLOSE procedure
** must be called at process termination to free system resources. C_PRCLOSE
** is automatically called by the system if error recovery takes place in
** the parent process. Calling C_PRCLOSE is equivalent to individually
** closing the IN and OUT streams to the subprocess (which is what happens
** if system error recovery takes place).
*/
int
c_prclose (
unsigned int pid /* process id returned by C_PROPEN */
)
{
XINT x_pid = pid;
return (PRCLOSE (&x_pid));
}
/* C_PRSTATI -- Get status on a connected subprocess. See <libc/iraf_prstat.h>
** for a list of parameters.
*/
int
c_prstati (
int pid, /* process id of process */
int param /* parameter for which value is ret */
)
{
XINT x_pid = pid, x_param = param;
return (PRSTATI (&x_pid, &x_param));
}
/* C_PRSIGNAL -- Send a signal, i.e., asynchronous interrupt, to a connected
** child process. Currently only the X_INT signal is implemented, and the
** second argument is not used. The value X_INT should nontheless be passed.
*/
int
c_prsignal (
unsigned pid, /* process id of process */
int signal /* not used at present */
)
{
XINT x_pid = pid, x_signal = signal;
iferr (PRSIGNAL (&x_pid, &x_signal))
return (ERR);
else
return (OK);
}
/* C_PRREDIR -- Redirect one of the standard i/o streams of the child process.
** By default the child inherits the standard i/o streams of the parent at
** C_PROPEN time, i.e., the STDOUT of the child is connected to the STDOUT of
** the parent. If the parent's STDOUT is subsequently redirected, e.g., with
** C_FREDIR, the child's output will be redirected as well. More commonly
** one or more of the child's streams will be explicitly redirected with
** C_PRREDIR. Such redirection remains in effect for the life of the
** process, i.e., until process termination via C_PRCLOSE or until another
** call to C_PRREDIR. Note that often this is not what is desired, rather,
** one wishes to redirect a stream for the duration of a task running within
** the process. For this reason it is recommended that C_PRREDIR be called
** for each standard stream (it costs almost nothing) immediately prior to
** task execution.
**
** Example:
** fp = fopen ("tmp$spoolfile", "w");
** if (c_prredir (pid, STDOUT, fileno(fp)) == ERR)
** ...
*/
int
c_prredir (
unsigned pid, /* process id of child */
int stream, /* child's stream to be redirected */
int new_fd /* FD of opened file in parent */
)
{
XINT x_pid = pid, x_stream = stream, x_new_fd = new_fd;
iferr (PRREDIR (&x_pid, &x_stream, &x_new_fd))
return (ERR);
else
return (OK);
}
/* C_PRCHDIR -- Change the current working directory of a child process.
** If pid=NULL all currently connected processes are updated. May only
** be called when the child process is idle.
*/
int
c_prchdir (
int pid,
char *newdir
)
{
XINT x_pid = pid;
return (PRCHDIR (&x_pid, c_sppstr (newdir)));
}
/* C_PRENVSET -- Transmit a set environment directive to the child process.
** If pid=NULL all currently connected processes are updated. May only
** be called when the child process is idle.
*/
int
c_prenvset (
int pid,
char *envvar,
char *value
)
{
XCHAR spp_value[SZ_LINE];
XINT x_pid = pid;
c_strupk (value, spp_value, SZ_LINE);
return (PRENVSET (&x_pid, c_sppstr (envvar), spp_value));
}
|