ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.
When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.
There is way to get a list of processes on a machine and there is a way to get the parent of the current process. Therefore, as an example, the inefficient way of doing this would be to run the system command 'ps -o pid,ppid ax', look at every ppid, and if it matches the current proccess pid, than it is your child.
I was hoping that there is a better way to do this. Any suggestions besides going through and looking at every process and its ppid?
I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.
When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.
Just call wait() in loop. Optionally with WNOHANG if you need to do other things in the parent besides waiting for children to change status. This way it is not necessary that your parent knows which processes are its child processes.
Another option would be to have a signal-handler for SIGCHLD that sets a global atomic boolean variable which is checked for by your main loop. If it is set call wait(..WNOHANG..) in a loop until no more childs are reported by wait().
If you really want/need the parent process to know which PID's are its child processes, just record all child PID's as returned by fork() in an array or so.
Keep in mind that if your child also fork()s off a subchild (grandchild) and the child exits before the grandchild, it will be the init process that inherits the grandchild, not your parent. This is why just storing the pid's returned by fork will do.
If you take a unique (i.e. easily greppable) name for the exutable (I used "qqq"), you can verify that the subchild has been inherited by init with these commands (you have 2 minutes (120 secs) to run them :-)
I'm currently writing a C++ program that, in short, forks and then the child execs. The parent than waits for the child that exec'ed to die, or quit, or terminate, or whatever, and report on it.
When this happens though, I want to know what happened with any of the other programs that spawned from that exec'ed child. So, if the exec'ed child forked twice and then exited, I want to know that the exec'ed child died (as I would receive a sig child) and that the parent has just inherited 2 new processes.
There is way to get a list of processes on a machine and there is a way to get the parent of the current process. Therefore, as an example, the inefficient way of doing this would be to run the system command 'ps -o pid,ppid ax', look at every ppid, and if it matches the current proccess pid, than it is your child.
I was hoping that there is a better way to do this. Any suggestions besides going through and looking at every process and its ppid?
A colleague of mine, Anton Rapp, suggested a very simple and elegant solution - provided children are unaware and not evil.
In the top father process you introduce an environment variable with a funky name.
Since children inherit environment, just look for that environment variable in every process on the machine.
...
And the funky environment variable may have father PID as its value - in case more than one father with the same name runs.
Last edited by Sergei Steshenko; 12-05-2008 at 01:23 PM.
Keep in mind that if your child also fork()s off a subchild (grandchild) and the child exits before the grandchild, it will be the init process that inherits the grandchild, not your parent. This is why just storing the pid's returned by fork will do.
I thought that the parent would inherit it. I'll have to look into this further.
Quote:
If you really want/need the parent process to know which PID's are its child processes, just record all child PID's as returned by fork() in an array or so.
Quote:
In the top father process you introduce an environment variable with a funky name.
Would it be sufficient to, every time you fork, record the child PID and have the child create a new session ID. Then, any grandchild of that child will be in the same session of that child and the parent will have a list of session IDs to check for children. (Granted of course that the grandchildren do not create additional session IDs).
...
Would it be sufficient to, every time you fork, record the child PID and have the child create a new session ID. Then, any grandchild of that child will be in the same session of that child and the parent will have a list of session IDs to check for children. (Granted of course that the grandchildren do not create additional session IDs).
I'm not sure I understand your intent.
Anton's idea was generic and non-intrusive.
I.e. suppose you have even a closed-source application which can spawn children.
Wrap it in a script which does that funky named environment variable stuff, and all your children have it. Kind of auto-attached tag.
The context was what I call "graceful killing" - suppose you have something which launches computer jobs in a network, and you need to kill the job and all its children. And while you are killing them (this is not atomic) they can still spawn other children.
I had a more complex algorithm to achieve that "graceful killing", but Anton's suggestion seems very simple and robust.
Well, I do not know what you need this for - knowing all your children.
I think the real question is why does the parent need to know about grandchildren exits? I have a similar system in which the main program is always a session leader and it gives every fork a new process group. Through waitpid with -pgid, it monitors that something is still in the original process group and once no process is in a particular group it writes off that particular fork. The child can fork as much as it wants because the process group is inherited, but if a grandchild creates a new session or a new group and everything else in the process group exits then the original program stops IPC (for which the sub-forks will have inherited pipes) and whatever that new session does is outside of the scope of the main program's responsibility. Keep in mind that a group leader can'tsetsid, so the original forks can never start new sessions in my application*.
ta0kira
*There is a special case I use to allow denial of terminal inheritance by creating a new session for the fork in lieu of a new process group, but that can be used in the same way as a process group when waiting for exits.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.