summaryrefslogtreecommitdiff
path: root/net9p.c
diff options
context:
space:
mode:
Diffstat (limited to 'net9p.c')
-rw-r--r--net9p.c174
1 files changed, 163 insertions, 11 deletions
diff --git a/net9p.c b/net9p.c
index 6587498..8890586 100644
--- a/net9p.c
+++ b/net9p.c
@@ -9,13 +9,162 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <endian.h>
+
#include "net9p.h"
+/* "T" messages are client->server requests, and "R" messages are
+ * server->client responses. I do not know what the Plan 9 designers
+ * intended "T" and "R" to stand for.
+ */
+enum v9fs_msg_type {
+ /* "9P2000" base protocol
+ * https://ericvh.github.io/9p-rfc/rfc9p2000.html
+ * https://github.com/ericvh/9p-rfc/blob/master/9p2000.xml
+ *
+ * But due to incompleteness, the Plan 9 manual section-5 and
+ * the Plan 9 headers (particularly fcall.h) are a better
+ * references.
+ */
+ V9FS_Tversion = 100, /* "412" "4s" */
+ V9FS_Rversion = 101, /* "412" "4s" */
+ V9FS_Tauth = 102, /* "412" "4ss" */
+ V9FS_Rauth = 103, /* "412" "TODO" */
+ V9FS_Tattach = 104, /* "412" "TODO" */
+ V9FS_Rattach = 105, /* "412" "TODO" */
+ /*V9FS_Terror = 106, /* There is no Terror request, only Rerror responses */
+ V9FS_Rerror = 107, /* "412" "TODO" */
+ V9FS_Tflush = 108, /* "412" "TODO" */
+ V9FS_Rflush = 109, /* "412" "TODO" */
+ V9FS_Twalk = 110, /* "412" "TODO" */
+ V9FS_Rwalk = 111, /* "412" "TODO" */
+ V9FS_Topen = 112, /* "412" "TODO" */
+ V9FS_Ropen = 113, /* "412" "TODO" */
+ V9FS_Tcreate = 114, /* "412" "TODO" */
+ V9FS_Rcreate = 115, /* "412" "TODO" */
+ V9FS_Tread = 116, /* "412" "TODO" */
+ V9FS_Rread = 117, /* "412" "TODO" */
+ V9FS_Twrite = 118, /* "412" "TODO" */
+ V9FS_Rwrite = 119, /* "412" "TODO" */
+ V9FS_Tclunk = 120, /* "412" "TODO" */
+ V9FS_Rclunk = 121, /* "412" "TODO" */
+ V9FS_Tremove = 122, /* "412" "TODO" */
+ V9FS_Rremove = 123, /* "412" "TODO" */
+ V9FS_Tstat = 124, /* "412" "TODO" */
+ V9FS_Rstat = 125, /* "412" "TODO" */
+ V9FS_Twstat = 126, /* "412" "TODO" */
+ V9FS_Rwstat = 127, /* "412" "TODO" */
+
+ /* "9P2000.u" Unix extension
+ * https://ericvh.github.io/9p-rfc/rfc9p2000.u.html
+ * https://github.com/ericvh/9p-rfc/blob/master/9p2000.u.xml
+ */
+
+ /* "9P2000.L" Linux extension
+ * https://github.com/ericvh/9p-rfc/blob/master/9p2000.L.xml
+ */
+ V9FS_TLERROR = 6,
+ V9FS_RLERROR,
+ V9FS_TSTATFS = 8,
+ V9FS_RSTATFS,
+ V9FS_TLOPEN = 12,
+ V9FS_RLOPEN,
+ V9FS_TLCREATE = 14,
+ V9FS_RLCREATE,
+ V9FS_TSYMLINK = 16,
+ V9FS_RSYMLINK,
+ V9FS_TMKNOD = 18,
+ V9FS_RMKNOD,
+ V9FS_TRENAME = 20,
+ V9FS_RRENAME,
+ V9FS_TREADLINK = 22,
+ V9FS_RREADLINK,
+ V9FS_TGETATTR = 24,
+ V9FS_RGETATTR,
+ V9FS_TSETATTR = 26,
+ V9FS_RSETATTR,
+ V9FS_TXATTRWALK = 30,
+ V9FS_RXATTRWALK,
+ V9FS_TXATTRCREATE = 32,
+ V9FS_RXATTRCREATE,
+ V9FS_TREADDIR = 40,
+ V9FS_RREADDIR,
+ V9FS_TFSYNC = 50,
+ V9FS_RFSYNC,
+ V9FS_TLOCK = 52,
+ V9FS_RLOCK,
+ V9FS_TGETLOCK = 54,
+ V9FS_RGETLOCK,
+ V9FS_TLINK = 70,
+ V9FS_RLINK,
+ V9FS_TMKDIR = 72,
+ V9FS_RMKDIR,
+ V9FS_TRENAMEAT = 74,
+ V9FS_RRENAMEAT,
+ V9FS_TUNLINKAT = 76,
+ V9FS_RUNLINKAT,
+};
+
+/* 1 - u8
+ * 2 - u16le
+ * 4 - u32le
+ * 8 - u16le
+ * d - data (u32le `n`, then `n` bytes of data)
+ * s - string (u16le `n`, then `n` bytes of UTF-8)
+ * q - qid (13 bytes, idk)
+ */
+
+static const char const *msgfmt[255] = {
+ /* All messages start with a "size[4] type[1] tag[2]"
+ * prefix; that is not included in this table. */
+
+ [V9FS_Tversion] = "max_msg_size[4] s",
+ [V9FS_Rversion] = "4s",
+
+ [V9FS_Tauth] = "4ss",
+ [V9FS_Rauth] = "q",
+
+ [V9FS_Rerror] = "s",
+
+ [V9FS_Tflush] = "2",
+ [V9FS_Rflush] = "",
+
+ [V9FS_Tattach] = "44ss",
+ [V9FS_Rattach] = "q",
+
+ [V9FS_Twalk] = "TODO",
+ [V9FS_Rwalk] = "TODO",
+
+ [V9FS_Topen] = "41",
+ [V9FS_Ropen] = "q4",
+
+ [V9FS_Tcreate] = "4s41",
+ [V9FS_Rcreate] = "q4",
+
+ [V9FS_Tread] = "484",
+ [V9FS_Rread] = "d",
+
+ [V9FS_Twrite] = "48d",
+ [V9FS_Rwrite] = "4",
+
+ [V9FS_Tclunk] = "4",
+ [V9FS_Rclunk] = "",
+
+ [V9FS_Tremove] = "4",
+ [V9FS_Rremove] = "",
+
+ [V9FS_Tstat] = "4",
+ [V9FS_Rstat] = "TODO",
+
+ [V9FS_Twstat] = "TODO",
+ [V9FS_Rwstat] = "",
+};
+
+
+
void net9p_listen_cr(void *_arg) {
(void)_arg;
- printf("listen initializing...\n");
cr_begin();
- printf("listen running...\n");
union {
struct sockaddr_in in;
@@ -35,12 +184,17 @@ void net9p_listen_cr(void *_arg) {
if (listen(fd, 5) < 0)
error(1, errno, "listen");
- int conn = 9;
- if (!coroutine_add(net9p_worker_cr, &conn))
- error(1, 0, "coroutine_add(net9p_worker_cr, &%d)", conn);
- printf("im back...\n");
- for (int i = 0; i < 10; i++) {
- cr_yield();
+ for (;;) {
+ int conn = accept(fd, NULL, NULL);
+ if (conn < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ cr_yield();
+ continue;
+ }
+ error(1, errno, "accept");
+ }
+ if (!coroutine_add(net9p_worker_cr, &conn))
+ error(1, 0, "coroutine_add(net9p_worker_cr, &%d)", conn);
}
cr_end();
@@ -48,11 +202,9 @@ void net9p_listen_cr(void *_arg) {
void net9p_worker_cr(void *_arg) {
int fd = *((int *)_arg);
- printf("worker %zu initializing...\n", cr_getcid());
cr_begin();
- printf("worker %zu running...\n", cr_getcid());
- //close(fd);
+ close(fd);
cr_end();
}