| 1916 | |
| 1917 | #ifndef _WIN32 |
| 1918 | int buffer::list::write_fd(int fd) const |
| 1919 | { |
| 1920 | // use writev! |
| 1921 | iovec iov[IOV_MAX]; |
| 1922 | int iovlen = 0; |
| 1923 | ssize_t bytes = 0; |
| 1924 | |
| 1925 | auto p = std::cbegin(_buffers); |
| 1926 | while (p != std::cend(_buffers)) { |
| 1927 | if (p->length() > 0) { |
| 1928 | iov[iovlen].iov_base = (void *)p->c_str(); |
| 1929 | iov[iovlen].iov_len = p->length(); |
| 1930 | bytes += p->length(); |
| 1931 | iovlen++; |
| 1932 | } |
| 1933 | ++p; |
| 1934 | |
| 1935 | if (iovlen == IOV_MAX || |
| 1936 | p == _buffers.end()) { |
| 1937 | iovec *start = iov; |
| 1938 | int num = iovlen; |
| 1939 | ssize_t wrote; |
| 1940 | retry: |
| 1941 | wrote = ::writev(fd, start, num); |
| 1942 | if (wrote < 0) { |
| 1943 | int err = errno; |
| 1944 | if (err == EINTR) |
| 1945 | goto retry; |
| 1946 | return -err; |
| 1947 | } |
| 1948 | if (wrote < bytes) { |
| 1949 | // partial write, recover! |
| 1950 | while ((size_t)wrote >= start[0].iov_len) { |
| 1951 | wrote -= start[0].iov_len; |
| 1952 | bytes -= start[0].iov_len; |
| 1953 | start++; |
| 1954 | num--; |
| 1955 | } |
| 1956 | if (wrote > 0) { |
| 1957 | start[0].iov_len -= wrote; |
| 1958 | start[0].iov_base = (char *)start[0].iov_base + wrote; |
| 1959 | bytes -= wrote; |
| 1960 | } |
| 1961 | goto retry; |
| 1962 | } |
| 1963 | iovlen = 0; |
| 1964 | bytes = 0; |
| 1965 | } |
| 1966 | } |
| 1967 | return 0; |
| 1968 | } |
| 1969 | |
| 1970 | int buffer::list::send_fd(int fd) const { |
| 1971 | return buffer::list::write_fd(fd); |