View
216
Download
2
Embed Size (px)
Citation preview
Friday, June 09, 2006
“I think there is a world market for maybe five computers”.
- Thomas Watson, Chairman of IBM, 1943
System Calls
Example :UNIX read system call
Highly machine dependant (Assembly code)
We can make system calls through C program using library procedures.
System Calls
UNIX has an almost 1-1 relationship between system calls and library procedures
openreadwriteclose
POSIX defines about 100 procedure calls
Library procedures:A procedure call may itself make a system
call
e.g.
fopen
malloc
In Windows the library calls and actual system calls are decoupled
Win32 API calls number in thousands.Large number of calls or managing
windows, menus, scroll bars, dialog boxes, fonts, text… Not very clear which are system calls and
which are user-space library calls
Process Management
fork creates a new process in UnixIt creates an exact duplicate of the
original parent process including file descriptors, registers, etc (everything)
All variables have identical values at the time of fork Remember: Parent’s data is copied Subsequent changes do not affect each other
Process Management
int pid = fork();pid contains zero in child processpid contains the process id of child in
parent
int main(void){ int counter=0, i, statloc, pid; pid=fork(); if (pid==-1){ perror("fork"); exit(1); } else if (pid==0){ counter=100; for(i=0;i<5; i++){ printf("Child counter is %d\n", counter); counter++; sleep(2); } }
else { counter=500; for(i=0;i<5; i++){ printf("Parent counter is %d\n", counter); counter++; sleep(2); } waitpid(pid, &statloc, 0);}
return 0;}
Parent counter is 500Child counter is 100Child counter is 101Parent counter is 501Parent counter is 502Child counter is 102Child counter is 103Parent counter is 503Parent counter is 504Child counter is 104
One Possible Output
Parent counter is 500Child counter is 100Child counter is 101Parent counter is 501Parent counter is 502Child counter is 102Parent counter is 503Child counter is 103Child counter is 104Parent counter is 504
Another possible output
sleep suspends execution for an intervalwaitpid
can wait for a specific child or any child by setting first parameter to -1
man sleep
int main(void){ int counter=0, i, statloc, pid; pid=fork(); if (pid==-1){ perror("fork"); exit(1); } else if (pid==0){ counter=100; for(i=0;i<5; i++){ printf("Child counter is %d\n", counter); counter++; sleep(2); } }
else { waitpid(pid, &statloc, 0); counter=500; for(i=0;i<5; i++){ printf("Parent counter is %d\n",counter); counter++; sleep(2); }}
return 0;}
Child counter is 100Child counter is 101Child counter is 102Child counter is 103Child counter is 104Parent counter is 500Parent counter is 501Parent counter is 502Parent counter is 503Parent counter is 504
int main(void){ int i; int* counter; int pid; counter=(int*) malloc(sizeof(int)); pid=fork(); if (pid==-1){ perror("fork"); exit(1); } else if (pid==0){ *counter=100; for(i=0;i<5; i++){ printf("Child counter is %d\n", *counter); (*counter)++; sleep(2); } }
else { *counter=500; for(i=0;i<5; i++){ printf("Parent counter is %d\n",*counter); (*counter)++; sleep(2); } waitpid(pid, &statloc, 0);
}
return 0;}
Parent counter is 500Child counter is 100Child counter is 101Parent counter is 501Parent counter is 502Child counter is 102Child counter is 103Parent counter is 503Parent counter is 504Child counter is 104
One Possible Output
exec system call replaces the current process image with a new process image.
int main(int argc, char *argv[]){int i;int pid;int child_status;pid = fork();if (pid<0){ printf("Fork Failed"); exit(-1); }else if (pid==0){
printf("Child first line\n"); execlp("/bin/ls","ls",”-l”,NULL);
}
else { wait(&child_status); printf("Child Complete\n");
}return 0;}
Child first line-rwxr-xr-x 1 username group 9203 Jun 4 09:43 fork-ex-rw-r--r-- 1 username group 348 Jun 4 09:43 fork-ex.c-rw-r--r-- 1 username group 355 May 6 14:44 ex1.c-rw-r--r-- 1 username group 657 May 6 17:13 ex2.c-rw-r--r-- 1 username group 657 May 6 17:00 ex3.cChild Complete
Output
int main(int argc, char *argv[]){int i, pid, pid2;int child_status;pid = fork();if (pid==0){ pid2=fork(); if (pid2==0){ printf("%d GChild first line\n", getpid()); } else{ printf("%d Child first line\n", getpid()); waitpid(pid2, &child_status, 0); }}else { printf("%d Parent first line\n", getpid()); waitpid(pid, &child_status, 0); }return 0;}
13242 GChild first line13240 Parent first line13241 Child first line
One Possible Output
13243 Parent first line13244 Child first line13245 GChild first line
Another Possible Output
int main(int argc, char *argv[]){ int pid; int child_status; pid = fork(); if (pid<0){ printf("Fork Failed"); exit(-1); } else if (pid==0){ printf("Child first line\n"); execlp("/bin/cal","cal",NULL); //what happens here? printf("Child second line\n"); printf("Child third line\n"); }
else {//what if we move wait statement down?
wait(&child_status); printf("Parent line 1\n"); printf("Parent line 2\n"); printf("Parent line 3\n"); } return 0;}
Child first line June 2006 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 1011 12 13 14 15 16 1718 19 20 21 22 23 2425 26 27 28 29 30
Parent line 1Parent line 2Parent line 3
OUTPUT
Simple shell
while(1) {type_prompt();read_command(command, parameters);if (fork()!=0){waitpid(-1, &status, 0);}else {exec(command, parameters, 0);}
}
Signals
Notification sent to a process in order to notify it of important events.
Each signal has an integer number (as well as symbolic name) that represents it
Signals
Why signals?
int main(int argc, char *argv[]){ int pid; int i; signal(SIGCHLD, catch_child); pid=fork(); if (pid==0){
execlp("/bin/ls", "ls", NULL);}
for (i=0; i<10; i++){ printf("%d\n", i); sleep(1); }
return 0;}
void catch_child(int sig_num){ int child_status; wait(&child_status); printf("child exited with code %d\n", child_status);}
int main(int argc, char *argv[]){ int i; int pid, pid2, pid3; int child_status; pid = fork(); //pid contains zero for child process if (pid==0){ pid2=fork(); if (pid2==0){ printf("hello"); } else{ printf("there"); wait(&child_status); } }
else { pid3=fork(); if (pid3==0){ printf("Good"); } else{ printf("Luck"); wait(&child_status); } } return 0;}
Process TerminationLast instructionexit() system call
After fork() call: The child process inherits all files that
were open in the parent process. If one of them reads from such an open file, the read/write pointer is advanced for both of them.
If one process closes a shared file, it is still kept open in the other process.
Files opened after the call to fork() are not shared by both processes.
Ctrl-C SIGINTCtrl-Z SIGTSTP
Default signal handlersSIGSEGV – Segmentation violation – Core
dumped
Comparison
System Calls for I/O 5 basic UNIX system calls for file I/O
open
close
read
write
lseekDifferent from regular procedure calls.
How?
open System Call
open ( path, mode flags)
int fd = open("/dir1/file1", O_RDONLY);
int fd = open("/dir1/file1", O_WRONLY | O_APPEND);
System Calls for I/OEvery process in Unix starts out with three
file descriptors file descriptor 0 is standard inputfile descriptor 1 is standard outputfile descriptor 2 is standard error
read(0, …) //read from standard inputwrite(1, …) //write to standard output
open System Call
O_RDONLY Open the file in read-only mode.
O_WRONLY Open the file in write-only mode.
O_RDWR Open the file for both reading and writing.
In addition, any of the following flags may be OR-ed with the mode flag:
O_CREAT If the file does not exist already - create it.
open System Call
O_EXCL If used together with O_CREAT, the call will fail if the file already exists.
O_TRUNC If the file already exists, truncate it (i.e. erase its
contents).
O_APPEND Open the file in append mode. Any data written to the file is
appended at the end of the file.
close System Call
close (filedescriptor)
if (close(fd) == -1) { perror("close"); exit(1);}
read System Call
int num_read = read(filedescriptor, buffer, nbytes);
num_read == 0 ? num_read < 0 ?
write System Call
int num = write(filedescriptor, buffer, nbytes);
num < 0 ?
File permissions
access( “/dir1/file1”, R_OK) ==0read access granted
access( “/dir1/file1”, R_OK | W_OK ) ==0
read/ write access granted
R_OK Test for read permission.W_OK Test for write permission. X_OK Test for execute or search permission. F_OK Check existence of file
File permissions
chmod( “/dir1/file1”, S_IRGRP)
ps -ef | grep yourusernameps -ef | grep init
execlp("/bin/ls","ls","-l",”..”, NULL);
cat filea fileb filec | sort > /dev/lp &
man -s 2 readman –a read
gcc -g -Wall fork-ex.c -o fork-exIt is good practice to always use the -Wall option
lseek System Call
int num = lseek( filedescriptor, offset, whence);
num < 0 ?
Practice Homework
open System Call
S_IRWXU Owner of the file has read, write and execute
permissions to the file.
S_IRUSR Owner of the file has read permission to the file.
S_IWUSR Owner of the file has write permission to the file.
S_IXUSR Owner of the file has execute permission to the file.
Practice Homework
open System Call
S_IRWXG Group of the file has read,write and execute
permissions to the file.
S_IRGRP Group of the file has read permission to the file.
S_IWGRP Group of the file has write permission to the file.
S_IXGRP Group of the file has execute permission to the file.
Practice Homework
open System Call
S_IRWXO Other users have read,write and execute permissions to
the file.
S_IROTH Other users have read permission to the file.
S_IWOTH Other users have write permission to the file.
S_IXOTH Other users have execute permission to the file.
Practice Homework
Directories
#include <dirent.h>/* open the directory for reading. */DIR* dir = opendir("/dir1/subdir2/");if (!dir) { perror("opendir"); exit(1);}
if (closedir(dir) == -1) { perror("closedir"); exit(1); }
Practice Homework
Directories
struct dirent* entry;
while ( (entry = readdir(dir)) != NULL)
{
printf("%s\n", entry->d_name);
}
Practice Homework
void function(DIR* dirp, char* dir_path){ struct dirent* dir_entry; char* full_path; while ( (dir_entry = readdir(dirp)) != NULL) { if (strcmp(dir_entry->d_name, ".") == 0) continue; if (strcmp(dir_entry->d_name, "..") == 0) continue; full_path=(char*)malloc(strlen(dir_path)
+strlen(dir_entry->d_name)+1); strcpy(full_path, dir_path); strcat(full_path, dir_entry->d_name); printf("dir_entry->d_name = %s\n",dir_entry->d_name); if (access(full_path, R_OK) == -1) { printf("read permission to file denied.\n"); return; } free(full_path); }}
Practice Homework
File status
struct stat file_status
stat( “/dir1/file1”, &file_status)
if (S_ISDIR(file_status.stmode))
if (S_ISFIFO(file_status.stmode))
Practice Homework