diff --git a/docs/README.md b/docs/README.md index 4d877a4a..9bae268b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -528,21 +528,23 @@ by `buf`, and `len` specifies number of bytes currently stored. ### mg\_iobuf\_init() ```c -void mg_iobuf_init(struct mg_iobuf *io, size_t size); +int mg_iobuf_init(struct mg_iobuf *io, size_t size); ``` -Initialise IO buffer, allocate `size` bytes. +Initialise IO buffer, allocate `size` bytes. Return 1 on success, +0 on allocation failure. ### mg\_iobuf\_resize() ```c -void mg_iobuf_resize(struct mg_iobuf *io, size_t size); +int mg_iobuf_resize(struct mg_iobuf *io, size_t size); ``` Resize IO buffer, set the new size to `size`. The `io->buf` pointer could change after this, for example if the buffer grows. If `size` is 0, then the `io->buf` is freed and set to NULL, and both `size` and `len` are set to 0. +Return 1 on success, 0 on allocation failure. ### mg\_iobuf\_free() diff --git a/mongoose.c b/mongoose.c index 938766cf..9c386d89 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1195,7 +1195,8 @@ struct mg_connection *mg_http_listen(struct mg_mgr *mgr, const char *url, #include -void mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { +int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { + int ok = 1; if (new_size == 0) { free(io->buf); io->buf = NULL; @@ -1210,16 +1211,20 @@ void mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { io->buf = (unsigned char *) p; io->size = new_size; } else { + ok = 0; LOG(LL_ERROR, ("%lu->%lu", (unsigned long) io->size, (unsigned long) new_size)); } } + return ok; } -void mg_iobuf_init(struct mg_iobuf *io, size_t size) { +int mg_iobuf_init(struct mg_iobuf *io, size_t size) { + int ok = 1; io->buf = NULL; io->len = io->size = 0; - if (size > 0) mg_iobuf_resize(io, size); + if (size > 0) ok = mg_iobuf_resize(io, size); + return ok; } size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len, @@ -2622,6 +2627,7 @@ int mg_send(struct mg_connection *c, const void *buf, size_t len) { int fail, n = c->is_udp ? ll_write(c, buf, (SOCKET) len, &fail) : (int) mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE); + if (len > 0 && n == 0) fail = 1; return n; } @@ -2696,8 +2702,9 @@ static void read_conn(struct mg_connection *c, // NOTE(lsm): do only one iteration of reads, cause some systems // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data if (c->recv.size - c->recv.len < MG_IO_SIZE && - c->recv.size < MG_MAX_RECV_BUF_SIZE) { - mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE); + c->recv.size < MG_MAX_RECV_BUF_SIZE && + !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) { + c->is_closing = 1; } buf = c->recv.buf + c->recv.len; len = (int) (c->recv.size - c->recv.len); diff --git a/mongoose.h b/mongoose.h index 61114449..fdbdf95f 100644 --- a/mongoose.h +++ b/mongoose.h @@ -516,8 +516,8 @@ struct mg_iobuf { size_t size, len; }; -void mg_iobuf_init(struct mg_iobuf *, size_t); -void mg_iobuf_resize(struct mg_iobuf *, size_t); +int mg_iobuf_init(struct mg_iobuf *, size_t); +int mg_iobuf_resize(struct mg_iobuf *, size_t); void mg_iobuf_free(struct mg_iobuf *); size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t); size_t mg_iobuf_delete(struct mg_iobuf *, size_t); diff --git a/src/iobuf.c b/src/iobuf.c index e7d1968c..f5eb61bf 100644 --- a/src/iobuf.c +++ b/src/iobuf.c @@ -3,7 +3,8 @@ #include -void mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { +int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { + int ok = 1; if (new_size == 0) { free(io->buf); io->buf = NULL; @@ -18,16 +19,20 @@ void mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { io->buf = (unsigned char *) p; io->size = new_size; } else { + ok = 0; LOG(LL_ERROR, ("%lu->%lu", (unsigned long) io->size, (unsigned long) new_size)); } } + return ok; } -void mg_iobuf_init(struct mg_iobuf *io, size_t size) { +int mg_iobuf_init(struct mg_iobuf *io, size_t size) { + int ok = 1; io->buf = NULL; io->len = io->size = 0; - if (size > 0) mg_iobuf_resize(io, size); + if (size > 0) ok = mg_iobuf_resize(io, size); + return ok; } size_t mg_iobuf_append(struct mg_iobuf *io, const void *buf, size_t len, diff --git a/src/iobuf.h b/src/iobuf.h index c3306464..a9683f25 100644 --- a/src/iobuf.h +++ b/src/iobuf.h @@ -7,8 +7,8 @@ struct mg_iobuf { size_t size, len; }; -void mg_iobuf_init(struct mg_iobuf *, size_t); -void mg_iobuf_resize(struct mg_iobuf *, size_t); +int mg_iobuf_init(struct mg_iobuf *, size_t); +int mg_iobuf_resize(struct mg_iobuf *, size_t); void mg_iobuf_free(struct mg_iobuf *); size_t mg_iobuf_append(struct mg_iobuf *, const void *, size_t, size_t); size_t mg_iobuf_delete(struct mg_iobuf *, size_t); diff --git a/src/sock.c b/src/sock.c index 620daba7..f3e75055 100644 --- a/src/sock.c +++ b/src/sock.c @@ -161,6 +161,7 @@ int mg_send(struct mg_connection *c, const void *buf, size_t len) { int fail, n = c->is_udp ? ll_write(c, buf, (SOCKET) len, &fail) : (int) mg_iobuf_append(&c->send, buf, len, MG_IO_SIZE); + if (len > 0 && n == 0) fail = 1; return n; } @@ -235,8 +236,9 @@ static void read_conn(struct mg_connection *c, // NOTE(lsm): do only one iteration of reads, cause some systems // (e.g. FreeRTOS stack) return 0 instead of -1/EWOULDBLOCK when no data if (c->recv.size - c->recv.len < MG_IO_SIZE && - c->recv.size < MG_MAX_RECV_BUF_SIZE) { - mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE); + c->recv.size < MG_MAX_RECV_BUF_SIZE && + !mg_iobuf_resize(&c->recv, c->recv.size + MG_IO_SIZE)) { + c->is_closing = 1; } buf = c->recv.buf + c->recv.len; len = (int) (c->recv.size - c->recv.len);