A process, also known as a task under Linux, is a
	running instance of a program. This means that if 10 users on
	a server are all using the same program, such as
	emacs, there are 10 emacs processes
	running on the server, although they all share the same
	executable code.
	
	The processes on a UNIX system can be viewed using the
	ps command:
	
[ealtieri@italia labos]$ ps -e
  PID TTY          TIME CMD
    1 ?        00:00:04 init
    2 ?        00:00:00 keventd
    3 ?        00:00:00 ksoftirqd_CPU0
    4 ?        00:00:00 kswapd
    5 ?        00:00:00 bdflush
    6 ?        00:00:00 kupdated
    8 ?        00:00:00 khubd
    9 ?        00:00:00 kjournald
   14 ?        00:00:00 devfsd
  128 ?        00:00:00 kjournald
  ...          ...      ...
 2322 pts/1    00:00:05 emacs
 2421 pts/2    00:00:07 emacs
 2922 ?        00:00:00 aterm
 2923 pts/3    00:00:00 bash
 2979 pts/3    00:00:00 emacs
 2981 pts/3    00:00:00 ps
        
	The -e option tells the command to show all of
	the processes on the system. Without this option, the command
	shows only the processes on the current terminal.
	
	In the example above, the CMD column identifies
	the name of the running process, such as "emacs".
	The first column indicates the process identifier (PID)
	assigned to the process by the operating system. The second
	column shows the terminal associated with a process, or "?" if
	the process is not associated with any terminal (e.g. it's a
	terminal itself!).  Finally, the third column shows the CPU
	time of the process.
	
	We can see from the example above that there are three
	emacs processes running at the same time. Each of
	them corresponds to an emacs window on the screen.  These
	processes have PIDs 2322, 2421 and 2979. Also notice the
	ps command at the end of the list. This is
	because the command itself is of course a process too.
	
	The process ID (PID) is a unique identifier for a process. The
	operating system uses a 32-bit counter last_pid
	to keep track of the last PID assigned to a process. When a
	process is created, the counter is increased and its value
	becomes the PID of the new process. Because the counter may
	wrap around at some point, the kernel needs to check if the
	value of last_pid++ already belongs to a task,
	before it can assign it to a new process.
	
	More information about the process list can be displayed using the
	-l option of the ps command.
	
[ealtieri@italia os]$ ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 000 S 500 1518 1517 0 75 0 - 645 11cf00 pts/1 00:00:00 bash 000 S 500 1549 1518 0 71 0 - 2557 147d0d pts/1 00:00:02 emacs 000 R 500 1874 1518 0 79 0 - 660 - pts/1 00:00:00 ps
	Recall that without the -e option,
	ps only shows the processes on the current
	terminal, in this case pts/1.
	
The first column (F) of the output above identifies the process flags (see manual page if you are interested). The "S" column indicates the state of a process. Possible state codes are the following:
D   uninterruptible sleep         (TASK_UNINTERRUPTIBLE)
R   runnable (on run queue)       (TASK_RUNNING)
S   sleeping                      (TASK_INTERRUPTIBLE)
T   traced or stopped             (TASK_STOPPED)
Z   a defunct ("zombie") process  (TASK_ZOMBIE)
        
	You will notice that most of the processes on the system are
	sleeping, that is waiting for some kind of event, such as a
	mouse click or a key press. In the example above, the only
	running command is ps.
	
	The output also shows the user owning the process (UID), the
	process identifier (PID), and the
	parent PID (PPID). The PPID identifies the process from
	which a given process originated. For example, you can see
	above that both emacs and ps have
	originated from the same bash shell (PID=1418),
	because their PPIDs are equal to the PID of
	bash. On the other hand, a process that
	originates from another process is called a child
	process.
	
	Thanks to the PPID field, the process list can also be viewed
	as a tree, at the top of which lies the father of
	all of the processes: the init process
	(PID=1). This tree can be viewed with the pstree
	command.
	
[ealtieri@italia os]$ pstree 
init-+-atd
     |-bonobo-moniker-
     |-crond
     ...
     |-evolution-execu
     |-evolution-mail---evolution-mail---5*[evolution-mail]
     |-gconfd-1
     |-gdict
     |-gdm---gdm-+-X
     |           `-gnome-session---ssh-agent
     |-gmc
     |-gnome-name-serv
     |-gnome-smproxy
     |-gpm
     |-gweather
     |-kbdd-+-aterm---bash-+-emacs
     |      |              `-pstree
     |      |-evolution
     |      `-opera---opera---opera
     |-keventd
     ...
        
	In bold you can see the three processes from the previous
	ps output.
	
	Processes whose PPID equals 1 (init) and that do
	not have a controlling terminal are called
	daemons. These processes run in the background and are
	not normally visible to the user.
	
	Another useful command is top. This command
	provides an ongoing look at the processor activity in real
	time. It displays a listing of the most CPU-intensive tasks on
	the system, and can provide an interactive interface for
	manipulating processes. The GUI counterpart of this command,
	called gnome-system-monitor, is shown below.
	

gtop
![]()  | 
	     Q1. Give some examples of daemons running on your computer | 
![]()  | 
	     Q2. Draw the process relationship tree for the following
	     processes. Next to each node of the tree, write the PID
	     of the corresponding process.
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 000 S 500 1492 1491 0 75 0 - 641 11cf00 pts/0 00:00:00 bash 000 S 500 2281 1492 0 69 0 - 2790 147d0d pts/0 00:00:00 emacs 000 S 500 2284 1492 0 69 0 - 767 147d0d pts/0 00:00:00 aterm 000 S 500 2336 1492 0 69 0 - 4282 148496 pts/0 00:00:00 xmms 040 S 500 2337 2336 0 69 0 - 4282 148496 pts/0 00:00:00 xmms 040 S 500 2338 2337 0 69 0 - 4282 147d0d pts/0 00:00:00 xmms 040 S 500 2342 2337 0 69 0 - 4282 121f03 pts/0 00:00:00 xmms 000 S 500 2352 1492 0 69 0 - 554 11cf00 pts/0 00:00:00 opera 000 S 500 2353 2352 1 70 0 - 4597 147d0d pts/0 00:00:01 opera 040 S 500 2354 2353 0 68 0 - 4597 148496 pts/0 00:00:00 opera 000 R 500 2359 1492 0 79 0 - 660 - pts/0 00:00:00 ps  | 
	Signals are sometimes referred to as software
	interrupts. Similarly to hardware interrupts, signals are
	random interruptions in the execution of program that signal
	an event to that program. Examples of events could be a
	segmentation fault caused by the program itself
	(SIGSEGV), or a CTRL-C key combination sent by
	the user (SIGINT). A complete list of signals can
	be viewd by typing "man 7 signal". Signals
	are defined in include/asm/signal.h (line 31).
	
	Signals are sent to a program using the kill command.
	For example:
	
[ealtieri@italia os]$ sleep 20 & [1] 2611 [ealtieri@italia os]$ ps PID TTY TIME CMD 2535 pts/4 00:00:00 bash 2611 pts/4 00:00:00 sleep 2612 pts/4 00:00:00 ps [ealtieri@italia os]$ kill -s SIGINT 2611 [ealtieri@italia os]$ [1]+ Interrupt sleep 20 [ealtieri@italia os]$
	The sleep command creates a process that sleeps
	for 20 seconds and then terminates (the "&" symbol tells
	bash to run the command in the background). We can see this
	process in the output of ps immediately next. We
	then send a CTRL-C signal (SIGINT) to the
	sleep command using kill and the PID
	of sleep. The signal terminates the program. This
	is confirmed by the message that appears on the terminal if
	you press enter once after the kill command has
	been issued.
	
	One of the most useful applications of signals is to request
	the termination of a program. There are two termination
	signals that can be sent to a program: SIGTERM
	and SIGKILL.
	
SIGTERM terminates a process
		nicely. The process has a chance to catch this
		signal and do some cleanup work before
		terminating. However, a process can also choose to
		ignore this signal.SIGKILL terminates a process
		immediately. The process does not have a
		chance to catch this signal. SIGKILL
		should only be used to kill a process that crashed and
		does not respond to the SIGTERM
		signal.
	The following example shows how to kill emacs
	nicely:
	
[ealtieri@italia os]$ emacs & [1] 2695 [ealtieri@italia os]$ ps PID TTY TIME CMD 2535 pts/4 00:00:00 bash 2695 pts/4 00:00:00 emacs 2696 pts/4 00:00:00 ps [ealtieri@italia os]$ kill -s SIGTERM 2695 [ealtieri@italia os]$ [1]+ Terminated emacs [ealtieri@italia os]$
	Without the -s <sig> option, kill sends a 
	SIGTERM signal by default, so the third line above could 
	be rewritten simply as:
	
kill 2695
	From the point of view of a process, a signal can be either
	ignored, sent to a default handler, or caught by a function
	handler provided by the process. To make your program catch a
	signal you simply need to add the following code to the
	beginning of main():
	
#include <signal.h>
...
int main(void)
{
	signal(SIGINT, &on_sigint);   /* catch CTRL^C */
	...
	
	where on_sigint is the function in charge of handling
	the signal, and could be implemented as shown below:
	
/* CTRL^C handler */
void on_sigint(int signo)
{
	printf("CTRL^C pressed!\n");
	
	/* do cleanup work... */
	
	exit(0);
}
        
         ![]()  |  sigint.c is the
	        simplest example on how to catch the
	        SIGINT (CTRL^C) signal. |  
![]()  | 
	     Q3. Modify signint.c so that it also catches
	     the SIGTERM signal. Make the program display different
	     messages for the SIGINT and SIGTERM signals. | 
![]()  | 
	     Q4. The counterpart of the kill bash command
	     in C is the kill(pid_t pid, int sig)
	     function (see the kill(2) manual page). Use
	     this function to create a program that sends a
	     SIGINT signal to the PID specified in the
	     command line. | 
![]()  | 
	     Q5. Some signals cannot be ignored or caught by
	     processes. One example is the SIGKILL
	     signal, described earlier.  Read the
	     signal(7) manual page and find out which
	     other signal cannot be ignored or caught by a
	     process. Also find out the default action for the
	     SIGINT signal. | 
	Process creation under Linux is made possible by a few system
	calls. The most important is the fork()
	function.
	
#include <sys/types.h> #include <unistd.h> pid_t fork(void);
	fork() works by splitting the caller process into
	a parent and child process. Both the parent and the child
	processes share the same executable code, but have different
	data and stack segments. An example on how to use this system
	call is shown below:
	
#include <sys/types.h>
#include <unistd.h>
int main() {
        pid_t pid;
	pid = fork();  /* the process is split here !! */
	/* 
	 * Now we have two processes (child and parent) running on the
	 * same executable code. The way we tell who we are is by
	 * looking at the return value of fork() - 0 for the child
	 * process and > 0 for the parent.
	 */
	
	if (pid == 0) {   
                /* CHILD PROCESS */
		printf("Child process!\n");
		exit(0);
	}
        /* PARENT PROCESS */
	printf("Parent process!\n");
	exit(0);
}
        
	A slight modified version of the program above prints the
	process list before and after the fork()
	function is called. This is the resulting output:
	
[ealtieri@italia process]$ ./a.out Processes before forking: UID PID PPID C STIME TTY TIME CMD ealtieri 2242 2241 0 11:23 pts/2 00:00:00 bash ealtieri 2980 2242 0 15:35 pts/2 00:00:00 ./a.out ealtieri 2981 2980 0 15:35 pts/2 00:00:00 ps -f Processes after forking: UID PID PPID C STIME TTY TIME CMD ealtieri 2242 2241 0 11:23 pts/2 00:00:00 bash ealtieri 2980 2242 0 15:35 pts/2 00:00:00 ./a.out // parent ealtieri 2982 2980 0 15:35 pts/2 00:00:00 ./a.out // child ealtieri 2983 2980 0 15:35 pts/2 00:00:00 ps -f
	As you can see, after fork() the original process
	is split into two processes, the child and the parent. By
	looking at the PID and PPID of the two a.out
	processes we can tell that the second a.out is
	the child, while the first is the parent.
	
 ![]()  |  fork.c uses
	        fork() to create a child process. The
	        program prints the list of processes before and after
	        the forking. | 
![]()  | 
	     Q6. Consider the following fragment of code taken from 
	     fork1.c:
int main()
{
	pid_t pid;
	int look_this;
        look_this = 99;
        if ((pid = fork()) < 0) {
                perror("fork()");
		exit(1);
        }
	else if (pid == 0)
		/* CHILD PROCESS */
                look_this = 33;
		exit(0);
	}
	/* PARENT PROCESS */
	wait(NULL);  /* wait for child to terminate */
	printf("The value of look_this is %d\n", look_this);
	
	exit(0);
}
    
        The wait(2) function puts the parent process to
	sleep until the child process terminates. According to the
	definition of fork(), which value of
	look_this will be displayed on the screen?
	Explain your answer. | 
	So far we talked about how to fork a new process from an
	existing one, but what if we want to execute a program?  For
	this purpose Linux provides the exec()
	family of functions (see the exec(3) manual
	page). Differently from fork(), the
	exec() functions do
	not create a process. The functions replace the image
	of the caller process with the program specified as the first
	argument.  This means that the caller process terminates and
	the program specified in exec() takes its place.
	
For example:
#include <unistd.h>
int main()
{
	/*    FILE TO EXECUTE          ARG0        */
        execl("/usr/local/bin/emacs", "emacs", NULL);
	/* should never get here, unless execl() returned with an error */
	perror("execl()");
	exit(1);
}
	
	The program above tries to execute emacs. If the
	execl() function succedes, the process will be
	replaced by emacs and we will never reach the
	following lines.  However, execl() may not find
	the specified program, return an error and continue execution
	of the current process, therefore we always need to provide
	some error handling after the call.
	
	A slightly modified version of the program above prints the
	process list just before calling execl(). We can
	then manually check the list again with the ps
	command after the exec() fnction has been called.
	
[ealtieri@italia process]$ ./a.out & [2] 3106 Processes before the exec() call: UID PID PPID C STIME TTY TIME CMD ealtieri 2242 2241 0 11:23 pts/2 00:00:00 bash ealtieri 3106 2242 0 16:14 pts/2 00:00:00 ./a.out ealtieri 3107 3106 0 16:14 pts/2 00:00:00 ps -f [ealtieri@italia process]$ ps -f UID PID PPID C STIME TTY TIME CMD ealtieri 2242 2241 0 11:23 pts/2 00:00:00 bash ealtieri 3106 2242 0 16:14 pts/2 00:00:00 emacs ealtieri 3108 2242 0 16:15 pts/2 00:00:00 ps -f
	After the call to execl(), the original process
	disappeared and in its place we have emacs. Notice
	how emacs maintains the PID and PPID of the original
	process.
	
 ![]()  |  exec.c shows the
		use of the execl() function. | 
![]()  | 
	     Q7. The execution of a program involves two steps. First,
	     a new process has to be forked by a parent task, such as
	     a shell. Second, the child process executes the desired
	     program using one of the exec(3)
	     functions. This way, the child is replaced with the image
	     of the new program, while the parent is untouched. Implement a small shell that repeatedly asks for the path of a program and then executes that program using fork() and execlp().  The
	     shell must terminate when the user types "exit". The
	     shell shouldn't prompt for a new program to execute until
	     the previous one has terminated. You can use the
	     wait(2) function to make the parent process
	     wait for the child to terminate. | 
![]()  | Advanced Programming in the UNIX Environment, by Richard W. Stevens. Addison Wesley | 
   
