APUE2e之Exercise 10.6 Solution A

来源:互联网 发布:知天下图吧 编辑:程序博客网 时间:2024/06/09 18:35

Using File I/O to read and write the file.


/**    * apue-chap10: exercise10-6a.c * * Description: FILE I/O * * Created On: Feb 15, 2012  * * @author: Huang Zhu * * @email: zhuhuang.zp@gmail.com */ #include <apueerr.h>#include <signal.h>#include <stdio.h>#include <fcntl.h> static volatile sig_atomic_t sigflag;static sigset_t newmask, oldmask, zeromask; static void sig_usr(int signo){sigflag = 1;} void TELL_WAIT(void){if(signal(SIGUSR1, sig_usr) == SIG_ERR)perror("signal(SIGUSR1) error");if(signal(SIGUSR2, sig_usr) == SIG_ERR)perror("signal(SIGUSR2) error");sigemptyset(&zeromask);sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);sigaddset(&newmask, SIGUSR2); //block SIGUSR1 and SIGUSR2, and save current signal maskif(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)perror("SIG_BLOCK error");} void TELL_PARENT(pid_t pid){kill(pid, SIGUSR2);} void TELL_CHILD(pid_t pid){kill(pid, SIGUSR1);} void WAIT_PARENT(void){while(sigflag == 0)sigsuspend(&zeromask);  //set mask and sleep and waitsigflag = 0; if(sigprocmask(SIG_SETMASK, &oldmask,  NULL) < 0)perror("SIG_SETMASK error");} void WAIT_CHILD(void){while(sigflag == 0)sigsuspend(&zeromask);  //set mask and sleep and waitsigflag = 0; if(sigprocmask(SIG_SETMASK, &oldmask,  NULL) < 0)perror("SIG_SETMASK error");} int main(void){int fd, pid, ppid, counter, round = 5;char *filename = "counter.file";char *rbuf, *wbuf;int i, j; rbuf = (char *)malloc(sizeof(int));wbuf = (char *)malloc(sizeof(int)); if((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)err_sys("open error"); if(sprintf(wbuf, "%d", 0) < 0)err_sys("sprintf error"); if(write(fd, wbuf, sizeof(int)) > 0 ){printf("Writing initial value of the counter: %s\n", wbuf);fsync(fd);} if((pid = fork()) < 0){err_sys("fork error");}else if(pid == 0){ //childppid = getppid(); for(i = 0;  i < round; i++){printf("\nChild: round %d\n", i+1); TELL_WAIT(); //set up signal handler counter = -1; if(lseek(fd, 0, SEEK_SET) != 0)err_sys("Child: lseek error");if(read(fd, rbuf, sizeof(int)) < 0)err_sys("Child: read error");if(sscanf(rbuf, "%d", &counter) == EOF)err_sys("Child: sscanf error");printf("Child: read counter from the file: %d\n", counter); counter++;printf("Child: increase counter to: %d\n", counter); if(lseek(fd, 0, SEEK_SET) != 0)err_sys("Child: lseek error");if(sprintf(wbuf, "%d", counter) < 0)err_sys("Child: sprintf error"); if(write(fd, wbuf, sizeof(int)) > 0 ){printf("Child: Write counter to the file: %s\n", wbuf);fsync(fd);} TELL_PARENT(ppid); WAIT_PARENT();} counter = -1;if(lseek(fd, 0, SEEK_SET) != 0)err_sys("Child: lseek error");if(read(fd, rbuf, sizeof(int)) < 0)err_sys("Child: read error");if(sscanf(rbuf, "%d", &counter) == EOF)err_sys("Child: sscanf error");printf("\nChild: read counter from the file: %d\n", counter); close(fd);exit(0);}else{ //parentfor(j = 0; j < round; j++){TELL_WAIT(); //set up signal handler WAIT_CHILD();printf("\nParent: round %d\n", j+1);counter = -1; if(lseek(fd, 0, SEEK_SET) != 0)err_sys("Parent: lseek error");if(read(fd, rbuf, sizeof(int)) < 0)err_sys("Parent: read error");if(sscanf(rbuf, "%d", &counter) == EOF)err_sys("Parent: sscanf error");printf("Parent: read counter from the file: %d\n", counter); counter++;printf("Parent: increase counter to: %d\n", counter); if(lseek(fd, 0, SEEK_SET) != 0)err_sys("Parent: lseek error");if(sprintf(wbuf, "%d", counter) < 0)err_sys("Parent: sprintf error"); if(write(fd, wbuf, sizeof(int)) > 0 ){printf("Parent: Write counter to the file: %s\n", wbuf);fsync(fd);} TELL_CHILD(pid);}} close(fd);return 0;}


原创粉丝点击