Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 318ad07

Browse files
committed
implement fd_write()
1 parent c27d977 commit 318ad07

File tree

5 files changed

+56
-33
lines changed

5 files changed

+56
-33
lines changed

Diff for: deps/uvwasi/src/fd_table.c

+17-10
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,12 @@ static uvwasi_errno_t uvwasi__get_type_and_rights(uv_file fd,
124124
} else if (S_ISSOCK(mode)) {
125125
handle_type = uv_guess_handle(fd);
126126

127-
if (handle_type == UV_TCP) {
127+
if (handle_type == UV_TCP)
128128
*type = UVWASI_FILETYPE_SOCKET_STREAM;
129-
} else if (handle_type == UV_UDP) {
129+
else if (handle_type == UV_UDP)
130130
*type = UVWASI_FILETYPE_SOCKET_DGRAM;
131-
} else {
131+
else
132132
*type = UVWASI_FILETYPE_UNKNOWN;
133-
*rights_base = 0;
134-
*rights_inheriting = 0;
135-
return UVWASI_EINVAL;
136-
}
137133

138134
*rights_base = UVWASI__RIGHTS_SOCKET_BASE;
139135
*rights_inheriting = UVWASI__RIGHTS_SOCKET_INHERITING;
@@ -239,6 +235,9 @@ static uvwasi_errno_t uvwasi__fd_table_insert(struct uvwasi_fd_table_t* table,
239235
uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
240236
uint32_t init_size) {
241237
struct uvwasi_fd_wrap_t* wrap;
238+
uvwasi_filetype_t type;
239+
uvwasi_rights_t base;
240+
uvwasi_rights_t inheriting;
242241
uvwasi_errno_t err;
243242
uvwasi_fd_t i;
244243

@@ -255,13 +254,21 @@ uvwasi_errno_t uvwasi_fd_table_init(struct uvwasi_fd_table_t* table,
255254

256255
/* Create the stdio FDs. */
257256
for (i = 0; i < 3; ++i) {
257+
err = uvwasi__get_type_and_rights(i,
258+
UV_FS_O_RDWR,
259+
&type,
260+
&base,
261+
&inheriting);
262+
if (err != UVWASI_ESUCCESS)
263+
goto error_exit;
264+
258265
err = uvwasi__fd_table_insert(table,
259266
i,
260267
"",
261268
"",
262-
UVWASI_FILETYPE_UNKNOWN,
263-
0,
264-
0,
269+
type,
270+
base,
271+
inheriting,
265272
0,
266273
&wrap);
267274
if (err != UVWASI_ESUCCESS)

Diff for: deps/uvwasi/src/uvwasi.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,7 @@ uvwasi_errno_t uvwasi_fd_write(uvwasi_t* uvwasi,
10031003
if (err != UVWASI_ESUCCESS)
10041004
return err;
10051005

1006-
r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, 0, NULL);
1006+
r = uv_fs_write(NULL, &req, wrap->fd, bufs, iovs_len, -1, NULL);
10071007
uvwritten = req.result;
10081008
uv_fs_req_cleanup(&req);
10091009
free(bufs);

Diff for: src/node_wasi.cc

+24-2
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
769769
uint32_t iovs_ptr;
770770
uint32_t iovs_len;
771771
uint32_t nwritten_ptr;
772+
char* memory;
773+
size_t mem_size;
772774
RETURN_IF_BAD_ARG_COUNT(args, 4);
773775
CHECK_TO_TYPE_OR_RETURN(args, args[0], Uint32, fd);
774776
CHECK_TO_TYPE_OR_RETURN(args, args[1], Uint32, iovs_ptr);
@@ -781,17 +783,37 @@ void WASI::FdWrite(const FunctionCallbackInfo<Value>& args) {
781783
iovs_ptr,
782784
iovs_len,
783785
nwritten_ptr);
784-
// TODO(cjihrig): Handle iovs properly instead of passing nullptr.
786+
GET_BACKING_STORE_OR_RETURN(wasi, args, &memory, &mem_size);
785787
// TODO(cjihrig): Check for buffer overflows.
788+
uvwasi_ciovec_t* iovs =
789+
static_cast<uvwasi_ciovec_t*>(calloc(iovs_len, sizeof(*iovs)));
790+
791+
if (iovs == nullptr) {
792+
args.GetReturnValue().Set(UVWASI_ENOMEM);
793+
return;
794+
}
795+
796+
for (uint32_t i = 0; i < iovs_len; ++i) {
797+
uint32_t buf_ptr;
798+
uint32_t buf_len;
799+
800+
wasi->readUInt32(&buf_ptr, iovs_ptr);
801+
wasi->readUInt32(&buf_len, iovs_ptr + 4);
802+
iovs_ptr += 8;
803+
iovs[i].buf = static_cast<void*>(&memory[buf_ptr]);
804+
iovs[i].buf_len = buf_len;
805+
}
806+
786807
size_t nwritten;
787808
uvwasi_errno_t err = uvwasi_fd_write(&wasi->uvw_,
788809
fd,
789-
nullptr,
810+
iovs,
790811
iovs_len,
791812
&nwritten);
792813
if (err == UVWASI_ESUCCESS)
793814
err = wasi->writeUInt32(nwritten, nwritten_ptr);
794815

816+
free(iovs);
795817
args.GetReturnValue().Set(err);
796818
}
797819

Diff for: test/wasi/test-wasi-binding.js

+2-9
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,13 @@ const assert = require('assert');
66
const fixtures = require('../common/fixtures');
77
const buffer = fixtures.readSync(['wasi', 'simple-wasi.wasm']);
88
const { WASI } = require('wasi');
9-
10-
const memory = new WebAssembly.Memory({ initial: 1 });
11-
const wasi = new WASI({ args: [], env: process.env, memory });
12-
9+
const wasi = new WASI({ args: [], env: process.env });
1310
const importObject = {
1411
wasi_unstable: wasi.wasiImport
1512
};
1613

1714
WebAssembly.instantiate(buffer, importObject)
1815
.then(common.mustCall((results) => {
1916
assert(results.instance.exports._start);
20-
// Currently when running this the exit status of the process will be 71
21-
// which if I'm reading the uvwasi error codes correctly matches __WASI_ESRCH
22-
// which is "No such process".
23-
// TODO(danbev) enable start when the above issue has been sorted out.
24-
// WASI.start(results.instance);
17+
wasi.start(results.instance);
2518
}));

Diff for: test/wasi/test-wasi.js

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
'use strict';
2-
const common = require('../common');
2+
require('../common');
33

44
if (process.argv[2] === 'wasi-child') {
55
const fs = require('fs');
66
const path = require('path');
77
const { WASI } = require('wasi');
88
const wasmDir = path.join(__dirname, 'wasm');
9-
const memory = new WebAssembly.Memory({ initial: 3 });
10-
const wasi = new WASI({ args: [], env: process.env, memory });
9+
const wasi = new WASI({ args: [], env: process.env });
1110
const importObject = { wasi_unstable: wasi.wasiImport };
1211
const modulePath = path.join(wasmDir, `${process.argv[3]}.wasm`);
1312
const buffer = fs.readFileSync(modulePath);
@@ -23,18 +22,20 @@ if (process.argv[2] === 'wasi-child') {
2322

2423
function runWASI(options) {
2524
console.log('executing', options.test);
26-
const child = cp.fork(__filename, ['wasi-child', options.test], {
27-
execArgv: ['--experimental-wasm-bigint']
28-
});
25+
const child = cp.spawnSync(process.execPath, [
26+
'--experimental-wasm-bigint',
27+
__filename,
28+
'wasi-child',
29+
options.test
30+
]);
2931

30-
child.on('exit', common.mustCall((code, signal) => {
31-
assert.strictEqual(code, options.exitCode || 0);
32-
assert.strictEqual(signal, null);
33-
}));
32+
assert.strictEqual(child.status, options.exitCode || 0);
33+
assert.strictEqual(child.signal, null);
34+
assert.strictEqual(child.stdout.toString(), options.stdout || '');
3435
}
3536

3637
runWASI({ test: 'cant_dotdot' });
3738
runWASI({ test: 'exitcode', exitCode: 120 });
3839
runWASI({ test: 'fd_prestat_get_refresh' });
39-
runWASI({ test: 'read_file' });
40+
runWASI({ test: 'read_file', stdout: 'hello from input.txt\n' });
4041
}

0 commit comments

Comments
 (0)