简体   繁体   中英

Child doesn't work properly after fork

I'm trying to pass an expression from main to 3 children. Each child modifies the expression and after 3rd child is finished the expression returns back to main and is printed on the screen.

I have run each child on its own and seems to be working just fine. But when i try execlp in main something goes wrong.

Every child reads after the file(channel) is filled with data and then deletes the contents of the channel.

int main(int argc, char* argv[]){
    char expr_buffer[MAX_CHAR + 1];
    int rmv,i;
    int fd1,fd2,fd3,fd4, expr_len, sync;
    ssize_t bytes_written, bytes_read;
    off_t offset;

do{



fd1 = open("Channel_1.txt", O_RDWR | O_CREAT, NULL );
if (fd1 < 0){
    perror("Error opening \"Channel_1.txt\".\n");
    return(1);
}

fd2 = open("Channel_2.txt", O_RDWR | O_CREAT, NULL );
if (fd2 < 0){
    perror("Error opening \"Channel_2.txt\".\n");
    return(1);
}

fd3 = open("Channel_3.txt", O_RDWR | O_CREAT, NULL );
if (fd3 < 0){
    perror("Error opening \"Channel_3.txt\".\n");
    return(1);
}

fd4 = open("Channel_4.txt", O_RDWR | O_CREAT, NULL );
if (fd4 < 0){
    perror("Error opening \"Channel_4.txt\".\n");
    return(1);
}



char formatstring[13];

printf("Waiting for expression...\n");
sprintf(formatstring,"%%%ds",MAX_CHAR);
scanf(formatstring, expr_buffer );

for(i=0; i<MAX_CHAR + 1; i++){
    if ((expr_buffer[i] == '\0') && (i != MAX_CHAR)){
        expr_buffer[i] ='\n';
        expr_buffer[i+1] = '\0';
        break;
    }   
    else if((expr_buffer[i] == '\0') && (i == MAX_CHAR)){
        expr_buffer[i-1]= '\n';
        break;
    }

}

expr_len = strlen(expr_buffer);
struct stat file_stat;
off_t file_size;

int pid_1, pid_2, pid_3;
int status_1, status_2, status_3;

if (ftruncate(fd1, (off_t)0) == -1){
    perror("Error erasing content of file: \"Channel_1.txt\".\n");
    return -1;
}

bytes_written = write(fd1, expr_buffer, expr_len*sizeof(char));

if (bytes_written < 0) {
    perror("Error writing to file: \"Channel_1.txt\"");
    if (close(fd1) < 0) {
        perror(NULL);
    }
    return 1;
}
if (bytes_written < expr_len) {
    printf("Incomplete data written to file: \"Channel_1.txt\".\n");
}   
sync = fsync(fd1);
if (sync == 0){
    printf("Data written successfully to file: \"Channel_1.txt\".\n");
}
else {
    perror("Error syncing data to disk.\n");
    return(-2);//
}


if (!(pid_1 = fork())) {
    printf("trying to execute Child_1\n");
    execlp("./Child_1","Channel_1.txt","Channel_2.txt", NULL );
    perror("execlp");
    return(1);
}
waitpid(pid_1,&status_1,0);
if (WIFEXITED(status_1)) {
    printf("child returned %d\n", WEXITSTATUS(status_1));
}
else {
    printf("child_1 terminated abnormally\n");
} 

if (!(pid_2=fork())) {
    printf("trying to execute Child_2\n");
    execlp("./Child_2", "Channel_2.txt","Channel_3.txt", NULL );
    perror("execlp");
    return(1);
}

waitpid(pid_2,&status_2,0);
if (WIFEXITED(status_2)) {
    printf("child returned %d\n", WEXITSTATUS(status_2));
}
else {
    printf("child_2 terminated abnormally\n");
} 

if (!(pid_3 = fork())) {
    printf("trying to execute Child_3\n");
    execlp("./Child_3", "Channel_3.txt","Channel_4.txt",NULL);
    perror("execlp");
    return(1);
}

waitpid(pid_3,&status_3,0);
if (WIFEXITED(status_3)) {
    printf("child returned %d\n", WEXITSTATUS(status_3));
}
else {
    printf("child_3 terminated abnormally\n");
} 

while(1){


    if (fstat(fd4, &file_stat) == -1) {
        perror("Fstat.");
        return(-1);
    }

    file_size = file_stat.st_size;
    if (file_size == 0){
        printf("\"Channel_4.txt\" is  empty.\n");
    }
    else{
        break;
    }
}

bytes_read = read(fd4, expr_buffer, MAX_CHAR*sizeof(char));
if (bytes_read < 0) {
    perror("Read failure for file: \"Channel_4.txt\"\n");
    close(fd1);
    return 1;
}
printf("%s\n",expr_buffer);

if (close(fd1) < 0) {
    perror(NULL);
    return 2;//
}
if (close(fd2) < 0) {
    perror(NULL);
    return 2;//
}
if (close(fd3) < 0) {
    perror(NULL);
    return 2;//
}
if (close(fd4) < 0) {
    perror(NULL);
    return 2;//
}

}while(expr_buffer[0] != 'q');  


rmv = remove("Channel_1.txt");
if (rmv == -1){
    perror("Error removing Channel_1.txt.\n");
}
rmv = remove("Channel_2.txt");
if (rmv == -1){
    perror("Error removing Channel_2.txt.\n");
}
rmv = remove("Channel_3.txt");
if (rmv == -1){
    perror("Error removing Channel_3.txt.\n");
}
rmv = remove("Channel_4.txt");
if (rmv == -1){
    perror("Error removing Channel_4.txt.\n");
}

return(0);

}

And that's a part of child_1

int main(int argc, char *argv[]){
    int expr_len;
    int fd5,fd2,i,j,k;
    off_t offset;
    int bytes_read,bytes_written;
    char expr_buffer[MAX_CHAR +1];
    //elegxos ean grafthkan ta arxeia
    struct stat file_stat;
    off_t file_size;
    int sync;

sleep(1);
fd5 = open(argv[1], O_RDWR | O_CREAT, NULL );
if (fd5 < 0){
    perror("Error opening \"Channel_1.txt\".\n");
    return(1);
}
fd2 = open(argv[2], O_RDWR | O_CREAT, NULL );
if (fd5 < 0){
    perror("Error opening \"Channel_2.txt\".\n");
    return(1);
}
while(1){


    if (fstat(fd5, &file_stat) == -1) {
        perror("Fstat.");
        return(-1);
    }

    file_size = file_stat.st_size;
    if (file_size == 0){
        printf("\"Channel_1.txt\" is  empty.\n");
    }
    else{
        break;
    }
}



offset = lseek(fd5, (off_t)(0*sizeof(char)), SEEK_SET);
if( lseek(fd5, 0*sizeof(char), SEEK_SET) < 0) { 
    printf("%d\n", errno);
        perror("lseek to beginning of file: \"Channel_1.txt\"\n");
        close(fd5);
        return 1;
}
bytes_read = read(fd5, expr_buffer, MAX_CHAR*sizeof(char)); 
if (bytes_read < 0) {
    perror("Read failure for file: \"Channel_1.txt\"\n");
    close(fd5);
    return 1;
}

When i execute the program it says Channel_1.txt is empty without ever edning.

纯粹回答您的特定问题,而不是解决代码中的任何其他问题:输入文件Channel_1.txt为空时,遵循的Child_1中的代码路径没有return语句或任何其他退出代码的方式。 while(1)循环。

You are creating the files Channel_1.txt etc. with mode NULL , ie no permissions. Thus, Child_1 cannot succeed opening Channel_1.txt with O_RDWR - open has to set errno to EACCES .

Since this is not the behaviour you describe, the program you speak of cannot be the one that you posted (which doesn't compile without adding missing includes, defines and brace anyway).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM