proc.c File Reference

Utilities for keeping track of jobs, processes and subshells, as well as signal handling functions for tracking children. More...

#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <wchar.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>
#include <dirent.h>
#include <sys/time.h>
#include <ncurses.h>
#include <termio.h>
#include <term.h>
#include <sys/select.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "proc.h"
#include "common.h"
#include "reader.h"
#include "sanity.h"
#include "env.h"
#include "parser.h"
#include "event.h"
#include "halloc.h"
#include "halloc_util.h"
#include "output.h"

Defines

#define MESS_SIZE   256
 Size of message buffer.
#define BUFFER_SIZE   4096
 Size of buffer for reading buffered output.
#define FN_SIZE   256
 Maximum length of a /proc/[PID]/stat filename.

Functions

void proc_init ()
 Initializations.
static int job_remove (job_t *j)
 Remove job from list of jobs.
void job_free (job_t *j)
 Remove the specified job.
void proc_destroy ()
 Clean up before exiting.
void proc_set_last_status (int s)
 Sets the status of the last process to exit.
int proc_get_last_status ()
 Returns the status of the last process to exit.
job_tjob_create ()
 Create a new job.
job_tjob_get (int id)
 Return the job with the specified job id.
job_tjob_get_from_pid (int pid)
 Return the job with the specified pid.
int job_is_stopped (const job_t *j)
 Tests if the job is stopped.
int job_is_completed (const job_t *j)
 Tests if the job has completed, i.e.
void job_set_flag (job_t *j, int flag, int set)
 Add the specified flag to the bitset of flags for the specified job.
int job_get_flag (job_t *j, int flag)
 Returns one if the specified flag is set in the specified job, 0 otherwise.
int job_signal (job_t *j, int signal)
 Send the specified signal to all processes in the specified job.
static void mark_process_status (job_t *j, process_t *p, int status)
 Store the status of the process pid that was returned by waitpid.
static void handle_child_status (pid_t pid, int status)
 Handle status update for child pid.
void job_handle_signal (int signal, siginfo_t *info, void *con)
 Signal handler for SIGCHLD.
static void format_job_info (const job_t *j, const wchar_t *status)
 Format information about job status for the user to look at.
void proc_fire_event (const wchar_t *msg, int type, pid_t pid, int status)
 Send a process/job exit event notification.
int job_reap (int interactive)
 Notify the user about stopped or terminated jobs.
unsigned long proc_get_jiffies (process_t *p)
 Get the CPU time for the specified process.
void proc_update_jiffies ()
 Update the CPU time for all jobs.
static int select_try (job_t *j)
 Check if there are buffers associated with the job, and select on them for a while if available.
static void read_try (job_t *j)
 Read from descriptors until they are empty.
static int terminal_give_to_job (job_t *j, int cont)
 Give ownership of the terminal to the specified job.
static int terminal_return_from_job (job_t *j)
 Returns contol of the terminal to the shell, and saves the terminal attribute state to the job, so that we can restore the terminal ownership to the job at a later time .
void job_continue (job_t *j, int cont)
 Reassume a (possibly) stopped job.
int proc_format_status (int status)
 Format an exit status code as returned by e.g.
void proc_sanity_check ()
 Perform a set of simple sanity checks on the job list.
void proc_push_interactive (int value)
 Set new value for is_interactive flag, saving previous value.
void proc_pop_interactive ()
 Set is_interactive flag to the previous value.

Variables

static int last_status = 0
 Status of last process to exit.
static sig_atomic_t got_signal = 0
 Signal flag.
job_tfirst_job = 0
 Linked list of all living jobs.
int is_interactive = -1
 Whether we are reading from the keyboard right now.
int is_interactive_session = 0
 Whether this shell is attached to the keyboard at all.
int is_subshell = 0
 Whether we are running a subshell command.
int is_block = 0
 Whether we are running a block of commands.
int is_login = 0
 Whether we are a login shell.
int is_event = 0
 Whether we are running an event handler.
int proc_had_barrier
 Whether a universal variable barrier roundtrip has already been made for the currently executing command.
pid_t proc_last_bg_pid = 0
 Pid of last process to be started in the background.
int job_control_mode = JOB_CONTROL_INTERACTIVE
 The current job control mode.
int no_exec = 0
 If this flag is set, fish will never fork or run execve.
static event_t event
 The event variable used to send all process event.
static string_buffer_t event_pid
 Stringbuffer used to create arguments when firing events.
static string_buffer_t event_status
 Stringbuffer used to create arguments when firing events.
static array_list_tinteractive_stack
 A stack containing the values of is_interactive.


Detailed Description

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.

Some of the code in this file is based on code from the Glibc manual.


Function Documentation

static void format_job_info ( const job_t j,
const wchar_t *  status 
) [static]

Format information about job status for the user to look at.

Parameters:
j the job to test
status a string description of the job exit type

References _, job::command, job::job_id, and writeb().

Referenced by job_reap().

static void handle_child_status ( pid_t  pid,
int  status 
) [static]

Handle status update for child pid.

This function is called by the signal handler, so it mustn't use malloc or any such hitech nonsense.

Parameters:
pid the pid of the process whose status changes
status the status as returned by wait

References process::completed, current_block, job::first_process, is_interactive_session, mark_process_status(), process::next, job::next, block::outer, process::pid, and block::skip.

Referenced by job_continue(), and job_handle_signal().

void job_continue ( job_t j,
int  cont 
)

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.

Parameters:
j The job
cont Whether the function should wait for the job to complete before returning

References CHECK_BLOCK, job::command, debug(), job::first_process, got_signal, handle_child_status(), is_interactive, JOB_CONTROL, JOB_FOREGROUND, job_get_flag(), job::job_id, job_is_completed(), job_is_stopped(), JOB_NEGATE, JOB_NOTIFIED, job_remove(), job_set_flag(), JOB_TERMINAL, process::next, job::next, job::pgid, process::pid, proc_format_status(), proc_set_last_status(), quit, read_try(), reader_exit_forced(), select_try(), signal_block(), signal_unblock(), process::status, process::stopped, terminal_give_to_job(), terminal_return_from_job(), and wperror().

Referenced by builtin_fg(), exec(), and send_to_bg().

job_t* job_create (  ) 

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.

References halloc(), is_interactive, JOB_CONTROL, job_control_mode, job_get(), job::job_id, job_set_flag(), and job::next.

Referenced by eval_job().

job_t* job_get ( int  id  ) 

Return the job with the specified job id.

If id is 0 or less, return the last job used.

References job::job_id, and job::next.

Referenced by event_get_desc(), find_process(), functions_def(), and job_create().

void job_handle_signal ( int  signal,
siginfo_t *  info,
void *  con 
)

Signal handler for SIGCHLD.

Mark any processes with relevant information.

References got_signal, and handle_child_status().

Referenced by handle_chld().

int job_is_completed ( const job_t j  ) 

Tests if the job has completed, i.e.

if the last process of the pipeline has ended.

References process::completed, job::first_process, and process::next.

Referenced by builtin_bg(), builtin_fg(), builtin_jobs(), handle_end_loop(), job_continue(), job_reap(), and proc_sanity_check().

int job_reap ( int  interactive  ) 

static void mark_process_status ( job_t j,
process_t p,
int  status 
) [static]

Store the status of the process pid that was returned by waitpid.

Return 0 if all went well, nonzero otherwise.

References process::completed, MESS_SIZE, process::pid, process::status, and process::stopped.

Referenced by handle_child_status().

void proc_fire_event ( const wchar_t *  msg,
int  type,
pid_t  pid,
int  status 
)

Send a process/job exit event notification.

This function is a conveniance wrapper around event_fire().

References al_push(), al_truncate(), event_t::arguments, buffer::buff, event_fire(), sb_clear(), and sb_printf().

Referenced by job_reap(), and main().

int proc_format_status ( int  status  ) 

Format an exit status code as returned by e.g.

wait into a fish exit code number as accepted by proc_set_last_status.

Referenced by exec(), and job_continue().

void proc_pop_interactive (  ) 

Set is_interactive flag to the previous value.

If needed, update signal handlers.

References al_pop_long(), is_interactive, and signal_set_handlers().

Referenced by builtin_read(), complete_from_args(), eval_args(), event_fire_internal(), exec_prompt(), reader_read(), and reader_write_title().

void proc_push_interactive ( int  value  ) 

Set new value for is_interactive flag, saving previous value.

If needed, update signal handlers.

References al_push_long(), is_interactive, and signal_set_handlers().

Referenced by builtin_read(), complete_from_args(), eval_args(), event_fire_internal(), exec_prompt(), proc_init(), reader_read(), and reader_write_title().

void proc_sanity_check (  ) 

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.

References _, process::actual_cmd, process::argv, job::command, process::completed, debug(), job::first_process, JOB_CONSTRUCTED, JOB_FOREGROUND, job_get_flag(), job_is_completed(), job_is_stopped(), process::next, job::next, sanity_lose(), process::stopped, and validate_pointer().

Referenced by sanity_check().

static void read_try ( job_t j  )  [static]

Read from descriptors until they are empty.

Parameters:
j the job to test

References _, b_append(), buff, BUFFER_SIZE, job::command, debug(), job::io, io_data::io_mode, io_data::next, io_data::out_buffer, io_data::param1, io_data::param2, io_data::pipe_fd, read_blocked(), and wperror().

Referenced by job_continue().

static int select_try ( job_t j  )  [static]

Check if there are buffers associated with the job, and select on them for a while if available.

Parameters:
j the job to test
Returns:
1 if buffers were avaialble, zero otherwise

References debug(), job::io, io_data::io_mode, maxi(), io_data::next, io_data::param1, and io_data::pipe_fd.

Referenced by job_continue().

static int terminal_give_to_job ( job_t j,
int  cont 
) [static]

Give ownership of the terminal to the specified job.

Parameters:
j The job to give the terminal to.
cont If this variable is set, we are giving back control to a job that has previously been stopped. In that case, we need to set the terminal attributes to those saved in the job.

References _, job::command, debug(), job::job_id, job::pgid, job::tmodes, and wperror().

Referenced by job_continue().


Variable Documentation

A stack containing the values of is_interactive.

Used by proc_push_interactive and proc_pop_interactive.

int job_control_mode = JOB_CONTROL_INTERACTIVE

The current job control mode.

Must be one of JOB_CONTROL_ALL, JOB_CONTROL_INTERACTIVE and JOB_CONTROL_NONE

Referenced by builtin_status(), and job_create().

int no_exec = 0

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.

Referenced by exec(), fish_parse_opt(), and main().

Whether a universal variable barrier roundtrip has already been 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.

Both setting it to one when it should be zero and the opposite may cause concurrency bugs.

Referenced by env_exist(), env_export_arr(), env_get(), env_set(), and eval_job().


Generated on Sun Mar 8 15:46:55 2009 for fish by  doxygen 1.5.6