URN Logo
UNIX Resources » Linux » China Linux Forum » C/C++编程版 » 38 » 一个关于网络daemon程序的诡异问题
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
一个关于网络daemon程序的诡异问题
一个关于网络daemon程序的诡异问题 - Qiaoxd [2005-02-24 22:43 | 3,587 byte(s)]
 
Re: 一个关于网络daemon程序的诡异问题 - Qiaoxd [2005-02-27 00:56 | 4,731 byte(s)]
 
Subject: 一个关于网络daemon程序的诡异问题
Author: Qiaoxd    Posted: 2005-02-24 22:43    Length: 3,587 byte(s)
[Original] [Print] [Top]
fwtk是TIS公司的开源的代理工具包,编译通过后,我的问题是当手动在控制台启动代理服务程序时程序一切正常,而通过自己编写的程序自动启动该代理服务时,却总是报错说子进程的连接socket为“Bad file descriptor”.很奇怪,不知哪里出错?请高手们给指点迷津。
下面为代理服务程序的do_daemon函数
int do_daemon( port)
int port;
{ struct sockaddr_in sa;
int sock,sockl;
pid_t pid;
int boundok = 1;
int reuse = 1;
int devnull;

#ifdef HAVE_SETSID
(void) setsid();
#endif
if ((pid = fork()) == -1)
return (-1);
if (pid)
exit(0); /* parent exits */
devnull = open("/dev/null", O_RDWR, 0);
if (devnull != -1) {
(void) dup2(devnull, 0);
(void) dup2(devnull, 1);
(void) dup2(devnull, 2);
if (devnull > 2)
(void) close(devnull);
}
sa.sin_family = AF_INET;
bzero( (char *)&sa.sin_addr, sizeof(sa.sin_addr));
sa.sin_port = htons(port);
sock = socket(AF_INET, SOCK_STREAM, 0);
if( sock < 0){
syslog(LLEV,"Failed to create socket, %m");
exit(1);
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
while( bind(sock, (struct sockaddr *)&sa, sizeof(sa))){
syslog(LLEV,"Failed to bind port %d, %m", port);
syslog(LLEV,"Sleeping for 2 minutes");
sleep(120);
boundok=0;
}
#ifndef SOMAXCONN
#define SOMAXCONN 4
#endif
if( listen(sock, SOMAXCONN) < 0){
syslog(LLEV,"Failed to listen, %m");
exit(1);
}

if( boundok == 0){
syslog(LLEV,"Now ready on port %d", port);
}
signal(SIGCHLD,waitwaitwait);
signal(SIGHUP, hup_exit);
signal(SIGINT, hup_exit);
signal(SIGTERM,hup_exit);

while(1){
int cstat;

sockl = accept(sock, (struct sockaddr *)0, (int *)0);
if( sockl < 0){
if( errno == EINTR)
continue;
syslog(LLEV,"Accept failed, %m");
continue;
}
pid = fork();
if( pid < 0){
syslog(LLEV,"Fork failed, %m");
/* 9/8/95 pjc. Make fork failure non-fatal, just throw connection for now */
close(sockl);
continue;
}
if( pid == 0)
break; /* We are the child */
close(sockl);
}
#ifdef HAVE_SETSID
(void)setsid();
#endif
close(0);
close(1);
close(2);
dup(sockl);
dup(sockl);
dup(sockl);
//这里0和子进程的sockl可以互用了,可自动执行时子进程运行总是报 0为Bad file descriptor
//而手动启动该代理服务daemon就一切正常,没有出现该问题。
close(sockl);
close(sock);
}

我自己写的自动执行程序段为:
int
Exe_cmd (char *str) //str为已编译好的代理服务程序绝对路径
{
int result = OK, i, max_fd_num;
if (fork () == 0)
{
max_fd_num = 64;
for (i = 0; i < max_fd_num; i++)
close (i);
system (str);
exit (0);
}
return result;
[Original] [Print] [Top]
Subject: Re: 一个关于网络daemon程序的诡异问题
Author: Qiaoxd    Posted: 2005-02-27 00:56    Length: 4,731 byte(s)
[Original] [Print] [Top]
各位老大,怎么没人回答我的问题呀,真的很急,很郁闷。
问题简单的说就是一个网络daemon 程序,通过shell执行一切正常。而通过如下system调用就总是说daemon程序子进程的socketfd 非法, char *cmdline 为daemon程序绝对路径名
int
run_cmd (char *cmdline)
{
int result = SUCCESS, i, max_fd_num;
if (fork () == 0)
{
max_fd_num = getdtablesize ();
for (i = 0; i < max_fd_num; i++)
close (i);
system (cmdline);
exit (0);
}
return result;
}

下面为daemon服务程序中的do_daemon函数
int
do_daemon(int port)
{
struct sockaddr_in sa;
static struct sockaddr_in serv_addr;
int length = sizeof (serv_addr);
int sock, sockl;
pid_t pid;
int boundok = 1;
char reuse = 1;
int devnull;
int cnt;
#ifdef HAVE_SETSID
(void) setsid ();
#endif
if ((pid = fork ()) == -1)
return (-1);
if (pid)
exit (0); /* parent exits */
devnull = open ("/dev/null", O_RDWR, 0);
if (devnull != -1)
{
(void) dup2 (devnull, 0);
(void) dup2 (devnull, 1);
(void) dup2 (devnull, 2);
if (devnull > 2)
(void) close (devnull);
}

sa.sin_family = AF_INET;
bzero ((char *) &sa.sin_addr, sizeof (sa.sin_addr));
sa.sin_port = htons (port);

// to bind proxy with inside interface
if(inside_ip[0])
{
sa.sin_addr.s_addr = inet_addr(inside_ip);
syslog(LOG_INFO,"bind with inside ip : %s:%d",inside_ip,inet_addr(inside_ip));
}

sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
syslog (LOG_ERR, "Failed to create socket, %m");
exit (1);
}
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof (reuse));
while (bind (sock, (struct sockaddr *) &sa, sizeof (sa)))
{
syslog (LOG_INFO, "Failed to bind port %d, %m,exit!", port);
syslog (LOG_INFO, "Sleeping for 15 seconds");
//test
// exit(0);
sleep(15);
// boundok = 0;
}
#ifndef SOMAXCONN
#define SOMAXCONN 20
#endif
if (listen (sock, SOMAXCONN) < 0)
{
syslog (LOG_ERR, "Failed to listen, %m");
exit (1);
}
#if 0
if (boundok == 0)
{
syslog (LOG_WARNING, "Now ready on port %d", port);
}
#endif
//信号处理
signal (SIGCHLD, xxxx);

while (1)
{
int cstat;
memset (buffer, 0, 1500);
sockl = accept (sock, (struct sockaddr *) 0, (int *) 0);
if (sockl < 0)
{
if (errno == EINTR)
continue;
syslog (LOG_ERR, "Accept failed, %m");
continue;
}

pid = fork ();
if (pid < 0)
{
syslog (LOG_ERR, "Fork failed, %m");
/* 9/8/95 pjc. Make fork failure non-fatal, just throw connection for now */
close (sockl);
continue;
}
if (pid == 0)
break; /* We are the child */
close (sockl);
}
#ifdef HAVE_SETSID
(void) setsid ();
#endif
close (0);
close (1);
close (2);
dup (sockl);
dup (sockl);
dup (sockl);
close (sockl);
close (sock);
}

显然这里把子进程连接套接字重定向到0,可是在子进程调用
getsockname (0, (struct sockaddr *) &serv_addr, &length)时总是报Bad file descriptor.
但是通过shell命令行启动daemon则无问题。
真是急死人了,为这问题都快忙活半个月,郁闷死了
[Original] [Print] [Top]
« Previous thread
popen时怎么达到ctrl + d的效果
C/C++编程版
38
Next thread »
档案文件路径?
     

Copyright © 2007 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
备案序号: 京ICP备05006143    webmaster: webmaster@unixresources.net
This page created on 2008-07-17 03:53:09, cost 0.040055990219116 ms.