Systems Programming: P.K.Pattanayak
Systems Programming: P.K.Pattanayak
P.K.Pattanayak
An Introduction …
Unix Kernel: a large C program that
implements a general interface to a
computer to be used for writing programs
System Call
Well-defined entry point into kernel to request a
service
pid_t fork();
fork
Heap Heap
Data Segment, bss Data Segment, bss
Program Text Program Text
Args, environment
Stack
child
Heap
Data Segment, bss
Program Text
Returning from fork
• fork() returns twice
– Once in parent and once in child
• Value returned by fork is different for each
process
– Returns 0 to child process
– Returns pid of child to parent
– Returns -1 to parent if error
• Both processes resume from same point after
fork(), but with different return values
Analogy: Fork ()
2
Under fork
Child has same age (progress) as parent!!!!
Folk
28 28
Tom Jack
Process Creation: fork()
pid_t child_pid;
int x=1;
Fork bomb !!
Example 2
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int i, pid;
i = 5;
printf("%d (pid %d,ppid %d)\n",i,getpid(),getppid());
pid = fork();
if (pid != 0)
i = 6; /* only the parent gets here */
else
i = 4; /* only the child gets here */
printf("%d (pid %d,ppid %d)\n",i,getpid(),getppid());
}
Process Execution: exec
• fork creates identical clones
• But what if the child wants to execute some
other program?
• 6 variations of exec
– Use the same system call execve
– Differ in parameters
•
exec variations
There are several front-ends to execve:
– int execv(char *path, char *argv[]);
uses the environment vars of the current process
– int execl(char *path,
char *arg1, char *arg2, ... NULL);
takes arguments as separate parameters
– int execle(char *path,
char *arg1, ... NULL, char *envp[]);
like execl but with explicit environment
– int execvp(char *filename, char *argv[]);
like execv but searches PATH
– int execlp(char *filename,
char *arg1, char *arg2, ... NULL);
like execl but searches PATH
Heap 1
0
Folk
28 28
Process Execution: exec
pid_t child_pid;
int x=1;
child_pid=fork();
if (child_pid==0)
/* This is child process */
{
execv(“/bin/ls”, “ls –l”);
printf (“I’m child process: x=%d\n”, x);
}
else if (child_pid>0)
/* This is parent process */
printf (“I’m parent process: x=%d\n”, x);
How to collect information
from child process
Uses of wait
• Synchronization
– Allows parent to synchronize its execution
with the child/children
– Useful for interactive applications like the shell
• Reaping
– OS removes a process only when its parent
waits for it
– Need to notify the exit status of the process
Waiting for a Child: wait
• Sometime parent wants to wait for the child to
finish execution
• Example: “ls –l”
– Shell waits until command is executed
#include
#include <unistd.h>
<unistd.h>
pid_t
pid_t wait(int
wait(int *status);
*status);
wait
parent
fork
exit
child
exec
Waiting for a Specific Child:
waitpid
• A process may have many children, but
may want to wait for a specific child
pid_t
pid_t waitpid(pid_t
waitpid(pid_t pid,
pid, int
int *status,
*status,
int
int opt);
opt);
– Zombies unlike
orphans do not
consume many
resources.
Zombie Removal
parent
fork
child
exec
Daemons
• Forever running background processes
• Similar to shell
– Get some input
– Do something useful
– Print results, log errors if required
• Differences from shell:
– Each implements specific service
– May not be interactive
• Examples: Web server (httpd), print server
(lpd), ssh daemon (sshd)
How to kill a process using signal
• A signal is a notification of some
"'unexpected" occurrence.
• Synchronous signals arise from inside your
program: segmentation fault, divide by
zero, etc.
• Asynchronous signals arise outside your
program: user hits ^C, I/O completion, for
example.
• kill -s <signal> <pid> sends signal to
process pid. From a C program:
#include
#include <signal.h>
<signal.h>
int
int kill(pid_t
kill(pid_t pid,
pid, int
int signal);
signal);
What we learned
• Difference between program and process
• What are the resources related to
processes?
• How we can access them?
• How we can manipulate them?
• How to create processes?
• How to control the running states of
processes?