123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #include <stdio.h>
- #include "stream.h"
- #include "alloc.h"
- #include "writer.h"
- static Cell* fs_list;
- static int num_fs;
- static int stream_id;
- typedef Cell* (*funcptr2)(Cell* a1, Cell* a2);
- // TODO: include fs_list in gc mark
- Cell* get_fs_list() {
- return fs_list;
- }
- Cell* fs_open(Cell* path) {
- Cell* fsl = fs_list;
- Cell* fs_cell;
-
- if (!path || path->tag!=TAG_STR) {
- printf("[open] error: string required.");
- return alloc_nil();
- }
-
- while ((fs_cell = car(fsl))) {
- Filesystem* fs = (Filesystem*)fs_cell->dr.next;
- //printf("compare %s : %s : %p\n",fs->mount_point->ar.addr, path->ar.addr, strstr(fs->mount_point->ar.addr, path->ar.addr));
- if (path->ar.addr && strstr(path->ar.addr, fs->mount_point->ar.addr) == path->ar.addr) {
- Stream* s = malloc(sizeof(Stream));
- Cell* stream_cell;
-
- printf("[open] found matching fs: %s for path: %s\r\n", fs->mount_point->ar.addr, path->ar.addr);
- s->fs = fs;
- s->path = path;
- s->id = stream_id;
- // TODO: integrate in GC
- stream_cell = alloc_int(stream_id);
- stream_cell->tag = TAG_STREAM;
- stream_cell->ar.addr = s;
- stream_id++;
- // open the filesystem
- if (s->fs->open_fn && s->fs->open_fn->dr.next) {
- Cell* open_fn = s->fs->open_fn;
- printf("[open] open_fn: %p\r\n", s->fs->open_fn->dr.next);
- ((funcptr2)open_fn->dr.next)(path, NULL);
- }
- return stream_cell;
- }
- fsl = cdr(fsl);
- }
- return alloc_nil();
- }
- Cell* fs_mmap(Cell* path) {
- Cell* fsl = fs_list;
- Cell* fs_cell;
-
- if (!path || path->tag!=TAG_STR) {
- printf("[mmap] error: string required.");
- return alloc_nil();
- }
-
- while ((fs_cell = car(fsl))) {
- Filesystem* fs = (Filesystem*)fs_cell->dr.next;
- if (path->ar.addr && strstr(path->ar.addr, fs->mount_point->ar.addr) == path->ar.addr) {
- printf("[mmap] found matching fs: %s for path: %s\r\n", fs->mount_point->ar.addr, path->ar.addr);
- if (fs->mmap_fn && fs->mmap_fn->dr.next) {
- Cell* mmap_fn = fs->mmap_fn;
- return (Cell*)((funcptr2)mmap_fn->dr.next)(path, NULL);
- } else {
- printf("[mmap] error: fs has no mmap implementation.");
- return alloc_nil();
- }
- }
- fsl = cdr(fsl);
- }
- return alloc_nil();
- }
- Cell* fs_mount(Cell* path, Cell* handlers) {
- Filesystem* fs;
- Cell* fs_cell;
-
- if (!path || path->tag!=TAG_STR) {
- printf("[mount] error: string required.");
- return alloc_nil();
- }
- fs = malloc(sizeof(Filesystem));
- fs->open_fn = car(handlers);
- handlers = cdr(handlers);
- fs->read_fn = car(handlers);
- handlers = cdr(handlers);
- fs->write_fn = car(handlers);
- handlers = cdr(handlers);
- fs->delete_fn = car(handlers);
- handlers = cdr(handlers);
- fs->mmap_fn = car(handlers);
- handlers = cdr(handlers);
- fs->mount_point = path;
- fs->close_fn = NULL;
- fs_cell = alloc_int(num_fs++);
- fs_cell->dr.next = fs;
- fs_cell->tag = TAG_FS;
-
- printf("[fs] mounted: %s\r\n",path->ar.addr);
- fs_list = alloc_cons(fs_cell, fs_list);
- return fs_cell;
- }
- Cell* wrap_in_lambda(void* cfunc) {
- Cell* lbd = alloc_lambda(alloc_nil());
- lbd->dr.next = cfunc;
- return lbd;
- }
- // TODO: pass stream (context) to handlers
- Cell* stream_read(Cell* stream) {
- Stream* s;
- Cell* read_fn;
-
- if (!stream || stream->tag!=TAG_STREAM) {
- printf("[fs] error: non-stream passed to recv\r\n");
- return alloc_nil();
- }
- s = (Stream*)stream->ar.addr;
- read_fn = s->fs->read_fn;
- //char debug_buf[256];
- //lisp_write(read_fn, debug_buf, 256);
- //printf("[stream_read] fn: %s ptr: %p\n",debug_buf,read_fn->dr.next);
- return (Cell*)((funcptr2)read_fn->dr.next)(stream,NULL);
- }
- Cell* stream_write(Cell* stream, Cell* arg) {
- Stream* s;
- Cell* write_fn;
-
- if (!stream || stream->tag!=TAG_STREAM) {
- printf("[fs] error: non-stream passed to send\r\n");
- return alloc_nil();
- }
- s = (Stream*)stream->ar.addr;
- write_fn = s->fs->write_fn;
- //char debug_buf[256];
- //lisp_write(arg, debug_buf, 256);
- //printf("[stream_write] fn: %s ptr: %p\n",debug_buf,write_fn->dr.next);
- //printf("[stream_write] arg: %s\n",debug_buf);
- return (Cell*)((funcptr2)write_fn->dr.next)(stream,arg);
- }
- void fs_mount_builtin(char* path, void* open_handler, void* read_handler, void* write_handler, void* delete_handler, void* mmap_handler) {
- Cell* items[] = {
- wrap_in_lambda(open_handler),
- wrap_in_lambda(read_handler),
- wrap_in_lambda(write_handler),
- wrap_in_lambda(delete_handler),
- wrap_in_lambda(mmap_handler),
- };
- Cell* handlers = alloc_list(items,5);
- fs_mount(alloc_string_copy(path), handlers);
- }
- Cell* filesystems_init() {
- fs_list = alloc_nil();
- }
|