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?
Fall semester CEG/CSC 3150 Page 2
2008-2009
3. Program vs Process
What is a Program?
Fall semester CEG/CSC 3150 Page 3
2008-2009
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.
Fall semester CEG/CSC 3150 Page 4
2008-2009
5. Building a program – initial phase…
hello.c hello.c
High-level Expanded
programming Pre-processor
code
language
#define TXT “hello” Compiler hello.s
int main(void) {
printf(“%sn”, TXT);
Assembly
return 0; Optimizer
} code
Program: hello.c
Fall semester CEG/CSC 3150 Page 5
2008-2009
6. Pre-processor
• The pre-processor expands:
– #define, #include, #ifdef, #ifndef,
#endif, etc.
– Try: gcc –E define.c
#define TXT “hello”
int main(void) {
int main(void) { printf(“%sn”, “hello” );
printf(“%sn”, TXT ); return 0;
return 0; }
} Pre-processor
Program: hello.c
Fall semester CEG/CSC 3150 Page 6
2008-2009
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 = %dn", i, j);
SWAP(i, j);
printf("after swap: i = %d, j = %dn", i, j);
} Program: swap.c
int main(void) {
int i = 10, j = 20;
printf("before swap: i = %d, j = %dn", i, j)
Pre-processor { int c; c = i; i = j; j = c; };
printf("after swap: i = %d, j = %dn", i, j);
}
Fall semester CEG/CSC 3150 Page 7
2008-2009
8. Pre-processor
• How about #include?
#include “header.h” int add_fun(int a, int b) {
return (a + b);
int main(void) { }
add_fun(1,2);
return 0; Program: header.h
}
Program: include.c
int add_fun(int a, int b) {
return (a + b);
}
int main(void) {
Pre-processor add_fun(1,2);
return 0;
}
Fall semester CEG/CSC 3150 Page 8
2008-2009
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.
Fall semester CEG/CSC 3150 Page 9
2008-2009
10. Compiler and Optimizer
• The optimizer optimizes codes.
– In other words: it improves stupid “-O” means optimize.
The number is the
codes! optimization level.
– Try:
-O0: means no optimization.
• gcc –S add.c –O0 –o add_O0.s
• gcc –S add.c –O1 –o add_O1.s Max is level 3, i.e., -O3
int main(void) {
• Important notice: Don’t write int x =1;
x = x + 1;
stupid codes because there is x = x + 1;
return x;
an optimizer! }
Program: add.c
An example of stupid codes.
Fall semester CEG/CSC 3150 Page 10
2008-2009
11. Building a program – next phase…
hello.s hello.o
Assembly Assembler Object
code “as” code
Static/Dynamic Linker Executable
library “ld”
hello.exe
lib*.a or lib*.so
Fall semester CEG/CSC 3150 Page 11
2008-2009
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
Fall semester CEG/CSC 3150 Page 12
2008-2009
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.
Fall semester CEG/CSC 3150 Page 13
2008-2009
14. Library File
Static library file. Dynamic library file.
A smaller
The final program!
program is the
combination of
the above two
codes. The OS will look for this file
when the program runs.
Fall semester CEG/CSC 3150 Page 14
2008-2009
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.
SO – Shared Object
Jargon
Alert
Fall semester CEG/CSC 3150 Page 15
2008-2009
16. Extra Notes
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.
Fall semester CEG/CSC 3150 Page 16
2008-2009
17. Extra Notes
Compiling Multiple Files
Step 1.
Step 2.
Step 3.
$ gcc –c code.c
......
$ gcc –o prog *.o
*.c
*.o
Prepare all the source
files.
Important: there must be
one and only one file prog
containing the main
function. Compile them into object
codes one by one. Construct the program
together with all the object
codes.
Fall semester CEG/CSC 3150 Page 17
2008-2009
18. Extra Notes
Compiling Multiple Files
int add_int(int a, int b) {
return (a + b); gcc –Wall –c add_int.c
}
Program: add_int.c
File: add_int.o
int multi_int(int a, int b) {
if(b == 0)
“add_int” is a new
return 0;
vocabulary, and gcc
else if(b == 1)
doesn’t know where it is.
return a;
else
return add_int(a, multi_int(a, b-1));
}
Program: multi_int.c
$ gcc –Wall –c multi_int.c
multi_int.c: In function ‘multi_int’:
multi_int.c:8: warning: implicit declaration of function ‘add_int’
$ _
Fall semester CEG/CSC 3150 Page 18
2008-2009
19. Extra Notes
Compiling Multiple Files
int add_int(int a, int b);
Header file: int_header.h The header file provides the
declaration of a function.
#include “int_header.h”
It is the same as saying: “there is
int multi_int(int a, int b) { a function named add_int()”.
if(b == 0)
return 0;
You don’t have to provide the
else if(b == 1)
return a; implementation in the header file.
else Implementation should be
return add_int(a, multi_int(a, b-1)); 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.
Fall semester CEG/CSC 3150 Page 19
2008-2009
20. Extra Notes
Compiling Multiple Files
int add_int(int a, int b); Using double quotes
int multi_int(int a, int b); means looking for the file
Header file: int_header.h in the current working
directory.
#include “int_header.h”
#include <stdio.h> Using “<......>”
means looking for the file
int main(void) { in the default include
printf(“3 + 10 = %dn”, add_int(3, 10) ); directories, e.g.
printf(“3 * 10 = %dn”, multi_int(3, 10) ); “/usr/include/”.
return 0;
}
Program: int_main.c
We expand the header file so that the main
function knows that “there are functions
gcc –c add_int.c
gcc –c multi_int.c
gcc –c int_main.c called add_int() and multi_int()”.
gcc –o int_main *.o
Executable: int_main
Fall semester CEG/CSC 3150 Page 20
2008-2009
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.
Fall semester CEG/CSC 3150 Page 21
2008-2009
22. Process
System calls about processes
Fall semester CEG/CSC 3150 Page 22
2008-2009
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.
Fall semester CEG/CSC 3150 Page 23
2008-2009
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.
$ getpid
int main(void) { My PID is 1234
printf(“My PID is %dn”, getpid() ); $ getpid
return 0; My PID is 1235
} $ getpid
My PID is 1240
$ _
Program: getpid.c
Fall semester CEG/CSC 3150 Page 24
2008-2009
25. Process Creation
• To create a process, we use the system
call fork().
– 分叉 in Chinese. The process splits into two!
Original execution flow
of a process
The process
invokes fork().
Flow of original process
Flow of newly-created process
Not this fork anyway…
Fall semester CEG/CSC 3150 Page 25
2008-2009
26. Process Creation
• So, how does fork() behave?
Process 1234 is the
$ ./fork_example_1 Process 1234 original process, and we
Ready to fork! call it the parent process.
My PID is 1234
My PID is 1235
$
Process 1235 is created by
Process 1235 the fork() system call, and
we call it the child process.
int main(void) {
printf(“Ready to fork!n”);
fork();
printf(“My PID is %dn”, getpid() );
return 0;
}
Program: fork_example_1.c
Fall semester CEG/CSC 3150 Page 26
2008-2009
27. Process Creation
• So, how does fork() behave?
Process 1234 is the
$ ./fork_example_1 Process 1234 original process, and we
Ready to fork! call it the parent process.
My PID is 1234
My PID is 1235
$
Process 1235 is created by
Process 1235 the fork() system call, and
we call it the child process.
• 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.
Fall semester CEG/CSC 3150 Page 27
2008-2009
28. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
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 %dn”, getpid());
10 }
11 else
12 printf(“I’m the parent.n”);
13 printf(“My PID is %dn”, getpid());
14 }
15 Process
16 printf(“program terminated.n”); 1234
17 }
Fall semester CEG/CSC 3150 Page 28
2008-2009
29. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
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 %dn”, getpid());
10 }
11 else
12 printf(“I’m the parent.n”);
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
Process 1234 produces
Process 1235
Fall semester CEG/CSC 3150 Page 29
2008-2009
30. Process Creation
• Another example. Program: fork_example_2.c
• Let there be only one CPU. Then…
1 int main(void) {
2 – Only one process is allowed to be executed./fork_example_2
int result; $ at one time.
3 printf(“before fork …n”);
– However, we can’t predict which process before fork … by
will be chosen the
4 result = fork();
5 OS.
printf(“result = %d.n”, result);
6 – This mechanism is called Process Scheduling. It will be
7
8
discussed== 0) { child.n”);
if(result
in details in the next chapter.
printf(“I’m the
9 printf(“My PID is %dn”, getpid());
10 }
• In this case, let’s assume that Process 1234 will be
11 else
12 printf(“I’m the parent.n”);
executed first.
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
Process 1234 produces
Process 1235
Fall semester CEG/CSC 3150 Page 30
2008-2009
31. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
4 result = fork(); result = 1235.
5 printf(“result = %d.n”, result);
6
7 if(result == 0) {
8 printf(“I’m the child.n”);
9 printf(“My PID is %dn”, getpid());
10 }
11 else
12 printf(“I’m the parent.n”);
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
“result” is set to the PID of the child process. Process scheduling
Fall semester CEG/CSC 3150 Page 31
2008-2009
32. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
4 result = fork(); result = 1235.
5 printf(“result = %d.n”, result); I’m the parent.
6 My PID is 1234
7 if(result == 0) { program terminated.
8 printf(“I’m the child.n”);
9 printf(“My PID is %dn”, getpid());
10 }
11 else
12 printf(“I’m the parent.n”);
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
Process 1234: rest in peace. Process scheduling
Fall semester CEG/CSC 3150 Page 32
2008-2009
33. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
4 result = fork(); result = 1235.
5 printf(“result = %d.n”, result); I’m the parent.
6 My PID is 1234
7 if(result == 0) { program terminated.
8 printf(“I’m the child.n”); result = 0.
9 printf(“My PID is %dn”, getpid());
10 }
11 else
12 printf(“I’m the parent.n”);
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
“result” is set to zero! Process scheduling
Fall semester CEG/CSC 3150 Page 33
2008-2009
34. Process Creation
• Another example. Program: fork_example_2.c
1 int main(void) {
2 int result; $ ./fork_example_2
3 printf(“before fork …n”); before fork …
4 result = fork(); result = 1235.
5 printf(“result = %d.n”, result); I’m the parent.
6 My PID is 1234
7 if(result == 0) { program terminated.
8 printf(“I’m the child.n”); result = 0.
9 printf(“My PID is %dn”, getpid()); I’m the child.
10 } My PID is 1235
11 else program terminated.
12 printf(“I’m the parent.n”); $ _
13 printf(“My PID is %dn”, getpid());
14 }
15 Process Process
16 printf(“program terminated.n”); 1234 1235
17 }
Process 1235: rest in peace. Process scheduling
Fall semester CEG/CSC 3150 Page 34
2008-2009
35. Process Creation
• fork() behaves like “cell division”.
– fork() creates the child process by cloning
from 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.
Fall semester CEG/CSC 3150 Page 35
2008-2009
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.
Fall semester CEG/CSC 3150 Page 36
2008-2009
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.
Fall semester CEG/CSC 3150 Page 37
2008-2009
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.
Fall semester CEG/CSC 3150 Page 38
2008-2009
39. Program Execution
• A member of exec system call family –
execl()
Program name
Program arguments
int main(void) {
$ ./exec_example_1
printf(“before execl …n”); before execl ...
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...n”);
return 0;
}
Process
Program: exec_example.c 1234
Fall semester CEG/CSC 3150 Page 39
2008-2009
40. Program Execution
• A member of exec system call family –
execl()
Result from “/bin/ls”
int main(void) {
$ ./exec_example_1
printf(“before execl …n”); before execl ...
exec_example_1
execl(“/bin/ls”, “/bin/ls”, NULL); exec_example_1.c
printf(“after execl ...n”);
return 0;
}
Process
Program: exec_example.c 1234
Fall semester CEG/CSC 3150 Page 40
2008-2009
41. Program Execution
• A member of exec system call family –
execl() What? Terminated?!
What’d happened to these two lines of codes?
int main(void) {
$ ./exec_example_1
printf(“before execl …n”); before execl ...
exec_example_1
execl(“/bin/ls”, “/bin/ls”, NULL); exec_example_1.c
$ _
printf(“after execl ...n”);
return 0;
}
Process
Program: exec_example.c 1234
Fall semester CEG/CSC 3150 Page 41
2008-2009
42. Program Execution
• The exec system call family is not simply a
function that “invokes” a command.
– It is doing a very complex thing…
int main(void) {
printf(“before execl …n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...n”);
return 0;
}
Originally, I’m Process
executing this code. 1234
Fall semester CEG/CSC 3150 Page 42
2008-2009
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
int main(void) {
printf(“before execl …n”);
execl(“/bin/ls”, “/bin/ls”, NULL);
printf(“after execl ...n”); Now, I change to
execute the program:
return 0; /bin/ls.
}
Process
1234
Fall semester CEG/CSC 3150 Page 43
2008-2009
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.
Fall semester CEG/CSC 3150 Page 44
2008-2009
45. Program Execution
• The exec system call family has 6 members and they are
named as…
Function Path Argument Argument Original Provided
File name
Name name list Array ENV ENV
execl Yes Yes Yes
execlp Yes Yes Yes
execle Yes Yes Yes
execv Yes Yes Yes
execvp Yes Yes Yes
execve Yes Yes Yes
letter
p l v e
in name
Fall semester CEG/CSC 3150 Page 45
2008-2009
46. Program Execution
• Pathname vs Filename
Environment will be
covered in tutorials
/home/tywong/os/shell.c
• Argument list vs array
array[0] /bin/ls
execl(“/bin/ls”, “/bin/ls”, “-l”, NULL);
array[1] /bin/ls
execle(“/bin/ls”, array);
array[2] -l
array[3] NULL
Fall semester CEG/CSC 3150 Page 46
2008-2009
47. Program Execution
• Simple Challenge
– Can you write two programs that behave as
follows by using the exec system call family?
Program: Program:
yoyo1.c yoyo2.c
$ ./yoyo1
running yoyo1 for the 1 time ... Code execution is
running yoyo2 for the 1 time ... swinging back and forth.
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
Fall semester CEG/CSC 3150 Page 47
2008-2009
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?
$ ./system_example
int main(void) { before system ...
printf(“before system …n”); exec_example_1
system(“ls”); exec_example_1.c
printf(“after system …n”); after system ...
} $ _
Program: system_example.c
system(): what a great function!
Fall semester CEG/CSC 3150 Page 48
2008-2009
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) {
We are now going to
printf(“before system …n”);
system(“ls”); implement the system()
printf(“after system …n”); function using system calls.
}
Program: system_example.c
Fall semester CEG/CSC 3150 Page 49
2008-2009
50. system() Implementation
Program: system_implement_1.c
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
3 return -1;
4
“/bin/sh” is the shell
5 if(fork() == 0) { program.
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr, We actually want to
8 "%s: command not foundn", execute the command:
9 cmd_str);
10 exit(-1);
/bin/sh -c [cmd_str]
11 }
12
13 return 0;
14 }
15 $ ./system_implement_1
16 int main(void) { before system_ver_3150 ...
17 printf("before system_ver_3150 ...n"); system_implement_1
18 system_ver_3150("/bin/ls"); system_implement_1.c
19 printf("after system_ver_3150 ...n"); after system_ver_3150 ...
20 return 0; $ _
21 }
Fall semester CEG/CSC 3150 Page 50
2008-2009
51. system() Implementation
Program: system_implement_1.c
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
3 return -1;
4
5 if(fork() == 0) {
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr,
8 "%s: command not foundn",
9 cmd_str);
10 exit(-1); However, when I run it for the
11 } 2nd time…
12 What’d happened?!
13 return 0;
14 }
15 $ ./system_implement_1
16 int main(void) { before system_ver_3150 ...
17 printf("before system_ver_3150 ...n"); after system_ver_3150 ...
18 system_ver_3150("/bin/ls"); system_implement_1
19 printf("after system_ver_3150 ...n"); system_implement_1.c
20 return 0; $ _
21 }
Fall semester CEG/CSC 3150 Page 51
2008-2009
52. system() Implementation
Program: system_implement_1.c
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
3 return -1; Let’s re-color the program!
4
5 if(fork() == 0) { Parent process
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr,
Child process
8 "%s: command not foundn",
9 cmd_str); Both processes
10 exit(-1);
11 }
12
13 return 0;
14 }
15 $ ./system_implement_1
16 int main(void) { before system_ver_3150 ...
17 printf("before system_ver_3150 ...n"); after system_ver_3150 ...
18 system_ver_3150("/bin/ls"); system_implement_1
19 printf("after system_ver_3150 ...n"); system_implement_1.c
20 return 0; $ _
21 }
Fall semester CEG/CSC 3150 Page 52
2008-2009
53. system() Implementation
It is because of the OS’
process scheduling…
First Execution Sequence Second Execution Sequence
fork() fork()
Parent Child Parent Parent
Parent Child
$ ./system_implement_1 $ ./system_implement_1
before system_ver_3150 ... before system_ver_3150 ...
system_implement_1 after system_ver_3150 ...
system_implement_1.c system_implement_1
after system_ver_3150 ... system_implement_1.c
$ _ $ _
Fall semester CEG/CSC 3150 Page 53
2008-2009
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?
Fall semester CEG/CSC 3150 Page 54
2008-2009
55. system() Implementation
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
Program: system_implement_2.c
3 return -1;
4
5 if(fork() == 0) {
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr,
8 "%s: command not foundn",
9 cmd_str);
10 exit(-1);
11 }
12 Put something useful here! We introduce you
13 return 0; the wait()
14 } system call!
15
16 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 }
Fall semester CEG/CSC 3150 Page 55
2008-2009
56. system() Implementation – with wait()
• The wait() system call allows a wake up
parent process to be suspended. wait()
• wait() returns and wakes up the
Parent is
parent process when the status of suspended.
the child process changes from
– running to suspended; or
– running to terminated. fork() Terminate
Case 1.
• Another similar system call is Case 2.
waitpid(). wait()
– wait() returns when one of the
children change status.
– waitpid() returns when the no suspension
child specified by a PID changes is needed.
status.
fork() Terminate
Fall semester CEG/CSC 3150 Page 56
2008-2009
57. system() Implementation – with wait()
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
3 return -1; Program: system_implement_2.c
4
5 if(fork() == 0) {
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr,
8 "%s: command not foundn",
9 cmd_str);
10 exit(-1); When wait() returns, the parameter can
11 }
tell the parent about the current status of
12 wait(NULL);
13 return 0; the child process, i.e., terminated or
14 } suspended.
15
16 int main(void) { The parameter NULL means that “I don’t
17 printf("before system_ver_3150 care about the child’s status”.
...n");
18 system_ver_3150("/bin/ls");
19 printf("after system_ver_3150 ...n");
20 return 0;
Look up the man page of wait by yourself.
21 } In Linux, the command is: “man 2 wait”
Fall semester CEG/CSC 3150 Page 57
2008-2009
58. system() Implementation – with wait()
1 int system_ver_3150(const char *cmd_str) {
2 if(cmd_str == NULL)
3 return -1; Program: system_implement_2.c
4
5 if(fork() == 0) {
6 execl("/bin/sh", "/bin/sh", "-c", cmd_str, NULL);
7 fprintf(stderr,
8 "%s: command not foundn",
9 cmd_str);
10 exit(-1);
11 }
12 wait(NULL);
13 return 0; Pop Quiz!
14 }
15
16 int main(void) { Can we remove the “exit()” statement?
17 printf("before system_ver_3150 ...n");
18 system_ver_3150("/bin/ls");Hint. when the path “/bin/sh” cannot be
19 printf("after system_ver_3150 ...n");
found, the execl() call will continue
20 return 0; executing this program code.
21 }
Fall semester CEG/CSC 3150 Page 58
2008-2009
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.
Fall semester CEG/CSC 3150 Page 59
2008-2009