我正在为一些项目编写一个多进程客户端和一个多线程服务器。
服务器是守护进程。 为了实现这一点,我使用以下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)
知道造成这种情况的原因是什么?
谢谢
答案 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");
。)