mirror of
https://github.com/subhobhai943/SUB-OS.git
synced 2026-10-25 16:52:29 +00:00
100 lines
2.4 KiB
C
100 lines
2.4 KiB
C
#include <ipc/pipe.h>
|
|
#include <mm/kmalloc.h>
|
|
#include <lib/string.h>
|
|
|
|
static ssize_t pipe_vfs_read(vfs_node_t* node, off_t offset, size_t size, uint8_t* buffer) {
|
|
(void)offset;
|
|
pipe_t* p = (pipe_t*)node->ptr;
|
|
if (!p) return 0;
|
|
return pipe_read(p, buffer, size);
|
|
}
|
|
|
|
static ssize_t pipe_vfs_write(vfs_node_t* node, off_t offset, size_t size, const uint8_t* buffer) {
|
|
(void)offset;
|
|
pipe_t* p = (pipe_t*)node->ptr;
|
|
if (!p) return 0;
|
|
return pipe_write(p, buffer, size);
|
|
}
|
|
|
|
int pipe_create(int pipefd[2]) {
|
|
if (!pipefd) return -1;
|
|
|
|
pipe_t* p = (pipe_t*)kzalloc(sizeof(pipe_t));
|
|
if (!p) return -1;
|
|
|
|
p->read_open = true;
|
|
p->write_open = true;
|
|
|
|
vfs_node_t* rnode = (vfs_node_t*)kzalloc(sizeof(vfs_node_t));
|
|
vfs_node_t* wnode = (vfs_node_t*)kzalloc(sizeof(vfs_node_t));
|
|
if (!rnode || !wnode) {
|
|
kfree(p);
|
|
if (rnode) kfree(rnode);
|
|
if (wnode) kfree(wnode);
|
|
return -1;
|
|
}
|
|
|
|
strcpy(rnode->name, "pipe:[r]");
|
|
rnode->flags = FS_CHARDEVICE;
|
|
rnode->read = pipe_vfs_read;
|
|
rnode->ptr = (struct vfs_node*)p;
|
|
|
|
strcpy(wnode->name, "pipe:[w]");
|
|
wnode->flags = FS_CHARDEVICE;
|
|
wnode->write = pipe_vfs_write;
|
|
wnode->ptr = (struct vfs_node*)p;
|
|
|
|
p->read_node = rnode;
|
|
p->write_node = wnode;
|
|
|
|
pipefd[0] = vfs_open_node(rnode, O_RDONLY);
|
|
pipefd[1] = vfs_open_node(wnode, O_WRONLY);
|
|
|
|
return 0;
|
|
}
|
|
|
|
ssize_t pipe_read(pipe_t* p, void* buf, size_t count) {
|
|
if (!p || !buf || count == 0) return 0;
|
|
|
|
size_t read_bytes = 0;
|
|
uint8_t* out = (uint8_t*)buf;
|
|
|
|
while (read_bytes < count && p->count > 0) {
|
|
out[read_bytes++] = p->buffer[p->tail];
|
|
p->tail = (p->tail + 1) % PIPE_BUF_SIZE;
|
|
p->count--;
|
|
}
|
|
|
|
return (ssize_t)read_bytes;
|
|
}
|
|
|
|
ssize_t pipe_write(pipe_t* p, const void* buf, size_t count) {
|
|
if (!p || !buf || count == 0) return 0;
|
|
if (!p->read_open) return -1; // EPIPE
|
|
|
|
size_t written = 0;
|
|
const uint8_t* in = (const uint8_t*)buf;
|
|
|
|
while (written < count && p->count < PIPE_BUF_SIZE) {
|
|
p->buffer[p->head] = in[written++];
|
|
p->head = (p->head + 1) % PIPE_BUF_SIZE;
|
|
p->count++;
|
|
}
|
|
|
|
return (ssize_t)written;
|
|
}
|
|
|
|
void pipe_close_read(pipe_t* p) {
|
|
if (p) {
|
|
p->read_open = false;
|
|
if (!p->write_open) kfree(p);
|
|
}
|
|
}
|
|
|
|
void pipe_close_write(pipe_t* p) {
|
|
if (p) {
|
|
p->write_open = false;
|
|
if (!p->read_open) kfree(p);
|
|
}
|
|
}
|