4 11 IPC using PIPE Overview Example Functions








![Section 01 08 05 Results $ ex 11 -01 [parent] hello! [fork 1] hello! Section 01 08 05 Results $ ex 11 -01 [parent] hello! [fork 1] hello!](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-9.jpg)








![Section 02 01 【Ex. 11 -6】ex 11 -06. c 20 write(filedes[1], msg 1, strlen(msg Section 02 01 【Ex. 11 -6】ex 11 -06. c 20 write(filedes[1], msg 1, strlen(msg](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-18.jpg)

















![Section 07 01 dup 2 Connect stdio to a process pipe(p); … dup 2(p[0], Section 07 01 dup 2 Connect stdio to a process pipe(p); … dup 2(p[0],](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-36.jpg)











- Slides: 47

4장 11 IPC using PIPE Overview Example Functions - pipe pathconf / fpathconf select mkfifo dup 2

Section 01 Overview Functions Function role pipe Create a pipe for IPC. fpathconf Get information about the file system. select Select the changed file descriptor from a set of File descriptors. mkfifo Create a named pipe, FIFO. dup 2 Create a copy of a file descriptor. 2

Section 02 01 【Ex. 11 -1】ex 11 -01. c(1/4) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 #include <unistd. h> #include <sys/types. h> #include <fcntl. h> #define MSGSIZE 100 05 통신용 메시지의 길이 main() { pid_t Int fd_set int char 10 파이프와 관련된 파일 기술자 pid 1, pid 2; filedes, p 1[2], p 2[2]; initset, newset; nread; msg[MSGSIZE]; 11 파일 기술자 집합(select 함수에 서 사용) 15 두 쌍의 파이프를 생성한다 pipe(p 1); pipe(p 2); 19 자식 프로세스를 생성한다 20 부모 프로세스는 자식 프로세스 pid 1 = pid 2 = 0; pid 1 = fork(); if(pid 1 > 0) pid 2 = fork(); 를 하나 더 생성한다 표준입력 스트림 3

Section 02 01 【Ex. 11 -1】ex 11 -01. c(2/4) 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 if(pid 1 > 0 && pid 2 > 0) { /* parent */ printf("[parent] hello!n"); close(p 1[1]); close(p 2[1]); 22 부모 프로세스르 수행할 부분 24 사용하지 않는 파이프를 닫는다 27 파일 기술자 집합을 초기화하고 FD_ZERO(&initset); FD_SET(p 1[0], &initset); FD_SET(p 2[0], &initset); 파이프에 해당하는 두 개의 파일 기술자를 등록한다 newset = initset; while(select(p 2[0]+1, &newset, NULL, NULL) > 0) 32 newset에 등록된 파일 기술자 { if(FD_ISSET(p 1[0], &newset)) if(read(p 1[0], msg, MSGSIZE) > 0) printf("[parent] %sn", msg); if(FD_ISSET(p 2[0], &newset)) if(read(p 2[0], msg, MSGSIZE) > 0) printf("[parent] %sn", msg); newset = initset; } 중에서 읽을거리가 있는 상태로 변한 파일 기술자를 찾는다 36 p 1[0]과 p 2[0] 중에서 읽을거리 가 있는 파일 기술자로부터 메시 지를 읽어와 표준출력한다. 표준입력 스트림 } 4


Section 02 01 【Ex. 11 -1】ex 11 -01. c(4/4) 53 else if(pid 1 > 0 && pid 2 == 0) 54 { /* 2 nd child */ 55 printf("[fork 2] hello!n"); 56 close(p 1[0]); 57 close(p 1[1]); 58 close(p 2[0]); 59 write(p 2[1], "from fork 2 via pipe", MSGSIZE); 60 61 mkfifo(". /fifo", 0666); 62 filedes = open(". /fifo", O_RDWR); 63 nread = read(filedes, msg, MSGSIZE); 64 printf("%s (%d)n", msg, nread); 65 close(filedes); 66 unlink(". /fifo"); 67 } 68 else 69 exit(1); 70 } 6 53 두번째 자식 프로세스 56 사용하지 않는 파이프를 닫는다 59 파이프로 메시지를 송신한다 61 네임드 파이프 “fifo”를 만든다 62 fifo를 열고 메시지를 읽어와 표 준 출력한다. 66 fifo를 삭제한다 표준입력 스트림

Section 02 01 【Ex. 11 -1】ex 11 -01 c. c 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 #include <unistd. h> #include <fcntl. h> #define MSGSIZE 100 04 메시지의 길이 main() { int filedes; printf("[exec] standard outputn"); sleep(1); 10 표준 출력으로 문자열을 출력한 다. 표준 출력이 부모 프로세스와 연결된 파이프의 사본이 되어 있 으므로 파이프를 통한 출력이 된 filedes = open(". /fifo", O_WRONLY); write(filedes, "from exec via FIFO", MSGSIZE); close(filedes); 다 14 “fifo”를 열어 메시지를 쓴다. “fifo”에 쓰여진 메시지는 첫 번째 자식 프로세스가 읽어갈 것이다. } 표준입력 스트림 7

Section 01 Interactions of the processes (ex 11 -01. c와 ex 11 -01 c. c) 8
![Section 01 08 05 Results ex 11 01 parent hello fork 1 hello Section 01 08 05 Results $ ex 11 -01 [parent] hello! [fork 1] hello!](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-9.jpg)
Section 01 08 05 Results $ ex 11 -01 [parent] hello! [fork 1] hello! [fork 2] hello! [parent] from fork 2 via pipe from exec via FIFO (100) [parent] [exec] standard output ^C $ 9

Section 02 01 pipe Create a pipe for IPC #include <unistd. h> int pipe(int filedes[2]); filedes An set of file descriptors where filedes[0] is for read while filedes[1]is for write. return 0 for success, -1 otherwise Create two file descriptors of the inode for pipe. filedes[0] for read filedes[1] for write ※ Process can treat them as normal file descriptor. 10

Section 01 【Ex. 11 -2】ex 11 -02. c 02 A process creates a pipe. Read back the messages from the pipe. 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 $ ex 11 -02 input a message apple is red input a message banana is yellow input a message cherry is red #include <unistd. h> #include <stdio. h> #define SIZE 512 main() { char msg[SIZE]; int filedes[2]; int i; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } for(i = 0; i < 3; i++) { printf("input a message₩n"); fgets(msg, SIZE, stdin); write(filedes[1], msg, SIZE); } 11 apple is red banana is yellow cherry is red $ 22 23 24 25 26 27 } printf("₩n"); for(i = 0; i < 3; i++) { read(filedes[0], msg, SIZE); printf("%s", msg); }

Section 02 01 【Ex. 11 -3】ex 11 -03. c(1/2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 #include <unistd. h> #include <stdio. h> #include <sys/types. h> #define SIZE 512 main() { char msg[SIZE]; int filedes[2]; pid_t pid; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } 표준입력 스트림 12

Section 02 01 【Ex. 11 -3】ex 11 -03. c(2/2) 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 } if((pid = fork()) == -1) { printf("fail to call fork()₩n"); exit(1); } else if(pid > 0) { strcpy(msg, "apple is red. ₩n"); write(filedes[1], msg, SIZE); printf("[parent] %s₩n", msg); } 표준입력 스트림 else { sleep(1); $ ex 11 -03 read(filedes[0], msg, SIZE); [parent] apple is red. printf("[child] %s₩n", msg); [child] apple is red. } $ 13

Section 02 01 【Ex. 11 -4】ex 11 -04. c(1/2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 #include <unistd. h> #include <stdio. h> #include <sys/types. h> #define SIZE 512 main() { char *msg[] = {"apple is red", "banana is yellow", "cherry is red"}; char buffer[SIZE]; int filedes[2], nread, i; pid_t pid; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } 14

Section 02 01 【Ex. 11 -4】ex 11 -04. c(2/2) 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 } if((pid = fork()) == -1) { printf("fail to call fork()₩n"); exit(1); } else if(pid > 0) { for(i = 0; i < 3; i++) { strcpy(buffer, msg[i]); write(filedes[1], buffer, SIZE); } nread = read(filedes[0], buffer, SIZE); printf("[parent] %s₩n", buffer, nread); 표준입력 스트림 write(filedes[1], buffer, SIZE); printf("[parent] bye!₩n"); } else { for(i = 0; i < 3; i++) { nread = read(filedes[0], buffer, SIZE); printf("[child] %s₩n", buffer, nread); } printf("[child] bye!₩n"); } 15 $ ex 11 -04 [parent] apple is red [parent] bye! [child] banana is yellow [child] cherry is red [child] apple is red [child] bye! $

Section 02 01 【Ex. 11 -5】ex 11 -05. c 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <unistd. h> #include <stdio. h> #include <sys/types. h> #define SIZE 512 main() { int filedes[2]; pid_t pid; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } if((pid = fork()) == -1) { /* fork() 호출 실패 */ Close the unused file descriptor. } else if(pid > 0) { close(filedes[0]); /* filedes[1]을 지정하여 파이프에 메시지 쓰기 */ } else { close(filedes[1]); /* filedes[0]을 지정하여 파이프로부터 메시지 읽기 */ } } 16

Section 03 01 Size of message buffer vs. size of a PIPE The size of a message passing thru a pipe(length) May be fixed or variable. Sending message or receiving a message thru the PIPE Using variable size of message The size will be limited by the size of the pipe. No way to check the size of sending msg. By the receiver. Using fixed size For a short message there may be a waste of buffer. The sender and the receiver agree on the size of the message. 17
![Section 02 01 Ex 11 6ex 11 06 c 20 writefiledes1 msg 1 strlenmsg Section 02 01 【Ex. 11 -6】ex 11 -06. c 20 write(filedes[1], msg 1, strlen(msg](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-18.jpg)
Section 02 01 【Ex. 11 -6】ex 11 -06. c 20 write(filedes[1], msg 1, strlen(msg 1) + 1); write(filedes[1], msg 2, strlne(msg 2) + 1); 21 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 #include <unistd. h> #include <stdio. h> 22 23 #define SIZE 512 24 25 main() 26 { 27 char *msg 1 = "apple is red"; } char *msg 2 = "banana is yellow"; char buffer[SIZE]; nread = read(filedes[0], buffer, SIZE); printf("%d, %s₩n", nread, buffer); ※The size of the message differs. int filedes[2]; int nread; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } 18 $ ex 11 -06 30, apple is red ^C $

Section 02 01 【Ex. 11 -7】ex 11 -07. c 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 #include <unistd. h> #include <stdio. h> #define SIZE 512 20 21 22 23 24 25 main() 26 { 27 } char *msg 1 = "apple is red"; char *msg 2 = "banana is yellow"; char buffer[SIZE]; write(filedes[1], msg 1, len 1); write(filedes[1], msg 2, len 2); nread = read(filedes[0], buffer, len 1); printf("%d, %s₩n", nread, buffer); nread = read(filedes[0], buffer, len 2); printf("%d, %s₩n", nread, buffer); ※The sender and the receiver uses same size for the buffer. int filedes[2], nread; int len 1 = strlen(msg 1) + 1; int len 2 = strlen(msg 2) + 1; if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } 19 $ ex 11 -07 13, apple is red 17, banana is yellow $

Section 02 01 【Ex. 11 -8】ex 11 -08. c( partial) … 01 #define SIZE 512 02 03 main() 04 { 05 char *msg 1 = "apple is red"; 06 char *msg 2 = "banana is yellow"; 07 char buffer[SIZE]; … 20 21 22 23 24 25 26 27 28 29 30 31 } 표준입력 스트림 if(pipe(filedes) == -1) … write(filedes[1], msg 1, SIZE); write(filedes[1], msg 2, SIZE); nread = read(filedes[0], buffer, SIZE); printf("%d, %s₩n", nread, buffer); 20 $ ex 11 -08 512, apple is red 512, banana is yellow $

Section 04 01 fpathconf, fpathconf Check the information of a file from the file system. #include <unistd. h> long fpathconf(int filedes, int name); long pathconf(char *path, int name); filedes File descriptor. path Pathname to the file. name Entry to the file. 반환값 Returns the set value of the entry “name” from the file. If the value is not set or error occurs, it returns -1 21

Section 04 01 fpathconf, fpathconf int name Name means _PC_LINK_MAX Number of links. _PC_NAME_MAX Maximum size of a file. _PC_PATH_MAX Maximum size of a relative pathname. _PC_PIPE_BUF Maximum size of the buffer in a pipe. Check the size of pipe to adjust the size of a message. 22

Section 02 01 【Ex. 11 -9】ex 11 -09. c(1/2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 #include <unistd. h> #include <signal. h> #include <limits. h> int nc; void alarm_action(int); main() { int filedes[2]; char msg = 'A'; struct sigaction act; act. sa_handler = alarm_action; sigfillset(&(act. sa_mask)); if(pipe(filedes) == -1) { printf("fail to call pipe()₩n"); exit(1); } 23 표준입력 스트림

Section 02 01 【Ex. 11 -9】ex 11 -09. c(2/2) 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 printf("PIPE size : %d bytes₩n", fpathconf(filedes[1], _PC_PIPE_BUF)); nc = 0; sigaction(SIGALRM, &act, NULL); alarm(1); while(1) { write(filedes[1], &msg, 1); nc++; } } void alarm_action(int signo) { printf("₩n₩nblocked after %d characters₩n", nc); exit(1); } $ ex 11 -09 PIPE size : 4096 bytes blocked after 4096 characters $ 표준입력 스트림 24

Section 05 01 select Check if there is a changed file descriptor from a set of FDs. #include <sys/time. h> #include <sys/types. h> #niclude <unistd. h> int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_CLR(int fd, fd_set *set); FD_ISSET(int fd, fd_set *set); FD_ZERO(fd_set *set); 25

Section 05 01 select int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); n A number that is max(readfds, wirtefds, exceptfds)+1. readfds The set of FDs to read. (to check if the reading is blocked or not) writefds The set of FDs to write. (to check if the write is possible. ) exceptfds The set of FDs for error handling. timeout The time given to select to return the result. fd A file descriptor. set A set of FDs. 반홥값 Returns a file descriptor for success. Returns 0 if time is over. – 1 for failure. 26

Section 05 01 select When a process communicates with multiple processes Need a pipe for each message stream. Not sharing a single pipe. The order of message is incosistant. It is not wise to wait messages by the order of file descriptors. Better to handle the messages to its arriving order select Returns a file descriptor that has changed. Ex. Can monitor several pipes at the same time. 27

Section 05 01 select struct timeval { long tv_sec; long tv_usec; }; /* seconds */ /* microseconds */ By setting non-zero value to either tv_sec or tv_usec, we can monitor a set of FDs. 28

Section 05 01 select usefule macros The set of FDs is a set of masked bits. If a specific bit is 1, the FD that is connected by the bit is readable/writable. Macro mean FD_SET Add an FD to the set of FDs. FD_CLR Delete an FD from the set of FDs. FD_ISSET Check if a specific FD is set to 1. Used when select returns. FD_ZERO Initialize the set of FDs. fd_set initset; … FD_ZERO(&initset); FD_SET(pipe[0], &initset); … select(…, &initset, …); … FD_ISSET(pipe[0], &initset); 29

Section 02 01 【Ex. 11 -10】ex 11 -10. c(1/3) 01 02 03 04 05 06 07 08 09 #include <sys/time. h> <sys/wait. h> <sys/types. h> <unistd. h> 10 void onerror(char *msg) 11 { 12 printf("%s"); 13 exit(1); 14 } #define MSGSIZE 16 void parent(int [][]); int child(int []); 15 main() 16 { 17 int p 1[2], p 2[2]; 18 char msg[MSGSIZE]; 19 int i; 20 pid_t pid 1, pid 2; 21 fd_set initset, newset; 22 23 pid 1 = pid 2 = 0; 24 25 if(pipe(p 1) == -1) 26 onerror("fail to call pipe() #1₩n"); 27 if(pipe(p 2) == -1) 28 onerror("fail to call pipe() #2₩n"); 30 표준입력 스트림

Section 02 01 【예제 11 -10】ex 11 -10. c(2/3) 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 if((pid 1 = fork()) == -1) onerror("fail to call fork() #1₩n"); if(pid 1 > 0) if((pid 2 = fork()) == -1) onerror("fail to call fork() #2₩n"); if(pid 1 > 0 && pid 2 > 0) { /* parent process */ printf("parent: %d₩n", getpid()); close(p 1[1]); FD_ZERO(&initset); FD_SET(p 1[0], &initset); FD_SET(p 2[0], &initset); newset = initset; while(select(p 2[0] + 1, &newset, NULL, NULL) > 0) { if(FD_ISSET(p 1[0], &newset)) if(read(p 1[0], msg, MSGSIZE) > 0) printf("[parent] %s from child 1₩n", msg); if(FD_ISSET(p 2[0], &newset)) if(read(p 2[0], msg, MSGSIZE) > 0) printf("[parent] %s from child 2₩n", msg); newset = initset; } } 31

Section 02 01 【Ex. 11 -10】ex 11 -10. c(3/3) 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 } else if(pid 1 == 0 && pid 2 == 0) { /* first child */ printf("child 1: %d₩n", getpid()); close(p 1[0]); close(p 2[1]); for(i = 0; i < 3; i++) { sleep((i + 1) % 4); printf("child 1: send message %d₩n", i); write(p 1[1], "i'm child 1", MSGSIZE); } printf("child 1: bye!₩n"); exit(0); } else if(pid 1 > 0 && pid 2 == 0) { /* second child */ printf("child 2: %d₩n", getpid()); close(p 1[0]); close(p 1[1]); close(p 2[0]); for(i = 0; i < 3; i++) { sleep((i + 3) % 4); printf("child 2: send message %d₩n", i); write(p 2[1], "i'm child 2", MSGSIZE); } printf("child 2: bye!₩n"); exit(0); } 표준입력 스트림 32

Section 01 08 05 Results $ ex 11 -10 parent: 5347 child 1: 5348 child 2: 5349 child 1: send [parent] i'm child 2: send [parent] i'm child 1: send [parent] i'm child 2: send child 2: bye! [parent] i'm child 1: send child 1: bye! [parent] i'm ^C $ message 0 child 1 from message 0 message 1 child 2 from message 1 child 1 from message 2 Two child processes are sending messages at random time. child 1 First child 1 sec. , 2 sec. , 3 sec. child 2 Second child 3 sec. , 0 sec. , 1 sec. child 1 child 2 from child 2 message 2 child 1 from child 1 33

Section 06 01 Pipe and the call of exec Two processes use a pipe for IPC ex) $ ls –al | more Inheritance of the FDs The status of the FDs are inherited to child processes created using fork or exec. Files open to a parent process are open to the child process. Fork inherits the contents of FDs. Exec does not inherit the contents. 34

Section 07 01 dup 2 Copy a file desciptor #include <unistd. h> int dup 2(int oldfd, int newfd); oldfd original. newfd Copy of the original. return Returns the FD for success or -1. 35
![Section 07 01 dup 2 Connect stdio to a process pipep dup 2p0 Section 07 01 dup 2 Connect stdio to a process pipe(p); … dup 2(p[0],](https://slidetodoc.com/presentation_image_h2/514486c4ec0702ba7a8a51366bd08034/image-36.jpg)
Section 07 01 dup 2 Connect stdio to a process pipe(p); … dup 2(p[0], 0); … dup 2([[1], 1); /* create a pipe */ /* stdin is connected to p[0]. */ /* stdout is connected to p[1]. */ After the execution of the code Reading from stdin is same as reading from p[0]. Writing to stdout is same as writing to p[1]. 36

Section 02 01 【Ex. 11 -11】ex 11 -11. c(1/2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 #include <sys/types. h> #include <unistd. h> main() { char *msg[3] = {"apple is red₩n", "banana is yellow₩n", "cherry is red₩n"}; int p[2]; pid_t pid; int cnt; if(pipe(p) == -1) { printf("fail to call pipe()₩n"); exit(1); } if((pid = fork()) == -1) { printf("fail to call fork()₩n"); exit(1); } 37

Section 02 01 【Ex. 11 -11】ex 11 -11. c(2/2) 21 else if(pid > 0) { 22 printf("[parent]₩n"); 23 close(p[0]); 24 for(cnt = 0; cnt < 3; cnt++) 25 write(p[1], msg[cnt], strlen(msg[cnt]) + 1); 26 } $ ex 11 -11 27 else { [parent] 28 printf("[child]₩n"); [child] 29 close(p[1]); 3 9 30 dup 2(p[0], 0); $ 31 execlp("wc", (char *)0); 32 printf("[child] fail to call execlp()₩n"); 33 } 34 } 38 47

【Ex. 11 -11】ex 11 Section 02 01 11. c(changed)(1/2) 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 #include <sys/types. h> #include <unistd. h> main() { int p[2]; pid_t pid; if(pipe(p) == -1) { printf("fail to call pipe()₩n"); exit(1); } if((pid = fork()) == -1) { printf("fail to call fork()₩n"); exit(1); } 39 표준입력 스트림

【Ex. 11 -11】ex 11 Section 02 01 11. c(changed)(2/2) 18 else if(pid > 0) 19 { 20 printf("[parent]₩n"); 21 close(p[0]); 22 dup 2(p[1], 1); 23 execlp("ls", "-al", (char *)0); 24 printf("[parent] fail to call execlp()₩n"); 25 } $ ex 11 -12 26 else [parent] [child] 27 { 46 407 28 printf("[child]₩n"); $ ls -al | wc 29 close(p[1]); 46 407 30 dup 2(p[0], 0); $ 31 execlp("wc", (char *)0); 32 printf("[child] fail to call execlp()₩n"); 33 } 34 } 40 2856

Section 08 01 mkfifo Create a named pipe. #include <sys/types. h> #include <sys/stat. h> int mkfifo(const char *pathname, mode_t mode); pathname The pathname of the named pipe. mode Access rights to the pipe. return 0 for success, -1 otherwise. 41

Section 08 01 mkfifo IPC using FIFO Processes without any relation can communicate The processes should Know the name of the FIFO. Have the rights to access the FIFO. Can read and write to the FIFO same as general files. 1. Open for write 3. Write to the FIFO 2. Open for write only if some process opened it for write. FIFO 4. Read from the FIFO. If there is no msg the read is blocked. 42

Section 02 01 【Ex. 11 -13】ex 11 -13. c(1/2) Receiver 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 #include <fcntl. h> #include <sys/stat. h> #include <unistd. h> #define MSGSIZE 64 main() { char msg[MSGSIZE]; int filedes; int nread, cnt; if(mkfifo(". /fifo", 0666) == -1) { printf("fail to call fifo()₩n"); exit(1); } 표준입력 스트림 43

Section 02 01 【Ex. 11 -13】ex 11 -13. c(2/2) 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 } if((filedes = open(". /fifo", O_RDWR)) < 0) { printf("fail to call fifo()₩n"); exit(1); } for(cnt = 0; cnt < 3; cnt++) { if((nread = read(filedes, msg, MSGSIZE)) < 0) { printf("fail to call read()₩n"); exit(1); } printf("recv: %s₩n", msg); } unlink(". /fifo"); 표준입력 스트림 44

Section 02 01 【Ex. 11 -14】ex 11 -14. c(1/2) Sender 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 #include <fcntl. h> #include <sys/stat. h> #include <unistd. h> #define MSGSIZE 64 main() { char msg[MSGSIZE]; int filedes; int cnt; if((filedes = open(". /fifo", O_WRONLY)) < 0) { printf("fail to call open()₩n"); exit(1); } 45

Section 02 01 【Ex. 11 -14】ex 11 -14. c(2/2) 18 for(cnt = 0; cnt < 3; cnt++) 19 { 20 printf("input a message: "); 21 scanf("%s", msg); 22 23 if(write(filedes, msg, MSGSIZE) == -1) 24 { 25 printf("fail to call write()₩n"); 26 exit(1); 27 } 28 29 30 sleep(1); } 31 } 표준입력 스트림 46

Section 01 08 05 Results $ ls -al fifo ls: fifo: No such file or directory $ ex 11 -13 & [1] 17296 $ ls -al fifo prw-r--r-1 usp student $ ex 11 -14 input a message: apple_is_red recv: apple_is_red input a message: banana_is_yellow recv: banana_is_yellow input a message: cherry_is_red recv: cherry_is_red [1]+ Done ex 11 -13 $ 47 0 Nov 14 17: 20 fifo