Skip to content

Commit

Permalink
Move stdin echoing to BufferedIO
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthomas23 committed Dec 11, 2024
1 parent 430ad63 commit e8cf573
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 13 deletions.
66 changes: 64 additions & 2 deletions src/buffered_io.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { IOutputCallback } from './callback';
import { OutputFlag, Termios } from './termios';
import { InputFlag, LocalFlag, OutputFlag, Termios } from './termios';

/**
* Classes to deal with buffered IO between main worker and web worker. Both have access to the same
Expand Down Expand Up @@ -280,13 +280,15 @@ export class WorkerBufferedIO extends BufferedIO {

read(): number[] {
Atomics.wait(this._readArray, READ_MAIN, this._readCount);
const ret = this._loadFromSharedArrayBuffer();
const read = this._loadFromSharedArrayBuffer();
this._readCount++;

// Notify main worker that character has been read and a new one can be stored.
Atomics.store(this._readArray, READ_WORKER, this._readCount);
Atomics.notify(this._readArray, READ_WORKER, 1);

const ret = this._processReadChars(read);
this._maybeEchoToOutput(ret);
return ret;
}

Expand Down Expand Up @@ -318,6 +320,66 @@ export class WorkerBufferedIO extends BufferedIO {
}
}

_maybeEchoToOutput(chars: number[]): void {
const NL = 10; // Linefeed \n
const echo = (this.termios.c_lflag & LocalFlag.ECHO) > 0;
const echoNL = (this.termios.c_lflag & LocalFlag.ECHONL) > 0;
if (!echo && !echoNL) {
return;
}

const ret: number[] = [];
for (const char of chars) {
switch (char) {
case NL:
ret.push(NL);
break;
case 4:
break;
default:
if (echo) {
ret.push(char);
}
break;
}
}

if (ret.length > 0) {
this.write(ret);
}
}

private _processReadChars(chars: number[]): number[] {
const NL = 10; // Linefeed \n
const CR = 13; // Carriage return \r

const ret: number[] = [];
for (const char of chars) {
switch (char) {
case CR:
if ((this.termios.c_iflag & InputFlag.IGNCR) === 0) {
if ((this.termios.c_iflag & InputFlag.ICRNL) > 0) {
ret.push(NL);
} else {
ret.push(CR);
}
}
break;
case NL:
if ((this.termios.c_iflag & InputFlag.INLCR) > 0) {
ret.push(CR);
} else {
ret.push(NL);
}
break;
default:
ret.push(char);
break;
}
}
return ret;
}

private _processWriteChars(chars: Int8Array | number[]): number[] {
const NL = 10; // Linefeed \n
const CR = 13; // Carriage return \r
Expand Down
10 changes: 0 additions & 10 deletions src/commands/wasm_command_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ export abstract class WasmCommandRunner implements ICommandRunner {
_getCharBuffer = utf16codes.slice(1);
}

if (stdin.isTerminal()) {
if (utf16 === 10) {
context.stdout.write('\n');
context.stdout.flush();
} else if (utf16 > 31 && utf16 !== 127) {
context.stdout.write(String.fromCharCode(...utf16codes));
context.stdout.flush();
}
}

// What to do with length other than 1?
if (utf16 === 4) {
// EOT
Expand Down
2 changes: 1 addition & 1 deletion test/tests/shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ test.describe('Shell', () => {
]);
return output.text;
});
expect(output).toMatch(/^wc\r\nab {6}0 {7}1 {7}5\r\n/);
expect(output).toMatch('wc\r\na\x1B[Bb 0 1 5\r\n');
});

test('should support terminal stdin more than once', async ({ page }) => {
Expand Down

0 comments on commit e8cf573

Please sign in to comment.