aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extension/background.js137
-rw-r--r--fs/hello.c59
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));
};
diff --git a/fs/hello.c b/fs/hello.c
index 38e94b6..ef77584 100644
--- a/fs/hello.c
+++ b/fs/hello.c
@@ -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. */
};