kill a process started with popen

前端 未结 8 1351
温柔的废话
温柔的废话 2020-12-04 15:04

After opening a pipe to a process with popen, is there a way to kill the process that has been started? (Using pclose is not what I want because th

8条回答
  •  隐瞒了意图╮
    2020-12-04 15:13

    I have follow idea of @slacy that create function popen2.
    But found problem when child process is die, parent process that still read file descripter outfp not return from function.

    That could fix by add close unuse pipe on parent process.

    close(p_stdin[READ]);
    close(p_stdout[WRITE]);
    

    We can get correct pid of new process by using bash as shell.

    execl("/bin/bash", "bash", "-c", command, NULL);
    

    When child process die the caller of function popen2 should collect status of child process by call pclose2. if we don't collect that status child process could be zombie process when it terminate.

    This is the full code that tested and work as expect.

    #define READ 0
    #define WRITE 1
    
    pid_t
    popen2(const char *command, int *infp, int *outfp)
    {
        int p_stdin[2], p_stdout[2];
        pid_t pid;
    
        if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
            return -1;
    
        pid = fork();
    
        if (pid < 0)
            return pid;
        else if (pid == 0)
        {
            dup2(p_stdin[READ], STDIN_FILENO);
            dup2(p_stdout[WRITE], STDOUT_FILENO);
    
         //close unuse descriptors on child process.
         close(p_stdin[READ]);
         close(p_stdin[WRITE]);
         close(p_stdout[READ]);
         close(p_stdout[WRITE]);
    
            //can change to any exec* function family.
            execl("/bin/bash", "bash", "-c", command, NULL);
            perror("execl");
            exit(1);
        }
    
        // close unused descriptors on parent process.
        close(p_stdin[READ]);
        close(p_stdout[WRITE]);
    
        if (infp == NULL)
            close(p_stdin[WRITE]);
        else
            *infp = p_stdin[WRITE];
    
        if (outfp == NULL)
            close(p_stdout[READ]);
        else
            *outfp = p_stdout[READ];
    
        return pid;
    }
    
    int
    pclose2(pid_t pid) {
        int internal_stat;
        waitpid(pid, &internal_stat, 0);
        return WEXITSTATUS(internal_stat);
    }
    

提交回复
热议问题