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
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);
}