2005-09-20 17:26:39 +04:00
/** \file proc.h
Prototypes for utilities for keeping track of jobs , processes and subshells , as
well as signal handling functions for tracking children . These
functions do not themselves launch new processes , the exec library
will call proc to create representations of the running jobs as
needed .
*/
2005-10-04 19:11:39 +04:00
# ifndef FISH_PROC_H
# define FISH_PROC_H
# include <wchar.h>
# include <signal.h>
# include <unistd.h>
2006-01-20 17:27:21 +03:00
# include <sys/time.h>
2005-10-04 19:11:39 +04:00
# include "util.h"
2005-10-08 15:20:51 +04:00
# include "io.h"
2005-10-04 19:11:39 +04:00
2005-09-20 17:26:39 +04:00
/**
2005-12-15 16:59:02 +03:00
Types of processes
2005-09-20 17:26:39 +04:00
*/
enum
{
2005-12-15 16:59:02 +03:00
/**
A regular external command
*/
2005-09-20 17:26:39 +04:00
EXTERNAL ,
2005-12-15 16:59:02 +03:00
/**
A builtin command
*/
2005-09-20 17:26:39 +04:00
INTERNAL_BUILTIN ,
2005-12-15 16:59:02 +03:00
/**
A shellscript function
*/
2005-09-20 17:26:39 +04:00
INTERNAL_FUNCTION ,
2005-12-15 16:59:02 +03:00
/**
A block of commands
*/
2005-09-20 17:26:39 +04:00
INTERNAL_BLOCK ,
2005-12-15 16:59:02 +03:00
/**
The exec builtin
*/
INTERNAL_EXEC ,
2005-09-20 17:26:39 +04:00
}
;
2006-01-30 20:54:26 +03:00
enum
{
JOB_CONTROL_ALL ,
JOB_CONTROL_INTERACTIVE ,
JOB_CONTROL_NONE ,
}
;
2005-09-20 17:26:39 +04:00
/**
2005-10-21 15:59:45 +04:00
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 .
2005-09-20 17:26:39 +04:00
*/
2005-10-21 15:59:45 +04:00
typedef struct process
{
2005-09-20 17:26:39 +04:00
/**
Type of process . Can be one of \ c EXTERNAL , \ c
2005-10-21 15:59:45 +04:00
INTERNAL_BUILTIN , \ c INTERNAL_FUNCTION , \ c INTERNAL_BLOCK or
INTERNAL_EXEC
2005-09-20 17:26:39 +04:00
*/
int type ;
2005-10-21 15:59:45 +04:00
/** argv parameter for for execv, builtin_run, etc. */
wchar_t * * argv ;
/** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC */
wchar_t * actual_cmd ;
/** process ID */
pid_t pid ;
2005-10-07 18:08:57 +04:00
/** File descriptor that pipe output should bind to */
int pipe_fd ;
2005-09-20 17:26:39 +04:00
/** true if process has completed */
volatile int completed ;
/** true if process has stopped */
volatile int stopped ;
/** reported status value */
volatile int status ;
/** next process in pipeline */
struct process * next ;
# ifdef HAVE__PROC_SELF_STAT
/** Last time of cpu time check */
struct timeval last_time ;
/** Number of jiffies spent in process at last cpu time check */
unsigned long last_jiffies ;
# endif
2005-10-21 15:59:45 +04:00
}
process_t ;
2005-09-20 17:26:39 +04:00
2005-10-21 15:59:45 +04:00
/** A pipeline of one or more processes. */
2005-09-20 17:26:39 +04:00
typedef struct job
{
/** command line, used for messages */
wchar_t * command ;
/** list of processes in this job */
process_t * first_process ;
/** process group ID */
pid_t pgid ;
/** true if user was told about stopped job */
int notified ;
/** saved terminal modes */
struct termios tmodes ;
/** The job id of the job*/
int job_id ;
/** Whether this job is in the foreground */
int fg ;
/**
Whether the specified job is completely constructed ,
i . e . completely parsed , and every process in the job has been
2005-10-21 15:59:45 +04:00
forked , etc .
2005-09-20 17:26:39 +04:00
*/
int constructed ;
/**
2005-10-11 23:23:43 +04:00
Whether the specified job is a part of a subshell , event handler or some other form of special job that should not be reported
2005-09-20 17:26:39 +04:00
*/
int skip_notification ;
/** List of IO redrections for the job */
io_data_t * io ;
2005-10-21 15:59:45 +04:00
/** Should the exit status be negated? This flag can only be set by the not builtin. */
2005-09-20 17:26:39 +04:00
int negate ;
2005-10-21 15:59:45 +04:00
2005-12-09 05:41:16 +03:00
/** This flag is set to one on wildcard expansion errors. It means that the current command should not be executed */
int wildcard_error ;
2006-01-05 18:37:53 +03:00
/** Skip executing this job. This flag is set by the short-circut builtins, i.e. and and or */
int skip ;
2006-01-18 15:42:48 +03:00
2006-01-30 20:54:26 +03:00
/** Whether the job is under job control */
int job_control ;
2006-02-01 15:27:15 +03:00
/** Whether the job wants to own the terminal when in the foreground */
int terminal ;
2005-10-21 15:59:45 +04:00
/** Pointer to the next job */
2005-09-20 17:26:39 +04:00
struct job * next ;
2005-10-21 15:59:45 +04:00
}
job_t ;
2005-09-20 17:26:39 +04:00
2005-12-15 16:59:02 +03:00
/**
Whether we are running a subshell command
*/
2005-09-20 17:26:39 +04:00
extern int is_subshell ;
2005-12-15 16:59:02 +03:00
/**
Whether we are running a block of commands
*/
2005-09-20 17:26:39 +04:00
extern int is_block ;
2005-12-15 16:59:02 +03:00
/**
Whether we are reading from the keyboard right now
*/
2005-09-20 17:26:39 +04:00
extern int is_interactive ;
2005-12-15 16:59:02 +03:00
/**
Whether this shell is attached to the keyboard at all
*/
2005-09-20 17:26:39 +04:00
extern int is_interactive_session ;
2005-12-15 16:59:02 +03:00
/**
Whether we are a login shell
*/
2005-09-20 17:26:39 +04:00
extern int is_login ;
2005-12-15 16:59:02 +03:00
/**
Whether we are a event handler
*/
2005-10-06 02:37:08 +04:00
extern int is_event ;
2005-12-15 16:59:02 +03:00
/**
Linked list of all jobs
*/
2005-09-20 17:26:39 +04:00
extern job_t * first_job ;
2005-09-24 03:15:38 +04:00
/**
Whether a universal variable barrier roundtrip has already been
made for this command . Such a roundtrip only needs to be done once
on a given command , unless a unversal variable value is
changed . Once this has been done , this variable is set to 1 , so
that no more roundtrips need to be done .
Both setting it to one when it should be zero and the opposite may
cause concurrency bugs .
*/
extern int proc_had_barrier ;
2005-09-20 17:26:39 +04:00
2006-01-23 23:40:14 +03:00
/**
Pid of last process to be started in the background
*/
2005-09-20 17:26:39 +04:00
extern pid_t proc_last_bg_pid ;
2006-01-30 20:54:26 +03:00
/**
Can be one of JOB_CONTROL_ALL , JOB_CONTROL_INTERACTIVE and JOB_CONTROL_NONE
*/
extern int job_control_mode ;
2006-03-18 04:04:59 +03:00
/**
If this flag is set , fish will never fork or run execve .
*/
extern int no_exec ;
2005-09-20 17:26:39 +04:00
/**
Sets the status of the last process to exit
*/
void proc_set_last_status ( int s ) ;
2005-12-15 16:59:02 +03:00
2005-09-20 17:26:39 +04:00
/**
Returns the status of the last process to exit
*/
int proc_get_last_status ( ) ;
/**
Remove the specified job
*/
void job_free ( job_t * j ) ;
2005-12-15 16:59:02 +03:00
2005-09-20 17:26:39 +04:00
/**
2006-02-06 17:25:02 +03:00
Create a new job . Job struct is allocated using halloc , so anything
that should be freed with the job can uset it as a halloc context
when allocating .
2005-09-20 17:26:39 +04:00
*/
job_t * job_create ( ) ;
/**
Return the job with the specified job id .
2006-04-28 17:21:37 +04:00
If id is 0 or less , return the last job used .
2005-09-20 17:26:39 +04:00
*/
job_t * job_get ( int id ) ;
/**
Return the job with the specified pid .
*/
job_t * job_get_from_pid ( int pid ) ;
/**
Tests if the job is stopped
*/
int job_is_stopped ( const job_t * j ) ;
/**
Tests if the job has completed
*/
int job_is_completed ( const job_t * j ) ;
/**
Reassume a ( possibly ) stopped job . Put job j in the foreground . If
cont is nonzero , restore the saved terminal modes and send the
process group a SIGCONT signal to wake it up before we block .
\ param j The job
\ param cont Whether the function should wait for the job to complete before returning
*/
void job_continue ( job_t * j , int cont ) ;
2005-12-15 16:59:02 +03:00
2005-09-20 17:26:39 +04:00
/**
2006-06-05 04:42:01 +04:00
Notify the user about stopped or terminated jobs . Delete terminated
jobs from the job list .
2005-10-11 23:23:43 +04:00
\ param interactive whether interactive jobs should be reaped as well
2005-09-20 17:26:39 +04:00
*/
2005-10-11 23:23:43 +04:00
int job_reap ( int interactive ) ;
2005-12-15 16:59:02 +03:00
2005-09-20 17:26:39 +04:00
/**
2006-06-05 04:42:01 +04:00
Signal handler for SIGCHLD . Mark any processes with relevant
2005-09-20 17:26:39 +04:00
information .
*/
void job_handle_signal ( int signal , siginfo_t * info , void * con ) ;
# ifdef HAVE__PROC_SELF_STAT
/**
Use the procfs filesystem to look up how many jiffies of cpu time
was used by this process . This function is only available on
systems with the procfs file entry ' stat ' , i . e . Linux .
*/
unsigned long proc_get_jiffies ( process_t * p ) ;
/**
Update process time usage for all processes by calling the
proc_get_jiffies function for every process of every job .
*/
void proc_update_jiffies ( ) ;
# endif
/**
Perform a set of simple sanity checks on the job list . This
includes making sure that only one job is in the foreground , that
every process is in a valid state , etc .
*/
void proc_sanity_check ( ) ;
2005-12-03 22:46:18 +03:00
/**
2006-05-02 20:29:50 +04:00
Send a process / job exit event notification . This function is a
conveniance wrapper around event_fire ( ) .
2005-12-03 22:46:18 +03:00
*/
void proc_fire_event ( const wchar_t * msg , int type , pid_t pid , int status ) ;
2006-01-23 23:40:14 +03:00
/**
2005-10-14 15:40:33 +04:00
Initializations
*/
void proc_init ( ) ;
/**
Clean up before exiting
*/
void proc_destroy ( ) ;
2006-02-16 16:36:32 +03:00
/**
Set new value for is_interactive flag , saving previous value . If
needed , update signal handlers .
*/
void proc_push_interactive ( int value ) ;
/**
Set is_interactive flag to the previous value . If needed , update
signal handlers .
*/
void proc_pop_interactive ( ) ;
2005-10-04 19:11:39 +04:00
# endif