开发者

Daemonize() issues on Debian

开发者 https://www.devze.com 2022-12-26 13:51 出处:网络
I\'m currently writing a multi-process client and a multi-treaded server for some project i have. The server is a Daemon.

I'm currently writing a multi-process client and a multi-treaded server for some project i have.

The server is a Daemon. In order to accomplish that, i'm using the following daemonize() code:

static void daemonize(void)
{
    pid_t pid, sid;

    /* already a daemon */
    if ( getppid() == 1 ) return;

    /* Fork off the parent process */
    pid = fork();
    if (pid < 0) {
        exit(EXIT_FAILURE);
    }
    /* If we got a good PID, then we can exit the parent process. */
    if (pid > 0) {
        exit(EXIT_SUCCESS);
    }

    /* At this point we are executing as the child process */

    /* Change the file mode mask */
    umask(0);

    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0) {
        exit(EXIT_FAILURE);
    }

    /* Change the current working directory.  This prevents the current
       directory from being locked; hence not being able to remove it. */
    if ((chdir("/")) < 0) {
        exit(EXIT_FAILURE);
    }

    /* Redirect standard files to /dev/null */
    freopen( "/dev/null", "r", stdin);
    freopen( "/dev/null", "w", stdout);
    freopen( "/dev/null", "w", stderr);
}

int main( int argc, char *argv[] ) {
    daemonize();

    /* Now we are a daemon -- do the work for which we were paid */
    return 0;
}

I have a strange side effect when testing the server on Debian (Ubuntu).

The accept() function always fail to accept connections, the pid returned is -1

I have no idea what causing this, since in RedHat & CentOS it works well.

When i remove the call to daemonize(), everything works well on Debian, when i add it back, same accept() error reproduce.

I'v开发者_如何学Pythone been monitring the /proc//fd, everything looks good.

Something in the daemonize() and the Debian release just doesn't seem to work. (Debian GNU/Linux 5.0, Linux 2.6.26-2-286 #1 SMP)

Any idea what causing this?

Thank you


The accept(2) manpage says:

EINVAL Socket is not listening for connections, or addrlen is invalid (e.g., is negative).

Likely you have something like

struct sockaddr_in;
socklen_t len;
...

new_fd = new_fd = accept(sockfd,(struct sockaddr *)&addr,&len);

However, you need to set len to the size of the address you pass in:

struct sockaddr_in addr;
socklen_t len;
len = sizeof(addr);
...
new_fd = new_fd = accept(sockfd,(struct sockaddr *)&addr,&len);

So, by some (un)lucky means your uninitialized 'len' variable get some nonsense value in some cases, and accept fails, while it happens to work in other scenarios.


May I direct you to existing library function daemon(3) to accomplish the same?


Here, when the parent exits:

/* If we got a good PID, then we can exit the parent process. */
if (pid > 0) {
    exit(EXIT_SUCCESS);
}

You should be calling _exit(), not exit(). (I am not certain that this is causing your problem, but it's possible).

What is errno set to when accept() returns -1? (You could put a perror("accept"); in the code there).

0

精彩评论

暂无评论...
验证码 换一张
取 消