0

I have a simple server which does fork for a new socket connection. If I set signal(SIGCHLD, SIG_IGN); to avoid zombies when I call system() in child process to execute needed script - everything is executed fine but seems like child gets removed from table of processes before it exited, so it's strange. Here is the example of output:

server started. version 0.20
opening socket 
binding 
listening 
parent process does nothing
client message: print.php
executing php script: "print.php" 
full command line of execution: "php print.php" <-- we call system() which executes php script on server
Hello, World!                      <-- this is output of php script
return value from script execution: -1      <-- should be ok but -1 instead
system returns -1 error: No child processes
child is closing socket 
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
pulse
  • 303
  • 4
  • 18
  • It's because `system` expects the zombie. http://stackoverflow.com/questions/25039369/system-function-while-sigchld-is-ignored – cnicutar Jan 20 '15 at 17:16
  • should I change system() to something from exec() family or just ignore that? – pulse Jan 20 '15 at 17:19
  • Implementing a completely reliable `system` is hard. You could leave `SIGCHLD` alone (don't set it or reset it to `SIG_DFL`) and `system` will take care of zombies. – cnicutar Jan 20 '15 at 17:21
  • I've read you link, thanks. But If I don't set SIGCHLD then no one takes care about zombies: – pulse Jan 20 '15 at 17:41
  • `system` calls `wait` for its children so it does take care of zombies. – cnicutar Jan 20 '15 at 17:43
  • yeah, but its like I have a server, which does fork() on every new connection. After that child process run do_stuff() function. inside system() called and message goes back to the client. After that I have zombie: /mnt/repos/repos/sched/src/sched$ ps -A | grep insta 11801 pts/13 00:00:00 insta 11817 pts/13 00:00:00 insta – pulse Jan 20 '15 at 17:46
  • Okay so set IGN in your parent process but reset it to `SIG_DFL` in the processes that you yourself fork. Or just wait for the processes you fork. – cnicutar Jan 20 '15 at 17:49
  • or just call `wait()` or `waitpid()` in your parent process after forking -- `waitpid()` can be used with option WNOHANG so it doesn't really wait but picks up the exit status of terminated children so the zombies will go – Ingo Leonhardt Jan 20 '15 at 17:52
  • wait() is not an option because I don't want server to be blocked after every new connection for unknown time. waitpid(-1 – pulse Jan 20 '15 at 17:55
  • I also tried with waitpid(-1, &status, WNOHANG) but it doesn't work well as expected. It's like it kills one zombie per time. So if I have 10 connections and waitpid() called in parent code it is not able to kill any child process because there are no zombies yet, but there will be 10 in few seconds. On next connection when waitpid() called it kills only 1 zombie and 9 still left. – pulse Jan 20 '15 at 17:59
  • `wait()` and `waitpid()` return the process PID of one child process, so if you have more than one, you need to loop over all the possible children. Something like `while(waitpid(...) > 0);` (assuming you do not want to check for errors, etc.) – Alexis Wilke Jun 25 '16 at 18:05

0 Answers0