diff options
author | José Bollo <jose.bollo@iot.bzh> | 2017-11-28 11:13:27 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2017-11-29 18:20:23 +0100 |
commit | 0891ef4826e347d5554c630b5c0ce73c68f76c9c (patch) | |
tree | 709e83f364bc7950d2716f65b513384a9d335ef7 /src/afb-ws.c | |
parent | 45c8372c2b4137691a38c2a04f4a5759a110f2f7 (diff) |
afb-ws & websocket: Fix writing very long data
This version loops to write very long data on
websockets.
Bug-AGL: SPEC-1091
Change-Id: I8f17e75e4ef483be29fa8cae2c0af159783ec2c6
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'src/afb-ws.c')
-rw-r--r-- | src/afb-ws.c | 57 |
1 files changed, 47 insertions, 10 deletions
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); } } |