|
[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]
|
|
[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]
|
|