(守护进程)如何关闭所有已经打开的文件描述符

时间:2021-11-11 03:27:50
在写daemon_init函数时使用了以下代码(守护进程):
void closeall(int fd)
{
    int fdlimit = sysconf(_SC_OPEN_MAX);
    while (fd < fdlimit)
        close(fd++);
}
然后我发现日志仅仅记录close了0,1,2三个文件描述符,此时停止,后面的代码也不再执行。
在这之后我看到《APUE》针对上述代码有这样一段话:从close(EBADF)出错返回并不区分无效描述符和没有打开的描述符。如果使用此技术,而且描述符9未打开,描述符10却打开了,那么将停止在9上,而不会关闭10.
也就是说我的程序停在了close(3)这里,不再继续执行!!!!!!

那么我该如何解决这个问题呢?

还望各位大神不吝赐教!!!!

11 个解决方案

#1


再补充一句:《APUE》上给出了原因但是并没有给出合适的解决方案啊。

#2


检查close的返回值啊,0成功,-1失败

RETURN VALUE

    Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and  errno set to indicate the error.

ERRORS
    The close() function shall fail if:

     [EBADF]
        The fildes argument is not a valid file descriptor.
    [EINTR]
        The close() function was interrupted by a signal.

    The close() function may fail if:

    [EIO]
        An I/O error occurred while reading from or writing to the file system.

#3


引用 2 楼 ipqtjmqj 的回复:
检查close的返回值啊,0成功,-1失败

RETURN VALUE

    Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and  errno set to indicate the error.

ERRORS
    The close() function shall fail if:

     [EBADF]
        The fildes argument is not a valid file descriptor.
    [EINTR]
        The close() function was interrupted by a signal.

    The close() function may fail if:

    [EIO]
        An I/O error occurred while reading from or writing to the file system.


我想问的是如何关闭全部打开的文件描述符,即便我判断了返回值为-1;那么我要怎么做?跳出while循环?那么如题目上例(9未打开,10打开),9中跳出,但是10是打开的啊,10仍然未关闭呀。

#4


查看一下源码原理

#5


提醒:Linux是开源的。

#6


参考知名开源软件中人家的守护进程是怎样做的。

#7


调用exit()。

#8


你先pa -A看看守护进程建立起来没有,我遇到了和你一样的问题,莫名其妙,进程建立起来了。

#9


日志文件也是这个进程打开的话,它也是占用一个文件描述符的,在循环中如果把日志文件也关了,那么日志中是写不进去东西的。
如果是open方式打开的话,可以得到文件描述符,如果是fopen打开的,可以通过fileno获得文件描述符,然后在上面循环中不要把它关闭,就可以正常记录日志了。

或者直接不关闭标准输出(1),然后用printf打印循环变量,可以看到执行了256次。

#10


可先加个判断,判断是否是有效文件描述符。
用fcntl函数做F_GETFD操作,如果文件不是一个已打开的合法描述符,errno会设置为EBADF。

#11


引用 9 楼 zhenzai123 的回复:
日志文件也是这个进程打开的话,它也是占用一个文件描述符的,在循环中如果把日志文件也关了,那么日志中是写不进去东西的。
如果是open方式打开的话,可以得到文件描述符,如果是fopen打开的,可以通过fileno获得文件描述符,然后在上面循环中不要把它关闭,就可以正常记录日志了。

或者直接不关闭标准输出(1),然后用printf打印循环变量,可以看到执行了256次。

感谢!

#1


再补充一句:《APUE》上给出了原因但是并没有给出合适的解决方案啊。

#2


检查close的返回值啊,0成功,-1失败

RETURN VALUE

    Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and  errno set to indicate the error.

ERRORS
    The close() function shall fail if:

     [EBADF]
        The fildes argument is not a valid file descriptor.
    [EINTR]
        The close() function was interrupted by a signal.

    The close() function may fail if:

    [EIO]
        An I/O error occurred while reading from or writing to the file system.

#3


引用 2 楼 ipqtjmqj 的回复:
检查close的返回值啊,0成功,-1失败

RETURN VALUE

    Upon successful completion, 0 shall be returned; otherwise, -1 shall be returned and  errno set to indicate the error.

ERRORS
    The close() function shall fail if:

     [EBADF]
        The fildes argument is not a valid file descriptor.
    [EINTR]
        The close() function was interrupted by a signal.

    The close() function may fail if:

    [EIO]
        An I/O error occurred while reading from or writing to the file system.


我想问的是如何关闭全部打开的文件描述符,即便我判断了返回值为-1;那么我要怎么做?跳出while循环?那么如题目上例(9未打开,10打开),9中跳出,但是10是打开的啊,10仍然未关闭呀。

#4


查看一下源码原理

#5


提醒:Linux是开源的。

#6


参考知名开源软件中人家的守护进程是怎样做的。

#7


调用exit()。

#8


你先pa -A看看守护进程建立起来没有,我遇到了和你一样的问题,莫名其妙,进程建立起来了。

#9


日志文件也是这个进程打开的话,它也是占用一个文件描述符的,在循环中如果把日志文件也关了,那么日志中是写不进去东西的。
如果是open方式打开的话,可以得到文件描述符,如果是fopen打开的,可以通过fileno获得文件描述符,然后在上面循环中不要把它关闭,就可以正常记录日志了。

或者直接不关闭标准输出(1),然后用printf打印循环变量,可以看到执行了256次。

#10


可先加个判断,判断是否是有效文件描述符。
用fcntl函数做F_GETFD操作,如果文件不是一个已打开的合法描述符,errno会设置为EBADF。

#11


引用 9 楼 zhenzai123 的回复:
日志文件也是这个进程打开的话,它也是占用一个文件描述符的,在循环中如果把日志文件也关了,那么日志中是写不进去东西的。
如果是open方式打开的话,可以得到文件描述符,如果是fopen打开的,可以通过fileno获得文件描述符,然后在上面循环中不要把它关闭,就可以正常记录日志了。

或者直接不关闭标准输出(1),然后用printf打印循环变量,可以看到执行了256次。

感谢!