From a91c5fa86a28c769e0e9525861c6a819549c4fe7 Mon Sep 17 00:00:00 2001 From: axel Date: Fri, 21 Oct 2005 21:59:45 +1000 Subject: [PATCH] Code cleanups and API documentation updates darcs-hash:20051021115945-ac50b-bce8377b3a711cd2269bc21d71d99f6d6ad4c931.gz --- exec.c | 37 ++++++++++++++++++++++---------- proc.h | 66 ++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 76 insertions(+), 27 deletions(-) diff --git a/exec.c b/exec.c index 074ec5b47..c09758dc1 100644 --- a/exec.c +++ b/exec.c @@ -59,7 +59,7 @@ pid_t getpgid( pid_t pid ); #define FORK_ERROR L"Could not create child process - exiting" /** - DEfault value for the umask + Default value for the umask */ #define UMASK_DEFAULT 0664 @@ -71,12 +71,14 @@ pid_t getpgid( pid_t pid ); static array_list_t *open_fds=0; /** - The umask. Recalculated every time exec is run. + The umask. Recalculated every time exec is run. by calling get_umask(). */ static int umask_val; /** - Calculated the current value of the umask + Calculate the current value of the umask. Should be done once at + the beginning of each call to exec. Uses the $umask environment + variable, if available, defaults to the constant UMASK_DEFAULT. */ static int get_umask() { @@ -189,8 +191,9 @@ static int use_fd_in_pipe( int fd, io_data_t *io ) /** Close all fds in open_fds, except for those that are mentioned in - the redirection list io - + the redirection list io. This should make sure that there are no + stray opened file descriptors in the child. + \param io the list of io redirections for this job. Pipes mentioned here should not be closed. */ static void close_unused_internal_pipes( io_data_t *io ) @@ -263,7 +266,16 @@ void free_fd( io_data_t *io, int fd ) } } +/** + Set up a childs io redirections. Should only be called by + setup_child_process(). Does the following: First it closes any open + file descriptors not related to the child by calling + close_unused_internal_pipes() and closing the universal variable + server file descriptor. It then goes on to perform all the + redirections described by \c io. + \param io the list of IO redirections for the child +*/ static void handle_child_io( io_data_t *io ) { @@ -393,7 +405,8 @@ static void handle_child_io( io_data_t *io ) Initialize a new child process. This should be called right away after forking in the child process. If job control is suitable, the process is put in the jobs group, all signal handlers are reset, - SIGCHLD is unblocked, and all IO redirections are performed. + SIGCHLD is unblocked (the exec call blocks blocks SIGCHLD), and all + IO redirections and other file descriptor actions are performed. */ static void setup_child_process( job_t *j ) { @@ -455,7 +468,6 @@ static void launch_process( process_t *p ) Check if the IO redirection chains contains redirections for the specified file descriptor */ - static int has_fd( io_data_t *d, int fd ) { return io_get( d, fd ) != 0; @@ -468,7 +480,6 @@ static int has_fd( io_data_t *d, int fd ) suitable for use as block-level io, since the file won't be repeatedly reopened for every command in the block. */ - static io_data_t *io_transmogrify( io_data_t * in ) { io_data_t *out; @@ -713,7 +724,13 @@ void exec( job_t *j ) signal_block(); + /* + This loop loops over every process_t in the job, starting it as + appropriate. This turns out to be rather complex, since a + process_t can be one of many rather different things. + The loop also has to handle pipelining between the jobs. + */ for (p = j->first_process; p; p = p->next) { @@ -1183,9 +1200,7 @@ void exec( job_t *j ) } } - signal_unblock(); - - + signal_unblock(); debug( 3, L"Job is constructed" ); diff --git a/proc.h b/proc.h index 67539f719..665ffc3da 100644 --- a/proc.h +++ b/proc.h @@ -34,21 +34,52 @@ enum /** - A structure representing a single process. Contains variables for - tracking process state and the process argument list. + A structure representing a single fish process. Contains variables + for tracking process state and the process argument + list. Actually, a fish process can be either a regular externa + lrocess, an internal builtin which may or may not spawn a fake IO + process during execution, a shellscript function or a block of + commands to be evaluated by calling eval. Lastly, this process can + be the result of an exec command. The role of this process_t is + determined by the type field, which can be one of EXTERNAL, + INTERNAL_BUILTIN, INTERNAL_FUNCTION, INTERNAL_BLOCK and + INTERNAL_EXEC. + + The process_t contains information on how the process should be + started, such as command name and arguments, as well as runtime + information on the status of the actual physical process which + represents it. Shellscript functions, builtins and blocks of code + may all need to spawn an external process that handles the piping + and redirecting of IO for them. + + If the process is of type EXTERNAL or INTERNAL_EXEC, argv is the + argument array and actual_cmd is the absolute path of the command + to execute. + + If the process is of type ITERNAL_BUILTIN, argv is the argument + vector, and argv[0] is the name of the builtin command. + + If the process is of type ITERNAL_FUNCTION, argv is the argument + vector, and argv[0] is the name of the shellscript function. + + If the process is of type ITERNAL_BLOCK, argv has exactly one + element, which is the block of commands to execute. + */ -typedef struct process{ - /** argv parameter for for execv */ +typedef struct process +{ + /** + Type of process. Can be one of \c EXTERNAL, \c + INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK or + INTERNAL_EXEC + */ + int type; + /** argv parameter for for execv, builtin_run, etc. */ wchar_t **argv; - /** actual command to pass to exec */ + /** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC */ wchar_t *actual_cmd; /** process ID */ pid_t pid; - /** - Type of process. Can be one of \c EXTERNAL, \c - INTERNAL_BUILTIN, \c INTERNAL_FUNCTION, \c INTERNAL_BLOCK - */ - int type; /** File descriptor that pipe output should bind to */ int pipe_fd; /** true if process has completed */ @@ -65,10 +96,11 @@ typedef struct process{ /** Number of jiffies spent in process at last cpu time check */ unsigned long last_jiffies; #endif -} process_t; +} + process_t; -/** Represents a pipeline of one or more processes. */ +/** A pipeline of one or more processes. */ typedef struct job { /** command line, used for messages */ @@ -88,7 +120,7 @@ typedef struct job /** Whether the specified job is completely constructed, i.e. completely parsed, and every process in the job has been - forked + forked, etc. */ int constructed; /** @@ -99,11 +131,13 @@ typedef struct job /** List of IO redrections for the job */ io_data_t *io; - /** Should the exit status be negated */ + /** Should the exit status be negated? This flag can only be set by the not builtin. */ int negate; - /** Is this a conditional short circut thing? If so, is it an COND_OR or a COND_AND */ + + /** Pointer to the next job */ struct job *next; -} job_t; +} + job_t; /** Whether we are running a subshell command */ extern int is_subshell;