Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a C/C++ program put itself into background?

What's the best way for a running C or C++ program that's been launched from the command line to put itself into the background, equivalent to if the user had launched from the unix shell with '&' at the end of the command? (But the user didn't.) It's a GUI app and doesn't need any shell I/O, so there's no reason to tie up the shell after launch. But I want a shell command launch to be auto-backgrounded without the '&' (or on Windows).

Ideally, I want a solution that would work on any of Linux, OS X, and Windows. (Or separate solutions that I can select with #ifdef.) It's ok to assume that this should be done right at the beginning of execution, as opposed to somewhere in the middle.

One solution is to have the main program be a script that launches the real binary, carefully putting it into the background. But it seems unsatisfying to need these coupled shell/binary pairs.

Another solution is to immediately launch another executed version (with 'system' or CreateProcess), with the same command line arguments, but putting the child in the background and then having the parent exit. But this seems clunky compared to the process putting itself into background.

Edited after a few answers: Yes, a fork() (or system(), or CreateProcess on Windows) is one way to sort of do this, that I hinted at in my original question. But all of these solutions make a SECOND process that is backgrounded, and then terminate the original process. I was wondering if there was a way to put the EXISTING process into the background. One difference is that if the app was launched from a script that recorded its process id (perhaps for later killing or other purpose), the newly forked or created process will have a different id and so will not be controllable by any launching script, if you see what I'm getting at.

Edit #2:

fork() isn't a good solution for OS X, where the man page for 'fork' says that it's unsafe if certain frameworks or libraries are being used. I tried it, and my app complains loudly at runtime: "The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec()."

I was intrigued by daemon(), but when I tried it on OS X, it gave the same error message, so I assume that it's just a fancy wrapper for fork() and has the same restrictions.

Excuse the OS X centrism, it just happens to be the system in front of me at the moment. But I am indeed looking for a solution to all three platforms.

like image 369
Larry Gritz Avatar asked Sep 22 '08 18:09

Larry Gritz


4 Answers

My advice: don't do this, at least not under Linux/UNIX.

GUI programs under Linux/UNIX traditionally do not auto-background themselves. While this may occasionally be annoying to newbies, it has a number of advantages:

  • Makes it easy to capture standard error in case of core dumps / other problems that need debugging.

  • Makes it easy for a shell script to run the program and wait until it's completed.

  • Makes it easy for a shell script to run the program in the background and get its process id:

    gui-program &
    pid=$!
    # do something with $pid later, such as check if the program is still running
    

    If your program forks itself, this behavior will break.

"Scriptability" is useful in so many unexpected circumstances, even with GUI programs, that I would hesitate to explicitly break these behaviors.

Windows is another story. AFAIK, Windows programs automatically run in the background--even when invoked from a command shell--unless they explicitly request access to the command window.

like image 80
Dan Lenski Avatar answered Nov 14 '22 05:11

Dan Lenski


On Linux, daemon() is what you're looking for, if I understand you correctly.

like image 36
bstark Avatar answered Nov 14 '22 06:11

bstark


The way it's typically done on Unix-like OSes is to fork() at the beginning and exit from the parent. This won't work on Windows, but is much more elegant than launching another process where forking exists.

like image 7
Serafina Brocious Avatar answered Nov 14 '22 07:11

Serafina Brocious


Three things need doing,

fork
setsid
redirect STDIN, STDOUT and STDERR to /dev/null

This applies to POSIX systems (all the ones you mention claim to be POSIX (but Windows stops at the claiming bit))

like image 6
dsm Avatar answered Nov 14 '22 07:11

dsm