Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux:在不执行read()/write()操作的情况下检查套接字/管道是否损坏_Linux_Sockets_Pipe - Fatal编程技术网

Linux:在不执行read()/write()操作的情况下检查套接字/管道是否损坏

Linux:在不执行read()/write()操作的情况下检查套接字/管道是否损坏,linux,sockets,pipe,Linux,Sockets,Pipe,我有一段简单的代码,定期将数据写入传递给它的fd。fd很可能是管道或插座,但可能是任何东西。每当我向套接字/管道写入()时,我都可以检测到它何时关闭/断开,因为我得到了一个EPIPE错误(我忽略了SIGPIPE)。但我并不是一直在写,所以可能很长一段时间都检测不到关闭的套接字。我需要尽快对关闭做出反应。是否有一种不必执行write()即可检查fd的方法?如果我不写任何东西,我可以定期这样做。尝试使用select及其errorfds参数: int **select**(int nfds, fd_s

我有一段简单的代码,定期将数据写入传递给它的fd。fd很可能是管道或插座,但可能是任何东西。每当我向套接字/管道写入()时,我都可以检测到它何时关闭/断开,因为我得到了一个EPIPE错误(我忽略了SIGPIPE)。但我并不是一直在写,所以可能很长一段时间都检测不到关闭的套接字。我需要尽快对关闭做出反应。是否有一种不必执行write()即可检查fd的方法?如果我不写任何东西,我可以定期这样做。

尝试使用select及其errorfds参数:

int **select**(int nfds, fd_set *restrict readfds,
      fd_set *restrict writefds, **fd_set *restrict errorfds**,
      struct timeval *restrict timeout);
struct pollfd pfd={.fd=yourfd,.events=POLLERR};
如果(轮询(&pfd,1,无论什么)<0)中止();
如果(pfd.revents&POLLERR)printf(“管道破裂”);

这确实对我有用。请注意,套接字并不完全是管道,因此显示不同的行为(->使用polldhup)。

回答不错,我喜欢它们。。。我还需要摆脱选择习惯,进入(e)投票

如果您需要,这里有一些更传统的方法:

/* check whether a file-descriptor is valid */
int fd_valid(int fd)
{   
    if (fcntl(fd, F_GETFL) == -1 && errno == EBADF) return FALSE;
    return TRUE;
}       
这一个尝试复制套接字/fd。它比外观简单得多,我在中留下了很多调试

/* check a file descriptor */
int fd_check(int i) {
    int fd_dup = dup(i);
    if (fd_dup == -1) {
        strcpy(errst, strerror(errno));
        // EBADF  oldfd isn’t an open file descriptor, or newfd is out of the allowed range for file descriptors.
        // EBUSY  (Linux only) This may be returned by dup2() during a race condition with open(2) and dup().
        // EINTR  The dup2() call was interrupted by a signal; see signal(7).
        // EMFILE The process already has the maximum number of file descriptors open and tried to open a new one.

        if (errno == EBADF) {
            return FALSE;
        }   

        return TRUE;
    }   
    close(fd_dup);
    return TRUE;
}   

select、poll和epoll都会告诉youThanks答案,但我不确定如何使用管道来实现这一点。我在write和except fdset中使用我的fd尝试了select()调用,当管道断开时,调用的结果不会改变(始终在write集中返回我的fd)。我还尝试过在设置了所有事件的情况下使用poll(),同样没有区别。不要将fd推入写入fd集中。只有一个例外。尝试过了,管道没有问题。谢谢,但我尝试将我的fd添加到异常集中,当管道损坏时,无法使其表现出不同的行为。(使用socket可能会很好;我还没有尝试过,因为我当前的设置给了我一个管道)啊哈!我有一个打字错误,并检查事件的方式,而不是报复。非常感谢,这很有效。回答得很好。我太习惯于选择()调用。我必须在这一点上作出明确的努力+1.
/* check a file descriptor */
int fd_check(int i) {
    int fd_dup = dup(i);
    if (fd_dup == -1) {
        strcpy(errst, strerror(errno));
        // EBADF  oldfd isn’t an open file descriptor, or newfd is out of the allowed range for file descriptors.
        // EBUSY  (Linux only) This may be returned by dup2() during a race condition with open(2) and dup().
        // EINTR  The dup2() call was interrupted by a signal; see signal(7).
        // EMFILE The process already has the maximum number of file descriptors open and tried to open a new one.

        if (errno == EBADF) {
            return FALSE;
        }   

        return TRUE;
    }   
    close(fd_dup);
    return TRUE;
}