INTERFACE---------------------------------------------------------------------------System ; IMPORT Thread, AtomList, TextSeq, Rd, Wr, File, Process; IMPORT ProcessEnv, MsgIF; FROM Ctypes IMPORT int, char_star; FROM Cstddef IMPORT size_t;
EXCEPTION ExecuteError(TEXT); Error(TEXT);---------------------------------------------------------------------------
PROCEDURE AtomListToText(l : AtomList.T) : TEXT; (* Convert an AtomList.T to a text, inserting spaces between all elements. *)---------------------------------------------------------------------------
PROCEDURE ParListToText(params : TextSeq.T) : TEXT; (* Convert a parameter list to text. *)---------------------------------------------------------------------------
PROCEDURE ExecWithFileHandles(pgm : TEXT; params : TextSeq.T; stdin, stdout, stderr : File.T; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL; wd : TEXT := NIL; ) : INTEGER RAISES {ExecuteError}; (* Execute `pgm' with `params' and the given standard file handles. If any of the handles is NIL, the handle of the current process is used. IF `wd' is non-NIL, it is used as the working directory of the process. *)---------------------------------------------------------------------------
PROCEDURE Exec(pgm : TEXT; params : TextSeq.T; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL; wd : TEXT := NIL; pstdin : File.T := NIL; pstdout : File.T := NIL; pstderr : File.T := NIL) : INTEGER RAISES {ExecuteError}; (* Execute `pgm' with `params' as parameters. `Params' may contain simple input and output redirections. If param[i] is any of `>', `1>', `<', `2>', `&>', `>>', `1>>', `2>>', `&>>', then param[i+1] is treated as the corresponding filename that is to be used as source or sink of bytes. The redirections have the following meaning: | | < fn : read stdin from file fn | > fn : write stdout into file fn | 1> fn : write stdout into file fn | 2> fn : write stderr into file fn | &> fn : write stdout and stderr into file fn | >> fn : append stdout to file fn | 1>> fn : append stdout to file fn | 2>> fn : append stderr to file fn | &>> fn : append stdout and stderr to file fn | IF `wd' is non-NIL, it is used as the working directory of the process. *)---------------------------------------------------------------------------
PROCEDURE Execute(cmd : TEXT; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL; wd : TEXT := NIL) : INTEGER RAISES {ExecuteError, Thread.Alerted}; (* Split `cmd' into program name and parameters and try to execute it directly. No input and output redirections are performed. IF `wd' is non-NIL, it is used as the working directory of the process. *)---------------------------------------------------------------------------
PROCEDURE RdExecute(cmd : TEXT; VAR rd : Rd.T; wd : TEXT := NIL; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL) : Process.T RAISES {ExecuteError, Thread.Alerted}; (* Split `cmd' into program name and parameters and try to execute it directly. Via `rd' the stdout and stderr streams of the created program-process (the return result) can be read. `wd' is the working directory of the program. Command sequentialization (as in 'ExecuteList') is not supported because of the asynchronous execution of the user processes. (Problems: SystemExecute exception handling and transparent merging of serveral pipes (for each user process) to the rd parameter) *)---------------------------------------------------------------------------
PROCEDURE PipeTo(cmd : TEXT; VAR wr : Wr.T; wd : TEXT := NIL; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL) : Process.T RAISES {ExecuteError, Thread.Alerted}; (* Split `cmd' into program name and parameters and try to execute it directly. Create a writer `wr' that is connected to the stdin of the created process so we can pipe input data into it. *)---------------------------------------------------------------------------
PROCEDURE Filter(cmd : TEXT; VAR rd : Rd.T; VAR wr : Wr.T; wd : TEXT := NIL; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL) : Process.T RAISES {ExecuteError, Thread.Alerted}; (* Split `cmd' into program name and parameters and try to execute it directly. Create a writer `wr' that is connected to the stdin of the created process so we can pipe input data into it, and a reader `rd' that gathers the stdout of the process. *)---------------------------------------------------------------------------
PROCEDURE ExecuteShell(cmd : TEXT; shell := "/bin/sh"; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL; wd : TEXT := NIL) : INTEGER RAISES {ExecuteError}; (* Try to execute the given `cmd' via `shell', that is, call `shell -c cmd'. IF `wd' is non-NIL, it is used as the working directory of the process. *)---------------------------------------------------------------------------
PROCEDURE ExecuteList(cmd : TEXT; env : ProcessEnv.T := NIL; msgif : MsgIF.T := NIL; wd : TEXT := NIL) : INTEGER RAISES {ExecuteError, Thread.Alerted}; (* Parse `cmd', split it into single commands at every `;', `|', `&&', and `||', and execute every command via `Exec'. The concatenation characters have the usual Bourne Shell meaning. Token may be grouped by single or double quotes. Since Exec() is called internally, all input and output redirections that are described above will be performed. IF `wd' is non-NIL, it is used as the working directory of the process. *)---------------------------------------------------------------------------
PROCEDURE Hostname() : TEXT; (* return the name of the local computer *) PROCEDURE Wait(p: Process.T) : Process.ExitCode RAISES {Error}; (* Like Process.Wait, but the POSIX-Implementation is overridden to RAISE on instead of asserting false. WARNING: It's an unchecked runtime-error to call `Wait` or Process.Wait for a pid that's already waited for by `Wait` (on POSIX). On WIN32 `Wait` is just a wrapper for Process.Wait. *)---------------------------------------------------------------------------
We cannot access errno
directly as a variable, because on some systems
it is a C macro that expands to something more complicated.
The errno
value is preserved across thread switches.
copied from m3core/src/C/Common/Cerrno.i3 for bootstrapping against older releases
<*EXTERNAL System__GetErrno*> PROCEDURE GetErrno(): int; TYPE pid_t = INTEGER; (* generally only 32 bits but ok *) <*EXTERNAL System__waitpid*> PROCEDURE waitpid (pid: pid_t; status: UNTRACED REF int; options: int): pid_t; <*EXTERNAL System__gethostname*> PROCEDURE gethostname (name: char_star; namelen: size_t): int; <*EXTERNAL System__EINVAL*> VAR EINVAL: int; <*EXTERNAL System__ECHILD*> VAR ECHILD: int; <*EXTERNAL System__EINTR*> VAR EINTR: int; END System.