Debian 上的 Daemonize() 问题

发布于 2024-08-28 03:57:43 字数 1605 浏览 6 评论 0原文

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

服务器是一个守护进程。 为了实现这一点,我使用以下 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 & CentOS 运行良好。

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

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

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

知道是什么原因造成的吗?

谢谢

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've 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冬天旳寂寞 2024-09-04 03:57:43

Accept(2) 联机帮助页显示:

EINVAL 套接字未监听
连接数,或 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”变量在某些中获得一些无意义的值情况下,accept失败,而它恰好在其他场景下工作。

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.

萤火眠眠 2024-09-04 03:57:43

我可以引导您访问现有的库函数 daemon(3) 完成同样的任务?

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

我要还你自由 2024-09-04 03:57:43

在这里,当父进程退出时:

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

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文