Doge log

Abby CTO 雑賀 力王のオフィシャルサイトです

writevで全部書けなかった場合

なんか最近Cばっか書いてる気がするなあ。

Non Blockingで書いてるとよくあるケース。

static int
send_writev(int fd, struct iovec *iov, int iov_cnt, size_t total)
{
    size_t w;
    int i = 0;
    w = writev(fd, iov, iov_cnt);
    if(w == -1){
        //error
        if (errno == EAGAIN || errno == EWOULDBLOCK) { 
            /* try again later */
            usleep(1000);
            return send_writev(fd, iov, iov_cnt, total); 
        }else{
            return -1;
        }
    }if(w == 0){
        return 1;
    }else{
        if(total > w){
            for(; i < iov_cnt;i++){
                if(w > iov[i].iov_len){
                    //already write
                    w -= iov[i].iov_len;
                    iov[i].iov_len = 0;
                }else{
                    iov[i].iov_base += w;
                    iov[i].iov_len = iov[i].iov_len - w;
                    break;
                }
            }
            return send_writev(fd, iov, iov_cnt, total - w); 
        }
    }
    return 1;

}

頭からなめて、iov_lenを0にしていけばいいみたい。
実際にはusleepじゃなくwriteのeventでひっかけて再度書いた方がいいね。