diff options
-rw-r--r-- | extension/background.js | 137 | ||||
-rw-r--r-- | fs/hello.c | 59 |
2 files changed, 138 insertions, 58 deletions
diff --git a/extension/background.js b/extension/background.js index 912075d..72cfa73 100644 --- a/extension/background.js +++ b/extension/background.js @@ -1,14 +1,5 @@ const ws = new WebSocket("ws://localhost:8888"); -const ops = { - NONE: 0, - - GETATTR: 1, - OPEN: 2, - READDIR: 3, - READ: 4 -}; - const unix = { EPERM: 1, ENOENT: 2, @@ -34,10 +25,51 @@ function UnixError(error) { } UnixError.prototype = Error.prototype; +function getTab(id) { + return new Promise((resolve, reject) => chrome.tabs.get(id, resolve)); +} function queryTabs() { return new Promise((resolve, reject) => chrome.tabs.query({}, resolve)); } +function sendDebuggerCommand(tab, method, commandParams) { + return new Promise(resolve => chrome.debugger.sendCommand({tabId: id}, method, commandParams, resolve)); +} + +const fhManager = (function() { + const handles = {}; + let nextFh = 0; + return { + allocate(obj) { // -> fh + const fh = nextFh++; + handles[fh] = obj; + return fh; + }, + ref(fh) { + if (!handles[fh]) throw new UnixError(unix.EIO); + return handles[fh]; + }, + free(fh) { + delete handles[fh]; + } + }; +})(); + +// tabs/by-id/ID/title +// tabs/by-id/ID/url +// tabs/by-id/ID/console +// tabs/by-id/ID/mem (?) +// tabs/by-id/ID/cpu (?) +// tabs/by-id/ID/screenshot.png +// tabs/by-id/ID/printed.pdf +// tabs/by-id/ID/control +// tabs/by-id/ID/sources/ + +function pathComponent(path, i) { + const components = path.split('/'); + return components[i >= 0 ? i : components.length + i]; +} + const router = { "tabs": { "by-id": { @@ -47,13 +79,34 @@ const router = { }, "*": { - async getattr() { - return { - st_mode: unix.S_IFREG | 0444, - st_nlink: 1, - st_size: 10 // FIXME - }; - } + "url": { + async getattr() { + return { + st_mode: unix.S_IFREG | 0444, + st_nlink: 1, + st_size: 100 // FIXME + }; + }, + async open(path) { + return fhManager.allocate(await getTab(parseInt(pathComponent(path, -2)))); + }, + async read(path, fh, size, offset) { + const tab = fhManager.ref(fh); + return tab.url.substr(offset, size); + }, + async release(path, fh) { + fhManager.free(fh); + } + }, + /* "title": fileFromProperty('title'), + * "sources": folderFromResource( + * (tab, path) => new Promise(resolve => chrome.debugger.attach( + * { tabId: tab.id }, "1-3", resolve)), + * { + * readdir() { + + * } + * }*/ } } } @@ -73,7 +126,7 @@ function findRoute(path) { async function getattr(path) { let route = findRoute(path); if (route.getattr) { - return route.getattr(); + return route.getattr(path); } else { return { st_mode: unix.S_IFDIR | 0755, @@ -84,39 +137,62 @@ async function getattr(path) { async function readdir(path) { let route = findRoute(path); - if (route.readdir) { - return route.readdir(); - } + if (route.readdir) return route.readdir(path); return Object.keys(route); } +async function open(path) { + let route = findRoute(path); + if (route.open) return route.open(path); +} + +async function read(path, fh, size, offset) { + let route = findRoute(path); + if (route.read) return route.read(path, fh, size, offset); +} + +async function release(path, fh) { + let route = findRoute(path); + if (route.read) return route.release(path, fh); +} + ws.onmessage = async function(event) { const req = JSON.parse(event.data); - console.log('req', Object.entries(ops).find(([op, opcode]) => opcode === req.op)[0], req); let response = { op: req.op, error: unix.EIO }; try { - if (req.op === ops.GETATTR) { + if (req.op === 'getattr') { response = { - op: ops.GETATTR, + op: 'getattr', st_mode: 0, st_nlink: 0, st_size: 0, ...(await getattr(req.path)) }; - } else if (req.op === ops.OPEN) { - throw new UnixError(unix.EIO); + } else if (req.op === 'open') { + response = { + op: 'open', + fh: await open(req.path) + }; - } else if (req.op === ops.READDIR) { + } else if (req.op === 'readdir') { response = { - op: ops.READDIR, + op: 'readdir', entries: [".", "..", ...(await readdir(req.path))] }; - } else if (req.op === ops.READ) { + } else if (req.op === 'read') { + const buf = await read(req.path, req.fh, req.size, req.offset) + response = { + op: 'read', + buf, + size: buf.length + }; + + } else if (req.op === 'release') { + await release(req.path, req.fh); response = { - op: ops.READ, - buf: await read(req.path) + op: 'release' }; } @@ -127,6 +203,5 @@ ws.onmessage = async function(event) { } } - console.log('response', Object.entries(ops).find(([op, opcode]) => opcode === response.op)[0], response); ws.send(JSON.stringify(response)); }; @@ -20,15 +20,6 @@ struct wby_con *con = NULL; pthread_mutex_t request_data_mutex = PTHREAD_MUTEX_INITIALIZER; char *request_data = NULL; -enum opcode { - NONE = 0, - - GETATTR, - OPEN, - READDIR, - READ -}; - pthread_cond_t response_cv = PTHREAD_COND_INITIALIZER; pthread_mutex_t response_mutex = PTHREAD_MUTEX_INITIALIZER; cJSON *response = NULL; @@ -88,7 +79,7 @@ static cJSON *await_response() { if (disconnected) { ret = -EIO; goto done; } \ \ req = cJSON_CreateObject(); \ - cJSON_AddNumberToObject(req, "op", (int) op); \ + cJSON_AddStringToObject(req, "op", op); \ req_body \ \ dispatch_send_req(req); \ @@ -101,9 +92,9 @@ static cJSON *await_response() { if (ret != 0) goto done; \ } \ \ + ret = -1; \ resp_handler \ \ - ret = 0; \ done: \ if (req != NULL) cJSON_Delete(req); \ if (resp != NULL) cJSON_Delete(resp); \ @@ -121,25 +112,29 @@ hello_getattr(const char *path, struct stat *stbuf) memset(stbuf, 0, sizeof(struct stat)); printf("\n\ngetattr(%s)\n", path); - MAKE_REQ(GETATTR, { + MAKE_REQ("getattr", { cJSON_AddStringToObject(req, "path", path); }, { JSON_GET_PROP_INT(stbuf->st_mode, "st_mode"); JSON_GET_PROP_INT(stbuf->st_nlink, "st_nlink"); JSON_GET_PROP_INT(stbuf->st_size, "st_size"); printf("returning re getattr(%s)\n", path); + + ret = 0; }); } static int hello_open(const char *path, struct fuse_file_info *fi) { - MAKE_REQ(OPEN, { + MAKE_REQ("open", { cJSON_AddStringToObject(req, "path", path); cJSON_AddNumberToObject(req, "flags", fi->flags); }, { cJSON *fh_item = cJSON_GetObjectItemCaseSensitive(resp, "fh"); if (fh_item) fi->fh = fh_item->valueint; + + ret = 0; }); } @@ -149,8 +144,8 @@ hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, { printf("\n\nreaddir(%s)\n", path); - // send {op: READDIR, path} to the websocket handler - MAKE_REQ(READDIR, { + // send {op: "readdir", path} to the websocket handler + MAKE_REQ("readdir", { cJSON_AddStringToObject(req, "path", path); }, { cJSON *entries = cJSON_GetObjectItemCaseSensitive(resp, "entries"); @@ -159,6 +154,8 @@ hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, filler(buf, cJSON_GetStringValue(entry), NULL, 0); printf("entry: [%s]\n", cJSON_GetStringValue(entry)); } + + ret = 0; }); } @@ -166,7 +163,7 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - MAKE_REQ(OPEN, { + MAKE_REQ("read", { cJSON_AddStringToObject(req, "path", path); cJSON_AddNumberToObject(req, "size", size); cJSON_AddNumberToObject(req, "offset", offset); @@ -174,27 +171,35 @@ hello_read(const char *path, char *buf, size_t size, off_t offset, cJSON_AddNumberToObject(req, "fh", fi->fh); cJSON_AddNumberToObject(req, "flags", fi->flags); }, { - - }); + size_t resp_size; + JSON_GET_PROP_INT(resp_size, "size"); + size = resp_size < size ? resp_size : size; - if (strcmp(path, file_path) != 0) - return -ENOENT; + cJSON *resp_buf_item = cJSON_GetObjectItemCaseSensitive(resp, "buf"); + char *resp_buf = cJSON_GetStringValue(resp_buf_item); + size_t resp_buf_len = strlen(resp_buf); + size = resp_buf_len < size ? resp_buf_len : size; - if (offset >= file_size) /* Trying to read past the end of file. */ - return 0; + memcpy(buf, resp_buf, size); - if (offset + size > file_size) /* Trim the read to the file size. */ - size = file_size - offset; - - memcpy(buf, file_content + offset, size); /* Provide the content. */ + ret = size; + }); +} - return size; +static int hello_release(const char *path, struct fuse_file_info *fi) { + MAKE_REQ("release", { + cJSON_AddStringToObject(req, "path", path); + cJSON_AddNumberToObject(req, "fh", fi->fh); + }, { + ret = 0; + }); } static struct fuse_operations hello_filesystem_operations = { .getattr = hello_getattr, /* To provide size, permissions, etc. */ .open = hello_open, /* To enforce read-only access. */ .read = hello_read, /* To provide file content. */ + .release = hello_release, .readdir = hello_readdir, /* To provide directory listing. */ }; |