copy / copy/v86

Stream comunication between JavaScript and guest OS

Open
#530 8 comments 2 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
23.5k
Forks
1.9k
Avg merge
2d 14h
Merged PRs (30d)
7

Description

Hi, thank you so much for the fantastic project!

I'd like to comunicate or **stream** data between JavaScript and guest OS. I know `emulator.serial0_send()` and "serial0-output-line" event, using in the Lua intepreter, but the output might have noises.

For example, when we have device files such as `/dev/jsread` and `/dev/jswrite`, we can compress in a guest OS and use in JavaScript by using `cat /dev/jsread | gzip | /dev/jswrite`. You can also do `cat /dev/jsread | lua | /dev/jswrite`.

Another my idea is to use named pipes (FIFO). I tried to use them, but unfortunelly they don't use `FS.prototype.Read` or`FS.prototype.Write`, so I could not give or obtain data to the named pipe from JavaScript.

Could you tell me how to comunicate between JavaScript and guest OS streamingly?

### poor workaround

The script as follows create a large file`/root/myjsread` and `emulator.fs9p.Read` is modified to give arbitrary data to guest OS from JavaScript.

```js
var emulator = new V86Starter({...});

const rootId = emulator.fs9p.SearchPath("/root").id;
const filename = "myjsread";
const parentid = rootId;
const x = emulator.fs9p.CreateInode();
x.uid = emulator.fs9p.inodes[parentid].uid;
x.gid = emulator.fs9p.inodes[parentid].gid;
x.qid.type = S_IFREG >> 8;
x.mode = (emulator.fs9p.inodes[parentid].mode & 0x1B6) | S_IFREG;
emulator.fs9p.PushInode(x, parentid, filename);
emulator.fs9p.NotifyListeners(emulator.fs9p.inodes.length-1, 'newfile');
var id = emulator.fs9p.inodes.length-1;
x.size = Number.MAX_SAFE_INTEGER;

const originalRead = emulator.fs9p.Read.bind(emulator.fs9p);

console.log("ID", id);
emulator.fs9p.Read = async function (nodeid, offset, count) {
if (id === nodeid) {
console.log("!! READ HOOK !! reading ", arguments);
// You can return bytes what you want, but I just streams infinite "A"
return new Uint8Array(Array(count).fill(65));
}
return originalRead(nodeid, offset, count);
};
```

An example usage in a guest OS is as follows.

```
$ cat myjsread
AAAAAAAAAAAA...
AAAAAAAAAAAA...
...
```

In my experiment, reading the `/root/myjsread` stopped arround 2^32 bytes.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading emulator.serial0_send(), the serial0-output-line event, FS.prototype.Read and FS.prototype.Write, and the emulator.fs9p.Read workaround shown in the issue. Compare these entry points with the named-pipe and device-file examples; the issue needs a defined streaming interface and a testable guest-to-JavaScript communication path before implementation can be considered done.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.