diff options
Diffstat (limited to 'lib9p/core.c')
-rw-r--r-- | lib9p/core.c | 73 |
1 files changed, 30 insertions, 43 deletions
diff --git a/lib9p/core.c b/lib9p/core.c index d64e23a..58fe538 100644 --- a/lib9p/core.c +++ b/lib9p/core.c @@ -45,21 +45,6 @@ bool lib9p_str_eq(struct lib9p_s a, struct lib9p_s b) { (a.len == 0 || memcmp(a.utf8, b.utf8, a.len) == 0); } -/* ctx ************************************************************************/ - -void lib9p_ctx_clear_error(struct lib9p_ctx *ctx) { - assert(ctx); -#if CONFIG_9P_ENABLE_9P2000_u || CONFIG_9P_ENABLE_9P2000_L - ctx->err_num = 0; -#endif - ctx->err_msg[0] = '\0'; -} - -bool lib9p_ctx_has_error(struct lib9p_ctx *ctx) { - assert(ctx); - return ctx->err_msg[0]; -} - /* bounds checks **************************************************************/ static inline void assert_ver(enum lib9p_version ver) { @@ -109,29 +94,31 @@ void fmt_print_lib9p_msg(lo_interface fmt_dest w, struct lib9p_ctx *ctx, enum li _lib9p_table_msg[ctx->version][typ].print(w, ctx, body); } -#define _lib9p_validate(LOW_TYP_BIT, ERRMSG, TABLE) do { \ - assert_ver(ctx->version); \ - /* Inspect the first 5 bytes ourselves. */ \ - uint32_t net_size = uint32le_decode(net_bytes); \ - if (net_size < 5) \ - return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short"); \ - uint8_t typ = net_bytes[4]; \ - if (typ % 2 != LOW_TYP_BIT) \ - return lib9p_error(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, ERRMSG ": message_type=", lib9p_msgtype_str(ctx->version, typ)); \ - struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \ - if (!tentry.validate) \ - return lib9p_error(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "unknown message type: ", lib9p_msgtype_str(ctx->version, typ), \ - " (protocol_version=", lib9p_version_str(ctx->version), ")"); \ - \ - /* Now use the message-type-specific tentry to process the whole thing. */ \ - return tentry.validate(ctx, net_size, net_bytes); \ +#define _lib9p_validate(LOW_TYP_BIT, ERRMSG, TABLE) do { \ + assert_ver(ctx->version); \ + /* Inspect the first 5 bytes ourselves. */ \ + uint32_t net_size = uint32le_decode(net_bytes); \ + if (net_size < 5) \ + return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EBADMSG, "message is impossibly short")); \ + uint8_t typ = net_bytes[4]; \ + if (typ % 2 != LOW_TYP_BIT) \ + return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EOPNOTSUPP, ERRMSG ": message_type=", \ + lib9p_msgtype_str(ctx->version, typ))); \ + struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \ + if (!tentry.validate) \ + return ERROR_NEW_ERR(size_t, error_new(E_POSIX_EOPNOTSUPP, "unknown message type: ", \ + lib9p_msgtype_str(ctx->version, typ), \ + " (protocol_version=", lib9p_version_str(ctx->version), ")")); \ + \ + /* Now use the message-type-specific tentry to process the whole thing. */ \ + return tentry.validate(ctx, net_size, net_bytes); \ } while (0) -ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { +size_t_or_error lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv); } -ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { +size_t_or_error lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv); } @@ -171,20 +158,20 @@ void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, struct _lib9p_send_tentry tentry = TABLE[ctx->version][typ/2]; \ assert(tentry.marshal); \ \ - bool ret_erred = tentry.marshal(ctx, body, &_ret); \ + error ret_err = tentry.marshal(ctx, body, &_ret); \ if (_ret.net_iov[_ret.net_iov_cnt-1].iov_len == 0) \ _ret.net_iov_cnt--; \ \ ret->iov_cnt = _ret.net_iov_cnt; \ - return ret_erred; \ + return ret_err; \ } while (0) -bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, +error lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, struct lib9p_Tmsg_send_buf *ret) { _lib9p_marshal(0, _lib9p_table_Tmsg_send); } -bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, +error lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, struct lib9p_Rmsg_send_buf *ret) { _lib9p_marshal(1, _lib9p_table_Rmsg_send); } @@ -192,14 +179,14 @@ bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *bo /* `struct lib9p_stat` helpers ************************************************/ #if _LIB9P_ENABLE_stat -bool lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, +error lib9p_stat_validate(struct lib9p_ctx *ctx, uint32_t net_size, uint8_t *net_bytes, uint32_t *ret_net_size, size_t *ret_host_size) { - ssize_t host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size); - if (host_size < 0) - return true; + size_t_or_error host_size = _lib9p_stat_validate(ctx, net_size, net_bytes, ret_net_size); + if (host_size.is_err) + return host_size.err; if (ret_host_size) - *ret_host_size = (size_t)host_size; - return false; + *ret_host_size = host_size.size_t; + return ERROR_NULL; } void lib9p_stat_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, |