New Document
Process creation
  • Unless the system is being bootstrapped a process can only come into existance as the child of another process. This done by the fork system call.
  • The first process created is "hand tooled" by the boot process. This is the swapper process.
  • The swapper process creates the init process, which is the ancestor of all further processes. In particular, init forks off a process getty, which monitors terminal lines and allows users to log in.
  • Upon login, the command shell is run as the first process. The command shell for a given user is specified in the /etc/passwd file. From thereon, any process may fork to produce new processes, considered to be children of the forking process.
The process table and uarea
  • Information about processes is described in two data structures, the kernel process table and a "uarea" associated with each process.
  • The process table holds information required by the kernel
  • The uarea holds information required by the process itself.
  • The process table entry for a process holds (amongst other things):
  • Process state Several process IDs Several user IDs for determining process priviledges Pointer to text structure for shared text areas Pointer to page table for memory management Scheduling parameters, including the "nice" value which determines priority Timers for resource usage A pointer to the process uarea
  • The uarea of a process contains (amongst other things):
  • Real and effective user IDs Current working directory Timer fields to hold accumulated user and kernel mode time Information an how to react to signals Identification of any associated control terminal Identification of data areas relevant to IO activity Return values and error conditions from system calls Information on the file system environment of the process The user file descriptor table
Process IDs
  • There are three IDs associated with every process, the ID of the process itself (the PID), its parent process's ID (the PPID) and its process group ID (the PGID).
  • Every UNIX process has a unique PID in the range 0 to 30000.
  • The PID 0 is reserved for the swapper process, and 1 for the init process.
  • A process can get hold of its PID and PPID with the getpid and getppid calls.
  • int getpid(void)
    int getppid(void)
  • Process group IDs
  • UNIX provides a PGID that is used to group processes together. The PGID of a process may be obtained with int getpgrp(void) A process initially belongs to its parent's group, but new groups may be established with int setpgid(pid_t pid, pid_t pgid) Sets the process group ID of the process with ID pid to pgid. If pid is equal to 0, the process ID of the calling process is used. Groups may have a control terminal which is the first tty device opened by the group leader. Initially the group leader is the shell, and the login device is the control terminal. A new group that is started is not attached to the previous control terminal (if any). Interupt, quit and hangup signals from a terminal go to all process associated with that terminal. For example all processes that start from one given terminal belong to the same group. Then if the terminal goes down it's possible to find all its processes.

  • ProcessIDs.c - Program to play with PIDs
User IDs
  • Every process has a real user ID (the UID), an effective user ID (the EUID), a real user group ID (the GID), and an effective user group ID (the EGID). The user group ID is distinct from the process group ID.
  • The real IDs are used for accounting and user-user communication, while the effective IDs are used to control access to files and control signal sending.
  • A user ID is associated with each user login name in the password file /etc/passwd. This is assigned to the user's shell as its UID and EUID, and is inherited by processes spawned from the shell.
  • The user IDs can be accessed with the system calls: int getuid(void) which gets the UID of the process, and int geteuid(void) which gets the EUID of the process.
  • Each entry in /etc/passwd also has a group ID which is given to the shell as its initial GID and EGID.
  • The group IDs can be accessed with the system calls: int getgid(void) which gets the GID of the process and int getegid() which gets the EGID of the process.
  • Only the superuser may change the user IDs of a process, using the system calls: int setuid(int uid) which sets the UID and EUID, and int setgid(int gid) which sets the GID and EGID. Both calls return 0 on success, or -1 on error.
  • Ordinary users may change effective IDs to real IDs, by using these calls with the arguments equal to the real IDs.
  • UserIDs.c - Program to play with user IDs
The environment of a process
  • The environment of a process includes details of the home directory, path names to be searched for the program, the type of terminal being used, the user name, the shell being run, etc.
  • The environment of a program is held in strings which have the format =, e.g.
  • HOME=/usr/spg/geoff
    TERM=/tvi950
    PATH=/usr/bin:/usr/spg/geoff/bin
  • The environment of a program can be examined by looking at the system external variable environ, which is an array of char pointers: extern char *environ[]; A NULL pointer signifies the last such string.
  • The program may explicitly receive the environment strings as a third parameter to main. This parameter is an array of char pointers. int main(int argc,char *argv[],char *env[])
  • The value of a environment keyword can be examined with the getenv call: char *getenv(char keyword[]); getenv returns a pointer to the string value, or NULL if no value is specified.
  • The value of a environment keyword can be set with the setenv call: int setenv(char *name,char *value,int overwrite);
  • An environmeent variable can be deleted using the unsetenv call:
  • HOME=/usr/spg/geoff
    unsetenv(char *name);
  • Environment.c - Program to examine environment strings
Signals
  • A signal interrupts a process.
  • Signals are defined in signal.h. Basic ones are:
  •     SIGHUP: #1 - hangup (modem)
        SIGINT: #2 - interrupt (rubout key)
        SIGQUIT: #3 - quit (FS control \ key)
        SIGILL: #4 - illegal instruction
        SIGTRAP: #5 - trace or breakpoint
        SIGABRT: #6 - abort()
        SIGEMT: #7 - emulator trap instruction
        SIGFPE: #8 - floating point exception
        SIGKILL: #9 - kill, uncatchable quit
        SIGBUS: #10 - bus error
        SIGSEGV: #11 - segmentation violation
        SIGSYS: #12 - bad system call
        SIGPIPE: #13 - end of pipe
        SIGALRM: #14 - alarm clock
        SIGTERM: #15 - catchable termination
        SIGURG: #16 - urgent condition on IO channel
        SIGSTOP: #17 - sendable stop signal not from tty
        SIGTSTP: #18 - stop signal from tty
        SIGCONT: #19 - continue a stopped process
        SIGCHLD: #20 - child death (or stopped under Linux)
        SIGTTIN: #21 - to readers pgrp upon background tty read
        SIGTTOU: #22 - like TTIN for output
        SIGIO: #23 - input/output possible signal
        SIGXCPU: #24 - exceeded CPU time limit
        SIGXFSZ: #25 - exceeded file size limit
        SIGVTALRM: #26 - virtual time alarm
        SIGPROF: #27 - profiling time alarm
        SIGWINCH: #28 - window size changes
        SIGINFO: #29 - information request
        SIGUSR1: #30 - user defined signal 1
        SIGUSR2: #31 - user defined signal 2 
  • Signals have 6 basic sources
  • User typing control characters at the keyboard. These signals are sent to all processes in the group associated with the terminal - SIGHUP, SIGINT, SIGQUIT. Software errors - SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGSYS, SIGPIPE. Hardware errors - SIGEMT, SIGBUS, SIGSEGV. The alarm system call - SIGALRM The kill system call (see below) - All signals External events - SIGCHLD, SIGURG, SIGIO, SIGXCPU, SIGXFSZ, SIGWINCH, SIGINFO.

  • Signals either caught, ignored or terminate the process.
  • Signals either caught, ignored or terminate the process.
  • The signal system call The signal system call can be used to instruct receiving processes on how to deal with a signal. This associates a function with a given signal.
  • void (*signal(int TheSignal,void (*Function)(int)))(int);
    The pause system call
    
        The pause system call
        void pause(void);
    
  • Signal.c - Program that catches keyboard interrupts
  • The SIGKILL and SIGSTOP signals cannot be caught or ignored
  • Child processes inherit signal handling
The kill system call
int kill(int PID,int Signal);
kill sends the Signal to all processes identified by the PID, where the values are:

    +ve - process with the ID
    0 - processes with group ID equal to process ID of sender.
    -1 - if the EUID is super user then all processes, otherwise processes whose UID equals the EUID of sender.
    < -1 - processes whose GID is the absolute of the PID 

Returns -1 on error, 0 on success 
Process resource usage
  • Need to include sys/time.h, sys/resource.h, and unistd.h.
  • int getrlimit(int resource, struct rlimit *rlim); - Get the processes resource limits. resource is one of:
  •     RLIMIT_CPU - CPU time in seconds
        RLIMIT_FSIZE - Maximum filesize
        RLIMIT_DATA - max data size
        RLIMIT_STACK - max stack size
        RLIMIT_CORE - max core file size
        RLIMIT_RSS - max resident set size
        RLIMIT_NPROC - max number of processes
        RLIMIT_NOFILE - max number of open files
        RLIMIT_MEMLOCK - max locked-in-memory address space
        RLIMIT_AS - address space (virtual memory) limit 
Previous                                                                                                                                                       Next

Back to Top