Will Bowman
Will Bowman

Reputation: 417

c++ fork() & execl() dont wait, detach completely

So I have a simple fork and exec program. It works pretty good but I want to be able to detach the process that is started, I try a fork with no wait:

if((pid = fork()) < 0)
    perror("Error with Fork()");
else if(pid > 0) {
    return "";
}
else {
    if(execl("/bin/bash", "/bin/bash", "-c", cmddo, (char*) 0) < 0) perror("execl()");
    exit(0);
}

It starts the proc fine but when my main app is closed - so is my forked proc.

How do I keep the forked process running after the main proc (that started it) closes?

Thanks :D

Upvotes: 5

Views: 9038

Answers (3)

Jesse Stone
Jesse Stone

Reputation: 1

EX1: When client not exit, no wait

#include <spawn.h>
extern char** environ; //posix_spawn using environ that declare in glibc-2.xx/posix/environ.c
void main()
{
    pid_t   spawnid;
    char    param[64] = {0};
    char*   args[] = {"/usr/drive_server", param, NULL};
    posix_spawn(&spawnid, "/usr/drive_server", NULL, NULL, args, 
    environ);
    getchar();
}

EX2: When client exit, wait subprocess detach

#include <spawn.h>
extern char** environ;
void main()
{
    pid_t   spawnid;
    char    param[64] = {0};
    pid_t   sessionid;
    char*   args[] = {"/usr/drive_server", param, NULL};
    
    posix_spawn(&spawnid, "/usr/drive_server", NULL, NULL, args, environ);
    
    sessionid = 0;
    while( sessionid != spawnid )
    {
        sessionid = getsid(spawnid);
        printf("sessionid id %d\n", sessionid);
        usleep(200000);
    }
}

    //subprocess file
    void main()
    {
        setsid(); //detach
        getchar();
    }

EX3: when system have setsid command, no wait

#include <spawn.h>
extern char** environ;
void main()
{
    pid_t   id_spawn;
    char*   args[] = {"/usr/bin/setsid", "/volume1/drive_server", serviceName8, NULL};

    posix_spawn(&id_spawn, "/usr/bin/setsid", NULL, NULL, args, environ);
    printf("drive_server* spawn id %d\n", id_spawn);
}

there are 2 sources code can be referred to

  1. util-linux-2.xx.x/sys-utils/setsid.c
  2. busybox-1.xx.x/util-linux/setsid.c

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 154005

Probably all you really want is to ignore SIGHUP in your fork()ed process as this is normally the one which brings the program down. That is, what you need to do is

signal(SIGHUP, SIG_IGN);

Using nohup arranges for a reader to be present which would avoid possibly writing to close pipe. To avoid this you could either arrange for standard outputs not to be available or to also ignore SIGPIPE. There are a number of signals which terminate your program when not ignore (see man signal; some signals can't be ignored) but the one which will be sent to the child is is SIGHUP.

Upvotes: 5

araqnid
araqnid

Reputation: 133712

Various things to do if you want to start a detached/daemon process:

  • fork again and exit the first child (so the second child process no longer has the original process as its parent pid)
  • call setsid(2) to get a new session and process group
  • reopen stdin/stdout/stderr to dereference the controlling tty, if there was one. Or, for example, you might have inherited a pipe stdout that will be broken and give you SIGPIPE if you try to write it.
  • chdir to / to get away from the ancestor's current directory

Upvotes: 7

Related Questions