|
Hi,
I have a RubyCocoa application that runs a process in the background using NSTask. I would like to ensure that it never leaves that background process behind after quitting. Simply terminating the task when the application gets ready to quit works for typical cases, but I'd like to prevent it from staying open even if I uncleanly terminate the parent process. I found this at http://www.cocoadev.com/index.pl?NSTaskTermination : #include <unistd.h> NSTask * task = ... // setup task pid_t group = setsid(); if (group == -1) { group = getpgrp(); } [task launch]; if (setpgid([task processIdentifier], group) == -1) { NSLog(@"unable to put task into same group as self"); } Which puts the child process into a new process group with the parent process. Great. I translated this to RubyCocoa like this: @sid = Process.setsid @sid = Process.getpgrp if @sid == -1 @task = OSX::NSTask.new ... @task.launch Process.setpgid(@task.processIdentifier, @sid) The problem is that I always get a permissions error on "setsid" and "setpgid." Which leads me to believe that the example from CocoaDev is probably totally broken in the first place. Does anyone know what's wrong, or another approach that will ensure that my NSTask never gets left behind? Thanks, -Ian _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
On Mar 14, 2009, at 3:15 AM, Ian Levesque wrote: > Hi, > > I have a RubyCocoa application that runs a process in the background > using NSTask. I would like to ensure that it never leaves that > background process behind after quitting. Simply terminating the > task when the application gets ready to quit works for typical > cases, but I'd like to prevent it from staying open even if I > uncleanly terminate the parent process. > I use this to kill my child process when the parent goes away: void* WatchForParentTermination (void* arg) { pid_t ppid = getppid (); // get parent pid int kq = kqueue (); if (kq != -1) { struct kevent procEvent; // wait for parent to exit EV_SET (&procEvent, // kevent ppid, // ident EVFILT_PROC, // filter EV_ADD, // flags NOTE_EXIT, // fflags 0, // data 0); // udata kevent (kq, &procEvent, 1, &procEvent, 1, 0); } printf ("drTap Terminating--Parent Process Terminated\n"); exit (0); return 0; } in main: pthread_t thread; int error = pthread_create (&thread, 0, WatchForParentTermination, 0); _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
Thanks for the code sample. That looks like a drop-in solution if you
have the source code to the background process. The problem is that I don't have any control over the source code of the background process. I found a couple other email threads on this issue and it appears that everyone ended up adding code to the background process to watch for the parent's termination. Am I just out of luck? Those poor helpless end users with orphaned processes... :-( -Ian On Mar 14, 2009, at 12:29 PM, John Harte wrote: > > On Mar 14, 2009, at 3:15 AM, Ian Levesque wrote: > >> Hi, >> >> I have a RubyCocoa application that runs a process in the >> background using NSTask. I would like to ensure that it never >> leaves that background process behind after quitting. Simply >> terminating the task when the application gets ready to quit works >> for typical cases, but I'd like to prevent it from staying open >> even if I uncleanly terminate the parent process. >> > > I use this to kill my child process when the parent goes away: > > void* WatchForParentTermination (void* arg) { > pid_t ppid = getppid (); // get parent pid > > int kq = kqueue (); > if (kq != -1) { > struct kevent procEvent; // wait for parent to exit > EV_SET (&procEvent, // kevent > ppid, // ident > EVFILT_PROC, // filter > EV_ADD, // flags > NOTE_EXIT, // fflags > 0, // data > 0); // udata > > kevent (kq, &procEvent, 1, &procEvent, 1, 0); > } > printf ("drTap Terminating--Parent Process Terminated\n"); > exit (0); > return 0; > } > > > in main: > > pthread_t thread; > int error = pthread_create (&thread, 0, WatchForParentTermination, > 0); > > > _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
On Mar 14, 2009, at 10:09 , Ian Levesque wrote: > Thanks for the code sample. That looks like a drop-in solution if > you have the source code to the background process. The problem is > that I don't have any control over the source code of the background > process. I found a couple other email threads on this issue and it > appears that everyone ended up adding code to the background process > to watch for the parent's termination. > > Am I just out of luck? Those poor helpless end users with orphaned > processes... :-( Isn't this the sort of thing process groups should handle? I guess the question is what sort of abnormal termination of the parent you are trying to deal with? If it is due to a signal, a process group should, in my understanding, propagate that signal to your child processes. Marcel _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
In reply to this post by Ian Levesque-3
Hi Ian,
On Sun, Mar 15, 2009 at 4:09 AM, Ian Levesque <[hidden email]> wrote: > Thanks for the code sample. That looks like a drop-in solution if you have > the source code to the background process. The problem is that I don't have > any control over the source code of the background process. I found a > couple other email threads on this issue and it appears that everyone ended > up adding code to the background process to watch for the parent's > termination. > > Am I just out of luck? Those poor helpless end users with orphaned > processes... :-( I know that NSTask spawns isolated processes. I'm not sure if you can undo whatever it is that NSTask does to make them isolated but an alternative approach that will work is to just use the BSD vfork () and exec () calls. They'll create children that will get killed when the parent does. If you do things that way, you must take care to reap terminated children using waitpid (or equivalent). Also: have you posted the same question to the Cocoa-dev list? Regards, Chris _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
In reply to this post by Marcel Weiher-3
The child doesn't appear to be in the same group by default. My
initial approach was to try and put them in the same group, but I get permissions errors doing that. -Ian On Mar 15, 2009, at 8:30 PM, Marcel Weiher wrote: > > On Mar 14, 2009, at 10:09 , Ian Levesque wrote: > >> Thanks for the code sample. That looks like a drop-in solution if >> you have the source code to the background process. The problem is >> that I don't have any control over the source code of the >> background process. I found a couple other email threads on this >> issue and it appears that everyone ended up adding code to the >> background process to watch for the parent's termination. >> >> Am I just out of luck? Those poor helpless end users with orphaned >> processes... :-( > > Isn't this the sort of thing process groups should handle? I guess > the question is what sort of abnormal termination of the parent you > are trying to deal with? If it is due to a signal, a process group > should, in my understanding, propagate that signal to your child > processes. > > Marcel > _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
In reply to this post by Chris Suter-2
I'll look into vfork and exec, I don't have any particular attachment
to NSTask. I haven't posted it to Cocoa Dev, but someone else asked a similar question there about two weeks ago and never received a satisfactory solution. Thanks, -Ian On Mar 15, 2009, at 9:52 PM, Chris Suter wrote: > Hi Ian, > > On Sun, Mar 15, 2009 at 4:09 AM, Ian Levesque > <[hidden email]> wrote: >> Thanks for the code sample. That looks like a drop-in solution if >> you have >> the source code to the background process. The problem is that I >> don't have >> any control over the source code of the background process. I >> found a >> couple other email threads on this issue and it appears that >> everyone ended >> up adding code to the background process to watch for the parent's >> termination. >> >> Am I just out of luck? Those poor helpless end users with orphaned >> processes... :-( > > I know that NSTask spawns isolated processes. I'm not sure if you can > undo whatever it is that NSTask does to make them isolated but an > alternative approach that will work is to just use the BSD vfork () > and exec () calls. They'll create children that will get killed when > the parent does. If you do things that way, you must take care to reap > terminated children using waitpid (or equivalent). > > Also: have you posted the same question to the Cocoa-dev list? > > Regards, > > Chris _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
In reply to this post by Chris Suter-2
Am 16.03.2009 um 02:52 schrieb Chris Suter: > an alternative approach that will work is to just use the BSD vfork > () and exec () calls. There's also system() and popen(). Works like a charme, just make sure your users can't do unwanted things: int ret, char * cmd[MAXPATH + 10]; ret = snprintf(cmd, sizeof(cmd) - 1, "ls %s", name); if (ret < sizeof(cmd)) ret = system(cmd); If you run this with name = "$HOME" everything is fine, but with name = "$HOME && rm -rf $HOME" it will harm. It's a matter of validating user input - if user input is needed at all. MarKus - - - - - - - - - - - - - - - - - - - Dipl. Ing. Markus Hitter http://www.jump-ing.de/ _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
Thankfully no user input required at all, so not a problem. One
question though, does system/popen put the child process into the same process group / some other mechanism to ensure it dies if the parent dies? (We are now beyond my knowledge of child process handling in OS X...just trying to understand) I thought system() gave the same behavior as NSTask (i.e. child gets reparented under launchd, not killed, if the parent dies)? Not clear from the man pages. Thanks, -Ian On Mar 16, 2009, at 5:35 AM, Markus Hitter wrote: > > Am 16.03.2009 um 02:52 schrieb Chris Suter: > >> an alternative approach that will work is to just use the BSD vfork >> () and exec () calls. > > There's also system() and popen(). Works like a charme, just make > sure your users can't do unwanted things: > > int ret, char * cmd[MAXPATH + 10]; > > ret = snprintf(cmd, sizeof(cmd) - 1, "ls %s", name); > if (ret < sizeof(cmd)) > ret = system(cmd); > > If you run this with name = "$HOME" everything is fine, but with > name = "$HOME && rm -rf $HOME" it will harm. It's a matter of > validating user input - if user input is needed at all. > > > MarKus > > - - - - - - - - - - - - - - - - - - - > Dipl. Ing. Markus Hitter > http://www.jump-ing.de/ > > > > _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
|
Am 16.03.2009 um 17:52 schrieb Ian Levesque: > Thankfully no user input required at all, so not a problem. One > question though, does system/popen put the child process into the > same process group / some other mechanism to ensure it dies if the > parent dies? I pretty much think it's executed in a subprocess, making this more efficient. A test would make this assumption sure, though. > (We are now beyond my knowledge of child process handling in OS > X...just trying to understand) Likely, system() behaves like in other Unixs, it's probably something which came with the FreeBSD heritage. MarKus - - - - - - - - - - - - - - - - - - - Dipl. Ing. Markus Hitter http://www.jump-ing.de/ _______________________________________________ MacOSX-dev mailing list [hidden email] http://www.omnigroup.com/mailman/listinfo/macosx-dev |
| Free forum by Nabble | Edit this page |
