2011-12-27 11:18:46 +08:00
/** \file proc.h
2005-09-20 21:26:39 +08:00
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 .
2011-12-27 11:18:46 +08:00
2005-09-20 21:26:39 +08:00
*/
2005-10-04 23:11:39 +08:00
# ifndef FISH_PROC_H
# define FISH_PROC_H
# include <wchar.h>
# include <signal.h>
# include <unistd.h>
2006-01-20 22:27:21 +08:00
# include <sys/time.h>
2012-01-30 08:36:21 +08:00
# include <list>
2005-10-04 23:11:39 +08:00
# include "util.h"
2005-10-08 19:20:51 +08:00
# include "io.h"
2012-01-30 14:06:58 +08:00
# include "common.h"
2005-10-04 23:11:39 +08:00
2006-10-09 07:46:50 +08:00
/**
The status code use when a command was not found
*/
# define STATUS_UNKNOWN_COMMAND 127
2005-09-20 21:26:39 +08:00
2006-10-09 09:21:02 +08:00
/**
2008-01-09 03:31:45 +08:00
The status code use when an unknown error occured during execution of a command
2006-10-09 09:21:02 +08:00
*/
2008-01-09 03:31:45 +08:00
# define STATUS_NOT_EXECUTABLE 126
2006-10-09 09:21:02 +08:00
/**
The status code use when an unknown error occured during execution of a command
*/
# define STATUS_EXEC_FAIL 125
2008-01-09 03:31:45 +08:00
/**
The status code use when a wildcard had no matches
*/
# define STATUS_UNMATCHED_WILDCARD 124
2006-10-09 09:21:02 +08:00
/**
2006-12-13 22:34:31 +08:00
The status code used for normal exit in a builtin
*/
# define STATUS_BUILTIN_OK 0
/**
The status code used for erroneous argument combinations in a builtin
2006-10-09 09:21:02 +08:00
*/
# define STATUS_BUILTIN_ERROR 1
2005-09-20 21:26:39 +08:00
/**
2005-12-15 21:59:02 +08:00
Types of processes
2005-09-20 21:26:39 +08:00
*/
enum
{
2005-12-15 21:59:02 +08:00
/**
A regular external command
*/
2005-09-20 21:26:39 +08:00
EXTERNAL ,
2005-12-15 21:59:02 +08:00
/**
A builtin command
*/
2005-09-20 21:26:39 +08:00
INTERNAL_BUILTIN ,
2005-12-15 21:59:02 +08:00
/**
A shellscript function
*/
2005-09-20 21:26:39 +08:00
INTERNAL_FUNCTION ,
2005-12-15 21:59:02 +08:00
/**
A block of commands
*/
2005-09-20 21:26:39 +08:00
INTERNAL_BLOCK ,
2005-12-15 21:59:02 +08:00
/**
The exec builtin
*/
INTERNAL_EXEC ,
2006-08-22 09:24:51 +08:00
/**
A buffer
*/
INTERNAL_BUFFER ,
2011-12-27 11:18:46 +08:00
2005-09-20 21:26:39 +08:00
}
;
2006-01-31 01:54:26 +08:00
enum
{
2011-12-27 11:18:46 +08:00
JOB_CONTROL_ALL ,
2006-01-31 01:54:26 +08:00
JOB_CONTROL_INTERACTIVE ,
JOB_CONTROL_NONE ,
}
;
2005-09-20 21:26:39 +08:00
2011-12-27 11:18:46 +08:00
/**
2005-10-21 19:59:45 +08: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
2006-08-22 09:24:51 +08:00
INTERNAL_EXEC , INTERNAL_BUFFER
2005-10-21 19:59:45 +08:00
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 .
2006-08-22 09:24:51 +08:00
If the process is of type INTERNAL_BUILTIN , argv is the argument
2005-10-21 19:59:45 +08:00
vector , and argv [ 0 ] is the name of the builtin command .
2006-08-22 09:24:51 +08:00
If the process is of type INTERNAL_FUNCTION , argv is the argument
2005-10-21 19:59:45 +08:00
vector , and argv [ 0 ] is the name of the shellscript function .
2006-08-22 09:24:51 +08:00
If the process is of type INTERNAL_BLOCK , argv has exactly one
2005-10-21 19:59:45 +08:00
element , which is the block of commands to execute .
2005-09-20 21:26:39 +08:00
*/
2012-01-30 10:25:54 +08:00
class process_t
2005-10-21 19:59:45 +08:00
{
2012-01-30 14:06:58 +08:00
private :
2012-02-01 10:06:20 +08:00
/** argv parameter for for execv, builtin_run, etc. This is allocated via new, and furthermore, each string within it is allocated via new as well. Null terminated. */
2012-01-30 14:06:58 +08:00
wchar_t * * argv_array ;
2012-02-01 10:06:20 +08:00
void free_argv ( void ) ;
2012-01-30 14:06:58 +08:00
2012-01-30 10:25:54 +08:00
public :
2012-01-30 14:06:58 +08:00
process_t ( ) :
argv_array ( NULL ) ,
type ( 0 ) ,
actual_cmd ( NULL ) ,
pid ( 0 ) ,
pipe_write_fd ( 0 ) ,
pipe_read_fd ( 0 ) ,
completed ( 0 ) ,
stopped ( 0 ) ,
status ( 0 ) ,
count_help_magic ( 0 ) ,
next ( NULL )
# ifdef HAVE__PROC_SELF_STAT
, last_time ( ) ,
2012-01-31 00:15:02 +08:00
last_jiffies ( 0 )
2012-01-30 14:06:58 +08:00
# endif
{
}
~ process_t ( )
{
if ( this - > next ! = NULL )
delete this - > next ;
this - > free_argv ( ) ;
2012-01-30 15:22:42 +08:00
free ( ( void * ) actual_cmd ) ; //may be NULL
2012-01-30 14:06:58 +08:00
}
2011-12-27 11:18:46 +08:00
/**
2005-09-20 21:26:39 +08:00
Type of process . Can be one of \ c EXTERNAL , \ c
2006-08-22 09:24:51 +08:00
INTERNAL_BUILTIN , \ c INTERNAL_FUNCTION , \ c INTERNAL_BLOCK ,
INTERNAL_EXEC , or INTERNAL_BUFFER
2005-09-20 21:26:39 +08:00
*/
int type ;
2012-01-30 14:06:58 +08:00
/** Sets argv */
2012-02-01 10:06:20 +08:00
void set_argv ( const wcstring_list_t & argv ) ;
2012-01-30 14:06:58 +08:00
/** Returns argv */
const wchar_t * const * get_argv ( void ) const { return argv_array ; }
/** Returns argv[0] */
const wchar_t * argv0 ( void ) const { return argv_array [ 0 ] ; }
/** Returns argv[idx] */
const wchar_t * argv ( size_t idx ) const { return argv_array [ idx ] ; }
2007-08-01 05:23:32 +08:00
2012-01-30 15:22:42 +08:00
/** actual command to pass to exec in case of EXTERNAL or INTERNAL_EXEC. malloc'd! */
2012-01-30 14:06:58 +08:00
const wchar_t * actual_cmd ;
2007-08-01 05:23:32 +08:00
2005-10-21 19:59:45 +08:00
/** process ID */
pid_t pid ;
2007-08-01 05:23:32 +08:00
2005-10-07 22:08:57 +08:00
/** File descriptor that pipe output should bind to */
2007-01-07 22:10:52 +08:00
int pipe_write_fd ;
2007-08-01 05:23:32 +08:00
2007-01-07 22:10:52 +08:00
/** File descriptor that the _next_ process pipe input should bind to */
int pipe_read_fd ;
2007-08-01 05:23:32 +08:00
2005-09-20 21:26:39 +08:00
/** true if process has completed */
volatile int completed ;
2007-08-01 05:23:32 +08:00
2005-09-20 21:26:39 +08:00
/** true if process has stopped */
volatile int stopped ;
2007-08-01 05:23:32 +08:00
2005-09-20 21:26:39 +08:00
/** reported status value */
volatile int status ;
2007-08-01 05:23:32 +08:00
/** Special flag to tell the evaluation function for count to print the help information */
int count_help_magic ;
2012-01-30 14:06:58 +08:00
/** Next process in pipeline. We own this and we are responsible for deleting it. */
struct process_t * next ;
2005-09-20 21:26:39 +08:00
# 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 */
2011-12-27 11:18:46 +08:00
unsigned long last_jiffies ;
2005-09-20 21:26:39 +08:00
# endif
2012-01-30 10:25:54 +08:00
} ;
2005-09-20 21:26:39 +08:00
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
true if user was told about stopped job
2006-10-26 04:47:59 +08:00
*/
# define JOB_NOTIFIED 1
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
Whether this job is in the foreground
2006-10-26 04:47:59 +08:00
*/
# define JOB_FOREGROUND 2
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
Whether the specified job is completely constructed ,
i . e . completely parsed , and every process in the job has been
forked , etc .
*/
# define JOB_CONSTRUCTED 4
/**
Constant for the flag variable in the job struct
Whether the specified job is a part of a subshell , event handler or some other form of special job that should not be reported
*/
# define JOB_SKIP_NOTIFICATION 8
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
Should the exit status be negated ? This flag can only be set by the not builtin .
2006-10-26 04:47:59 +08:00
*/
# define JOB_NEGATE 16
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
This flag is set to one on wildcard expansion errors . It means that the current command should not be executed
2006-10-26 04:47:59 +08:00
*/
# define JOB_WILDCARD_ERROR 32
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
Skip executing this job . This flag is set by the short - circut builtins , i . e . and and or
2006-10-26 04:47:59 +08:00
*/
# define JOB_SKIP 64
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
Whether the job is under job control
2006-10-26 04:47:59 +08:00
*/
# define JOB_CONTROL 128
2011-12-27 11:18:46 +08:00
/**
2006-10-26 04:47:59 +08:00
Constant for the flag variable in the job struct
2011-12-27 11:18:46 +08:00
Whether the job wants to own the terminal when in the foreground
2006-10-26 04:47:59 +08:00
*/
# define JOB_TERMINAL 256
2005-09-20 21:26:39 +08:00
2011-12-27 11:18:46 +08:00
/**
2008-01-09 09:23:38 +08:00
A struct represeting a job . A job is basically a pipeline of one
or more processes and a couple of flags .
*/
2012-01-30 08:36:21 +08:00
class job_t
2005-09-20 21:26:39 +08:00
{
2012-01-30 08:36:21 +08:00
public :
2012-01-30 10:25:54 +08:00
job_t ( int jobid ) :
2012-01-30 14:06:58 +08:00
command ( ) ,
2012-01-30 10:25:54 +08:00
first_process ( NULL ) ,
pgid ( 0 ) ,
tmodes ( ) ,
job_id ( jobid ) ,
io ( NULL ) ,
flags ( 0 )
{
}
2012-01-30 14:06:58 +08:00
~ job_t ( ) {
if ( first_process ! = NULL )
delete first_process ;
2012-02-10 10:43:36 +08:00
io_data_t * data = this - > io ;
while ( data ) {
io_data_t * tmp = data - > next ;
delete data ;
data = tmp ;
}
2012-01-30 14:06:58 +08:00
}
2012-01-30 10:25:54 +08:00
2011-12-27 11:18:46 +08:00
/**
2008-01-09 09:23:38 +08:00
The original command which led to the creation of this
job . It is used for displaying messages about job status
on the terminal .
*/
2012-01-30 14:06:58 +08:00
wcstring command ;
const wchar_t * command_cstr ( ) const { return command . c_str ( ) ; }
2011-12-27 11:18:46 +08:00
/**
2012-01-30 14:06:58 +08:00
A linked list of all the processes in this job . We are responsible for deleting this when we are deallocated .
2008-01-09 09:23:38 +08:00
*/
2012-01-30 10:25:54 +08:00
process_t * first_process ;
2011-12-27 11:18:46 +08:00
/**
2008-01-09 09:23:38 +08:00
process group ID for the process group that this job is
2011-12-27 11:18:46 +08:00
running in .
2008-01-09 09:23:38 +08:00
*/
2011-12-27 11:18:46 +08:00
pid_t pgid ;
/**
2008-01-09 09:23:38 +08:00
The saved terminal modes of this job . This needs to be
saved so that we can restore the terminal to the same
state after temporarily taking control over the terminal
2011-12-27 11:18:46 +08:00
when a job stops .
2008-01-09 09:23:38 +08:00
*/
struct termios tmodes ;
2011-12-27 11:18:46 +08:00
2008-01-09 09:23:38 +08:00
/**
The job id of the job . This is a small integer that is a
unique identifier of the job within this shell , and is
used e . g . in process expansion .
*/
2012-01-30 10:25:54 +08:00
const int job_id ;
2011-12-27 11:18:46 +08:00
2008-01-09 09:23:38 +08:00
/**
2012-02-10 10:43:36 +08:00
List of all IO redirections for this job . This linked list is allocated via new , and owned by the object , which should delete them .
2008-01-09 09:23:38 +08:00
*/
2005-09-20 21:26:39 +08:00
io_data_t * io ;
2006-10-26 04:47:59 +08:00
/**
Bitset containing information about the job . A combination of the JOB_ * constants .
*/
int flags ;
2011-12-27 11:18:46 +08:00
2012-01-30 08:36:21 +08:00
} ;
2005-09-20 21:26:39 +08:00
2011-12-27 11:18:46 +08:00
/**
Whether we are running a subshell command
2005-12-15 21:59:02 +08:00
*/
2005-09-20 21:26:39 +08:00
extern int is_subshell ;
2005-12-15 21:59:02 +08:00
2011-12-27 11:18:46 +08:00
/**
Whether we are running a block of commands
2005-12-15 21:59:02 +08:00
*/
2005-09-20 21:26:39 +08:00
extern int is_block ;
2005-12-15 21:59:02 +08:00
2011-12-27 11:18:46 +08:00
/**
2005-12-15 21:59:02 +08:00
Whether we are reading from the keyboard right now
*/
2012-02-26 10:54:49 +08:00
int get_is_interactive ( void ) ;
2005-12-15 21:59:02 +08:00
2011-12-27 11:18:46 +08:00
/**
2005-12-15 21:59:02 +08:00
Whether this shell is attached to the keyboard at all
*/
2005-09-20 21:26:39 +08:00
extern int is_interactive_session ;
2005-12-15 21:59:02 +08:00
2011-12-27 11:18:46 +08:00
/**
2005-12-15 21:59:02 +08:00
Whether we are a login shell
*/
2005-09-20 21:26:39 +08:00
extern int is_login ;
2005-12-15 21:59:02 +08:00
2011-12-27 11:18:46 +08:00
/**
2008-01-09 09:23:38 +08:00
Whether we are running an event handler
2005-12-15 21:59:02 +08:00
*/
2005-10-06 06:37:08 +08:00
extern int is_event ;
2005-12-15 21:59:02 +08:00
2012-01-30 08:36:21 +08:00
/** List of all living jobs */
typedef std : : list < job_t * > job_list_t ;
job_list_t & job_list ( void ) ;
/** A class to aid iteration over jobs list */
class job_iterator_t {
job_list_t : : iterator current , end ;
public :
void reset ( void ) {
job_list_t & jobs = job_list ( ) ;
this - > current = jobs . begin ( ) ;
this - > end = jobs . end ( ) ;
}
job_t * next ( ) {
job_t * job = NULL ;
if ( current ! = end ) {
job = * current ;
+ + current ;
}
return job ;
}
job_iterator_t ( ) {
this - > reset ( ) ;
}
} ;
2005-09-20 21:26:39 +08:00
2005-09-24 07:15:38 +08:00
/**
Whether a universal variable barrier roundtrip has already been
2008-01-09 09:23:38 +08:00
made for the currently executing command . Such a roundtrip only
needs to be done once on a given command , unless a universal
variable value is changed . Once this has been done , this variable
is set to 1 , so that no more roundtrips need to be done .
2005-09-24 07:15:38 +08:00
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 21:26:39 +08:00
2006-01-24 04:40:14 +08:00
/**
Pid of last process to be started in the background
*/
2005-09-20 21:26:39 +08:00
extern pid_t proc_last_bg_pid ;
2006-01-31 01:54:26 +08:00
/**
2008-01-09 09:23:38 +08:00
The current job control mode .
Must be one of JOB_CONTROL_ALL , JOB_CONTROL_INTERACTIVE and JOB_CONTROL_NONE
2006-01-31 01:54:26 +08:00
*/
extern int job_control_mode ;
2006-03-18 09:04:59 +08:00
/**
2008-01-09 09:23:38 +08:00
If this flag is set , fish will never fork or run execve . It is used
to put fish into a syntax verifier mode where fish tries to validate
the syntax of a file but doesn ' t actually do anything .
*/
2006-03-18 09:04:59 +08:00
extern int no_exec ;
2008-01-09 09:23:38 +08:00
/**
Add the specified flag to the bitset of flags for the specified job
*/
2006-10-26 04:47:59 +08:00
void job_set_flag ( job_t * j , int flag , int set ) ;
2008-01-09 09:23:38 +08:00
/**
Returns one if the specified flag is set in the specified job , 0 otherwise .
*/
2006-10-26 04:47:59 +08:00
int job_get_flag ( job_t * j , int flag ) ;
2006-03-18 09:04:59 +08:00
2005-09-20 21:26:39 +08:00
/**
Sets the status of the last process to exit
*/
void proc_set_last_status ( int s ) ;
2005-12-15 21:59:02 +08:00
2005-09-20 21:26:39 +08: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 21:59:02 +08:00
2012-01-30 08:36:21 +08:00
/**
Promotes a job to the front of the job list .
*/
void job_promote ( job_t * job ) ;
2005-09-20 21:26:39 +08:00
/**
2012-02-16 16:24:27 +08:00
Create a new job .
2005-09-20 21:26:39 +08:00
*/
job_t * job_create ( ) ;
/**
Return the job with the specified job id .
2006-04-28 21:21:37 +08:00
If id is 0 or less , return the last job used .
2005-09-20 21:26:39 +08:00
*/
job_t * job_get ( int id ) ;
2012-01-30 08:36:21 +08:00
2005-09-20 21:26:39 +08:00
/**
Return the job with the specified pid .
*/
job_t * job_get_from_pid ( int pid ) ;
/**
2011-12-27 11:18:46 +08:00
Tests if the job is stopped
2005-09-20 21:26:39 +08:00
*/
int job_is_stopped ( const job_t * j ) ;
/**
2006-07-07 23:35:39 +08:00
Tests if the job has completed , i . e . if the last process of the pipeline has ended .
2005-09-20 21:26:39 +08:00
*/
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 21:59:02 +08:00
2005-09-20 21:26:39 +08:00
/**
2006-06-05 08:42:01 +08:00
Notify the user about stopped or terminated jobs . Delete terminated
jobs from the job list .
2005-10-12 03:23:43 +08:00
\ param interactive whether interactive jobs should be reaped as well
2005-09-20 21:26:39 +08:00
*/
2012-02-16 16:24:27 +08:00
int job_reap ( bool interactive ) ;
2005-12-15 21:59:02 +08:00
2005-09-20 21:26:39 +08:00
/**
2006-06-05 08:42:01 +08:00
Signal handler for SIGCHLD . Mark any processes with relevant
2005-09-20 21:26:39 +08:00
information .
*/
void job_handle_signal ( int signal , siginfo_t * info , void * con ) ;
2006-11-20 21:12:24 +08:00
/**
Send the specified signal to all processes in the specified job .
*/
int job_signal ( job_t * j , int signal ) ;
2005-09-20 21:26:39 +08:00
# 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-04 03:46:18 +08:00
/**
2006-05-03 00:29:50 +08:00
Send a process / job exit event notification . This function is a
conveniance wrapper around event_fire ( ) .
2005-12-04 03:46:18 +08:00
*/
void proc_fire_event ( const wchar_t * msg , int type , pid_t pid , int status ) ;
2006-01-24 04:40:14 +08:00
/**
2005-10-14 19:40:33 +08:00
Initializations
*/
void proc_init ( ) ;
/**
Clean up before exiting
*/
void proc_destroy ( ) ;
2006-02-16 21:36:32 +08: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 ( ) ;
2009-02-22 00:46:56 +08:00
/**
Format an exit status code as returned by e . g . wait into a fish exit code number as accepted by proc_set_last_status .
*/
int proc_format_status ( int status ) ;
2005-10-04 23:11:39 +08:00
# endif