mirror of
https://github.com/osnr/TabFS.git
synced 2024-05-03 22:33:11 +02:00
open/read work on url file!!!
Use string keys for opcodes to simplify the code.
This commit is contained in:
parent
b6f46e166d
commit
528467a55b
|
@ -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 === ops.READDIR) {
|
||||
} else if (req.op === 'open') {
|
||||
response = {
|
||||
op: ops.READDIR,
|
||||
op: 'open',
|
||||
fh: await open(req.path)
|
||||
};
|
||||
|
||||
} else if (req.op === 'readdir') {
|
||||
response = {
|
||||
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: ops.READ,
|
||||
buf: await read(req.path)
|
||||
op: 'read',
|
||||
buf,
|
||||
size: buf.length
|
||||
};
|
||||
|
||||
} else if (req.op === 'release') {
|
||||
await release(req.path, req.fh);
|
||||
response = {
|
||||
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));
|
||||
};
|
||||
|
|
63
fs/hello.c
63
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;
|
||||
|
||||
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;
|
||||
|
||||
memcpy(buf, resp_buf, size);
|
||||
|
||||
ret = size;
|
||||
});
|
||||
}
|
||||
|
||||
if (strcmp(path, file_path) != 0)
|
||||
return -ENOENT;
|
||||
|
||||
if (offset >= file_size) /* Trying to read past the end of file. */
|
||||
return 0;
|
||||
|
||||
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. */
|
||||
|
||||
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. */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue