diff options
-rw-r--r-- | src/c/include/unit/unit-wasm.h | 10 | ||||
-rw-r--r-- | src/c/libunit-wasm.c | 29 |
2 files changed, 39 insertions, 0 deletions
diff --git a/src/c/include/unit/unit-wasm.h b/src/c/include/unit/unit-wasm.h index 48079b1..c7625de 100644 --- a/src/c/include/unit/unit-wasm.h +++ b/src/c/include/unit/unit-wasm.h @@ -84,6 +84,15 @@ typedef enum { LUW_HTTP_GATEWAY_TIMEOUT = 504, } luw_http_status_t; +#if !defined(__DEFINED_ssize_t) +/* + * Match the typedef from wasm32-wasi/include/bits/alltypes.h + * without requiring the wasi-sysroot for building the rust + * stuff. + */ +typedef long ssize_t; +#endif + struct luw_hdr_field { u32 name_off; u32 name_len; @@ -239,6 +248,7 @@ extern int luw_mem_writep(luw_ctx_t *ctx, const char *fmt, ...); extern size_t luw_mem_writep_data(luw_ctx_t *ctx, const u8 *src, size_t size); extern void luw_req_buf_append(luw_ctx_t *ctx, const u8 *src); extern void luw_req_buf_copy(luw_ctx_t *ctx, const u8 *src); +extern ssize_t luw_mem_splice_file(const u8 *src, int fd); extern size_t luw_mem_fill_buf_from_req(luw_ctx_t *ctx, size_t from); extern void luw_mem_reset(luw_ctx_t *ctx); extern void luw_http_set_response_status(luw_http_status_t status); diff --git a/src/c/libunit-wasm.c b/src/c/libunit-wasm.c index fdf9499..1b36cf9 100644 --- a/src/c/libunit-wasm.c +++ b/src/c/libunit-wasm.c @@ -14,10 +14,16 @@ #include <stdarg.h> #include <string.h> #include <strings.h> +#include <unistd.h> #include <errno.h> #include "unit/unit-wasm.h" +#define MIN(a, b) \ + ({ __typeof__(a) _a = (a); \ + __typeof__ (b) _b = (b); \ + _a < _b ? _a : _b; }) + /* * Some handlers are required some are optional. * @@ -315,6 +321,29 @@ void luw_req_buf_copy(luw_ctx_t *ctx, const u8 *src) ctx->req->total_content_sent = req->total_content_sent; } +/* Copy data from the request to a given file-descriptor. */ +ssize_t luw_mem_splice_file(const u8 *src, int fd) +{ + struct luw_req *req = (struct luw_req *)src; + size_t written = 0; + size_t bytes_splice = 1024 * 128; /* It's what cp(1) uses */ + + do { + ssize_t bytes_wrote; + + bytes_splice = MIN(bytes_splice, req->content_sent - written); + + bytes_wrote = write(fd, src + req->content_off + written, + bytes_splice); + if (bytes_wrote == -1) + return -1; + + written += bytes_wrote; + } while (written < req->content_sent); + + return written; +} + /* * Convenience function to fill the response buffer with data from * the request buffer. |