进程终止不会影响waitpid()

时间:2011-10-30 10:43:59

标签: c linux operating-system system-calls

我需要在Linux下使用C模拟以下bash命令(使用fork,exec,kill,signal,wait,waitpid,dup2,open,sleep,pipe等)。

[0] echo 'tail-f $1' > /tmp/rtail
[1]/tmp/rtail ~/.bash_history >> /tmp/1.txt &
PID of process [1] should be saved.
[2] Expect termination of the command started on step [1]. After termination print on the screen: "Program 1 terminated."

到目前为止,我有这段代码:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>  
#include <sys/wait.h> 

int main(int argc, char *argv[]) {
    pid_t pID = fork();
    if (pID == 0) // child
    {
        int file = open("/tmp/rtail", O_CREAT | O_WRONLY);

        //Now we redirect standard output to the file using dup2
        dup2(file, 1);

        puts("tail -f $1");
        close(file);
        system("chmod 777 /tmp/rtail");
        exit(0);
    } else if (pID < 0) // failed to fork
    {
        printf("Failed to fork");
        exit(1);
        // Throw exception
    } else // parent
    {
        pid_t pID2 = fork();
        if (pID2 == 0) {
            char tmp1[20];
            sprintf(tmp1, "echo %i > /tmp/pidprog1", getpid());
            system(tmp1);


            int file = open("/tmp/1.txt", O_APPEND | O_WRONLY);

            //Now we redirect standard output to the file using dup2
            dup2(file, 1);
            FILE* proc = popen("sh /tmp/rtail ~/.bash_history", "r");
            char tmp[20];
            while (fgets(tmp, 40, proc) != NULL) {
                printf(tmp);
            }
            fclose(proc);

            exit(0);
        }
        else if (pID2 < 0) // failed to fork
        {
            printf("Failed to fork");
            exit(1);
            // Throw exception
        } else {
            FILE* fl = fopen("/tmp/pidprog1", "r");
            char buff[10];
            fgets(buff, 10, fl);
            int pidc = atoi(buff);
            fclose(fl);
            int status;
            waitpid(pidc, &status, 0);
            printf("Program 1 terminated\n");
        }
    }

    // Code executed by both parent and child.  

    return 0;
}

问题是当我使用保存在/ tmp / pidprog1中的PID手动终止进程时,父进程不会停止等待,也不会打印“程序1终止”行。

1 个答案:

答案 0 :(得分:1)

父母很可能将垃圾值读入pidc。你没有做任何事情来确保孙在父母试图读它之前实际上已经写了pid。您需要使用wait来确保有效的pid在文件中。 (或者,只需从fork的返回值跟踪pids。)

您没有做足够的错误检查:如果任何打开失败会发生什么? (例如,当你尝试 打开/tmp/1.txt进行追加但它还不存在?)

为什么使用fgets将40个字符读入20的缓冲区?

为什么要重复使用fput而不是只写入fd?

为什么要将错误消息打印到stdout而不是stderr(使用perror)。