Information OPERATIVSYSTEM UNIXPROGRAMMERING Lärare: Reine Lundin Rum: 5A 429 E-post: reine.lundin@kau.se Hemsida: www.cs.kau.se/~reine/ Telefon: 700 18 60 Laborationer Append (filhantering) Med Systemanrop. Enligt ANSI -standarden. Semaforer (processhantering) Kommandotolk (fil + processhantering) 6/25/03 RL - Operativsystem 1 6/25/03 RL - Operativsystem 2 1
Jämförelse mellan C och C++ Olika format cin - scanf int scanf(sträng, arg1, arg2,...) cout - printf int printf(sträng, arg1, arg2, ) g++ - gcc fil.cc - fil.c Alla dekl. överst i funktionerna. c Tecken d Heltal f Flyttal (float) lf Flyttal (double) s Textsträng Man kan även ange antal tecken: printf( %10d, ); 10 positioner upptas alltid vid utskrift. printf( %.2f, ); Utskrift med två decimaler. printf( %6.2f, ); Två decimaler och totalt sex tecken. scanf( %2f, ); Läser endast in två tecken. 6/25/03 RL - Operativsystem 3 6/25/03 RL - Operativsystem 4 2
Exempel 1 Filhantering 1 #include <stdio.h> int main(void) int age; char name[50]; printf( How old are you: ); scanf( %d, &age); printf( What is your name? ); scanf( %49s, name); printf( Hi %s, you are %d years old\n, name, age); Systemanrop open creat close read write lseek unlink ANSI-C fopen fread fwrite fseek fclose 6/25/03 RL - Operativsystem 5 6/25/03 RL - Operativsystem 6 3
Filhantering C++ Filhantering #include <fstream.h> int tal; fstream fil; fil.open( fil.txt, ios::in ios::out ios::trunc); cout << Mata in ett tal: ; cin >> tal; fil.write((char*)&tal,sizeof(tal)); fil.close(); Obuffrad Systemanrop filnummer read / write Formaterad scanf / printf Ett tecken getc / putc fgetc / fputc I/O Buffrad ANSI C strömmar Oformaterad En rad gets / puts fgets / fputs Direkt fread / fwrite 6/25/03 RL - Operativsystem 7 6/25/03 RL - Operativsystem 8 4
Filnummer open Kärnan använder sig utav filnummer för att referera till öppna filer. Ett filnummer är ett icke negativt heltal. Alla processer har (normalt) 0 standard input 1 standard output 2 standard error Processtabell filtabell 0 status 1 offset 2 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> char *name; int fd, rwmode, perms; fd = open(name, rwmode, perms); fd - filnummer, -1 vid fel. name - filens namn. 6/25/03 RL - Operativsystem 9 6/25/03 RL - Operativsystem 10 5
open creat rwmode - hur ska filen öppnas. O_RDONLY (0) Öppna för att läsa. O_WRONLY (1) Öppna för att skriva. O_RDWR (2) Öppna för att läsa och skriva. O_APPEND Börja skriva i slutet av filen. O_CREAT Skapa filen om den inte existerar. O_TRUNC Trunkera filen, ta bort tidigare innehåll. perms - filens accessrättigheter, används vid skapandet av nya filer. 0755 User, Group, other. #include <sys/types.h> #include <sys/stat.h> #include <fcntl> char *name; int fd, perms; fd = creat(name, perms); Det samma som: fd = open(name, O_WRONLY O_CREAT O_TRUNC, perms); 6/25/03 RL - Operativsystem 11 6/25/03 RL - Operativsystem 12 6
close read int fd, ok; ok = close(fd); ok - returvärde, 0 om OK och -1 vid fel. fd - filnummer. int fd, n, nread; char buffer[size]; nread = read(fd, buffer, n); nread - antal lästa tecken, 0 vid EOF och -1 vid fel. fd - filnummer. buffer - teckenbuffer. n - antal tecken som önskas läsas. 6/25/03 RL - Operativsystem 13 6/25/03 RL - Operativsystem 14 7
write Exempel 2 int fd, n, nwrite; char buffer[size]; nwrite = write(fd, buffer, n); nwrite - antalet skrivna tecken, -1 vid fel. fd - filnummer. buffer - teckenbuffer. n - antal tecken som önskas skrivas. #define SIZE 1024 #define STDIN 0 #define STDOUT 1 int nread; char buffer[size]; while((nread = read(stdin, buffer, SIZE)) > 0) write(stdout, buffer, nread); 6/25/03 RL - Operativsystem 15 6/25/03 RL - Operativsystem 16 8
lseek Exempel 3 #include <sys/types.h> int fd, origin; long offset, pos; pos = lseek(fd, offset, origo); #include my.h #define MAX 10 int fd, pos1, pos2; char buff[max]; pos - ny offset, -1 vid fel. fd - filnummer. offset - anger förflyttningen i bytes relativt origo. origo - anger utgångsposition SEEK_SET (filstart) SEEK_CUR (nuvarande filposition) SEEK_END (filslut) fd = open( text.txt, O_RDONLY); pos1 = lseek(fd, 0, SEEK_CUR); read(fd, buff, MAX); pos 2 = lseek(fd, 0, SEEK_CUR); printf( pos1 = %d, pos2 = %d\n, pos1, pos2); 6/25/03 RL - Operativsystem 17 6/25/03 RL - Operativsystem 18 9
unlink Exempel 4 char *name; int ok; ok = unlink(name); #define PERMS 0000 int f1, f1; ok - returvärde, 0 om OK och -1 vid fel. name - namnet på den fil som skall tas bort. unlink räknar ned antalet link count med ett, blir antalet noll tas filen bort. if((f1 = creat( test.txt, PERMS)) == -1) printf( Can t create test.txt (1)\n ); if((f2 = creat( test.txt, PERMS)) == -1) printf( Can t create test.txt (2)\n ); unlink( test.txt ); 6/25/03 RL - Operativsystem 19 6/25/03 RL - Operativsystem 20 10
Argument till main Exempel 5 #include <stdio.h> int main(int argc, char* argv[]) int i; printf( argc = %d\n, argc); for(i = 0; i < argc; i++) printf( argv[%d] = %s\n, i, argv[i]); 6/25/03 RL - Operativsystem 21 #include my.h #define PERMS 0644 #define SIZE 1024 int main(int argc, char *argv[]) int f1, f2, nread; char buffer[size]; if(argc!= 3) printf( Usage: %s <from> <to>\n, argv[0]); exit(-1); if((f1 = open(argv[1], O_RDONLY)) == -1) printf( Can t open %s\n, argv[1]); 6/25/03 RL - Operativsystem 22 11
Exempel 5 forts Filhantering enligt ANSI C exit(-1); if(f2 = creat(argv[2], PERMS)) == -1) printf( Can t create %s\n, argv[2]); exit(-1); while((nread = read(f1, buffer, SIZE)) > 0) if(write(f2, buffer, nread)!= nread) printf( Write error\n ); exit(-1); Strömmar istället för filnummer. Pekare till en strukt (FILE objekt). Funktioner fopen(name, mode) mode: r, w, a, r+, w+, a+ fread(objptr, size, nsize, streamptr) fwrite(objptr, size, nsize, streamptr) size är storleken på ett objekt. nsize är antalet objekt att skriva / läsa. fseek(streamptr, offset, origo) Fungerar som lseek. fclose(streamptr) Sök själva på mansidorna om dessa funktioner man nr cmd 6/25/03 RL - Operativsystem 23 6/25/03 RL - Operativsystem 24 12
Exempel 6 Uppgift 1 #include <stdio.h> FILE *infile, *outfile; char data; outfile = fopen( copy.dat, w ); infile = fopen( file.dat, r ); while(fread(&data, sizeof(char), 1, infile)!= 0) fwrite(&data, sizeof(char), 1, outfile); fclose(infile); fclose(outfile); 6/25/03 RL - Operativsystem 25 Vad gör programmet? #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> char buf1[] = abcdefghij ; char buf2[] = ABCDEFGHIJ void main() int fd; fd = creat( fil, 0755); write(fd, buf1, 10); lseek(fd,40,seek_set); write(fd, buf2, 10); 6/25/03 RL - Operativsystem 26 13
Processhantering 1 sleep sleep fork wait getpid waitpid Används för att få en process att sova. Sover den angivna tiden eller tills en signal skickas (som inte skall ignoreras). int value, time; value = sleep(time); value - 0 om sleep har sovit färdigt, annars det antal sekunder som är kvar att sova. time - det antal sekunder som en process skall sova. 6/25/03 RL - Operativsystem 27 6/25/03 RL - Operativsystem 28 14
Exempel 7 fork #include <stdio.h> printf( Nu skall processen sova\n ); sleep(5); printf( Nu har processen sovit färdigt\n ); Används för att skapa en ny process. #include <sys/types.h> int value; value = fork(); value = 0 barnprocessen exekverar. > 0 föräldraprocessen exekverar. = - 1 systemanropet misslyckades. 6/25/03 RL - Operativsystem 29 6/25/03 RL - Operativsystem 30 15
Exempel 8 Exempel 9 #include <stdio.h> #include <sys/types.h> #include <stdio.h> #include <sys/types.h> int child; int child; child = fork(); printf( In main: %d\n, child); child = fork(); child = fork(); printf( In main: %d\n, child); 6/25/03 RL - Operativsystem 31 6/25/03 RL - Operativsystem 32 16
Exempel 10 Exempel 11 #include <stdio.h> #include <sys/types.h> int child, i = 0; if((child = fork()) == 0) i = 1; printf( In main: %d:%d\n, child, i); #include <sys/types.h> while(1) fork(); 6/25/03 RL - Operativsystem 33 6/25/03 RL - Operativsystem 34 17
wait Används då föräldraprocessen ska invänta en barnprocess. #include <sys/types.h> #include <sys/wait.h> int childpid, status; childpid = wait(&status); childpid - barnprocessens pid-nummer, -1 vid fel. status - barnprocessens exitstatus (terminate / abort). #include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <fcntl.h> int fd, stat, pos; char buff[10]; Exempel 12 fd = open( data, O_RDONLY); read(fd, buff, 10); pos = lseek(fd, 0, SEEK_CUR); printf( Before fork %d\n, pos); 6/25/03 RL - Operativsystem 35 6/25/03 RL - Operativsystem 36 18
Exempel 12 forts... getpid switch(fork()) case 0: pos = lseek(fd, 0, SEEK_CUR); printf( Child before read %d\n, pos); read(fd, buff, 10); pos = lseek(fd, 0, SEEK_CUR); printf( Child after read %d\n, pos); exit(0); default: break; wait(&stat); pos = lseek(fd, 0, SEEK_CUR); printf( Parent after wait %d\n, pos); 6/25/03 RL - Operativsystem 37 Returnerar processens PID-nummer #include <sys/types.h> int pid; pid = getpid(); pid - processens pid-nummer. 6/25/03 RL - Operativsystem 38 19
Exempel 13 waitpid() #include <stdio.h> #include <sys/types.h> int child; child = fork(); if(child == 0) printf( Child (PID = %d)\n, getpid()); else if(child > 0) printf( Parent (PID = %d)\n, getpid()); else printf( Can t create new process\n ); Väntar på en specifik barnprocess. #include <sys/types.h> #include <sys/wait.h> int pid1, pid2, status, options; pid2 = waitpid(pid1, &status, options); pid1 - det pid som föräldern vill vänta på. pid2 - pid på det terminerande barnet, -1 vid fel. status - statusen på det terminerade barnet. options - vanligen WNOHANG (ej blockerande). 6/25/03 RL - Operativsystem 39 6/25/03 RL - Operativsystem 40 20
Exempel 14 Exempel 14 forts #include my.h int pid, status; switch(pid = fork()) case 0: default: printf( Child sleeping\n ); sleep(5); printf( Child terminates\n ); exit(0); break; while(waitpid(pid, &status, WNOHANG) == 0) printf( Still waiting \n ); sleep(1); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 41 6/25/03 RL - Operativsystem 42 21
Varför får man zombies? Ett barn dör när föräldern inte utför en wait. Vad händer om en förälder terminerar medans ett eller flera barn fortfarande exekverar? Init tar över. Hur undviker man att systemet blir nedlusat av zombies? wait, waitpid. signal (senare) 6/25/03 RL - Operativsystem 43 Uppgift 2 Antag att anrop till getpid() ger följande svar; 100, 101, 102 osv. Vad blir utskriften? Se till att alla kopplingar mellan processerna illustreras. #include my.h int i, c; for(i = 0; i <= 2; i++) c = fork(); printf( %5d:%5d:%5d\n, getpid(), c, i); 6/25/03 RL - Operativsystem 44 22
Processhantering 2 exec exec execl execv execle execve execlp execvp kill signal Används för att ladda ett nytt program i en process. int a, b; char *path, *file, *argv[]; a = execl(path, argv[0], ); b = execlp(file, argv[0], ); path - sökvägen till programmet som skall laddas. file- namnet på programmet som skall laddas. arg - kommando och argument som används för att starta upp det nyladdade programmet. a, b - Ingen retur vid ok, -1 vid fel. 6/25/03 RL - Operativsystem 45 6/25/03 RL - Operativsystem 46 23
Exempel 15 Exempel 16 #include my.h #include <stdio.h> execl( /bin/date, date, NULL); printf( Can t overlay process\n ); void main() int child, status; if((child = fork()) == 0) execl( /usr/bin/cal, cal, 10, 1999, NULL); printf( Can t overlay process\n ); else if(child > 0) wait(&status); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 47 6/25/03 RL - Operativsystem 48 24
Exempel 17 Exempel 17 forts #include my.h /* sleep5.c */ #include <stdio.h> int main(int argc, char *argv[]) printf( %s\n, argv[0]); sleep(5); void main() int child, status; if((child = fork()) == 0) execl(./sleep5, sleep5, NULL); printf( Can t overlay process\n ); else if(child > 0) wait(&status); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 49 6/25/03 RL - Operativsystem 50 25
Exempel 18 Signaler #include my.h void main() int child, status; if((child = fork()) == 0) execl(./sleep5, sleep5, NULL) else if(child > 0) wait(&status); if(fork() == 0) execl( /bin/date, date, NULL); wait(&status); printf( Parent terminates\n ); En signal är en notering till en process att en händelse har inträffat. Kallas ofta software interrupts. Inträffar vanligtvis asynkront, dvs en mottagare vet i förväg inte när en signal anländer Signaler kan skickas: Av en process till en annan, eller till sig själv, mha systemanropet kill. Av kärnan till en process. Alla signaler har ett namn, se headerfilen <signal.h> Observera att en signal dödar inte alltid en process. Vissa terminaltecken genererar signaler: ctrl - c SIGINT ctrl - \ SIGQUIT ctrl - z SIGSTF 6/25/03 RL - Operativsystem 51 6/25/03 RL - Operativsystem 52 26
Exempel 19 kill Är ett systemanrop, som används av processer för att skicka signaler till andra processer. #include <signal.h> int retcode, childpid; retcode = kill(childpid, SIGKILL); retcode - returvärde = 0 systemanropet lyckades = -1 systemanropet misslyckades childpid - processnumret på processen som skall terminera 6/25/03 RL - Operativsystem 53 #include my.h void main() int child; if((child = fork()) == 0) else printf( Barnet sover\n ); sleep(60); printf( Barnet vaknar\n ); sleep(1) // Barnet måste hinna skriva ut if(kill(child, SIGKILL) == 0) printf( Lyckades att döda barnet\n ); else printf( Barnet lever\n ); 6/25/03 RL - Operativsystem 54 27
signal Exempel 20 Anger hur en signal ska tas emot. #include <signal.h> signal(signal, func); signal - namet på en signal, t ex SIGINT. func - kan vare en av följande tre alternativ: SIG_DFL, signalen ska hanteras på normalt sätt. SIG_IGN, signalen ska ignoreras. Adressen till en funktion som skall anropas när signalen inträffar. #include <signal.h> #define SEC 1 #define FOREVER 1 /* ignorera CTRL - c */ signal(sigint, SIG_IGN); while(forever) sleep(sec); 6/25/03 RL - Operativsystem 55 6/25/03 RL - Operativsystem 56 28
#include <stdio.h> #include <signal.h> #define SEC 1 #define FOREVER 1 void mysighandler() Exempel 21 printf( Catching the signal\n ); signal(sigint, mysighandler); while(forever) sleep(sec); 6/25/03 RL - Operativsystem 57 Uppgift 3 Vad blir utskriften om användaren trycker CTRL-C var 7:e sekund? #include <stdio.h> #include <signal.h> void olle() printf( a\n ); signal(sigint, SIG_DFL); 6/25/03 RL - Operativsystem 58 29
Uppgift 3 forts Filhantering 2 int i; signal(sigint, olle); pipe dup dup2 fcntl printf( b\n ); for(i = 0; i < 10; i++) printf( c\n ); sleep(3); printf( d\n ); printf( e\n ); 6/25/03 RL - Operativsystem 59 6/25/03 RL - Operativsystem 60 30
pipe pipe i en process Används vid kommunikation mellan två processer. En pipe är en I/O-mekanism, som fungerar enligt principen FIFO. user process read fd write fd int pfd[2], retcode; retcode = pipe(pfd); kernel pfd[0] - Filnummer för läsning på pipen. Pfd[1] - Filnummer för skrivning på pipen. Retcode - returvärde vid skapande av pipen: >= 0 systemanropet lyckades. = -1 systemanropet misslyckades. flow of data 6/25/03 RL - Operativsystem 61 6/25/03 RL - Operativsystem 62 31
#include my.h #define MSGSIZE 16 char buff[msgsize]; int pfd[2], j; Exempel 22 pipe(pfd); write(pfd[1], Hello world, #1, MSGSIZE); write(pfd[1], Hello world, #2, MSGSIZE); write(pfd[1], Hello world, #3, MSGSIZE); for(j = 0; j <3; j++) read(pfd[0], buff, MSGSIZE); printf( %s\n, buff); 6/25/03 RL - Operativsystem 63 Exempel 23 #include my.h #define MSG hello world\n int pfd[2], n; char buff[100]; if(pipe(pfd) == -1) printf( Can t create pipe\n ); exit(-1); printf( rfd = %d, wfd = %d\n, pfd[0], pfd[1]); 6/25/03 RL - Operativsystem 64 32
Exempel 23 forts Exempel 24 if(write(pfd[1], MSG, sizeof(msg))!= sizeof(msg)) printf( Can t write to pipe\n ); exit(-1); if((n = read(pfd[0], buff, sizeof(buff))) == -1) printf( Can t read from pipe\n ); exit(-1); write(1, buff, n); #include my.h int pfd[2], j; pipe(pfd); for(j = 1; 1; j++) retrun 0; write(pfd[1], a, 1); printf( %d\n, j); I mitt test 4096 byte s, men detta är systemberoende. 6/25/03 RL - Operativsystem 65 6/25/03 RL - Operativsystem 66 33
Pipe mellan två processer parent process child process write fd read fd kernel flow of data 6/25/03 RL - Operativsystem 67 #include my.h #define MSIZE 16 void main() char buff[msize]; int pfd[2]; pipe(pfd); switch(fork()) case 0: Exempel 25 exit(0); default: break; write(pfd[1], Hello world, #1, MSIZE); read(pfd[0], buff, MSIZE); printf( Child %s\n, buff); write(pfd[1], Hello world, #2, MSIZE); read(pfd[0], buff, MSIZE); printf( Parent %s\n, buff); 6/25/03 RL - Operativsystem 68 34
#include my.h #define MSIZE 16 void main() char buff[msize]; int pfd[2]; pipe(pfd); switch(fork()) case 0: Exempel 26 exit(0); default: break; close(pfd[1]); read(pfd[0], buff, MSIZE); printf( Parent %s\n, buff); close(pfd[0]); write(pfd[1], Hello world, #1, MSIZE); 6/25/03 RL - Operativsystem 69 Uppgift 4 Vad blir utskriften? #include my.h int c, pfd[2]; char msg[13] = Good luck ; pipe(pfd); printf( %d\n, c = fork()); printf( %d\n, c = fork()); if(!c) write(pfd[1], Hello world\n, 13); else read(pfd[0], msg, 13); printf( %s\n, msg); 6/25/03 RL - Operativsystem 70 35
Pipe mellan tre processer Exempel 27 #include my.h #define MSIZE 16 P1 P2 P3 char buff[msize]; int pfd1[2], pfd2[2]; Pipe1 Kernel Pipe 2 6/25/03 RL - Operativsystem 71 pipe(pfd1); pipe(pfd2); if(!fork()) close(pfd1[0]); close(pfd2[0]); close(pfd2[1]); write(pfd1[1], Hello world, #1, MSIZE); exit(0); 6/25/03 RL - Operativsystem 72 36
Exempel 27 forts dup else if(!fork) close(pfd1[1]); close(pfd2[0]); read(pfd1[0], buff, MSIZE); printf( Child2 %s\n buff); write(pfd2[1], Hello world, #2, MSIZE); exit(0); close(pfd1[0]); close(pfd1[1]); close(pfd2[1]); read(pfd2[0], buff, MSIZE); printf( Parent %s\n, buff); Används för att skapa en kopia till ett filnummer. Det gamla och det nya filnumret refererar till samma fil. Det lägst lediga filnumret kommer att användas. int old_fd, new_fd; new_fd = dup(old_fd); old_fd - det gamla filnumret. new_fd - det nya filnumret >= 0 systemanropet lyckades. = -1 systemanropet misslyckades. 6/25/03 RL - Operativsystem 73 6/25/03 RL - Operativsystem 74 37
Exempel 28 Exempel 28 forts #include my.h #define PERMS 0644 #define OUT outfile #define SIZE 1024 #define STDOUT 1 int fd, status; if((fd = creat(out, PERMS)) == -1) printf( Can t create %s\n, OUT); exit(-1); if(fork() == 0) close(stdout); dup(fd); printf( Hello world!\n ); close(fd); exit(0); wait(&status); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 75 6/25/03 RL - Operativsystem 76 38
Uppgift 5 #include my.h char buff[128] = Exame time ; int pfd[2]; pipe(pfd); switch(fork()) case 0: close(1); dup(pfd[1]); default: break; strcpy(buff, summer ); printf( child, %s\n, buff); strcpy(buff, I will pass ); exit(0); read(pfd[0], buff); printf( Parent, %s\n, buff); 6/25/03 RL - Operativsystem 77 dup2 Används för att skapa en kopia till ett filnummer. int old_fd, new_fd, retur; retur = dup(old_fd, new_fd); old_fd - det gamla filnumret. new_fd - det nya filnumret retur - returnerar det nya filnumret >= 0 systemanropet lyckades. = -1 systemanropet misslyckades. dup2 gör new_fd till en kopia av old_fd, och stänger new_fd om det är nödvändigt. 6/25/03 RL - Operativsystem 78 39
Exempel 29 Exempel 29 forts #include my.h #define PERMS 0644 #define OUT outfile #define SIZE 1024 #define STDOUT 1 int fd, status; if((fd = creat(out, PERMS)) == -1) printf( Can t create %s\n, OUT); exit(-1); if(fork() == 0) dup2(fd, STDOUT); printf( Hello world!\n ); close(fd); exit(0); wait(&status); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 79 6/25/03 RL - Operativsystem 80 40
fcntl fcntl forts Används för att ändra egenskaper för en öppnad fil. #include <sys/types.h> #include <fcntl.h> int fd, cmd, arg, retur; retur = fcntl(fd, cmd, arg); fd - filnumret vilkens egenskaper ska ändras. arg - beroende av cmd retur - returvärde >= 0 systemanropet lyckades (beror av cmd). = -1 systemanropet misslyckades cmd - F_DUPFD (File Descriptor) F_GETFD F_SETFD F_GETFL (ststus FLags) F_SETFL F_GETOWN (OWNership) F_SETOWN F_GETLK (record LocKs) F_SETLK F_SETLKW 6/25/03 RL - Operativsystem 81 6/25/03 RL - Operativsystem 82 41
Exempel 30 Exempel 30 forts #include my.h #define PERMS 0644 #define OUT outfile #define SIZE 1024 #define STDOUT 1 int fd, status, old; if((fd = creat(out, PERMS)) == -1) printf( Can t create %s\n, OUT); exit(-1); if(fork() == 0) old = dup(stdout); dup2(fd, STDOUT); write(stdout,"hello world!\n", 14); close(stdout); fcntl(old, F_DUPFD, STDOUT); write(stdout,"child terminates\n",18); exit(0); wait(&status); printf( Parent terminates\n ); 6/25/03 RL - Operativsystem 83 6/25/03 RL - Operativsystem 84 42
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> Uppgift 6 #define RUNMSG " Running #define TERMMSG " Terminating #define MSGSIZE 20 Uppgift 6 forts void writemsg(int fdw) int i; char msg[msgsize]; void readmsg(int fdr) int nread; char buffer[msgsize]; while((nread = read(fdr, buffer, MSGSIZE))!= 0) puts(buffer); if(strcmp(strchr(buffer, ''), TERMMSG) == 0) return; sprintf(msg, "%d", getpid()); strcat(msg, RUNMSG); for(i = 0; i < 10; i++) write(fdw, msg, MSGSIZE); sleep(1); sprintf(msg, "%d", getpid()); strcat(msg, TERMMSG); write(fdw, msg, MSGSIZE); 6/25/03 RL - Operativsystem 85 6/25/03 RL - Operativsystem 86 43
int main(void) Uppgift 6 forts int pdf[2], childpid, stat; if(pipe(pdf) == -1) perror("can t create pipe"); exit(-1); if((childpid = fork()) == 0) readmsg(pdf[0]); else if(childpid > 0) writemsg(pdf[1]); else perror("can t fork"); exit(-1); wait(&stat); printf("process %d treminates...\n", getpid()); 6/25/03 RL - Operativsystem 87 #include my.h Uppgift 7 #define RUNMSG Running\0 #define TERMMSG Terminating\0 #define MSGSIZE 20 void readwritemsg(int fdr, int fdw) int nread; char buffer[msgsize]; while((nread = read(fdr, buffer, MSGSIZE))!= 0) puts(buffer); 6/25/03 RL - Operativsystem 88 44
Uppgift 7 forts Uppgift 7 forts if(strcmp(strchr(buffer, ), TERMMSG) == 0) else sprintf(buffer, %d, getpid()); strcat(buffer, TERMMSG); write(fdw, buffer, MSGSIZE); return; sleep(1); sprintf(buffer, %d, getpid()); strcat(buffer, RUNMSG); write(fdw, buffer, MSGSIZE); 6/25/03 RL - Operativsystem 89 void writereadmsg(int fdw, int fdr) time_t starttime, currenttime; char msg[msgsize]; starttime = time(&starttime); while(difftime(time(&curenttime), starttime) < 30.0) sprintf(msg, %d, getpid()); strcat(msg, RUNMSG); write(fdw, msg, MSGSIZE); read(fdr, msg, MSGSIZE); puts(msg); sleep(1); sprintf(msg, %d, getpid()); strcat(msg, TERMMSG); write(fdw, msg, MSGSIZE); read(fdr, msg, MSGSIZE); puts(msg); 6/25/03 RL - Operativsystem 90 45
Uppgift 7 forts int pdf1_2[2], pdf2_3[2], pdf3_1[2], stat, child1pid, child2pid; if(pipe(pfd1_2) == -1) perror( Can t create pipe ); exit(-1); if(pipe(pfd2_3) == -1) perror( Can t create pipe ); exit(-1); if(pipe(pfd3_1) == -1) perror( Can t create pipe ); exit(-1); 6/25/03 RL - Operativsystem 91 Uppgift 7 forts if((child1pid = fork()) == 0) readwritemsg(pdf1_2[0], pdf2_3[1]); else if(child1pid > 0) if((child2pid = fork()) == 0) readwritemsg(pfd2_3[0], pfd3_1[1]); else if(child2pid > 0) writereadmsg(pfd1_2[1], pfd3_1[0]); else perror( Can t fork ); exit(-1); else perror( Can t fork ); exit(-1); wait(&status); printf( Process %d terminates \n, getpid()); 6/25/03 RL - Operativsystem 92 46