Getting into raw mode works with bun...not yet returning to normal mode

This commit is contained in:
Timothy Warren 2023-10-31 17:38:15 -04:00
parent 103cd1ecf6
commit db83982d91
4 changed files with 71 additions and 27 deletions

View File

@ -1 +1,54 @@
// Bun-specific ffi code // Bun-specific ffi code
import { dlopen, ptr, FFIType, suffix, toArrayBuffer } from "bun:ffi";
import {STDIN_FILENO, TCSANOW} from "../common/ffi";
const termiosArray = new Uint8Array(60);
const getLib = (name: string) => {
return dlopen(
name,
{
tcgetattr: {
args: ['i32', 'pointer'],
returns: 'i32',
},
tcsetattr: {
args: ['i32', 'i32', 'pointer'],
returns: 'i32',
},
cfmakeraw: {
args: ['pointer'],
returns: 'void',
},
},
);
}
let cStdLib = {symbols: {}};
try {
cStdLib = getLib(`libc.${suffix}`);
} catch {
cStdLib = getLib(`libc.${suffix}.6`);
}
export const enableRawMode = () => {
// Get the current termios settings
const termiosPtr = ptr(termiosArray);
cStdLib.symbols.tcgetattr(STDIN_FILENO, termiosPtr);
const oldTermios = new Uint8Array(toArrayBuffer(termiosPtr, 0, 60), 0, 60);
console.info(oldTermios);
// Update termios struct with raw settings
cStdLib.symbols.cfmakeraw(termiosPtr);
// Actually set the new termios settings
cStdLib.symbols.tcsetattr(STDIN_FILENO, TCSANOW, termiosPtr);
return () => {
const oldTermiosPtr = ptr(oldTermios);
cStdLib.symbols.tcsetattr(STDIN_FILENO, TCSANOW, oldTermiosPtr);
}
}

View File

@ -1,15 +1,26 @@
/** /**
* The main entrypoint when using Deno as the runtime * The main entrypoint when using Bun as the runtime
*/ */
import {enableRawMode} from './ffi'
export async function main(): Promise<number> { export async function main(): Promise<number> {
const disableRawMode = enableRawMode();
const decoder = new TextDecoder(); const decoder = new TextDecoder();
for await (const chunk of Bun.stdin.stream()) { for await (const chunk of Bun.stdin.stream()) {
const char = String(decoder.decode(chunk)).trim(); const char = String(decoder.decode(chunk)).trim();
if (char === 'q') { if (char === 'q') {
disableRawMode();
return 0; return 0;
} }
} }
process.on("exit", (code) => {
console.log(`Process exited with code ${code}`);
disableRawMode();
});
return -1; return -1;
} }

4
src/common/ffi.ts Normal file
View File

@ -0,0 +1,4 @@
export const STDIN_FILENO = 0;
export const STOUT_FILENO = 1;
export const TCSANOW = 0;
export const TCSAFLUSH = 2;

View File

@ -11,37 +11,14 @@ switch (Deno.build.os) {
libSuffix = 'dylib'; libSuffix = 'dylib';
break; break;
default: default:
libSuffix = 'so'; libSuffix = 'so.6';
break; break;
} }
const cSharedLib = `./libc.${libSuffix}`; const cSharedLib = `libc.${libSuffix}`;
const cStdLib = Deno.dlopen( const cStdLib = Deno.dlopen(
cSharedLib, cSharedLib,
{ {
termios: {
type: {
struct: [
// c_iflag
'u32',
// c_oflag
'u32',
// c_cflag
'u32',
// c_lflag
'u32',
// c_cc[20]
'u8', 'u8', 'u8', 'u8', 'u8',
'u8', 'u8', 'u8', 'u8', 'u8',
'u8', 'u8', 'u8', 'u8', 'u8',
'u8', 'u8', 'u8', 'u8', 'u8',
// __ispeed
'i32',
// __ospeed
'i32',
]
}
},
tcgetattr: { tcgetattr: {
parameters: ['i32', 'pointer'], parameters: ['i32', 'pointer'],
result: 'i32', result: 'i32',
@ -58,7 +35,6 @@ const cStdLib = Deno.dlopen(
); );
export default cStdLib.symbols; export default cStdLib.symbols;
export const termios = cStdLib.symbols.termios;
export const tcgetattr = cStdLib.symbols.tcgetattr; export const tcgetattr = cStdLib.symbols.tcgetattr;
export const tcsetattr = cStdLib.symbols.tcsetattr; export const tcsetattr = cStdLib.symbols.tcsetattr;
export const cfmakeraw = cStdLib.symbols.cfmakeraw; export const cfmakeraw = cStdLib.symbols.cfmakeraw;