You are on page 1of 3

Lab on processes

I-Organization of the lab:


Examples to make work + Presentation of a report.

The « exec » function:


The exec function loads a file into the code area of the process that calls it, replacing the current code with that
file. One form of this function is execl:

int execl (char *fic, char * arg0, [arg1, ... argn,])

Comments:

• fic is the name of the executable file that will be loaded into the code area of the process that calls
execl.
• If this file is not in the current directory, you must give its full name (absolute path).
• The following parameters are pointers to character strings containing the arguments passed to this
program (cf. argv in C).
• UNIX convention dictates that the first be the name of the file itself and the last be a null pointer.

For example, if we want to load the file called prog which is in the current directory and which does not
use any arguments passed on the command line:

execl ("prog", "prog", (char *)0)

#include <unistd.h>
int execv (const char *FILENAME, char *const ARGV[])
int execl (const char *FILENAME, const char *ARG0,...)
int execve(const char *FILENAME, char *const ARGV[], char *const ENV[])
int execle(const char *FILENAME, const char *ARG0,...char *const ENV[])
int execvp(const char *FILENAME, char *const ARGV[])
int execlp(const char *FILENAME, const char *ARG0, ...)

These functions all do the same thing: activate an executable instead of the current process. They differ in the
way of specifying the parameters.

Work to do :

1. Run the program below after compilation. What does it show as a result on the screen?
2. put the line: execl("ls", "ls", "-lR", (char *)0); instead of execl("/bin/ls", "ls", "-lR", (char *)0); . What
will be the result in this case? Why?
1
3. Then, and still in the same program, replace execl("ls", "ls", "-lR", (char *)0); by execlp("ls", "ls", "-lR",
(char *)0);. What will be the result now? Why?
4. Add a 4th parameter « / » before the « NULL » parameter and the sleep(40) line; before "printf", while
determining its PID (by the command "ps -ef" executed in another shell) before and after the execution
of ls. What do you notice about the PID and the command name (CMD)? Interpret.

/* runls -- use "execl" to run ls */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

main()
{
printf("Executing ls \n");

execl("/bin/ls", "ls", "-lR", (char *)0);

//if execl returns, the call has failed, so...

perror("execl failed to run ls");


exit(1);
}

III. The « waitpid » function.


The waitpid() function is used to wait for the termination of one of the child processes designated by its PID
and to possibly retrieve its return code. It returns the child PID.

The WNOHANG option makes waitpid non-blocking (which then returns 0 if the expected process has not
terminated).

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

pid_t waitpid (pid_t pid, int *status, int options);

Work to do :
1. Compile the following program (“WaitPidEx.c”). Run it and interpret briefly.

/* --Programme “WaitPidEx.c”--*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

main ()
{
pid_t pid;

int status, exit_status;

int fatal(char *s)


{
perror(s);
2
exit(1);
}

if((pid = fork())<0)
fatal("fork failed");

if (pid == 0)
{
printf("Child %d sleeping...\n", getpid());
sleep(4);
exit(5);
}

while(waitpid(pid, &status, WNOHANG) == 0)


{
printf("Still waiting...\n");
sleep(1);
}

if(WIFEXITED(status))
{
exit_status = WEXITSTATUS(status);
printf("Exit status from %d was %d\n", pid, exit_status);
}
exit(0);
}

2. Add a new “fork()” to create another child (see code below) and name the program “WaitPidEx-mul.c” .
What does it change in the execution?
(NB: use the “ps –ef” command to see the PIDs and in order to see several cases of execution, have one of
the processes terminate before the other by playing on the values of “SECONDS” in “sleep(SECONDS)”.

if((pid1 = fork())<0)
fatal("fork failed");

if (pid1 == 0)
{
printf("Child2 %d sleeping...\n", getpid());
sleep(8);
exit(6);
}

3. Add a new "waitpid()" that corresponds the other child, and repeat the work in (2).

You might also like