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

前端 未结 20 1708
难免孤独
难免孤独 2020-12-09 18:16

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 fro

相关标签:
20条回答
  • 2020-12-09 18:42

    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))

    0 讨论(0)
  • 2020-12-09 18:43

    Backgrounding a process is a shell function, not an OS function.

    If you want an app to start in the background, the typical trick is to write a shell script to launch it that launches it in the background.

    #! /bin/sh
    /path/to/myGuiApplication &
    
    0 讨论(0)
  • 2020-12-09 18:44

    So, as you say, just fork()ing will not do the trick. What you must do is fork() and then re-exec(), as this code sample does:

    #include stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    #include <CoreFoundation/CoreFoundation.h>
    
    int main(int argc, char **argv)
    {
        int i, j;
    
        for (i=1; i<argc; i++)
            if (strcmp(argv[i], "--daemon") == 0)
            {
                for (j = i+1; j<argc; j++)
                    argv[j-1] = argv[j];
    
                argv[argc - 1] = NULL;
    
                if (fork()) return 0;
    
                execv(argv[0], argv);
    
                return 0;
            }
    
    
        sleep(1);
    
        CFRunLoopRun();
    
        CFStringRef hello = CFSTR("Hello, world!");
    
        printf("str: %s\n", CFStringGetCStringPtr(hello, CFStringGetFastestEncoding(hello)));
    
        return 0;
    }
    

    The loop is to check for a --daemon argument, and if it is present, remove it before re-execing so an infinite loop is avoided.

    I don't think this will work if the binary is put into the path because argv[0] is not necessarily a full path, so it will need to be modified.

    0 讨论(0)
  • 2020-12-09 18:45

    I'm not sure about Windows, but on UNIX-like systems, you can fork() then setsid() the forked process to move it into a new process group that is not connected to a terminal.

    0 讨论(0)
  • 2020-12-09 18:45

    I was trying the solution.

    Only one fork is needed from the parent process.

    The most important point is that, after fork, the parent process must die by calling _exit(0); and NOT by calling exit(0);

    When _exit(0); is used, the command prompt immediately returns on the shell.

    This is the trick.

    0 讨论(0)
  • 2020-12-09 18:54

    The simplest form of backgrounding is:

    if (fork() != 0) exit(0);
    

    In Unix, if you want to background an disassociate from the tty completely, you would do:

    1. Close all descriptors which may access a tty (usually 0, 1, and 2).
    2. if (fork() != 0) exit(0);
    3. setpgroup(0,getpid()); /* Might be necessary to prevent a SIGHUP on shell exit. */
    4. signal(SIGHUP,SIG_IGN); /* just in case, same as using nohup to launch program. */
    5. fd=open("/dev/tty",O_RDWR);
    6. ioctl(fd,TIOCNOTTY,0); /* Disassociates from the terminal */
    7. close(fd);
    8. if (fork() != 0) exit(0); /* just for good measure */

    That should fully daemonize your program.

    0 讨论(0)
提交回复
热议问题