シグナルとフォークを使用してファイルのコンテンツを読み取り、それを stdout (低レベル I/O) に書き戻す必要があるプロジェクトがあります。親プロセスと子プロセスの間で読み取りと書き込みの作業を分割する必要があり、最初に親プロセスを開始して、ファイルのコンテンツの読み取りと書き込みを行う必要があります。親プロセスが終了したら、シグナル SIGUSR1 を子プロセスに送信して、次のデータ ブロックの読み取りと書き込みを開始できるようにする必要があります。読み書き部分は正常に動作しますが、信号部分と処理部分に問題があります。プログラムを実行すると、正しい出力が表示されますが、終了しません。誰かが私のコードの何が問題なのかをチェックできますか?
これが私がこれまでに得たものです:
#define _XOPEN_SOURCE 600
#include <limits.h> /* For LONG_MAX */
#include <fcntl.h> /*For open()*/
#include <unistd.h> /*For close(), read(), write(), nice()*/
#include <stdlib.h> /*For exit()*/
#include <stdio.h> /*For fprintf(),perror()*/
#include <signal.h> /*For signal()*/
#include <sys/types.h> /* For pid_t */
#include <sys/wait.h> /* For wait() */
void my_handler(int);
void displayUsage(FILE *, const char *);
int main(int argc, char **argv) {
char c[BUFSIZ]; /* To hold the string that has been read from the file */
int fd; /* file descriptor */
int n;
long int nBytes; /* To hold the number of bytes to read */
pid_t pid;
int child_status;
/* Display usage if user use this process wrong */
if(argc != 3){
displayUsage(stderr, argv[0]);
exit(1);
}
/* Convert argv[1] to long - number of bytes to read */
nBytes = strtol(argv[1], NULL, 10);
if((nBytes <= 0) || (nBytes > INT_MAX)){
fprintf(stderr, "Bufferize %s is not a positive integer\n",
argv[1]);
exit(2);
}
/* Open a file */
if((fd = open(argv[2],O_RDONLY,0)) < 0){
perror(argv[2]);
exit(3);
}
/* Attempt to register a signal handler */
if(signal(SIGUSR1, my_handler) == SIG_ERR){
perror("Could not set a handler for SIGUSR1");
exit(4);
}
/* lowering the process priority */
if(nice(40) < 0){
perror("Cannot lower the priority");
exit(5);
}
/* Create a new process */
pid = fork();
if(pid < 0){
exit(6);
}
/* Allocating memory space for string/data to be read from the file
if(!(c = malloc(nBytes))){
perror("ERROR");
exit(4);
}*/
if(pid == 0){
pause();
/* I'm the child */
printf("Child's turn!\n");
/* Read The File */
while((n = read(fd, c, nBytes)) != 0){
/* Write content of 'c' to the stdout */
if(write(STDOUT_FILENO, c, n) < 0){
perror("Write Error!\n");
exit(7);
}
}
kill(pid,SIGUSR1);
}
else{
/* I'm the parent */
printf("Parent's turn!\n");
/* Read The File */
while((n = read(fd, c, nBytes)) != 0){
/* Write content of 'c' to the stdout */
if(write(STDOUT_FILENO, c, n) < 0){
perror("Write Error!\n");
exit(7);
}
}
/* Reap the child */
wait(&child_status);
kill(pid, SIGUSR1);
}
pause();
/* Close the file */
if(close(fd) < 0){
perror(argv[2]);
exit(8);
}
exit(0);
}
void displayUsage(FILE *fp, const char *arg){
fprintf(fp, "Usage: %s n filename\n", arg);
fprintf(fp, "where\n");
fprintf(fp,
"\tn\tNumber of bytes to read and write in each \"block\".\n");
fprintf(fp,"\tfilename\tName of file to be catted.\n");
}
void my_handler(int sig){
/* Re-registering the handler */
if(signal(SIGUSR1, my_handler) == SIG_ERR){
perror("Could not set a handler for SIGUSR1");
exit(4);
}
/*if(isParent == 1){
printf("Parent's turn!\n");
}
else{
printf("Child's turn!\n");
}*/
}