Is there a cleaner way to use the write() function reliably?

前端 未结 4 1758
悲哀的现实
悲哀的现实 2021-02-09 16:15

I read the man pages, and my understanding is that if write() fails and sets the errno to EAGAIN or EINTR, I may

4条回答
  •  孤街浪徒
    2021-02-09 16:55

    I would prefer to poll the descriptor in case of EAGAIN instead of just busy looping and burning up CPU for no good reason. This is kind of a "blocking wrapper" for a non-blocking write I use:

    ssize_t written = 0;
    
    while (written < to_write) {
        ssize_t result;
        if ((result = write(fd, buffer, to_write - written)) < 0) {
            if (errno == EAGAIN) {
                struct pollfd pfd = { .fd = fd, .events = POLLOUT };
                if (poll(&pfd, 1, -1) <= 0 && errno != EAGAIN) {
                    break;
                }
                continue;
            }
            return written ? written : result;
        }
        written += result;
        buffer += result;
    }
    return written;
    

    Note that I'm not actually checking the results of poll other than the return value; I figure the following write will fail if there is a permanent error on the descriptor.

    You may wish to include EINTR as a retryable error as well by simply adding it to the conditions with EAGAIN, but I prefer it to actually interrupt I/O.

提交回复
热议问题