Linux: Checking if a socket/pipe is broken without doing a read()/write()

前端 未结 3 641
暖寄归人
暖寄归人 2021-02-09 10:45

I have a simple piece of code that periodically writes data to a fd that\'s passed to it. The fd will most likely be a pipe or socket but could potentially be anything. I can de

相关标签:
3条回答
  • 2021-02-09 11:31
    struct pollfd pfd = {.fd = yourfd, .events = POLLERR};
    if (poll(&pfd, 1, whatever) < 0) abort();
    if (pfd.revents & POLLERR) printf("pipe is broken\n");
    

    This does work for me. Note that sockets are not exactly pipes and thus show different behavior (-> use POLLRDHUP).

    0 讨论(0)
  • 2021-02-09 11:42

    Try with select and its errorfds parameter:

    int **select**(int nfds, fd_set *restrict readfds,
          fd_set *restrict writefds, **fd_set *restrict errorfds**,
          struct timeval *restrict timeout);
    
    0 讨论(0)
  • 2021-02-09 11:46

    Nice answers, I like them... I also need to get out of the select habbit and into the (e)poll.

    Here's some more traditional methods, if you need them:

    /* check whether a file-descriptor is valid */
    int fd_valid(int fd)
    {   
        if (fcntl(fd, F_GETFL) == -1 && errno == EBADF) return FALSE;
        return TRUE;
    }       
    

    This one attempts to duplicate the socket/fd. It a lot simpler than in looks, I left a lot of debug in.

    /* 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;
    }   
    
    0 讨论(0)
提交回复
热议问题