Hi I have a simple function where i create a child process and parent process.
The child process suppose to run dd if=/some/file of=/somedisk. The parent process suppose to run in a loop (until the child exists) and send signal SIGUSR1 which is forcing the dd in child process to report progress data.
Of course i have pipes where i redirect stdio and stderr from the child to the parent. (this i use in other functions and it works fine)
The problem i have is that: 1. I don't get anything on my stderr; 2. As soon as i send SIGUSR1 the process exits somehow.
if(my_pid>0) //The parent part
{
close(FD_pipe_stdout[1]);// Parent process closes output side of the pipe
close(FD_pipe_stderr[1]);// Parent process closes output side of the pipe
while(0==waitpid(my_pid, &my_pid_status, WNOHANG))
{
kill(my_pid, SIGUSR1);
sleep(1);
//read(FD_pipe_stderr[0], pipe_error,PIPE_MAX_SIZE); // Read in a string from the stderror
//puts(pipe_error);
}
puts("going out");
read(FD_pipe_stdout[0], pipe_output,PIPE_MAX_SIZE); // Read in a string from the pipe's input side
close(FD_pipe_stdout[0]);//on the end close the other side of pipe
close(FD_pipe_stderr[0]);//on the end close the other side of pipe
}
else
{ // The child part
close(FD_pipe_stdout[0]);/* Child process closes input side of the pipe */
close(FD_pipe_stderr[0]);/* Child process closes input side of the pipe */
dup2(FD_pipe_stdout[1],1); //redirect the stdout(1) to the fd_pipe and then close the sdtout
dup2(FD_pipe_stderr[1],2);//redirect also stderr to the pipe
system(dd if=/image.img of=/dev/sda);
close(FD_pipe_stdout[1]); //on the end close the other side of pipe
close(FD_pipe_stderr[1]); //on the end close the other side of pipe
exit(0);
}
I see on the screen that the parent is going out from the while loop and i don't understand why.
Thanks in advance
system()
creates a child process to run the specified command, so you really have three processes here:
system()
You're signaling the child process instead of the dd process. SIGUSR1 by default causes a process to exit, so you're killing the child process.
To fix this, you could run dd using one of the exec
functions, instead of calling system()
:
{ // The child part
close(FD_pipe_stdout[0]);
close(FD_pipe_stderr[0]);
dup2(FD_pipe_stdout[1],1);
dup2(FD_pipe_stderr[1],2);
execlp("dd", "dd", "if=/image.img", "of=/dev/sda", NULL);
perror("exec failed");
exit(1);
}
Now you only have two processes, because the child process becomes the dd process. When the parent signals the child, the signal will go to dd .
Note that there is a race condition here. The parent process may send a SIGUSR1 signal before dd starts and sets up its signal handler. To be robust, you should handle this somehow.
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.