aboutsummaryrefslogtreecommitdiff
path: root/sys/libc/cprcon.c
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /sys/libc/cprcon.c
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'sys/libc/cprcon.c')
-rw-r--r--sys/libc/cprcon.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/sys/libc/cprcon.c b/sys/libc/cprcon.c
new file mode 100644
index 00000000..c0534a60
--- /dev/null
+++ b/sys/libc/cprcon.c
@@ -0,0 +1,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 (NULL);
+ 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/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));
+}