0% found this document useful (0 votes)
11 views45 pages

Tut 5

Uploaded by

f20211144
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views45 pages

Tut 5

Uploaded by

f20211144
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 45

Operating Systems

Yemineni Ashok
BITS Pilani Computer Science and Information Systems Department
BITS, Pilani
Pilani Campus

BITS Pilani, Pilani Campus


BITS Pilani
Pilani Campus

Process system calls


Tutorial 5

BITS Pilani, Pilani Campus


Today’s Agenda

o Unix System Calls


o Process Creation
o Process Execution

3
BITS Pilani, Pilani Campus
Process

• Process is an instance of executing program


• Main function of process is to execute the
instructions residing in main memory
• Process is characterized by
– Its code, Data, stack and set of registers
• During its life time, it can be in different states
such as running, not running

4
BITS Pilani, Pilani Campus
Process

• Includes
– The program code, also called text section
– Current activity including value of program
counter and processor registers
– Stack containing temporary data
• Function parameters, return addresses, local variables
– Data section containing global variables
– Heap containing memory dynamically allocated
during run time

BITS Pilani, Pilani Campus


Process in Memory

Temporary data,
Local variables

Local variables
(inside function)
vs
Global variable Dynamic memory
(outside function)
Global variables

program code

BITS Pilani, Pilani Campus


Process Creation

• Parent process create children processes,


which, in turn create other processes, forming
a tree of processes
• Generally, a process is identified and
managed via a process identifier (pid)
• Resource sharing
– Parent and children share all resources
– Children share subset of parent’s resources
• Execution
– Parent and children execute concurrently
– Parent waits until children terminate
BITS Pilani, Pilani Campus
Process Creation (Cont.)

• Address space
– Child process is duplicate of parent process
– Child process has a program loaded into it

• UNIX examples
– fork system call creates new process
– exec system call used after a fork to replace the
process’ memory space with a new program

BITS Pilani, Pilani Campus


Process Creation

BITS Pilani, Pilani Campus


C fork() program

#include <sys/types.h>
#include <studio.h>
#include <unistd.h>
int main()
{
pid_t pid;
/* fork another process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid == 0) { /* child process */
execlp("/bin/ls", "ls", NULL);
}
else { /* parent process */
/* parent will wait for the child */
wait (NULL);
printf ("Child Complete");
}
return 0;
}

BITS Pilani, Pilani Campus


getpid() & getppid() system
calls In Unix
 To obtain current process id, use getpid() system call.

 To obtain parent process id, use getppid() system call.

BITS Pilani, Pilani Campus


Example

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

int main() {
printf("I am process %ld\n",(long)getpid());
printf("My Parent is %ld\n",(long)getppid());
}

output
Ashok@Ashok-Latitude-E5450:~$ ./a.out
I am process 3193
My Parent is 2981

12
BITS Pilani, Pilani Campus
fork() and exec() system calls

 fork()
 It creates a new process which is an identical copy of an existing process.
 The newly created process will contain all the instructions and data of its
parent process.
 Hence it executes the same parent process.
 fork() is the only way to create new processes in UNIX
 exec()
 This on the other hand re-initializes the existing process with some other
designated program.
 It does not create a new process.
 It merely flushes the current context of a program and loads a new context
(new program).
 exec() call is the only way to execute programs in UNIX. In fact, the kernel
boots itself using the exec() call.
BITS Pilani, Pilani Campus
fork() system call
 fork() call creates a “new” process.
 The child process’ context will be the same as the parent
process.
 After a fork() call, two copies of the same context exist, one
belonging to the child and another to the parent.
 Contrast this to exec(), where a single context will exist
because of child context over-writing the parent.
 # include<unistd.h>
 int fork(void);
 /*Returns child process-ID and 0 on success and -1 on
error */

BITS Pilani, Pilani Campus


Return value of fork() system call
 After fork() returns
 The child receives a 0 as return value from fork() and the
parent receives the process-ID of the child.

BITS Pilani, Pilani Campus


Program to demonstrate simple fork() usage

1# include<stdio.h>
2 int main(void){
3 printf(“************ Before Fork************\n”);
4 system(“ps”);
5
6 fork();
7
8 printf(“************ After Fork *************\n”;
9 system(“ps”);
10 return 0;
11}

BITS Pilani, Pilani Campus


Output
************ Before Fork************ printf(“BF”)
PID TTY TIME CMD system(“ps”)
2967 pts/0 00:00:00 bash Fork()
2990 pts/0 00:00:00 a.out
printf(“AF”)
2991 pts/0 00:00:00 ps
System(“ps”)
************ After Fork *************
************ After Fork *************
PID TTY TIME CMD
PID TTY TIME CMD
2967 pts/0 00:00:00 bash
2967 pts/0 00:00:00 bash
printf(“AF”)
2990 pts/0 00:00:00 a.out
System(“ps”)
2990 pts/0 00:00:00 a.out
2992 pts/0 00:00:00 a.out
2992 pts/0 00:00:00 a.out
2993 pts/0 00:00:00 ps
2993 pts/0 00:00:00 ps
2994 pts/0 00:00:00 ps
2994 pts/0 00:00:00 ps
BITS Pilani, Pilani Campus
Modified code
1# include<stdio.h>
2int main(void){
3 int ret;
4 printf(“************ Before Fork************\n”);
5 system(“ps”);
6
7 ret=fork();
8 if(ret==0){
9 printf(“************ After Fork *************\n”;
10 system(“ps”);
11 }
12 else if(ret>0)
13 wait();
14 return 0;
15}

BITS Pilani, Pilani Campus


output
************ Before Fork************
PID TTY TIME CMD
2967 pts/0 00:00:00 bash
3005 pts/0 00:00:00 a.out
3006 pts/0 00:00:00 ps
************ After Fork *************
PID TTY TIME CMD
2967 pts/0 00:00:00 bash
3005 pts/0 00:00:00 a.out
3007 pts/0 00:00:00 a.out
3008 pts/0 00:00:00 ps

BITS Pilani, Pilani Campus


fork() example 2

int main(void) {
pid_t pid;
printf("************ Before Fork************\n");
system("ls -l");
pid = fork();
if(pid == 0){
printf("************ After Fork *************\n");
system("ps");
}
else if (pid > 0)
wait();
return 0; }
BITS Pilani, Pilani Campus
[user@localhost processes]$ ./a.out
************ Before Fork************
total 60
-rwxrwxr-x. 1 user user 6937 Sep 13 16:30 a.out
-rw-rw-r--. 1 user user 310 Sep 6 16:48 env.c
-rw-rw-r--. 1 user user 145 Sep 6 17:06 execL.c
-rw-rw-r--. 1 user user 219 Sep 13 15:50 execlp.c
-rw-rw-r--. 1 user user 219 Sep 5 15:41 pid_ppid.c
-rwxrwxr-x. 1 user user 6919 Sep 13 13:16 sum
-rw-rw-r--. 1 user user 280 Sep 13 13:16 sum.c
-rw-rw-r--. 1 user user 326 Sep 2 13:03 system1.c
************ After Fork *************
PID TTY TIME CMD
2806 pts/0 00:00:00 bash
3565 pts/0 00:00:00 a.out
3567 pts/0 00:00:00 a.out
3568 pts/0 00:00:00 ps
BITS Pilani, Pilani Campus
int main(int argc, char *argv[]){
int pid;
printf("*****before fork****\n ");
system("ps");
pid = fork();
if(pid == 0)
{
printf("*****after fork****\n ");
printf("child pid = %d\n",pid);
//execl("/bin/echo","echo","hello","world",(char *)NULL);
execlp("echo","echo","hello","world",(char *)NULL);
}
else {
printf("parent pid = %d\n",pid);
wait();
}
return 0; }
BITS Pilani, Pilani Campus
output

[user@localhost processes]$ ./a.out


*****before fork****
PID TTY TIME CMD
2806 pts/0 00:00:00 bash
4196 pts/0 00:00:00 a.out
4197 pts/0 00:00:00 ps
parent pid = 4198
*****after fork****
child pid = 0
hello world

BITS Pilani, Pilani Campus


Multiple Fork System Call

#include <stdio.h>
#include <sys/types.h>
int main()
{
fork();
fork();
fork();
printf("hello\n");
return 0;
}

24
BITS Pilani, Pilani Campus
output

S. Fork() system call in Print output Parent process Child Process


no program “Hello”
.
1 Fork() 2 1 1
2 Fork() 4 1 3
Fork()
3 Fork() 8 1 7
Fork()
Fork()

25
BITS Pilani, Pilani Campus
Forking Cost
• fork() calls are enormously costly in terms of computing resources.
• A clone of the parent’s context is made which involves copying of the data
segment.
• Copy of instruction segment (code) is not made because the segment is read-
only and hence is shared between parent and child.
• The data segment can be very huge. if fork() is immediately followed by
exec() then it overwrites the existing data and code segments. Hence copying
data segment is wasted.
• A scheme that overcomes this handicap is called the “copy-on-write” scheme.
• In this scheme, after fork() the parent and the child share the same data
segment as long as the data segment is unmodified. When the parent or child
modifies a particular page, a copy of only that page is made. So, there would
be two copies of modified pages while the unmodified pages would be
shared.

BITS Pilani, Pilani Campus


Fork bombs

• Repeated fork() calls (also known as fork bombs) can eventually lead to resource
exhaustion and may collapse the system.

Program to demonstrate repeated forking


int main(void){
int cnt=0;
int pid;
for(cnt=0;cnt<3;cnt++){
pid=fork();
printf("Now in process %d\n",getpid());
}
return 0;
}
• how many new processes would be created?
BITS Pilani, Pilani Campus
The number of children would
be : 7

In the first iteration, only the parent process


exists and it creates a single child, C1.
In the second iteration both P and C1 exist
and each fork to give C3 and C2 respectively
In the last iteration P,C1,C2,C3 exist and
each fork to give C7,C6,C4,C5 respectively.

BITS Pilani, Pilani Campus


Controlled forking

int main(void){
int cnt=0; int pid;
for(cnt=0;cnt<3;cnt++){
pid=fork();
if(pid==0)
continue;
else
break;
}
printf("Process %d\n",getpid());
return 0;
}

BITS Pilani, Pilani Campus


Exec () System Call

 Exec()
 This on the other hand re-initializes the existing process with some
other designated program.
 It does not create a new process.
 It merely flushes the current context of a program and loads a new
context (new program).
 exec() call is the only way to execute programs in UNIX. In fact, the
kernel boots itself using the exec() call.
 fork() is the only way to create new processes in UNIX

BITS Pilani, Pilani Campus


Other exec system calls
 The other exec calls are very similar to execl(). They provide
the following three features that are not available in execl().
 Arguments can be put into a vector/array instead of explicitly
listing them in the exec call. This feature is useful if the
arguments are not known at compile time.
 Searches an executable using the value of the PATH
environment variable. When this feature is used we don’t have
to specify the complete path in the exec call.
 Manually passing an explicit environment pointer instead of
automatically using environ.

BITS Pilani, Pilani Campus


Exec Family
 Exec system calls are a set six system call of the form
execAB
1. execl
2. execv
3. execlp
4. execvp
5. execle
6. execve

BITS Pilani, Pilani Campus


The six exec system calls
 execl: execute file with arguments explicitly in call
 execv : execute file with argument vector
 execlp: execute file with arguments explicitly in call and PATH search
 execvp: execute file with argument vector and PATH search
 execle: execute file with argument list and manually passed environment
pointer
 execve: execute file with argument vector and manually passed
environment pointer

BITS Pilani, Pilani Campus


Exec Family execAB

S.No. A B Name Meaning

1 l execl Execute file with arguments explicitly in call

2 v execv Execute file with argument vector

3 l p execlp Execute file with arguments explicitly in call and PATH search

4 v p execvp Execute file with argument vector and PATH search

5 l e execle Execute file with argument list and manually passed environment
pointer
6 v e execve Execute file with argument vector and manually passed
environment pointer

BITS Pilani, Pilani Campus


int execv (
const char *path, /* Program pathname */
char* const argv[] /* Argument vector */
);

int execvp (
const char *file, /* Program filename */
char* const argv[] /* Argument vector */
);

int execve (
const char *path, /* Program pathname */
char *const argv[], /* Argument vector */
char *const envv[] /* Environment vector */
);
BITS Pilani, Pilani Campus
int execlp (
const char *file, /* Program filename */
const char *arg0, /*First Argument(filename) */
const char *arg1,

(char *) NULL /* Arg list terminator */
);
int execle (
const char *path, /* Program pathname */
const char *arg0, /*First Argument(filename) */
const char *arg1,

(char *) NULL, /* Arg list terminator */
char *const envv[] /* Environment vector */
);
BITS Pilani, Pilani Campus
execl() system Call
 It execute file with arguments explicitly in call.
 Syntax
int execl (
const char *path, /* Complete Program pathname */
const char *arg0, /* First Argument(filename) */
const char *arg1, /* Second Argument(optional) */
… /* Remaining Arguments (if any) */
(char *) NULL /* Arg list terminator */
);
/* Returns -1 on error (sets errno) */

BITS Pilani, Pilani Campus


execl() system call
 After the call to execl() the context of the process is overwritten.
 Previous code is replaced by the code/instructions of the
executable in ‘path’.
 User data is also replaced with the data of the program in ‘path’
thereby reinitializing the stack.
 And the new program begins to execute from its main function.
 New program accesses the arguments of new program which are
mentioned in execl() through its ‘argc’ and ‘argv’ arguments of the
main function.
 Environment pointed to by ‘environ’ is also passed to the new
program.

BITS Pilani, Pilani Campus


Return of execl() system call
 Recall that the return address of any function is saved in the
stack.
 The return address is popped from the stack while a function
returns.
 But here the stack is reinitialized with the data of the new
program and the old program’s data is lost.
 So there is no way to pop the return address and hence there
is no way to return from execl() call if the call is successful.

BITS Pilani, Pilani Campus


execl() example to invoke user executable
int main(int argc,char *argv[])
{ int main()
int sum=0; {
int i; execl("./sum","sum","100","200","300",(char *)NULL);
if(argc != 4) printf("execl call unsuccessful\n");
{ }
printf("invalid argument\n");
exit(0);
}
for(i=0;i<argc;i++)
sum = sum + atoi(argv[i]);
printf("sum = %d\n",sum);
}

BITS Pilani, Pilani Campus


execl() Example to invoke UNIX
commands
# include<stdio.h>
# include<unistd.h>
int main(int argc, char ** argv){
printf("Hello World!");
execl("/bin/echo","echo","Print","from","execl",NULL);
return 0;
}

Output:- Print from execl

In the above program “Hello World!” is not printed


Reason:
Printf() function in C does not immediately prints the data on stdout but it buffers it
till the next printf() statement or program exit.
BITS Pilani, Pilani Campus
execv()

int main(int argc,char *argv[])


{
char *newargv[5];
int i,j=0;
for(i=1;i<5;i++){
newargv[j] = argv[i];
j++; }
newargv[4] = NULL;
execv("./sum",newargv);
printf("%s\n",strerror(errno));
printf("execv call unsuccessful\n");
}
BITS Pilani, Pilani Campus
execlp()

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

int main(int argc,char *argv[])


{
execlp("echo","echo","hello","world",(
char *)NULL);
printf("%s\n",strerror(errno));
printf("execlp call unsuccessful\n");
}

BITS Pilani, Pilani Campus


6. execve() System Function:

#include <unistd.h>

int main(void) {
char *binaryPath = "/bin/bash";
char *const args[] = {binaryPath, "-c", "echo YOU ARE THE PART OF $A $B ", NULL};
char *const env[] = {“A=BITS“,”B=PILANI”, NULL};

execve(binaryPath, args, env);


return 0;
}

Just like execle() you can provide your own environment variables
along with execve(). You can also pass arguments as arrays as you
did in execv().
44
BITS Pilani, Pilani Campus
Any Queries?

BITS Pilani, Pilani Campus

You might also like