jet@lavaca.uh.edu (J. Eric Townsend) (12/20/89)
Maybe there's an obvious answer to this that I didn't hit while RTFM'ing. While in process foo, I want to crank up process bar and have it run independently of foo. system("bar &") doesn't do the trick, as a wait() is still called for the parent shell of bar (it seems that's what happening, at least). Any suggestions? No flames, please, this is my first foray into doing sockets/networking/daemon code... work: Department of Mathematics University of Houston (713) 749 2120 Houston, Tx 77204-3476 jet@karazm.math.uh.edu home: jet@flatline.UUCP
klee@chico.pa.dec.com (Ken Lee) (12/20/89)
In article <1989Dec19.191032.21857@lavaca.uh.edu>, jet@lavaca.uh.edu (J. Eric Townsend) writes: > Maybe there's an obvious answer to this that I didn't hit while > RTFM'ing. While in process foo, I want to crank up process bar > and have it run independently of foo. The standard way of doing this is to fork (or vfork) and execl (or execv). Any good UNIX programming book should have example code. Ken Lee DEC Western Software Laboratory, Palo Alto, Calif. Internet: klee@decwrl.dec.com uucp: uunet!decwrl!klee
bph@buengc.BU.EDU (Blair P. Houghton) (12/21/89)
In article <1989Dec19.191032.21857@lavaca.uh.edu> jet@lavaca.uh.edu (J. Eric Townsend) writes: > >Maybe there's an obvious answer to this that I didn't hit while >RTFM'ing. It's not obvious. It's a bit of idiomatic wizardry that you would have found in any Unix-programming-in-C book, though. >While in process foo, I want to crank up process bar >and have it run independently of foo. system("bar &") doesn't do >the trick, as a wait() is still called for the parent shell of bar (it >seems that's what happening, at least). /* fork a nother process. */ if ( !fork() ) exec("bar",...); Read the manual pages for fork(), and use the correct exec-function (there are a slew of them that will work under ultrix: execl, execv, execle, execlp, execvp, exect, and execve) to get this to work. The basic thing is that fork() makes an exact, running copy of the process you are running. It returns to the original process the pid of the new process, and "returns" to the new process a 0. So, now there are two programs running separately on the system, with only their pid's, ppid's, and the return value from this fork() to distinguish them. They are totally independent, unless you use the returned pid of the child explicitly in a wait-call (there's a pile of those, too: wait, wait3, and waitpid). The trick is to take the new process and immediately change it, using one of the exec family, which clears out the running process and fires up the process in the file named in the argument to the exec call. You'd think something as common as this (and it's in about every program ever written that gets put into a unix release) would become a system call of its own. I guess the number and variety of the exec's keeps that from happening. Last hint: execv("bar",(char *)NULL) is your best bet, but look over the others to make sure you're using the features of these functions correctly. Absolute final hint: There is no function that is named exec(), and I have not the slightest idea why... --Blair "Down and dirty systems programming."
barmar@Think.COM (12/21/89)
In article <2308@bacchus.dec.com> klee@decwrl.dec.com writes: >In article <1989Dec19.191032.21857@lavaca.uh.edu>, jet@lavaca.uh.edu (J. >Eric Townsend) writes: >> While in process foo, I want to crank up process bar >> and have it run independently of foo. >The standard way of doing this is to fork (or vfork) and execl (or >execv). Don't you still have to wait() for it to prevent the child process from becoming a zombie when it exits? I think some versions of Unix check whether the parent has set up a handler for the SIGCHILD signal when deciding whether to zombify the child. Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
kline@tuna.cso.uiuc.edu (Charley Kline) (12/22/89)
> Don't you still have to wait() for it to prevent the child process from > becoming a zombie when it exits? The sleazy way around this is to ... if (!fork()) { if (!fork()) { execl("/usr/bin/foo", "foo", "bar", 0); _exit(1); /* in case exec fails */ } exit(0); /* exit child */ } wait(0); ... This double fork creates a child, which creates a grandchild, which execs the desired program. The child exits without waiting on the grandchild, thus the init process inherits the grandchild and will wait() for it. The parent then waits for the child, and since the child exits very quickly, the parent can continue in short order. Of course this isolates the parent from the grandchild, so the parent can't get any exit status information from the grandchild process. Of course the more proper way to do this is to create a SIGCHLD handler which, when fired, does a wait3() with the WNOHANG option in a loop until -1 is returned, then resets the signal and returns. This way the parent waits for the children as it's supposed to (and can get status information from the child). Yours in Section 2, _____ Charley Kline, University of Illinois Computing Services c-kline@uiuc.edu uunet!uiucuxc!kline "Oh Bliss! Oh Rapture!" "Oh Rapture! Oh Bliss!"