Title: CS 241 Section Week
1CS 241 Section Week 3(09/11/08)
2Topics This Section
- Review of HW1
- Lecture review
- MP1
- Processes
3Review of HW1
4Function (call by value vs call by reference)
5. void increment(int x) x ...
for(x0xlt10increment(x)) printf("xd\n",x
)
the x in the increment function is local to it
incrementing x there doesn't change the value
outside the function.
5Memory
10. char s s(char ) malloc (100)
s"hello" free(s)
s points to the string in the string constant
table and the allocated block is orphaned. Hence
a free() will cause segmentation fault.
6Dynamic allocation of two-dimensional arrays
int array int i,j,10 array
malloc(10sizeof(int)) for(i0ilt10i)
for(j0jlt10j) arrayij ij
While the first layer of array is allocated, the
second layer is not. Each arrayi needs to be
allocated to be used as an array. Therefore, add
a malloc statement inside the loop
7Precedence
27. char str,p ... pstr while(p!0)
p p
This code attempts to increment every value in a
string. However, binds more closely to p than
. Therefore "p" is the same as "(p)". This
program will not change str at all.
8Macros
30. define cube(x) xxx define double(x)
xx x 3 y cube(x 1) z 5 double(x)
The compiler simply replaces a macro reference
with expanded text according to the macro's
definition. Hence the compiler expands cube(x1)
as x 1x 1x 1. You can avoid many
problems with macros by following a simple rule
Put parentheses (or other explicit delimiters)
around the macro text and around each macro
argument within the macro text.
9String manipulation functions
- Read some source string(s), possibly write to
some destination location - char strcpy(char dst, char const src)
- char strcat (char dst, char const src)
- Programmers responsibility to ensure that
- destination region large enough to hold result
- source, destination regions dont overlap
- undefined behavior in this case
- according to C spec, anything could happen!
- char m10 ?dog?
- strcpy(m1, m)
Assuming that the implementation of strcpy starts
copying left-to-right without checking for the
presence of a terminating NUL first, what will
happen?
10Lecture Review
11Environment variables
- Setting an environment variable
- VAR/home/lchen2/doc
- export PATHPATH/home/lchen2/exec
- SYSTEMNAMEuname n
- Using environment variables
- echo VAR
- cd HOME (same as cd)
- echo You are running on SYSTEMNAME
12Some important environment variables
- HOME
- Your home directory (can often be abbreviated as
) - TERM
- The type of terminal you are running
- PWD
- Current working directory
- PATH
- List of directories to search for commands
13PATH environment variable
- Controls where commands are found
- PATH is a list of directory pathnames separated
by colons() - If a command does not begin with a slash, the
shell tries finding the command in each directory
in PATH. The first match is the command that is
run. - Same PATH
- PATH/bin/usr/bin/usr/X11R6/bin/usr/local/bin
- Some people include . in PATH
- It may be a security problem
14extern
- To indicate the existence of, and the type of, a
global variable - To inform the compiler about variables declared
outside of the current scope - Will not have any space allocated for them
- To allow data to span the scope of multiple files
15MP1
16MP1
- Part1
- Write your code between the markers we provide in
the code. Don't move the comments into one line. - Recall that a char value can be thought of as
either a character or a small integer - a 1 is b
- Z - A is 25
- Part2
- 2e we accept both
- (s1 s2) s3
- (s1 s2) (s2s3)
17Processes
18Process Creation with fork()
- fork() creates a new process
env
env
fork() creates
stack
stack
free
free
heap
heap
static
static
code
code
Parent Child
- The new (child) process is identical to the old
(parent) process, except
19Differences between parent and child
- Process ID (getpid())
- Parent ID (getppid())
- Return value of fork()
- In parent, fork() returns child pid
- In child, fork() returns 0
20fork() Example 1
- What does this do?
- fprintf(stdout,d\n,fork())
21fork() example 2
- include ltstdio.hgt
- include ltsys/types.hgt
- include ltunistd.hgt
- int main(int argc, char argv)
- pid_t child_pid fork()
- if (child_pid lt 0) // error code
- perror(Fork Failed)
- return 1
-
- fprintf(stdout, I am process d\n,getpid())
- if (child_pid 0) // child code
- fprintf(stdout,Im the child process.\n)
- else // parent code
- fprintf(stdout,Im the parent of child process
d.\n, child_pid) -
- return 0
-
22Example 2 contd
- This exits too quickly lets slow it down
if (child_pid 0) // child code sleep(15) fp
rintf(stdout,Im the child process.\n) else
// parent code sleep(20) fprintf(stdout,Im
the parent of child process d.\n,
child_pid)
23Example 2 contd
- In a second window, run ps a, and look for the
pids from the program output. - Periodically run ps a again, as the program in
the first window executes. - What happens when the program runs?
- What happens when the child finishes?
- What happens when the parent finishes?
- What happens when you switch the parent and child
sleep statements?
24Process Termination
- Normal exit (voluntary)
- End of main()
- Error exit (voluntary)
- exit(2)
- Fatal error (involuntary)
- Divide by 0, core dump / seg fault
- Killed by another process (involuntary)
- Kill procID, end task
25- How can a parent know when its children are done?
26Solution wait()
- wait() allows a parent to wait for its child
process, and save its return value - pid wait(status , options)
- pid waitpid(pid , status ,options)
- wait() waits for any child waitpid() waits for a
specific child.
27wait contd
- wait() blocks until child finishes
- wait() does not block if the option WNOHANG is
included. When would we want to use this? - The childs return value is stored in status
28wait(...) macros
- WIFEXITED(status) is true iff the process
terminated normally. - WEXITSTATUS(status) gives the last 8 bits of the
processs return value (assuming normal exit)
29Example 3 wait
- include ltsys/wait.hgt
-
-
- // add this to parent code
- if (waitpid(child_pid, result, 0) -1)
- perror(Wait failed)
- return -1
-
- if( WIFEXITED(result))
- fprintf(stdout, child d returned d\n,
child_pid, WEXITSTATUS(result))
30exec
- exec replaces the current process image(code,
variables, etc.) with that of a new program
Before
After
env
env
exec
stack
New Program
free
heap
static
code
The program may choose to change the environment
31exec variations
- There are 6 different ways of calling exec.
Which one to use depends on three conditions - How arguments are passed
- How the path is specified
- Whether a new environment is used
32exec variations passing parameters
- exec can have parameters passed to it two
different ways - List of parameters
- execl(/usr/bin/ls, ls, -l, NULL)
- Argument Vector (like argv)
- execv(argv1,argv1)
- Q When would you use execl?
- When would you use execv?
33exec variations command path
- Adding a p to an exec call tells the system to
look for the command in the environments path. - Compare
- execl(/usr/bin/ls, ls, -l, NULL)
- execlp(ls, ls, -l, NULL)
- The difference is similar for execv and execvp.
34exec variations (contd)
- By default, the new program inherits the old
programs environment. Adding an e to the exec
call allows the new program to run with a new
environment environ - execve and execle allow the user to specify the
environment. The others inherit the old
environment.
35fork exec
- If exec succeeds, it does not return, as it
overwrites the program. - No checking return values, executing multiple
commands, monitoring results, etc. - Solution fork a new process, and have the child
run exec
36Example 5 exec
- include ltunistd.hgt
- include ltstdio.hgt
- int main(int argc, char argv)
- child_pid fork()
- if (child_pid lt 0)
- perror(Fork failed)
- return 1
- else if (child_pid 0)
- if (execvp(argv1, argv1) lt 0)
- fprintf(stderr,Failed to execute s!\n,
argv1) - perror(child exec)
- return -1
-
-
- // What belongs here?
- ...
- return 0