Processes

Information stored in the process:
Field Meaning
rUID the real user ID (UID of parent)
rGID the real group ID (GID of parent)
eUID the effective user ID (changed on setuid bit or seteuid)
eGID the effective group ID (changed on setgid bit or setegid)
saved set-UIC
saved set-GIC
PGID Process group ID: process ID which identifies multiple processes and is the PID of the lead (ancestor) process
SID Session ID: process ID which identfies multiple processes which are part of the same terminal session
Additional GIDs a user can belong to multiple groups
Current directory current working directory inode id
Root directory root directory inode id
Signal handling pending signals, signal handlers, blocking during signal handlers
Blocked signals set of signals which are blocked
Umask set of permissions which are removed from created files
Nice value priority level of the process
Controlling Termininal Terminal associated with process

Ordinary users cannot change UID/GID except from the set of UIDs/GIDs (effective, real, or saved) or via setuid/setgid bit.

Process creation and management

New process creation

The initial process init is created by the kernel. All other processes are created from some process by a fork. On a fork, a new process is cloned from the original process (including the u area). The cloned process is called the child, the original process is called the parent.

The child differs from the parent in the following way:

Calls

The process management calls are:

fork

prototype:

pid_t fork(void);

If the fork succeeds, it returns 0 to the child, and the PID of the child to the parent.

If the fork fails, it returns -1 and sets the value errno with the value:

POSIX defines the maximum number of processes that can exist in a system (MAXPID) and for a single user (CHILD_MAX).

Clearly, a new process means copying over the u area, and inserting a new process in the process table. There are three parts of the process which reside in user space:

The text region, like file table entries, are shared (since they are read-only). Stack and data are not, and logically need to be copied, even though most likely a forked process will exec a different executable, replacing all the regions associated with the parent.

To save extraneous copies, a common implementation technique is copy-on-write in which the child shares read only copies of all regions. If the process writes a read-only region, a copy is then made with write permission.

_exit

The exit call terminates a process, freeing up the regions associated with the process (user memory), closing file descriptors, and releasing the u area. However, the process table entry remains intact. A process without u area but with a process table entry is called a zombie.

void _exit(int exit_code)

where the lower 8 bits of exit code is the value returned for the process. By convention, 0 indicates a successful termination.

Usually, users call exit, which performs the following functions:

Removing zombies

If a child process, c, dies before its parent, than c becomes a child of init. To remove the zombied process, a wait (or waitpid) must be performed by the parent.

pid_t wait(int *status_p);

pid_t waitpid(pid_t child_pid, int *status_p, int options);

Returns the process id of the child process, or -1 on failure. The parameters are:

The errno for wait/waitpid are: waitpid can be either blocking or non-blocking, and can wait for any child that is stopped due to job control.

Rather than use the bit positions, you should use the following macros:

exec

There are several different exec calls, enabling: The exec system call does the following: If the exec succeeds: Note that fork and exec are seperate calls, increasing the flexibility and enabling actions to occur between the fork and exec.

Race conditions, etc.

Process fork, wait and exec are a very effective means of building multi-process applications. We shall see when we get to networked machines, that these conditions do not hold.

Process groups

A process group is a set of process with the same PGID. The PGID is the PID of the lead process.

This is the primary mechanism for dealing with groups of processes.

#include 
#include 

pid_t setpgp(void);
pid_t getpgid(void);
The setpgp sets the process group id to the PID.

The getpgid returns the process group ID.

Sessions

A session contain one or more process groups
#include 
#include 

pid_t setsid(void);
The setsid sets the session Id and pocess group id to the PID.

Other API's

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);       // get process id
pid_t getppid(void);      // get parent process id
pid_t getuid(void);       // get real user id
pid_t getgid(void);       // get real group id
pid_t geteuid(void);      // get effective user id
pid_t getegid(void);      // get effective group id
pid_t setuid(uid_t uid);  // get real user id
pid_t setgid(gid_t gid);  // get real group id
pid_t seteuid(uid_t uid); // get effective user id
pid_t setegid(gid_t gid); // get effective group id
Notes: