X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-ws.c;h=c48a5e242576e157bc4dd8883421d1fbeede2adc;hb=0891ef4826e347d5554c630b5c0ce73c68f76c9c;hp=ff625fca3a0f3390d4e280670c775b52b8620b9a;hpb=45c8372c2b4137691a38c2a04f4a5759a110f2f7;p=src%2Fapp-framework-binder.git diff --git a/src/afb-ws.c b/src/afb-ws.c index ff625fca..c48a5e24 100644 --- a/src/afb-ws.c +++ b/src/afb-ws.c @@ -347,21 +347,58 @@ int afb_ws_binary_v(struct afb_ws *ws, const struct iovec *iovec, int count) */ static ssize_t aws_writev(struct afb_ws *ws, const struct iovec *iov, int iovcnt) { - ssize_t rc; + int i; + ssize_t rc, sz, dsz; + struct iovec *iov2; + struct pollfd pfd; + + /* compute the size */ + dsz = 0; + i = 0; + while (i < iovcnt) { + dsz += iov[i++].iov_len; + if (dsz < 0) { + errno = EINVAL; + return -1; + } + } + if (dsz == 0) + return 0; + + /* write the data */ + iov2 = (struct iovec*)iov; + sz = dsz; for (;;) { - rc = writev(ws->fd, iov, iovcnt); - if (rc == -1) { + rc = writev(ws->fd, iov2, iovcnt); + if (rc < 0) { if (errno == EINTR) continue; - else if (errno == EAGAIN) { - struct pollfd pfd; - pfd.fd = ws->fd; - pfd.events = POLLOUT; - poll(&pfd, 1, 10); - continue; + if (errno != EAGAIN) + return -1; + } else { + dsz -= rc; + if (dsz == 0) + return sz; + + i = 0; + while (rc >= (ssize_t)iov2[i].iov_len) + rc -= (ssize_t)iov2[i++].iov_len; + + iovcnt -= i; + if (iov2 != iov) + iov2 += i; + else { + iov += i; + iov2 = alloca(iovcnt * sizeof *iov2); + for (i = 0 ; i < iovcnt ; i++) + iov2[i] = iov[i]; } + iov2->iov_base += rc; + iov2->iov_len -= rc; } - return rc; + pfd.fd = ws->fd; + pfd.events = POLLOUT; + poll(&pfd, 1, 10); } }