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 | |
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>
-rw-r--r-- | src/afb-apiset.c | 1 | ||||
-rw-r--r-- | src/afb-ws.c | 57 | ||||
-rw-r--r-- | src/websock.c | 10 |
3 files changed, 47 insertions, 21 deletions
diff --git a/src/afb-apiset.c b/src/afb-apiset.c index cad12e97..ae1d9460 100644 --- a/src/afb-apiset.c +++ b/src/afb-apiset.c @@ -29,7 +29,6 @@ #include "afb-apiset.h" #include "afb-context.h" #include "afb-xreq.h" -#include "jobs.h" #define INCR 8 /* CAUTION: must be a power of 2 */ 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); } } diff --git a/src/websock.c b/src/websock.c index cc1e191e..84a11d78 100644 --- a/src/websock.c +++ b/src/websock.c @@ -84,16 +84,6 @@ static ssize_t ws_readv(struct websock *ws, const struct iovec *iov, int iovcnt) return ws->itf->readv(ws->closure, iov, iovcnt); } -#if 0 -static ssize_t ws_write(struct websock *ws, const void *buffer, size_t buffer_size) -{ - struct iovec iov; - iov.iov_base = (void *)buffer; /* const cast */ - iov.iov_len = buffer_size; - return ws_writev(ws, &iov, 1); -} -#endif - static ssize_t ws_read(struct websock *ws, void *buffer, size_t buffer_size) { struct iovec iov; |