views:

889

answers:

5

I want to launch a process from within my c program, but I don't want to wait for that program to finish. I can launch that process OK using system() but that always waits. Does anyone know of a 'non-blocking' version that will return as soon as the process has been started?

[Edit - Additional Requirement] When the original process has finished executing, the child process needs to keep on running.

+9  A: 

Why not use fork() and exec(), and simply don't call waitpid()?

For example, you could do the following:

// ... your app code goes here ...
pid = fork();
if( pid < 0 )
    // error out here!
if( !pid && execvp( /* process name, args, etc. */ )
    // error in the child proc here!
// ...parent execution continues here...
FreeMemory
hmmm, doesn't seem to be working for me. I think the problem might be that my program (it's a CGI app) exists as soon as it's called execvp - will this kill off the child process?Also... the code after execvp appears to be being run twice.
Simon Hodgson
Simon, can you place a code sample here? What might happens is the parent has exit as soon as child process had been forked. Have you used waitpid(chld_pid) as proposed by Mr./Ms. FreeMemory?
SashaN
@Simon: if the code after execvp() appears to run twice, most likely it means that the execvp() failed and the error handling for it didn't stop things going awry (return or exit). In a CGI program, do you know what the PATH is set to? It is probably more spartan than you expected.
Jonathan Leffler
OK, I've read up some more about fork() and now understand the above example better and know why some of the code was being run twice. It's a bit difficult to see what's happening, but I think the forked process is being killed off when the original process exits.
Simon Hodgson
@Simon: To make the child process live on, couldn't you trap SIGHUP?
FreeMemory
+3  A: 

One option is in your system call, do this:

 system("ls -l &");

the & at the end of the command line arguments forks the task you've launched.

Doug T.
+4  A: 

The normal way to do it, and in fact you shouldn't really use system() anymore is popen.
This also allows you to read or write from the spawned process's stdin/out

edit: See popen2() if you need to read and write - thansk quinmars

Martin Beckett
I think this should be read _or_ write
quinmars
A: 

In the end, this code appears to work. Bit of a mis-mash of the above answers:

pid = fork();

if (!pid)
{
    system("command here &");
}

exit(0);

Not quite sure why it works, but it does what I'm after, thanks to everyone for your help

Simon Hodgson
FreeMemory
why the extra fork()? Can't you just use the system("... call?
Carson Myers
A: 

You could use posix_spawnp() function. It's much similar to system() than the fork and exec* combination, but non-blocking.