summaryrefslogtreecommitdiff
path: root/lib9p/srv_include
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv_include')
-rw-r--r--lib9p/srv_include/lib9p/srv.h145
1 files changed, 79 insertions, 66 deletions
diff --git a/lib9p/srv_include/lib9p/srv.h b/lib9p/srv_include/lib9p/srv.h
index 89dc986..ce82e59 100644
--- a/lib9p/srv_include/lib9p/srv.h
+++ b/lib9p/srv_include/lib9p/srv.h
@@ -17,6 +17,11 @@
#include <lib9p/core.h>
+#ifndef CONFIG_9P_SRV_MAX_ERR_SIZE
+ #error config.h must define CONFIG_9P_SRV_MAX_ERR_SIZE
+#endif
+static_assert(CONFIG_9P_SRV_MAX_ERR_SIZE <= UINT16_MAX);
+
/* context ********************************************************************/
struct lib9p_srv_userid {
@@ -45,8 +50,7 @@ struct lib9p_srv_ctx {
struct _lib9p_srv_sess *parent_sess;
lib9p_tag_t tag;
uint8_t *net_bytes;
- _lib9p_srv_flush_ch_t flush_ch;
- bool flush_acknowledged;
+ _lib9p_srv_flush_ch_t flush_ch; /* flushers for this req _read_ from here */
bool responded;
END_PRIVATE(LIB9P_SRV_H);
};
@@ -55,20 +59,13 @@ struct lib9p_srv_ctx {
* Return whether there is an outstanding Tflush or Tversion
* cancellation of this request. After becoming true, this may go
* back to false if the Tflush itself is flushed.
+ *
+ * As a special case, returning E_POSIX_ECANCELED indicates that the
+ * flush has been observed, and a Rerror should not be sent ot the
+ * client.
*/
bool lib9p_srv_flush_requested(struct lib9p_srv_ctx *ctx);
-/**
- * Acknowledge that the handler is responding to an outstanding flush;
- * a non-Rerror R-message will be elided in favor of Rflush/Rversion.
- * lib9p_srv_flush_requested() must be true; so do not cr_yield()
- * between checking lib9p_srv_flush_requested() and calling
- * lib9p_srv_acknowledge_flush(). These are separate calls to
- * facilitate cases where a flush merely truncates a call, instead of
- * totally canceling it.
- */
-void lib9p_srv_acknowledge_flush(struct lib9p_srv_ctx *ctx);
-
/* version-independent stat ***************************************************/
struct lib9p_srv_stat {
@@ -95,18 +92,22 @@ struct lib9p_srv_stat {
struct lib9p_s extension;
#endif
};
+typedef struct lib9p_srv_stat lib9p_srv_stat;
+DECLARE_ERROR_OR(lib9p_srv_stat);
void lib9p_srv_stat_assert(struct lib9p_srv_stat stat);
/* interface definitions ******************************************************/
+typedef struct iovec iovec;
+DECLARE_ERROR_OR(iovec);
+
struct lib9p_srv_dirent {
struct lib9p_qid qid;
struct lib9p_s name;
};
-
-lo_interface lib9p_srv_fio;
-lo_interface lib9p_srv_dio;
+typedef struct lib9p_srv_dirent lib9p_srv_dirent;
+DECLARE_ERROR_OR(lib9p_srv_dirent);
/* FIXME: I don't like that the pointer returned by pread() has to
* remain live after it returns. Perhaps a `respond()`-callback? But
@@ -114,6 +115,46 @@ lo_interface lib9p_srv_dio;
*
* FIXME: It would be nice if pread() could return more than 1 iovec.
*/
+#define lib9p_srv_fio_LO_IFACE /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ \
+ LO_FUNC(struct lib9p_qid , qid ) \
+ LO_FUNC(void , iofree ) \
+ LO_FUNC(uint32_t , iounit ) \
+ LO_FUNC(iovec_or_error , pread , struct lib9p_srv_ctx *, \
+ uint32_t byte_count, \
+ uint64_t byte_offset) \
+ /** \
+ * If the file was append-only when fopen()ed, then byte_offset will \
+ * always be 0. \
+ */ \
+ LO_FUNC(uint32_t_or_error , pwrite , struct lib9p_srv_ctx *, \
+ void *buf, \
+ uint32_t byte_count, \
+ uint64_t byte_offset)
+LO_INTERFACE(lib9p_srv_fio); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+typedef lo_interface lib9p_srv_fio lib9p_srv_fio;
+DECLARE_ERROR_OR(lib9p_srv_fio);
+
+#define lib9p_srv_dio_LO_IFACE /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ \
+ LO_FUNC(struct lib9p_qid , qid ) \
+ LO_FUNC(void , iofree ) \
+ /** \
+ * Return the idx-th dirent. idx will always be either 0 or \
+ * prev_idx+1. A dirent with an empty name signals EOF. The string \
+ * must remain valid until the next dread() call or iofree(). \
+ */ \
+ LO_FUNC(lib9p_srv_dirent_or_error , dread , struct lib9p_srv_ctx *, \
+ size_t idx)
+LO_INTERFACE(lib9p_srv_dio); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+typedef lo_interface lib9p_srv_dio lib9p_srv_dio;
+DECLARE_ERROR_OR(lib9p_srv_dio);
+
+struct _lo_lib9p_srv_file_vtable;
+lo_interface lib9p_srv_file {
+ void *self;
+ const struct _lo_lib9p_srv_file_vtable *vtable;
+};
+typedef lo_interface lib9p_srv_file lib9p_srv_file;
+DECLARE_ERROR_OR(lib9p_srv_file);
#define lib9p_srv_file_LO_IFACE /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ \
/* resource management **********************************************/ \
\
@@ -139,16 +180,16 @@ lo_interface lib9p_srv_dio;
/* non-"opened" generic I/O *****************************************/ \
\
/** Strings returned from stat() must remain valid until free(). */ \
- LO_FUNC(struct lib9p_srv_stat , stat , struct lib9p_srv_ctx *) \
- LO_FUNC(void , wstat , struct lib9p_srv_ctx *, \
+ LO_FUNC(lib9p_srv_stat_or_error , stat , struct lib9p_srv_ctx *) \
+ LO_FUNC(error , wstat , struct lib9p_srv_ctx *, \
struct lib9p_srv_stat) \
- LO_FUNC(void , remove , struct lib9p_srv_ctx *) \
+ LO_FUNC(error , remove , struct lib9p_srv_ctx *) \
\
/* non-"opened" directory I/O ***************************************/ \
\
- LO_FUNC(lo_interface lib9p_srv_file, dwalk , struct lib9p_srv_ctx *, \
+ LO_FUNC(lib9p_srv_file_or_error , dwalk , struct lib9p_srv_ctx *, \
struct lib9p_s childname) \
- LO_FUNC(lo_interface lib9p_srv_file, dcreate, struct lib9p_srv_ctx *, \
+ LO_FUNC(lib9p_srv_file_or_error , dcreate, struct lib9p_srv_ctx *, \
struct lib9p_s childname, \
struct lib9p_srv_userid *user, \
struct lib9p_srv_userid *group, \
@@ -156,50 +197,22 @@ lo_interface lib9p_srv_dio;
\
/* open() for I/O ***************************************************/ \
\
- LO_FUNC(lo_interface lib9p_srv_fio , fopen , struct lib9p_srv_ctx *, \
+ LO_FUNC(lib9p_srv_fio_or_error , fopen , struct lib9p_srv_ctx *, \
bool rd, bool wr, \
bool trunc) \
- LO_FUNC(lo_interface lib9p_srv_dio , dopen , struct lib9p_srv_ctx *)
+ LO_FUNC(lib9p_srv_dio_or_error , dopen , struct lib9p_srv_ctx *)
LO_INTERFACE(lib9p_srv_file); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-#define lib9p_srv_fio_LO_IFACE /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ \
- LO_FUNC(struct lib9p_qid , qid ) \
- LO_FUNC(void , iofree ) \
- LO_FUNC(uint32_t , iounit ) \
- LO_FUNC(void , pread , struct lib9p_srv_ctx *, \
- uint32_t byte_count, \
- uint64_t byte_offset, \
- struct iovec *ret) \
- /** \
- * If the file was append-only when fopen()ed, then byte_offset will \
- * always be 0. \
- */ \
- LO_FUNC(uint32_t , pwrite , struct lib9p_srv_ctx *, \
- void *buf, \
- uint32_t byte_count, \
- uint64_t byte_offset)
-LO_INTERFACE(lib9p_srv_fio); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-#define lib9p_srv_dio_LO_IFACE /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ \
- LO_FUNC(struct lib9p_qid , qid ) \
- LO_FUNC(void , iofree ) \
- /** \
- * Return the idx-th dirent. idx will always be either 0 or \
- * prev_idx+1. A dirent with an empty name signals EOF. The string \
- * must remain valid until the next dread() call or iofree(). \
- */ \
- LO_FUNC(struct lib9p_srv_dirent , dread , struct lib9p_srv_ctx *, \
- size_t idx)
-LO_INTERFACE(lib9p_srv_dio); /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#define LIB9P_SRV_NOTDIR(TYP, NAM) \
- static lo_interface lib9p_srv_file NAM##_dwalk (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \
- static lo_interface lib9p_srv_file NAM##_dcreate(TYP *, struct lib9p_srv_ctx *, struct lib9p_s, \
- struct lib9p_srv_userid *, struct lib9p_srv_userid *, lib9p_dm_t) { assert_notreached("not a directory"); } \
- static lo_interface lib9p_srv_dio NAM##_dopen (TYP *, struct lib9p_srv_ctx *) { assert_notreached("not a directory"); }
+ static lib9p_srv_file_or_error NAM##_dwalk (TYP *, struct lib9p_srv_ctx *, struct lib9p_s) { assert_notreached("not a directory"); } \
+ static lib9p_srv_file_or_error NAM##_dcreate(TYP *, struct lib9p_srv_ctx *, struct lib9p_s, \
+ struct lib9p_srv_userid *, struct lib9p_srv_userid *, lib9p_dm_t) { assert_notreached("not a directory"); } \
+ static lib9p_srv_dio_or_error NAM##_dopen (TYP *, struct lib9p_srv_ctx *) { assert_notreached("not a directory"); } \
+ LM_FORCE_SEMICOLON
#define LIB9P_SRV_NOTFILE(TYP, NAM) \
- static lo_interface lib9p_srv_fio NAM##_fopen (TYP *, struct lib9p_srv_ctx *, bool, bool, bool) { assert_notreached("not a file"); }
+ static lib9p_srv_fio_or_error NAM##_fopen (TYP *, struct lib9p_srv_ctx *, bool, bool, bool) { assert_notreached("not a file"); } \
+ LM_FORCE_SEMICOLON
/* main server entrypoints ****************************************************/
@@ -215,9 +228,9 @@ LO_INTERFACE(net_stream_conn_unix);
struct lib9p_srv {
/* Things you provide */
- void /*TODO*/ (*auth )(struct lib9p_srv_ctx *, struct lib9p_s treename); /* optional */
- lo_interface lib9p_srv_file (*rootdir)(struct lib9p_srv_ctx *, struct lib9p_s treename);
- void (*msglog )(struct lib9p_srv_ctx *, enum lib9p_msg_type, void *hostmsg); /* optional */
+ error /*TODO*/ (*auth )(struct lib9p_srv_ctx *, struct lib9p_s treename); /* optional */
+ lib9p_srv_file_or_error (*rootdir)(struct lib9p_srv_ctx *, struct lib9p_s treename);
+ void (*msglog )(struct lib9p_srv_ctx *, enum lib9p_msg_type, void *hostmsg); /* optional */
#if CONFIG_9P_ENABLE_9P2000_p9p
lo_interface net_stream_conn_unix (*type_assert_unix)(lo_interface net_stream_conn); /* optional */
#endif
@@ -263,10 +276,10 @@ void lib9p_srv_accept_and_read_loop(struct lib9p_srv *srv, lo_interface net_stre
*
* Errors that this function itself may send to clients:
*
- * @errno L_EMSGSIZE T-message has size[4] bigger than max_msg_size
- * @errno L_EDOM Tversion specified an impossibly small max_msg_size
- * @errno L_EOPNOTSUPP T-message has an R-message type, or an unrecognized T-message type
- * @errno L_EBADMSG T-message has wrong size[4] for its content, or has invalid UTF-8
+ * @errno E_POSIX_EMSGSIZE T-message has size[4] bigger than max_msg_size
+ * @errno E_POSIX_EDOM Tversion specified an impossibly small max_msg_size
+ * @errno E_POSIX_EOPNOTSUPP T-message has an R-message type, or an unrecognized T-message type
+ * @errno E_POSIX_EBADMSG T-message has wrong size[4] for its content, or has invalid UTF-8
*/
void lib9p_srv_read(struct lib9p_srv *srv, lo_interface net_stream_conn conn);
@@ -291,7 +304,7 @@ void lib9p_srv_worker_loop(struct lib9p_srv *srv);
*
* Errors that this function itself may send to clients:
*
- * @errno L_ERANGE R-message does not fit into max_msg_size
+ * @errno E_POSIX_ERANGE R-message does not fit into max_msg_size
*/
void lib9p_srv_worker(struct lib9p_srv_ctx *req);