|
6 | 6 |
|
7 | 7 | addToLibrary({ |
8 | 8 | $TTY__deps: [ |
| 9 | + '$DEV', |
9 | 10 | '$FS', |
10 | 11 | '$UTF8ArrayToString', |
11 | | - '$FS_stdin_getChar' |
| 12 | + '$FS_stdin_getChar', |
12 | 13 | ], |
13 | | -#if !MINIMAL_RUNTIME |
14 | | - $TTY__postset: () => { |
15 | | - addAtInit('TTY.init();'); |
16 | | - addAtExit('TTY.shutdown();'); |
17 | | - }, |
18 | | -#endif |
19 | 14 | $TTY: { |
20 | | - ttys: [], |
21 | | - init() { |
22 | | - // https://github.com/emscripten-core/emscripten/pull/1555 |
23 | | - // if (ENVIRONMENT_IS_NODE) { |
24 | | - // // currently, FS.init does not distinguish if process.stdin is a file or TTY |
25 | | - // // device, it always assumes it's a TTY device. because of this, we're forcing |
26 | | - // // process.stdin to UTF8 encoding to at least make stdin reading compatible |
27 | | - // // with text files until FS.init can be refactored. |
28 | | - // process.stdin.setEncoding('utf8'); |
29 | | - // } |
30 | | - }, |
31 | | - shutdown() { |
32 | | - // https://github.com/emscripten-core/emscripten/pull/1555 |
33 | | - // if (ENVIRONMENT_IS_NODE) { |
34 | | - // // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)? |
35 | | - // // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation |
36 | | - // // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists? |
37 | | - // // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle |
38 | | - // // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call |
39 | | - // process.stdin.pause(); |
40 | | - // } |
41 | | - }, |
| 15 | + ttys: {}, |
42 | 16 | register(dev, ops) { |
43 | | - TTY.ttys[dev] = { input: [], output: [], ops: ops }; |
44 | | - FS.registerDevice(dev, TTY.stream_ops); |
45 | | - }, |
46 | | - stream_ops: { |
47 | | - open(stream) { |
48 | | - var tty = TTY.ttys[stream.node.rdev]; |
49 | | - if (!tty) { |
50 | | - throw new FS.ErrnoError({{{ cDefs.ENODEV }}}); |
| 17 | + const tty = { input: [], output: [], ops }; |
| 18 | + TTY.ttys[dev] = tty; |
| 19 | + const devops = { tty }; |
| 20 | + devops.write = (devops, buffer) => { |
| 21 | + if (!ops.put_char) { |
| 22 | + throw new FS.ErrnoError({{{ cDefs.ENXIO }}}); |
51 | 23 | } |
52 | | - stream.tty = tty; |
53 | | - stream.seekable = false; |
54 | | - }, |
55 | | - close(stream) { |
56 | | - // flush any pending line data |
57 | | - stream.tty.ops.fsync?.(stream.tty); |
58 | | - }, |
59 | | - fsync(stream) { |
60 | | - stream.tty.ops.fsync?.(stream.tty); |
61 | | - }, |
62 | | - read(stream, buffer, offset, length, pos /* ignored */) { |
63 | | - if (!stream.tty || !stream.tty.ops.get_char) { |
| 24 | + for (var i = 0; i < buffer.length; i++) { |
| 25 | + ops.put_char(tty, buffer[i]); |
| 26 | + } |
| 27 | + return i; |
| 28 | + }; |
| 29 | + devops.read = (devops, buffer) => { |
| 30 | + if (!ops.get_char) { |
64 | 31 | throw new FS.ErrnoError({{{ cDefs.ENXIO }}}); |
65 | 32 | } |
66 | 33 | var bytesRead = 0; |
67 | | - for (var i = 0; i < length; i++) { |
68 | | - var result; |
69 | | - try { |
70 | | - result = stream.tty.ops.get_char(stream.tty); |
71 | | - } catch (e) { |
72 | | - throw new FS.ErrnoError({{{ cDefs.EIO }}}); |
73 | | - } |
| 34 | + for (var i = 0; i < buffer.length; i++) { |
| 35 | + var result = ops.get_char(tty); |
74 | 36 | if (result === undefined && bytesRead === 0) { |
75 | 37 | throw new FS.ErrnoError({{{ cDefs.EAGAIN }}}); |
76 | 38 | } |
77 | 39 | if (result === null || result === undefined) break; |
78 | 40 | bytesRead++; |
79 | | - buffer[offset+i] = result; |
80 | | - } |
81 | | - if (bytesRead) { |
82 | | - stream.node.atime = Date.now(); |
| 41 | + buffer[i] = result; |
83 | 42 | } |
84 | 43 | return bytesRead; |
85 | | - }, |
86 | | - write(stream, buffer, offset, length, pos) { |
87 | | - if (!stream.tty || !stream.tty.ops.put_char) { |
88 | | - throw new FS.ErrnoError({{{ cDefs.ENXIO }}}); |
89 | | - } |
90 | | - try { |
91 | | - for (var i = 0; i < length; i++) { |
92 | | - stream.tty.ops.put_char(stream.tty, buffer[offset+i]); |
93 | | - } |
94 | | - } catch (e) { |
95 | | - throw new FS.ErrnoError({{{ cDefs.EIO }}}); |
96 | | - } |
97 | | - if (length) { |
98 | | - stream.node.mtime = stream.node.ctime = Date.now(); |
99 | | - } |
100 | | - return i; |
| 44 | + }; |
| 45 | + if (ops.fsync) { |
| 46 | + devops.fsync = (devops) => ops.fsync(tty) |
101 | 47 | } |
| 48 | + DEV.register(dev, devops); |
102 | 49 | }, |
103 | 50 | default_tty_ops: { |
104 | 51 | get_char(tty) { |
|
0 commit comments