Skip to content

Commit f282158

Browse files
committed
execvp
1 parent 6b99838 commit f282158

File tree

6 files changed

+96
-34
lines changed

6 files changed

+96
-34
lines changed

js/build-busybox

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
mkdir -p bin
33

44
export CFLAGS="-include `readlink -f runtime/em-shell.h` -g"
5-
export EM_LDFLAGS="--pre-js ../em-shell/js/pre.js --js-opts 0 `readlink -f runtime/em-shell.c`"
5+
export EM_LDFLAGS="--pre-js ../em-shell/js/pre.js --js-opts 0 `readlink -f runtime/em-shell.c` --js-library `readlink -f runtime/em-shell.js`"
66
export KBUILD_VERBOSE=1
77
export ARCH=em
88
export CROSS_COMPILE=em

js/console.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,14 @@ function serviceConnected() {
7676

7777
let messageChannel = new MessageChannel();
7878
messageChannel.port1.onmessage = e => {
79-
term.write(e.data.replace('\n', '\r\n'));
79+
if (e.data.command == 'writeConsole')
80+
term.write(e.data.msg.replace('\n', '\r\n'));
81+
else if(e.data.command == 'spawn') {
82+
e.data.port.postMessage(9);
83+
}
8084
};
8185
navigator.serviceWorker.controller.postMessage({
82-
'command': 'consoleSetOutputPort',
86+
'command': 'setMasterPort',
8387
'port': messageChannel.port2},
8488
[messageChannel.port2]);
8589

js/service.js

+39-28
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ let prefix = this.registration.scope + 'service/';
44
let consoleInput = '';
55
let consoleInputWaiting = [];
66
let consoleOutput = '';
7-
let consoleOutputPort = null;
7+
let masterPort = null;
88

99
console.log('starting');
1010

@@ -18,41 +18,52 @@ this.addEventListener('fetch', function (e) {
1818

1919
if (path === 'check')
2020
e.respondWith(new Response('connected'));
21-
else if (path === 'readConsole') {
22-
if (consoleInput.length) {
21+
else if (path === 'readConsole') {
22+
if (consoleInput.length) {
2323
e.respondWith(new Response(consoleInput));
24-
consoleInput = '';
25-
} else {
26-
e.respondWith(new Promise(function (resolve, reject) {
27-
consoleInputWaiting.push(resolve);
28-
}));
29-
}
30-
} else if (path === 'writeConsole') {
24+
consoleInput = '';
25+
} else {
26+
e.respondWith(new Promise(function (resolve, reject) {
27+
consoleInputWaiting.push(resolve);
28+
}));
29+
}
30+
} else if (path === 'writeConsole') {
3131
e.request.text().then(writeConsole);
32-
e.respondWith(new Response(''));
33-
}
32+
e.respondWith(new Response(''));
33+
} else if (path === 'spawn') {
34+
e.respondWith(new Promise(function (resolve, reject) {
35+
e.request.json().then(j => {
36+
let messageChannel = new MessageChannel();
37+
messageChannel.port1.onmessage = e => resolve(new Response(e.data));
38+
j.command = path;
39+
j.port = messageChannel.port2;
40+
masterPort.postMessage(j, [messageChannel.port2]);
41+
});
42+
}));
43+
} else
44+
writeConsole('fetch ' + e.request.url + '\r\n');
3445
});
3546

36-
self.addEventListener('message', function (e) {
47+
self.addEventListener('message', function (e) {
3748
if (!e.isTrusted)
3849
return;
39-
if (e.data.command == 'consoleSetOutputPort') {
40-
consoleOutputPort = e.data.port;
41-
consoleOutputPort.postMessage(consoleOutput);
42-
consoleOutput = '';
43-
} else if (e.data.command == 'consoleKeyPress') {
44-
if (consoleInputWaiting.length) {
45-
for(let w of consoleInputWaiting)
46-
w(new Response(e.data.consoleKeyPress));
47-
consoleInputWaiting = [];
50+
if (e.data.command == 'setMasterPort') {
51+
masterPort = e.data.port;
52+
masterPort.postMessage({ command: 'writeConsole', msg: consoleOutput });
53+
consoleOutput = '';
54+
} else if (e.data.command == 'consoleKeyPress') {
55+
if (consoleInputWaiting.length) {
56+
for(let w of consoleInputWaiting)
57+
w(new Response(e.data.consoleKeyPress));
58+
consoleInputWaiting = [];
4859
} else
49-
consoleInput += e.data.consoleKeyPress;
50-
}
60+
consoleInput += e.data.consoleKeyPress;
61+
}
5162
});
5263

53-
function writeConsole(msg) {
54-
if (consoleOutputPort)
55-
consoleOutputPort.postMessage(msg);
64+
function writeConsole(msg) {
65+
if (masterPort)
66+
masterPort.postMessage({ command: 'writeConsole', msg: msg });
5667
else
57-
consoleOutput += msg;
68+
consoleOutput += msg;
5869
}

runtime/em-shell.c

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,44 @@
11
#include "em-shell.h"
2+
#include <emscripten.h>
3+
#include <errno.h>
4+
5+
#undef _exit
26

37
jmp_buf vfork_jump_buffer;
48
static int vfork_child_active = 0;
59
static int vfork_child_pid = 0;
610

11+
static int em_createPid() {
12+
return 99; /* TODO: fetch new pid from service.js */
13+
}
14+
715
int em_vfork(int is_parent) {
816
if (is_parent) {
917
vfork_child_active = 0;
18+
errno = 0;
1019
return vfork_child_pid;
1120
}
1221
else {
1322
vfork_child_active = 1;
14-
vfork_child_pid = 99; /* TODO: fetch new pid from service.js */
23+
vfork_child_pid = em_createPid();
1524
return 0;
1625
}
1726
}
1827

19-
#undef _exit
2028
void em_vfork_exit(int status) {
2129
if (vfork_child_active)
22-
longjmp(vfork_jump_buffer, 1); /* TODO: send status to service.js if exec...() wasn't called */
30+
longjmp(vfork_jump_buffer, 1); /* TODO: send status to service.js */
2331
else
2432
_exit(status);
2533
}
34+
35+
int js_spawn(const char *file, char *const argv[]);
36+
int em_execvp(const char *file, char *const argv[]) {
37+
errno = js_spawn(file, argv);
38+
if (errno)
39+
return -1;
40+
else if (vfork_child_active)
41+
longjmp(vfork_jump_buffer, 1);
42+
else
43+
_exit(0); /* TODO: bypass sending status to service.js */
44+
}

runtime/em-shell.h

+2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
extern jmp_buf vfork_jump_buffer;
55
int em_vfork(int is_parent);
66
void em_vfork_exit(int status);
7+
int em_execvp(const char *file, char *const argv[]);
78

89
#define vfork() (em_vfork(setjmp(vfork_jump_buffer)))
910
#define _exit(status) (em_vfork_exit(status))
1011
#define _Exit(status) (em_vfork_exit(status))
12+
#define execvp(file, argv) (em_execvp((file), (argv)))

runtime/em-shell.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
mergeInto(LibraryManager.library, {
2+
// TODO: send pid
3+
// TODO: send environment
4+
// TODO: send open file handles
5+
js_spawn: function (file, argv) {
6+
'use strict';
7+
file = Pointer_stringify(file);
8+
var args = [];
9+
while (true) {
10+
var arg = getValue(argv, '*');
11+
if (arg === 0)
12+
break;
13+
args.push(Pointer_stringify(arg));
14+
argv += 4;
15+
}
16+
17+
var req = new XMLHttpRequest();
18+
req.open("POST", 'service/spawn', false);
19+
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
20+
req.send(JSON.stringify({ file: file, args: args }));
21+
if (req.status === 200) {
22+
return req.responseText | 0;
23+
} else
24+
return ERRNO_CODES.ENOMEM;
25+
}
26+
});

0 commit comments

Comments
 (0)