aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/user/ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/user/ipc.c')
-rw-r--r--src/kernel/user/ipc.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/kernel/user/ipc.c b/src/kernel/user/ipc.c
index dce1847..ff4d5c8 100644
--- a/src/kernel/user/ipc.c
+++ b/src/kernel/user/ipc.c
@@ -12,15 +12,17 @@
static size_t channel_read(fs_handle_t *c, size_t offset, size_t len, char* buf);
static size_t channel_write(fs_handle_t *c, size_t offset, size_t len, const char* buf);
static int channel_poll(fs_handle_t *c, void** out_wait_obj);
+static bool channel_open(fs_node_ptr c, int mode);
static bool channel_stat(fs_node_ptr c, stat_t *st);
static void channel_close(fs_handle_t *c);
+static void channel_dispose(fs_node_ptr c);
static fs_node_ops_t channel_ops = {
.read = channel_read,
.write = channel_write,
.close = channel_close,
.poll = channel_poll,
- .open = 0,
+ .open = channel_open,
.readdir = 0,
.ioctl = 0,
.stat = channel_stat,
@@ -28,7 +30,7 @@ static fs_node_ops_t channel_ops = {
.create = 0,
.move = 0,
.delete = 0,
- .dispose = 0,
+ .dispose = channel_dispose,
};
typedef struct channel {
@@ -41,6 +43,7 @@ typedef struct channel {
} channel_t;
fs_handle_pair_t make_channel(bool blocking) {
+ fs_node_t *na = 0, *nb = 0;
fs_handle_pair_t ret = { .a = 0, .b = 0 };
channel_t *a = 0, *b = 0;
@@ -56,17 +59,28 @@ fs_handle_pair_t make_channel(bool blocking) {
ret.b = (fs_handle_t*)malloc(sizeof(fs_handle_t));
if (ret.b == 0) goto error;
+ na = (fs_node_t*)malloc(sizeof(fs_node_t));
+ if (na == 0) goto error;
+
+ nb = (fs_node_t*)malloc(sizeof(fs_node_t));
+ if (nb == 0) goto error;
+
a->other_side = b;
b->other_side = a;
a->lock = b->lock = MUTEX_UNLOCKED;
a->buf_use_begin = a->buf_used = 0;
b->buf_use_begin = b->buf_used = 0;
+ memset(na, 0, sizeof(fs_node_t));
+ memset(nb, 0, sizeof(fs_node_t));
+ na->refs = nb->refs = 1;
+ na->ops = nb->ops = &channel_ops;
+ na->data = a;
+ nb->data = b;
+
ret.a->fs = ret.b->fs = 0;
- ret.a->node = ret.b->node = 0;
- ret.a->ops = ret.b->ops = &channel_ops;
- ret.a->data = a;
- ret.b->data = b;
+ ret.a->node = na;
+ ret.b->node = nb;
ret.a->refs = ret.b->refs = 1;
ret.a->mode = ret.b->mode = FM_READ | FM_WRITE | (blocking ? FM_BLOCKING : 0);
@@ -77,12 +91,14 @@ error:
if (b) free(b);
if (ret.a) free(ret.a);
if (ret.b) free(ret.b);
+ if (na) free(na);
+ if (nb) free(nb);
ret.a = ret.b = 0;
return ret;
}
size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_buf) {
- channel_t *c = (channel_t*)h->data;
+ channel_t *c = (channel_t*)h->node->data;
size_t ret = 0;
@@ -119,7 +135,7 @@ size_t channel_read(fs_handle_t *h, size_t offset, size_t req_len, char* orig_bu
}
size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char* orig_buf) {
- channel_t *tc = (channel_t*)h->data;
+ channel_t *tc = (channel_t*)h->node->data;
channel_t *c = tc->other_side;
if (c == 0) return 0;
@@ -160,7 +176,7 @@ size_t channel_write(fs_handle_t *h, size_t offset, size_t req_len, const char*
}
int channel_poll(fs_handle_t *h, void** out_wait_obj) {
- channel_t *c = (channel_t*)h->data;
+ channel_t *c = (channel_t*)h->node->data;
int ret = 0;
@@ -173,6 +189,13 @@ int channel_poll(fs_handle_t *h, void** out_wait_obj) {
return ret;
}
+bool channel_open(fs_node_ptr ch, int mode) {
+ int ok_modes = FM_READ | FM_WRITE | FM_BLOCKING;
+
+ if (mode & ~ok_modes) return false;
+ return true;
+}
+
bool channel_stat(fs_node_ptr ch, stat_t *st) {
channel_t *c = (channel_t*)ch;
@@ -188,7 +211,11 @@ bool channel_stat(fs_node_ptr ch, stat_t *st) {
}
void channel_close(fs_handle_t *ch) {
- channel_t *c = (channel_t*)ch->data;
+ // do nothing
+}
+
+void channel_dispose(fs_node_ptr ch) {
+ channel_t *c = (channel_t*)ch;
mutex_lock(&c->lock);