C под UNIX - C (СИ)
Формулировка задачи:
мужчины,есть вот программка но она вроде неправильно работает и в ней нельзя использовать "select" Помогите переделать, вот задание если что
задание: процесс 1 открывает файл и порождает потомков 2 и 3. Потомки после сигнала от предка пишут в файл по N байт, посылают сигналы процессу 1 и завершают работу. После этого процесс 1 считывает данные из файла и выводит на экран.
#include <signal.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> int sig = SIGUSR1; /* signal for sent */ int sigrecvd = 0; /* received 'sig' signals counter */ int nbytes = 10; char bytes[2] = "23"; /* bytes for write */ int pid, cpid2, cpid3, ppid; /* child & parent pids */ int fd; /* file descriptor */ int i,j; struct timeval ttwait = {1,0}; /* delay {seconds,microseconds} */ char outfile[128] = "out.txt"; /* file for write */ void sig_handler(int signal) { int pid; if (signal == sig ) sigrecvd++; pid=getpid(); fprintf(stderr, "%u: signal %u recieved.\n",pid,signal); } void run_child (int pnum) { pid=getpid(); fprintf(stderr, "Process %u pid is %u\n",pnum,pid ); ppid = getppid(); fprintf(stderr, "%u: stop until signal...\n",pid); for (;sigrecvd<1;) /* stop until signal */ { select(0,NULL,NULL,NULL,&ttwait); } fprintf(stderr, "%u: writing %u bytes to %s...\n",pid,nbytes,outfile); /* write nbytes times first byte of bytes */ for (j=0;j<nbytes;j++) write(fd, bytes-2+pnum, 1); fprintf(stderr, "%u: ..write done, send signal %u to parent (%u) and terminate.\n",pid,sig,ppid); kill(ppid,sig); exit(0); /* child */ } int main (int argc, char **argv) { /* 1-st arg = filename, if exist */ if (1 < argc) (void)strcpy(outfile,argv[1]); /* 1-st arg = N (bytes to write), if exist */ if (2 < argc) if ( 1 != sscanf(argv[2],"%u",&nbytes) ) fprintf(stderr, "N bytes is not %%u, ignored.\n"); fprintf(stderr, "N bytes set to [%u].\n",nbytes); fprintf(stderr, "Outfile set to [%s].\n",outfile); /* sigactions */ if (SIG_ERR == signal(sig,sig_handler)) { fprintf(stderr, "cant set signal %u handler - terminated.\n",sig); exit(-1); } /* open file outfile */ if (0 > ( fd = open(outfile,O_RDWR|O_APPEND|O_CREAT,0644))) { fprintf(stderr, "Process 1: cant open() file %s.\n",outfile); exit(-1); } /* fork */ if (0 == (cpid2 = fork()) ) run_child(2); if (0 == (cpid3 = fork()) ) run_child(3); pid=getpid(); fprintf(stderr, "Process 1 pid is %u\n",pid ); /* delay & send signals */ select(0,NULL,NULL,NULL,&ttwait); kill(cpid2,sig); kill(cpid3,sig); for (;sigrecvd<2;) /* wait for children */ select(0,NULL,NULL,NULL,&ttwait); fprintf(stderr, "%u: all chldren done, print outfile %s: ",pid,outfile ); lseek(fd,0,SEEK_SET); bytes[1]='\0'; for (j=1;j>0;) { j=read(fd, bytes, 1); fprintf(stderr, "%s",bytes); } fprintf(stderr, "\n"); if (j<0) fprintf(stderr, "%u: error read file %s\n",pid,outfile); exit(0); } /* main */
Решение задачи: «C под UNIX»
textual
Листинг программы
#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <signal.h> #include <stdlib.h> #define FILE_NAME "test.txt" #define SLEEP_TIME 100 static void sighandler(int sn) {} int main(void){ pid_t pid1, pid2; int chld_no, ret; FILE * f; char buf[BUFSIZ]; if ( signal(SIGUSR1, sighandler) == SIG_ERR ){ perror("signal"); exit(1); } if ( ( f = fopen(FILE_NAME, "w+") ) == NULL ){ perror("fopen"); exit(1); } chld_no = 1; if ( ( pid1 = fork() ) == -1 ){ perror("fork"); if ( fclose(f) ) perror("fclose"); exit(1); } else if ( ! pid1 ){ pause(); while ( ftrylockfile(f) ) usleep(SLEEP_TIME); if ( ( ret = fprintf(f, "Moya patomak #%d\n", chld_no) ) < 0 ) perror("fprintf"); funlockfile(f); return ( ret < 0 ) ? 1 : 0; } chld_no = 2; if ( ( pid2 = fork() ) == -1 ){ perror("fork"); if ( kill(pid1, SIGTERM) ) perror("kill"); if ( fclose(f) ) perror("fclose"); exit(1); } else if ( ! pid2 ){ pause(); while ( ftrylockfile(f) ) usleep(SLEEP_TIME); if ( ( ret = fprintf(f, "Moya patomak #%d\n", chld_no) ) < 0 ) perror("fprintf"); funlockfile(f); return ( ret < 0 ) ? 1 : 0; } if ( kill(pid1, SIGUSR1) ){ perror("kill"); if ( kill(pid1, SIGTERM) ) perror("kill"); if ( kill(pid2, SIGTERM) ) perror("kill"); if ( fclose(f) ) perror("fclose"); exit(1); } if ( kill(pid2, SIGUSR1) ){ perror("kill"); if ( kill(pid2, SIGTERM) ) perror("kill"); if ( fclose(f) ) perror("fclose"); exit(1); } waitpid(pid1, &ret, 0); waitpid(pid2, &ret, 0); rewind(f); while ( fgets(buf, BUFSIZ, f) ) printf("%s", buf); fclose(f); exit(0); }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д