免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2190 | 回复: 6
打印 上一主题 下一主题

为什么exec一个daemon,socket连接不会释放,要结束这个daemon才行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-06-21 11:53 |只看该作者 |倒序浏览
能不能exec一个干净的环境,不复制父进程的资源呀,以下是我的测试部分代码,如果我想把程序执行的输出到客户端(重定向,可是socket要关闭才没有问题),该怎么办呀,请各位大侠能否帮帮我,我才学unix下的c编程:
static void sigchild_handler(int signo)
{
        pid_t pid;
        int status;
        while(pid = waitpid(-1, &status, WNOHANG|WUNTRACED) > 0) {;};
}

void child(int listen_sock, int sock)
{
        int read_fd;
        int write_fd;
        FILE * in;
        FILE * out;
        char * s;
        int cfd;
        char * buf;
        struct stat conf_stat;
        read_fd = dup(sock);
        write_fd = dup(sock);
        in = fdopen(read_fd,"r");
        out = fdopen(write_fd,"w");
        fprintf(out,"220 localhost ServerAdmin\r\n");
        fflush(out);
        sleep(1);
        cfd = open(config_file, O_RDONLY);
        if(cfd == -1)
                haserror(config_file);
        fstat(cfd, &conf_stat);
        buf = malloc(conf_stat.st_size * sizeof(char));
        read(cfd, buf, conf_stat.st_size);
        fprintf(out,"%s", buf);
        free(buf);
        int pid=fork();
        fclose(in);
        fclose(out);
        if (pid==0) {
                close(sock); /*不关闭这两行的话,socket的资源就不释放,要等daemon退出才可以*/
                close(listen_sock);
                signal(SIGCHLD, SIG_DFL);
                system("/etc/init.d/apache2 stop");
                system("/etc/init.d/apache2 start");
                exit(0);
        }
        printf("pid is %d\n", pid);
}

int server_process()
{
        pid_t pid;
        int rc;
        int fd;
        int listen_sock;
        struct timeval tv;
        int port = server_port;
        struct sockaddr_in tcp_addr;
        struct sockaddr_in remote_addr;
        int addr_size = sizeof(remote_addr);
        int sock;
        tcp_addr.sin_family = AF_INET;
        tcp_addr.sin_addr.s_addr = INADDR_ANY;
        printf("%s", INADDR_ANY);
        tcp_addr.sin_port = htons(port);
        listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
        if (listen_sock == -1)
                haserror("Socket create error");
        rc = bind(listen_sock, (struct sockaddr *) &tcp_addr, sizeof(tcp_addr));
        if (rc == -1)
                haserror("Bind false");
        rc = listen(listen_sock, 128);
        if (rc == -1)
                haserror("Listen false");

        rc = fork();
        if (rc == -1)
        {
                haserror("Fork false");
        } else if (rc > 0) {
                printf("Daemon start success\n");
                exit(0);
        } else {
                signal(SIGCHLD, sigchild_handler);
                for (;;) {
                        sock = accept(listen_sock, (struct sockaddr *) &remote_addr, &addr_size);
                        if (sock == -1 && errno == EINTR)
                                continue;
                        rc  = fork();
                        if (rc == -1)
                                haserror("Fork false");
                        else if (rc > 0) {
                                close(sock);
                                continue;
                        }
                        child(listen_sock, sock);
                        close(sock);
                        break;
                 }
         }
        close(listen_sock);
}

[ 本帖最后由 guxing1841 于 2006-6-21 11:56 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-06-21 14:01 |只看该作者
高手请帮忙呀

论坛徽章:
0
3 [报告]
发表于 2006-06-21 20:03 |只看该作者
设置描述符的执行关闭位试试看
close on exec 的那个,不知道怎么翻译

论坛徽章:
0
4 [报告]
发表于 2006-06-21 20:14 |只看该作者
引用计数没有递减

论坛徽章:
0
5 [报告]
发表于 2006-06-21 20:31 |只看该作者
很正常啊,管它是什么进程.
我没有写过灵进程,重定向肯定不是通用的办法.
你在shell中启动xinetd的时候显然也是打开了一些文件,但是xinetd后来并没有一直打开这些文件
APUE中说了方法.

论坛徽章:
0
6 [报告]
发表于 2006-06-21 21:51 |只看该作者
原帖由 guxing1841 于 2006-6-21 11:53 发表
能不能exec一个干净的环境,不复制父进程的资源呀,以下是我的测试部分代码,如果我想把程序执行的输出到客户端(重定向,可是socket要关闭才没有问题),该怎么办呀,请各位大侠能否帮帮我,我才学unix下的c编程:
...


1) 首先你用的不是exec,当然system()会调用exec,问法不正确!
   用法是没有搞明白 描述符 的 引用记数, fork之后 引用记数 会增加 ,只有它  引用记数 为 0 时 描述字才真正关闭.

2) 其二 这个程序 也不是 守护进程 ,没有处理 信号 SIGHUP 和 umark等必须须的步踌.

3) 并发服务器的写法太乱.

[ 本帖最后由 frstq 于 2006-6-21 21:53 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2006-06-22 10:09 |只看该作者
高手呀,一针见血,能不能给一点稍微详细的说明呀,我以前没有写过这样的程序,谢谢帮助
fcntl(listen_sock, F_SETFD, 1);
fcntl(sock, F_SETFD, 1);
然后在exec前关闭所有的引用,是不是就可以了
SIGHUP应该怎么处理呀,请赐教

[ 本帖最后由 guxing1841 于 2006-6-22 10:17 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP