3150 chapter 2 part 1

59
Lecturer: Dr. T.Y. Wong Introduction to Operating Systems Chapter 2, part 1 Basic Process Management

Upload: tywong

Post on 06-May-2015

702 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 3150 Chapter 2 Part 1

Lecturer: Dr. T.Y. Wong

Introduction to Operating Systems

Chapter 2, part 1Basic Process Management

Page 2: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 2

Outline• Process vs Program

– What are they? Any difference?

• Process Creation– How to get it done using system calls?

• Program Execution– How to execute a program?

Page 3: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 3

Program vs Process

What is a Program?

Page 4: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 4

What is a program?• What is a program?

– A program is a just a piece of code.

• But, which code do you mean?– High level language code: C, C++, etc.– Low level language code: assembly code.– Not-yet an executable: object code.– Executable: contains only machine code.

Page 5: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 5

Building a program – initial phase…hello.c hello.c

Pre-processorHigh-level

programminglanguage

Expandedcode

Compiler#define TXT “hello”

int main(void) {printf(“%s\n”, TXT);return 0;

}

hello.s

OptimizerAssembly

code

Program: hello.c

Page 6: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 6

Pre-processor• The pre-processor expands:

– #define, #include, #ifdef, #ifndef, #endif, etc.

– Try: gcc –E define.c

#define TXT “hello”

int main(void) {printf(“%s\n”, TXT );return 0;

}

int main(void) {printf(“%s\n”, “hello” );return 0;

}Pre-processor

Program: hello.c

Page 7: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 7

Pre-processor• Another example: the macro!

#define SWAP(a,b) { int c; c = a; a = b; b = c; }

int main(void) {int i = 10, j = 20;printf("before swap: i = %d, j = %d\n", i, j);SWAP(i, j);printf("after swap: i = %d, j = %d\n", i, j);

} Program: swap.c

int main(void) {int i = 10, j = 20;printf("before swap: i = %d, j = %d\n", i, j){ int c; c = i; i = j; j = c; };printf("after swap: i = %d, j = %d\n", i, j);

}

Pre-processor

Page 8: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 8

Pre-processor• How about #include?

Program: include.c

#include “header.h”

int main(void) {add_fun(1,2);return 0;

}

Program: header.h

int add_fun(int a, int b) {return (a + b);

}

int add_fun(int a, int b) {return (a + b);

}

int main(void) {add_fun(1,2);return 0;

}

Pre-processor

Page 9: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 9

Compiler and Optimizer• The compiler performs:

– Syntax checking and analyzing;– If there is no syntax error, construct

intermediate codes, i.e., assembly codes;

– For syntax checking topics, we have the courses: CSC3130 and CSC3120.

– For assembly language: we have the courses: CSC2510 and CSC3420.

Page 10: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 10

Compiler and Optimizer• The optimizer optimizes codes.

– In other words: it improves stupid codes!

– Try:• gcc –S add.c –O0 –o add_O0.s• gcc –S add.c –O1 –o add_O1.s

• Important notice: Don’t write stupid codes because there is an optimizer!

int main(void) {int x =1;x = x + 1;x = x + 1;return x;

}Program: add.c

“-O” means optimize.The number is the optimization level.

-O0: means no optimization.

Max is level 3, i.e., -O3

An example of stupid codes.

Page 11: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 11

Building a program – next phase…hello.ohello.s

Assembler“as”

Assemblycode

Objectcode

Linker“ld”

Static/Dynamiclibrary

Executable

hello.exelib*.a or lib*.so

Page 12: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 12

Assembler and Linker• The assembler assembles “hello.s” and

generates an object code “hello.o”.– A step closer to machine code.– Try: as hello.s –o hello.o

• The linker puts together all object files as well as the libraries.– There are two kinds of libraries: statically-

linked ones and dynamically-linked ones

Page 13: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 13

Library File• A library file is nothing special.

– It is just a bunch of function implementations.– Of course, the linker knows how to look for the

function that the C program needs.

A library file.A bunch of “dot-o” files.

Page 14: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 14

Library File

Static library file. Dynamic library file.

The OS will look for this file when the program runs.

A smaller program!The final

program is the combination of the above two codes.

Page 15: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 15

Library File• The linker also verifies if the symbols

(functions and variables) that are needed by the program are completely satisfied.– A compiled executable does not include any

shared libraries.– E.g. “gcc math.c –lm” is to link libm.so.6,

the math library.

JargonAlert

SO – Shared Object

Page 16: 3150 Chapter 2 Part 1

Extra Notes

Fall semester2008-2009

CEG/CSC 3150 Page 16

How gcc compiles programs?• gcc by default hides all the intermediate steps.

– “gcc -o hello hello.c” generates the executable “hello” directly.

– “gcc -c hello.c” generates the object code“hello.o” directly.

• How about working with multiple files?

Extra Notes are the materials that the lecture will cover them, but they are not included in examinations. Nevertheless, those materials may be useful to assignments.

Page 17: 3150 Chapter 2 Part 1

Extra Notes

Fall semester2008-2009

CEG/CSC 3150 Page 17

Compiling Multiple FilesStep 1.

Step 2.

Step 3.

$ gcc –o prog *.o

$ gcc –c code.c......

*.c

*.o

prog

Prepare all the source files.Important: there must be one and only one file containing the main function. Compile them into object

codes one by one. Construct the program together with all the object codes.

Page 18: 3150 Chapter 2 Part 1

Extra Notes

Fall semester2008-2009

CEG/CSC 3150 Page 18

Compiling Multiple Files

int add_int(int a, int b) {return (a + b);

}

int multi_int(int a, int b) {if(b == 0)

return 0;else if(b == 1)

return a;else

return add_int(a, multi_int(a, b-1));}

gcc –Wall –c add_int.c

Program: add_int.c

Program: multi_int.c

File: add_int.o

$ gcc –Wall –c multi_int.cmulti_int.c: In function ‘multi_int’:multi_int.c:8: warning: implicit declaration of function ‘add_int’$ _

“add_int” is a new vocabulary, and gccdoesn’t know where it is.

Page 19: 3150 Chapter 2 Part 1

Extra Notes

Fall semester2008-2009

CEG/CSC 3150 Page 19

Compiling Multiple Files

#include “int_header.h”

int multi_int(int a, int b) {if(b == 0)

return 0;else if(b == 1)

return a;else

return add_int(a, multi_int(a, b-1));}

int add_int(int a, int b);

Header file: int_header.h The header file provides the declaration of a function.

It is the same as saying: “there is a function named add_int()”.

You don’t have to provide the implementation in the header file. Implementation should be provided in program files.

Of course, as we know what the pre-processor will do, the declaration of the function will be written into the program file.

Page 20: 3150 Chapter 2 Part 1

Extra Notes

Fall semester2008-2009

CEG/CSC 3150 Page 20

Compiling Multiple Files

#include “int_header.h”#include <stdio.h>

int main(void) {printf(“3 + 10 = %d\n”, add_int(3, 10) );printf(“3 * 10 = %d\n”, multi_int(3, 10) );return 0;

}

int add_int(int a, int b);int multi_int(int a, int b);

Header file: int_header.h

We expand the header file so that the main function knows that “there are functions called add_int() and multi_int()”.

Program: int_main.c

gcc –c add_int.cgcc –c multi_int.cgcc –c int_main.cgcc –o int_main *.o

Executable: int_main

Using double quotes means looking for the file in the current working directory.

Using “<......>”means looking for the file in the default include directories, e.g. “/usr/include/”.

Page 21: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 21

Conclusion on Programs• A program is just a file!

– It is static;– It may be associated with dynamically-linked

files;• “*.so” in Linux and “*.dll” in Windows.

– It may be compiled from more than one files.

Page 22: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 22

Process

System calls about processes

Page 23: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 23

Process• Process is irreplaceable in an OS.

– It associates with all the files opened by that process.– It attaches to all the memory that is allocated for it.– It contains every accounting information,

• such as the running time, current memory usage, who owns the process, etc.

• You can’t operate any things in an OS without processes.– So, this chapter is worth spending more than a month to cover.

• We start with some basic and important system calls.

Page 24: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 24

Process Identification• How can we identify processes from one to

another?– Each process is given an unique ID number, and is

called the process ID, or the PID.– The system call, getpid(), prints the PID of the

calling process.

$ getpidMy PID is 1234$ getpidMy PID is 1235$ getpidMy PID is 1240$ _

int main(void) {printf(“My PID is %d\n”, getpid() );return 0;

}

Program: getpid.c

Page 25: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 25

Process Creation• To create a process, we use the system

call fork().– 分叉 in Chinese.

Not this fork anyway…

Original execution flowof a process

The processinvokes fork().

The process splits into two!

Flow of original process

Flow of newly-created process

Page 26: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 26

Process Creation• So, how does fork() behave?

Process 1234

Process 1235

int main(void) {printf(“Ready to fork!\n”);fork();printf(“My PID is %d\n”, getpid() );return 0;

}

$ ./fork_example_1Ready to fork!My PID is 1234My PID is 1235$

Process 1234 is the original process, and we call it the parent process.

Process 1235 is created by the fork() system call, and we call it the child process.

Program: fork_example_1.c

Page 27: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 27

Process Creation

Process 1234

Process 1235

$ ./fork_example_1Ready to fork!My PID is 1234My PID is 1235$

Process 1234 is the original process, and we call it the parent process.

Process 1235 is created by the fork() system call, and we call it the child process.

• So, how does fork() behave?

• Summarize from the above printout:– Both the parent and the child processes execute the same program

code after fork().– The child process is not starting its execution from the beginning of the

program code.– The child process starts its execution after the location that fork() is

called.

Page 28: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 28

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Page 29: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 29

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Process1235

Process 1234 producesProcess 1235

Page 30: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 30

Process Creation

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …

Process1234

Process1235

• Let there be only one CPU. Then…– Only one process is allowed to be executed at one time.– However, we can’t predict which process will be chosen by the

OS.– This mechanism is called Process Scheduling. It will be

discussed in details in the next chapter.

• In this case, let’s assume that Process 1234 will be executed first.

Process 1234 producesProcess 1235

Page 31: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 31

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …result = 1235.

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Process1235

“result” is set to the PID of the child process. Process scheduling

Page 32: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 32

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Process1235

Process 1234: rest in peace. Process scheduling

Page 33: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 33

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.result = 0.

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Process1235

“result” is set to zero! Process scheduling

Page 34: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 34

Process Creation• Another example. Program: fork_example_2.c

$ ./fork_example_2before fork …result = 1235.I’m the parent.My PID is 1234program terminated.result = 0.I’m the child.My PID is 1235program terminated.$ _

1 int main(void) {2 int result;3 printf(“before fork …\n”);4 result = fork();5 printf(“result = %d.\n”, result);6 7 if(result == 0) {8 printf(“I’m the child.\n”);9 printf(“My PID is %d\n”, getpid());

10 }11 else12 printf(“I’m the parent.\n”);13 printf(“My PID is %d\n”, getpid());14 }1516 printf(“program terminated.\n”);17 }

Process1234

Process1235

Process 1235: rest in peace. Process scheduling

Page 35: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 35

Process Creation• fork() behaves like “cell division”.

– fork() creates the child process by cloningfrom the parent process, including…

Copied entities Description

Program counter That’s why they both execute from the same line of code after fork() returns.

Program code They are sharing the same piece of code.

Memory Including local variables, global variables, and allocated memory.

Opened file If the parent process has opened a file “A”, then the child process has also opened the file “A” automatically.

Page 36: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 36

Process Creation• However, fork() clones nearly all the

things from the parent process, except…

Distinct entities Parent process Child process

Return value of fork() PID of the child process Always 0.

PID number unchanged Different, not necessarily “parent PID +1”.

The parent unchanged Doesn’t have the same parent process as that of the parent process.

Running time unchanged Just created, so it is 0.

Page 37: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 37

Process Creation• Simple Exercise

– The command “pstree” is able to show the process relationship among the processes in the system.

– Modify “fork_example_*.c” so that you can see the process relationship of your created processes.

Page 38: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 38

Program Execution• fork() is rather boring…

– If a process can only duplicate itself and always runs the same program, then…

– how can we execute other programs?

• We have another set of system calls to do this job.– The exec() system call family.

Page 39: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 39

Program Execution• A member of exec system call family –execl()

Program: exec_example.c

$ ./exec_example_1before execl ...

Process1234

int main(void) {

printf(“before execl …\n”);

execl(“/bin/ls”, “/bin/ls”, NULL);

printf(“after execl ...\n”);

return 0;}

Program name

Program arguments

Page 40: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 40

Program Execution• A member of exec system call family –execl()

Program: exec_example.c

$ ./exec_example_1before execl ...exec_example_1exec_example_1.c

Process1234

Result from “/bin/ls”

int main(void) {

printf(“before execl …\n”);

execl(“/bin/ls”, “/bin/ls”, NULL);

printf(“after execl ...\n”);

return 0;}

Page 41: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 41

Program Execution• A member of exec system call family –execl()

Program: exec_example.c

$ ./exec_example_1before execl ...exec_example_1exec_example_1.c$ _

Process1234

int main(void) {

printf(“before execl …\n”);

execl(“/bin/ls”, “/bin/ls”, NULL);

printf(“after execl ...\n”);

return 0;}

What? Terminated?!What’d happened to these two lines of codes?

Page 42: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 42

Program Execution• The exec system call family is not simply a

function that “invokes” a command.– It is doing a very complex thing…

Process1234

int main(void) {

printf(“before execl …\n”);

execl(“/bin/ls”, “/bin/ls”, NULL);

printf(“after execl ...\n”);

return 0;}

Originally, I’m executing this code.

Page 43: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 43

Program Execution• The exec system call family is not simply a

function that “invokes” a command.– It is doing a very complex thing… file: /bin/ls

Process1234

int main(void) {

printf(“before execl …\n”);

execl(“/bin/ls”, “/bin/ls”, NULL);

printf(“after execl ...\n”);

return 0;}

Now, I change to execute the program: /bin/ls.

Page 44: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 44

Program Execution• The process is changing the code that it is executing and

never returns to the original code.– The last two lines of codes are therefore not executed.

• The process that calls any one of the member of the exec system call family will throw away many things, e.g.,– Memory: including local variables, global variables, and allocated

memory;– Register value: e.g., the program counter;

• But, the process will preserve something, such as– PID;– Process relationship;– Running time, etc.

Page 45: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 45

Program Execution• The exec system call family has 6 members and they are

named as…

Function Name

Path name File name Argument

list

Yes

Yes

Yes

letter in name p l v e

Yes

Yes

Yes

Yes

Yes

Yes

Argument Array

Original ENV

Provided ENV

execl Yes

execlp Yes

execle Yes

execv Yes Yes

execvp Yes Yes

execve Yes Yes

Page 46: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 46

Program Execution• Pathname vs Filename

• Argument list vs array

/home/tywong/os/shell.c

execl(“/bin/ls”, “/bin/ls”, “-l”, NULL);/bin/ls

-l

array[0]

array[1]

array[2]

NULLarray[3]

/bin/ls

execle(“/bin/ls”, array);

Environment will be covered in tutorials

Page 47: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 47

Program Execution• Simple Challenge

– Can you write two programs that behave as follows by using the exec system call family?

Program:yoyo1.c

Program:yoyo2.c

$ ./yoyo1running yoyo1 for the 1 time ...running yoyo2 for the 1 time ...running yoyo1 for the 2 time ...running yoyo2 for the 2 time ...running yoyo1 for the 3 time ...running yoyo2 for the 3 time .........(going indefinitely) Process

1234

Code execution is swinging back and forth.

Page 48: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 48

The system() call…• Someone may ask:

– Hey! I know there is a function called “system()”and it is convenient to use.

– Why would there be some stupid guys inventing the troublesome exec system call family?

int main(void) {printf(“before system …\n”);system(“ls”);printf(“after system …\n”);

}

$ ./system_examplebefore system ...exec_example_1exec_example_1.cafter system ...$ _

Program: system_example.c system(): what a great function!

Page 49: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 49

The system() library function call• Well…you’re reversing the order…

– “system()” is a library function call, and– it is built based on “fork()”, and exec system call

family.– (That’s why I’ve told you that system calls are not

programmer-friendly.)

int main(void) {printf(“before system …\n”);system(“ls”);printf(“after system …\n”);

}

We are now going to implement the system()function using system calls.

Program: system_example.c

Page 50: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 50

1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

system() Implementation

$ ./system_implement_1before system_ver_3150 ...system_implement_1system_implement_1.cafter system_ver_3150 ...$ _

Program: system_implement_1.c

“/bin/sh” is the shell program.

We actually want to execute the command:

/bin/sh -c [cmd_str]

Page 51: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 51

system() Implementation1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

Program: system_implement_1.c

However, when I run it for the 2nd time…

$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _

What’d happened?!

Page 52: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 52

1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

system() ImplementationProgram: system_implement_1.c

Let’s re-color the program!

Parent process

Child process

Both processes

$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _

$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _

Page 53: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 53

system() Implementation

$ ./system_implement_1before system_ver_3150 ...after system_ver_3150 ...system_implement_1system_implement_1.c$ _

$ ./system_implement_1before system_ver_3150 ...system_implement_1system_implement_1.cafter system_ver_3150 ...$ _

First Execution Sequence Second Execution Sequence

Parentfork()

Child

Parent

Parentfork()

Child

Parent

It is because of the OS’process scheduling…

Page 54: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 54

system() Implementation• Don’t forget that we’re trying to implement a system()-compatible function…– it is very weird to allow different execution orders.

• Our current problem is …how to let the child to execute first?– Sorry…we can’t control the process scheduling of the

OS to this extent.

• Then, our problem becomes…– How to suspend the execution of the parent process?– How to wake the parent up after the child is

terminated?

Page 55: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 55

system() Implementation1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }1213 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

Put something useful here!

Program: system_implement_2.c

We introduce you the wait()system call!

Page 56: 3150 Chapter 2 Part 1

system() Implementation – with wait()

Fall semester2008-2009

CEG/CSC 3150 Page 56

• The wait() system call allows a parent process to be suspended.

• wait() returns and wakes up the parent process when the status of the child process changes from– running to suspended; or– running to terminated.

• Another similar system call is waitpid().– wait() returns when one of the

children change status.– waitpid() returns when the

child specified by a PID changes status.

wait()

fork() Terminate

wake up

Case 1.

Parent is suspended.

wait()

fork() Terminate

Case 2.

no suspensionis needed.

Page 57: 3150 Chapter 2 Part 1

system() Implementation – with wait()

Fall semester2008-2009

CEG/CSC 3150 Page 57

1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }12 wait(NULL);13 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

When wait() returns, the parameter can tell the parent about the current status of the child process, i.e., terminated or suspended.

The parameter NULL means that “I don’t care about the child’s status”.

Look up the man page of wait by yourself.In Linux, the command is: “man 2 wait”

Program: system_implement_2.c

Page 58: 3150 Chapter 2 Part 1

system() Implementation – with wait()

Fall semester2008-2009

CEG/CSC 3150 Page 58

1 int system_ver_3150(const char *cmd_str) {2 if(cmd_str == NULL)3 return -1;45 if(fork() == 0) {6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);7 fprintf(stderr, 8 "%s: command not found\n",9 cmd_str);

10 exit(-1);11 }12 wait(NULL);13 return 0;14 }1516 int main(void) {17 printf("before system_ver_3150 ...\n");18 system_ver_3150("/bin/ls");19 printf("after system_ver_3150 ...\n");20 return 0;21 }

Pop Quiz!

Can we remove the “exit()” statement?

Hint. when the path “/bin/sh” cannot be found, the execl() call will continue executing this program code.

Program: system_implement_2.c

Page 59: 3150 Chapter 2 Part 1

Fall semester2008-2009

CEG/CSC 3150 Page 59

Summary• A process is created by cloning.

– fork() is the system call that clones processes.– Cloning is copying: the new process inherits many

things from the parent process.– (But, where is the first process?)

• Program execution is not trivial.– A process is the place that hosts a program and run it.– exec system call family changes the program that a

process is running.– A process can run more than one program.

• as long as there is a set of programs that keeps on calling the exec system call family.