Debian上的Daemonize()问题

时间:2010-04-07 12:36:39

标签: c linux sockets posix daemon

我正在为一些项目编写一个多进程客户端和一个多线程服务器。

服务器是守护进程。 为了实现这一点,我使用以下daemonize()代码:

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;
}

在Debian(Ubuntu)上测试服务器时,我有一个奇怪的副作用。

accept()函数总是无法接受连接,返回的pid是-1

我不知道是什么造成这种情况,因为在RedHat&amp; CentOS运行良好。

当我删除对daemonize()的调用时,一切都在Debian上运行良好,当我将其添加回来时,同样的accept()错误重现。

我一直在监视/ proc // fd,一切看起来都不错。

daemonize()和Debian版本中的某些东西似乎不起作用。 (Debian GNU / Linux 5.0,Linux 2.6.26-2-286#1 SMP)

知道造成这种情况的原因是什么?

谢谢

3 个答案:

答案 0 :(得分:3)

我可以指导您使用现有的库函数daemon(3)来完成同样的工作吗?

答案 1 :(得分:3)

accept(2)联机帮助页说:

  

EINVAL Socket没有收听   连接或addrlen无效   (例如,是否定的)。

可能你有像

这样的东西
struct sockaddr_in;
socklen_t len;
...

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

但是,您需要将len设置为您传入的地址大小:

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

所以,通过一些(非)幸运意味着你的未初始化的'len'变量在某些情况下会得到一些无意义的值,并且接受失败,而它恰好在其他场景中起作用。

答案 2 :(得分:1)

这里,父母退出时:

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

您应该致电_exit(),而不是exit()。 (我不确定这是否会导致您的问题,但这是可能的)。

errno返回-1时,accept()设置为什么? (您可以在代码中加perror("accept");。)