代码改变世界

select应用于read函数 超时非阻塞方式

2015-09-18 16:32  夏洛克·福尔摩斯  阅读(3052)  评论(0编辑  收藏  举报
/*
 * "Timed" read - timout specifies the # of seconds to wait before
 * giving up (5th argument to select controls how long to wait for
 * data to be readable).  Returns # of bytes read or -1 on error.
 *
 * LOCKING: none.
 */
ssize_t
tread(int fd, void *buf, size_t nbytes, unsigned int timout)
{
    int                nfds;
    fd_set            readfds;
    struct timeval    tv;

    tv.tv_sec = timout;
    tv.tv_usec = 0;
    FD_ZERO(&readfds);
    FD_SET(fd, &readfds);
    nfds = select(fd+1, &readfds, NULL, NULL, &tv);
    if (nfds <= 0) {
        if (nfds == 0)
            errno = ETIME;
        return(-1);
    }
    return(read(fd, buf, nbytes));
}

/*
 * "Timed" read - timout specifies the number of seconds to wait
 * per read call before giving up, but read exactly nbytes bytes.
 * Returns number of bytes read or -1 on error.
 *
 * LOCKING: none.
 */
ssize_t
treadn(int fd, void *buf, size_t nbytes, unsigned int timout)
{
    size_t    nleft;
    ssize_t    nread;

    nleft = nbytes;
    while (nleft > 0) {
        if ((nread = tread(fd, buf, nleft, timout)) < 0) {
            if (nleft == nbytes)
                return(-1); /* error, return -1 */
            else
                break;      /* error, return amount read so far */
        } else if (nread == 0) {
            break;          /* EOF */
        }
        nleft -= nread;
        buf += nread;
    }
    return(nbytes - nleft);      /* return >= 0 */
}