\input{myHead}

\newcommand{\exec}{{\tt exec*(...)}}
\newcommand{\fork}{{\tt fork()}}
\renewcommand{\PP}{{\tt P}}
\renewcommand{\QQ}{{\tt Q}}
\newcommand{\pp}{{\tt p}}
\newcommand{\qq}{{\tt q}}

\title{{\small Operating Systems V22.0202, Yap\hfill Fall 2007}
	\\[1in]
	Notes on Exec and Fork}

\maketitle

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Introduction}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Processes are the main entities in an operating system.
Indeed, one view of an OS is as a manager of processes.
Homework 1 gives you an brief introduction
to the programming of processes.

In order to do homework 1, you will need to
know something about \exec\ and \fork.
Both are unix system calls. All unix system calls
can be accessed from a C program.  They are found
in the Standard C Library (named {\tt libc.a}),
and sometimes you may need to include the header file:

\begin{verbatim}
     #include <unistd.h>
\end{verbatim}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Exec*}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

The ``exec'' system call is used to execute a program 
from within a process.  Suppose your process \QQ\ is
currently executing a program \qq.  If \qq\ wants to
execute another program \pp\, it can make the ``exec'' system call
with suitable arguments.  Then the current process image
is replaced (overlaid) by the image for the program \pp.
There is no return to the original program \qq.

To call ``exec'', you need to the following arguments:
where to find the executable file for program \pp,
the name of the program \pp, and any arguments that
must be passed to \pp.

Passing these arguments to ``exec'' might be troublesome:
\\(1)
The arguments to be passed to \pp\ is quite
arbitrary, depending on \pp.  For instance, exec does
not know in advance how many arguments \pp\ takes.
\\(2)
Second, it may not be obvious where the executable
image for program \pp\ is located, even if we know
its name.  E.g., \pp\ might be
standard system programs like {\tt date} or {\tt ls}, we may not
know where {\tt date} is located in the OS.
This would require searching the directories in the
environmental variable {\tt PATH}.

For these two reasons, we provide several versions of the
``exec'' to provide various conveniences in
making this system call.  In fact, there are 7 variants:

	{\tt \myprog{
	\>\> execl,  execle,  execlp\\
	\>\> execv,  execve,  execvp\\
	\>\> exect
	}}

Note that they are placed in 3 groups (l, v, t).
We shall collectively call them \exec.
To begin, we illustrate with an easy-to-use version: {\tt execlp}.

Suppose your program \qq\ wants to list the files in
the current directory.   It can use the following system call:

	\myprog{
	\>\>\tt execlp("ls", "ls", NULL);
	}

The first argument tells us where to find the executable
file for {\tt ls}.  This might be in {\tt /bin} or {\tt /usr/bin} or
some other directory.  The version {\tt execlp} will
search the directories of {\tt PATH} to look for {\tt ls}.
The remaining arguments will be passed to the {\tt ls} program.
Since the number of arguments is unknown, we have the
convention to adding {\tt NULL} to the list of arguments
to signal the end of the list.  

So the {\tt ls} program receives only one argument, namely,
its own name.  Recall the convention that
all C programs can access their
list of arguments from the {\tt argv} argument in the {\tt main}
program.  Moreover, the first argument is always
the name of the program itself.   

\bigskip \hrule \bigskip

QUESTION:
Write the system call
if you want to list the help message for {\tt ls}.

ANSWER: 
	\myprog{
	\>\>\tt execlp("ls", "ls", "--help", NULL);
	}

\bigskip
QUESTION:
What is the system call if you do not want to use the {\tt PATH} searching
facility but know the exact location of the {\tt ls} program?

ANSWER:  Just give the absolute path name of the program file,
instead of a relative path name.  E.g., if the absolute path name
for the {\tt ls} program is {\tt /usr/bin/ls.exe} then issue:
	\myprog{
	\>\>\tt execlp("/usr/bin/ls.exe", "ls", NULL);
	}

\bigskip \hrule \bigskip

We just described the ``lp'' version of \exec.
The ``l'' refers to ``list'' since the arguments are explicitly
listed by their list elements.  The ``p'' refers to the
facility of searching directories in {\tt PATH}.
Sometimes, it is convenient to gather the list of
arguments into an array (or ``vector'').  This is the ``v''
version \exec:

	\myprog{
	\>\>\tt execvp("ls", argp);
	}
where {\tt argp} is an array of points to the arguments,
structured exactly like {\tt argv} in the standard
{\tt main()} subroutine. 

This version is useful if this invocation of {\tt ls} may
have different number of arguments at runtime.
You would have to assemble (at runtime) these arguments into {\tt argp}
just before you make the system call.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Fork}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

What if the process \QQ\ want to return to the calling program \qq\ after
executing \pp?
It can create another process \PP\ just for the
sole purpose of executing \pp.  The system
call to create another process is called \fork\ which takes
no arguments.

When the process \QQ\ calls \fork, a new process \PP\ is created that
is identical to the calling process.  We call \PP\ a \dt{child process}
of \QQ\ (the \dt{parent process}).
There is only one difference: \fork\ returns a \dt{process ID}
(of type {\tt int}).  The value returned to \QQ\ is the process ID
of \PP, but the value returned to \PP\ is $0$.  Therefore
if we want \PP\ to behave differently from \QQ\ we must
have code that tests this returned value and branch on this:

	{\tt \myprog{
	\>\>	int status;\\
	\>\>	if (fork() == 0)\\
	\>\>\>		execlp("ls", "ls", NULL);
		\>\>\>\>\>\>\>/* child */\\
	\>\>	wait(\&status);   
		\>\>\>\>\>\>\>\>/* parent */	
	}}

The child process \PP\ will reach the \exec\ statement in this
code, and since there is no return from an \exec, it will not
see the following wait statement.

The parent process \QQ\ will execute the wait statement, meaning
that it will wait until its child process terminates.
In general, if it has many children, it waits until the
first child that terminates.
The value of the \ttt{status} variable returned by \ttt{wait}
has the child's exit status stored in its low-order eight bits
(where \ttt{0} indicates normal return).
The next eight bits of \ttt{status} is the
argument given to the \ttt{exit} statement
or the \ttt{return} statement of main, whichever
terminated the child process.


REFERENCE: Kernighan and Pike (Chapter 7).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Older Version of Exec}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

In homework 1, you need to make two systems calls: fork() and exec*().
Note that almost all calls to fork() is followed by an exec*()
call.  Another common system call is wait().

We will explain "exec" here.  
Basically, "exec" is called to execute a binary file
(i.e., compiled, executable program).
These binary files might perform basic
tasks provided by an operating system, such as listing
a directory.

There are actually 6 or 7 variants of exec(),
and none of them are actually called "exec".
We write exec*() to refer to all these variants:

	\begin{center} \tt
	% execl, execle, execlp, execv, execve, execvp
	execl, execle, execlp, execv, execve, execvp, exect
	\end{center}

These are available from the \dt{Standard C Library} (libc.a).
To make any of these system calls, your C program
must include the header file "unistd.h".
Here is the calling sequence for \texttt{execlp} which
is used in our homework:

\begin{center}
\begin{verbatim}
#include <unistd.h>

int execlp (
	File, 
	Arg0 [, Arg1, ...], NULL)

	const char *File, *Arg0, *Arg1, ...;

\end{verbatim}
\end{center}

The first argument is the name of an executable file,
and the remaining arguments  \texttt{Arg0, Arg1}, etc,
depends on the arguments needed by the executable file.

Since execlp does not know how many arguments are needed by
your executable file, you must explicitly terminate
your argument list with the NULL argument.  Since NULL is
literally zero, you can write $0$ in place of NULL.

A standard convention in UNIX i that \texttt{Arg0} should be
the name of the executable file itself.  Hence, every
executable program takes at least one argument.  E.g., 

	\fbox{
	\texttt{execlp("sleep", "sleep", "10", 0)}
	}

where the program "sleep" sends the calling process to
sleep for 10 seconds, and

	\fbox{
	\texttt{execlp("echo", "echo", "Hello World!", NULL)}
	}

will call the "echo" program to print on the screen
the string "Hello World!".

\paragraph{Return Values.}
Upon successful completion, the exec subroutines do not return because
the calling process image is overlaid by the new-process image. If
the exec subroutines return to the calling process, the value of $-1$
is returned and the errno global variable is set to identify the error.

\paragraph{Other Variants.}
	The first argument of exec*() is the name of the program to execute. 
	E.g., execl("ls", ...)
	says that we want to execute the unix "ls" program.
	The remaining arguments depends on the variant AND on
	the program to be executed:

	\begin{center}
	\begin{tabular}{|l| lll|}\hline
	System Call & Argument Format & Environment Passing & Path Search
	\\\hline\hline
	execl & list & auto & no\\
	execv & array & auto & no\\
	execle & list & manual & no\\
	execve & array & manual & no\\
	execlp & list & auto & yes\\
	execvp & array & auto & yes\\\hline
	\end{tabular}
	\end{center}

	The arguments to the program to be executed
	can be given in ARRAY format or in LIST format:

	E.g., execl("ls", "ls", "-lt", NULL);

	In this example of the list format, we see that
	the list of arguments is terminated by a NULL argument.

	The environment for executing the program can
	also be passed explicitly or implicitly inherited
	from the current environment.

	Path searching uses the standard unix concept of
	a list of search paths defined in the environment.
	A given file name is searched for in each of the
	paths until one is found (or failure reported).

\ignore{
\begin{verbatim}
#include <unistd.h>

extern 
char **environ;

int execl (
Path, 
Argument0 [, Argument1, ...], 0)

const char *Path, *Argument0, *Argument1, ...;

int execle (
Path, 
Argument0 [, Argument1, ...], 0,
        
EnvironmentPointer)
const 
char *Path, *Argument0, *Argument1, ...;
char *const EnvironmentPointer[ ];

int execlp (
File, 
Argument0 [, Argument1, ...], 0)
const char *File, *Argument0, *Argument1, ...;

int execv (
Path, 
ArgumentV)
const char *Path;
char *const ArgumentV[ ];

int execve (
Path, 
ArgumentV,
EnvironmentPointer)
const char *Path;
char *const ArgumentV[ ], *EnvironmentPointer [ ];

int execvp (
File, 
ArgumentV)
const char *File;
char *const ArgumentV[ ];

int exect (
Path,
ArgumentV,
EnvironmentPointer)
char *Path, *ArgumentV, *EnvironmentPointer [ ];

\end{verbatim}
}%ignore

The exec subroutine, in all its forms, executes a new program in the
calling process. The exec subroutine does not create a new process,
but overlays the current program with a new one,
which is called the new-process image.
The new-process image file can be one of three file types:

    * An executable binary file in XCOFF file format.

    * An executable text file that contains a shell procedure
    (only the execlp and execvp subroutines allow this type of
    new-process image file).

    * A file that names an executable binary file or shell procedure to be run.

\ignore{
The new-process image inherits the following attributes from 
the calling process image: session membership, supplementary group IDs, process signal mask, and pending signals.

The last of the types mentioned is recognized by a header with the following syntax:

\#! Path [String]

The \#! is the file magic number, which identifies the file type. The path name of the file to be executed is specified by the Path parameter. The String parameter is an optional character string that contains no tab or space characters. If specified, this string is passed to the new process as an argument in front of the name of the new-process image file. The header must be terminated with a new-line character. When called, the new process passes the Path parameter as ArgumentV[0]. If a String parameter is specified in the new process image file, the exec subroutine sets ArgumentV[0] to the String and Path parameter values concatenated together. The rest of the arguments passed are the same as those passed to the exec subroutine.

The exec subroutine attempts to cancel outstanding asynchronous I/O requests by this process. If the asynchronous I/O requests cannot be canceled, the application is blocked until the requests have completed.

The exec subroutine is similar to the load subroutine, except that the exec subroutine does not have an explicit library path parameter. Instead, the exec subroutine uses the LIBPATH environment variable. The LIBPATH variable is ignored when the program that the exec subroutine is run on has more privilege than the calling program, for example, the suid program.

The exect subroutine is included for compatibility with older programs being traced with the ptrace command. The program being executed is forced into hardware single-step mode.

    Note: exect is not supported in 64-bit mode.

Parameters
Path 	Specifies a pointer to the path name of the new-process image file. If Network File System (NFS) is installed on your system, this path can cross into another node. Data is copied into local virtual memory before proceeding.
File 	Specifies a pointer to the name of the new-process image file. Unless the File parameter is a full path name, the path prefix for the file is obtained by searching the directories named in the PATH environment variable. The initial environment is supplied by the shell.

    Note: The execlp subroutine and the execvp subroutine take File parameters, but the rest of the exec subroutines take Path parameters. (For information about the environment, see the environment miscellaneous facility and the sh command.)

Argument0 [, Argument1, ...] 	Point to null-terminated character strings. The strings constitute the argument list available to the new process. By convention, at least the Argument0 parameter must be present, and it must point to a string that is the same as the Path parameter or its last component.
ArgumentV 	Specifies an array of pointers to null-terminated character strings. These strings constitute the argument list available to the new process. By convention, the ArgumentV parameter must have at least one element, and it must point to a string that is the same as the Path parameter or its last component. The last element of the ArgumentV parameter is a null pointer.
EnvironmentPointer 	An array of pointers to null-terminated character strings. These strings constitute the environment for the new process. The last element of the EnvironmentPointer parameter is a null pointer.

When a C program is run, it receives the following parameters:

main (ArgumentCount, ArgumentV, EnvironmentPointer)
int ArgumentCount;
char *ArgumentV[ ], *EnvironmentPointer[ 
];

In this example, the ArgumentCount parameter is the argument count, and the ArgumentV parameter is an array of character pointers to the arguments themselves. By convention, the value of the ArgumentCount parameter is at least 1, and the ArgumentV[0] parameter points to a string containing the name of the new-process image file.

The main routine of a C language program automatically begins with a runtime start-off routine. This routine sets the environ global variable so that it points to the environment array passed to the program in EnvironmentPointer. You can access this global variable by including the following declaration in your program:

extern char **environ;

The execl, execv, execlp, and execvp subroutines use the environ global variable to pass the calling process current environment to the new process.

File descriptors open in the calling process remain open, except for those whose close-on-exec flag is set. For those file descriptors that remain open, the file pointer is unchanged. (For information about file control, see the fcntl.h file.)

The state-of-conversion descriptors and message-catalog descriptors in the new process image are undefined. For the new process, an equivalent of the setlocale subroutine, specifying the LC\_ALL value for its category and the "C" value for its locale, is run at startup.

If the new program requires shared libraries, the exec subroutine finds, opens, and loads each of them into the new-process address space. The referenced counts for shared libraries in use by the issuer of the exec are decremented. Shared libraries are searched for in the directories listed in the LIBPATH environment variable. If any of these files is remote, the data is copied into local virtual memory.

The exec subroutines reset all caught signals to the default action. Signals that cause the default action continue to do so after the exec subroutines. Ignored signals remain ignored, the signal mask remains the same, and the signal stack state is reset. (For information about signals, see the sigaction subroutine.)

If the SetUserID mode bit of the new-process image file is set, the exec subroutine sets the effective user ID of the new process to the owner ID of the new-process image file. Similarly, if the SetGroupID mode bit of the new-process image file is set, the effective group ID of the new process is set to the group ID of the new-process image file. The real user ID and real group ID of the new process remain the same as those of the calling process. (For information about the SetID modes, see the chmod subroutine.)

At the end of the exec operation the saved user ID and saved group ID of the process are always set to the effective user ID and effective group ID, respectively, of the process.

When one or both of the set ID mode bits is set and the file to be executed is a remote file, the file user and group IDs go through outbound translation at the server. Then they are transmitted to the client node where they are translated according to the inbound translation table. These translated IDs become the user and group IDs of the new process.

    Note: setuid and setgid bids on shell scripts do not affect user or group IDs of the process finally executed.
}%ignore 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Examples}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   1. To run a command and pass it a parameter, enter:

      \texttt{execlp("ls", "ls", "-al", 0);}

      The execlp subroutine searches each of the directories listed in the
      PATH environment variable for the \ttt{ls} command, and then it overlays
      the current process image with this command. The execlp subroutine
      is not returned, unless the \ttt{ls} command cannot be executed.

      Note: This example does not run the shell command processor,
      so operations interpreted by the shell, such as using wildcard
      characters in file names, are not valid.

   2. To run the shell to interpret a command, enter:

      \texttt{execl("/usr/bin/sh", "sh", "-c", "ls -al *.c", 0);}

      This runs the sh command with the -c flag, which indicates that the
      following parameter is the command to be interpreted. This example
      uses the execl subroutine instead of the execlp subroutine because
      the full path name /usr/bin/sh is specified, making a path search
      unnecessary.

      Running a shell command in a child process is generally more useful
      than simply using the exec subroutine, as shown in this example.
      The simplest way to do this is to use the system subroutine.

   3. The following is an example of a new-process file that names
      a program to be run:

      \texttt{\#! /usr/bin/awk -f}
      \texttt{{ for (i = NF; i > 0; --i) print \$i }}

      If this file is named reverse, entering the following command on
      the command line:

      reverse chapter1 chapter2

      This command runs the following command:

      /usr/bin/awk -f reverse chapter1 chapter2

          Note: The exec subroutines use only the first line of the
	  new-process image file and ignore the rest of it. Also,
	  the awk command interprets the text that follows a \#
	  (pound sign) as a comment. 


\myTail




\myTail
