mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-29 21:58:20 +00:00
pipefs: prepare pipefs_open for named pipe support
This commit is contained in:
+59
-17
@@ -17,23 +17,6 @@ static uintmax_t currentinode;
|
|||||||
|
|
||||||
static vops_t vnops;
|
static vops_t vnops;
|
||||||
|
|
||||||
int pipefs_open(vnode_t **node, int flags, cred_t *cred) {
|
|
||||||
VOP_LOCK(*node);
|
|
||||||
|
|
||||||
pipenode_t *pipenode = (pipenode_t *)(*node);
|
|
||||||
|
|
||||||
if (flags & V_FFLAGS_READ) {
|
|
||||||
++pipenode->readers;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & V_FFLAGS_WRITE) {
|
|
||||||
++pipenode->writers;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOP_UNLOCK(*node);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pipefs_close(vnode_t *node, int flags, cred_t *cred) {
|
int pipefs_close(vnode_t *node, int flags, cred_t *cred) {
|
||||||
VOP_LOCK(node);
|
VOP_LOCK(node);
|
||||||
pipenode_t *pipenode = (pipenode_t *)node;
|
pipenode_t *pipenode = (pipenode_t *)node;
|
||||||
@@ -56,6 +39,64 @@ int pipefs_close(vnode_t *node, int flags, cred_t *cred) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pipefs_open(vnode_t **node, int flags, cred_t *cred) {
|
||||||
|
if ((flags & (V_FFLAGS_WRITE | V_FFLAGS_READ)) == 0)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
VOP_LOCK(*node);
|
||||||
|
pipenode_t *pipenode = (pipenode_t *)(*node);
|
||||||
|
|
||||||
|
if (flags & V_FFLAGS_READ) {
|
||||||
|
++pipenode->readers;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & V_FFLAGS_WRITE) {
|
||||||
|
++pipenode->writers;
|
||||||
|
}
|
||||||
|
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (pipenode->writers > 0 && pipenode->readers > 0)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
if (flags & V_FFLAGS_NONBLOCKING) {
|
||||||
|
if (flags & V_FFLAGS_READ) {
|
||||||
|
goto leave;
|
||||||
|
} else if (flags & V_FFLAGS_WRITE) {
|
||||||
|
error = ENXIO;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// from this point on, flags has only one of V_FFLAGS_READ or V_FFLAGS_WRITE
|
||||||
|
// and there are either no writers or no readers.
|
||||||
|
eventlistener_t listener;
|
||||||
|
EVENT_INITLISTENER(&listener);
|
||||||
|
EVENT_ATTACH(&listener, &pipenode->openevent);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
VOP_UNLOCK(*node);
|
||||||
|
error = EVENT_WAIT(&listener, 0);
|
||||||
|
VOP_LOCK(*node);
|
||||||
|
|
||||||
|
if (error || (pipenode->writers > 0 && pipenode->readers > 0))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENT_DETACHALL(&listener);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (error) {
|
||||||
|
VOP_UNLOCK(*node);
|
||||||
|
pipefs_close(*node, flags, cred);
|
||||||
|
} else {
|
||||||
|
EVENT_SIGNAL(&pipenode->openevent);
|
||||||
|
VOP_UNLOCK(*node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO for pipefs_read and pipefs_write, the return actually depends on how much data is in the pipe
|
// TODO for pipefs_read and pipefs_write, the return actually depends on how much data is in the pipe
|
||||||
static int internalpoll(vnode_t *node, polldata_t *data, int events) {
|
static int internalpoll(vnode_t *node, polldata_t *data, int events) {
|
||||||
pipenode_t *pipenode = (pipenode_t *)node;
|
pipenode_t *pipenode = (pipenode_t *)node;
|
||||||
@@ -333,6 +374,7 @@ static void ctor(scache_t *cache, void *obj) {
|
|||||||
VOP_INIT(&node->vnode, &vnops, 0, V_TYPE_FIFO, NULL);
|
VOP_INIT(&node->vnode, &vnops, 0, V_TYPE_FIFO, NULL);
|
||||||
node->attr.inode = ++currentinode;
|
node->attr.inode = ++currentinode;
|
||||||
POLL_INITHEADER(&node->pollheader);
|
POLL_INITHEADER(&node->pollheader);
|
||||||
|
EVENT_INITHEADER(&node->openevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pipefs_init() {
|
void pipefs_init() {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <ringbuffer.h>
|
#include <ringbuffer.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <kernel/poll.h>
|
#include <kernel/poll.h>
|
||||||
|
#include <kernel/event.h>
|
||||||
|
|
||||||
typedef struct pipenode_t {
|
typedef struct pipenode_t {
|
||||||
vnode_t vnode;
|
vnode_t vnode;
|
||||||
@@ -12,6 +13,7 @@ typedef struct pipenode_t {
|
|||||||
ringbuffer_t data;
|
ringbuffer_t data;
|
||||||
size_t readers, writers;
|
size_t readers, writers;
|
||||||
pollheader_t pollheader;
|
pollheader_t pollheader;
|
||||||
|
eventheader_t openevent;
|
||||||
} pipenode_t;
|
} pipenode_t;
|
||||||
|
|
||||||
void pipefs_init();
|
void pipefs_init();
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ static void open(file_t *file, vnode_t *node, int flags) {
|
|||||||
file->flags = flags;
|
file->flags = flags;
|
||||||
file->offset = 0;
|
file->offset = 0;
|
||||||
file->mode = 0777;
|
file->mode = 0777;
|
||||||
VOP_OPEN(&node, fileflagstovnodeflags(flags), &_cpu()->thread->proc->cred);
|
VOP_OPEN(&node, fileflagstovnodeflags(flags) | V_FFLAGS_NONBLOCKING, &_cpu()->thread->proc->cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
syscallret_t syscall_pipe2(context_t *, int flags) {
|
syscallret_t syscall_pipe2(context_t *, int flags) {
|
||||||
|
|||||||
Reference in New Issue
Block a user