@@ -9,12 +9,27 @@ export async function readStdin(stdinStream: typeof process.stdin = process.stdi
99 // The best showcase of what this does: https://stackoverflow.com/a/59024214
1010 const pipedIn = await fstat ( 0 )
1111 . then ( ( stat ) => {
12+ if ( process . env . STDIN_DEBUG ) {
13+ console . error ( {
14+ stat,
15+ isFIFO : stat . isFIFO ( ) ,
16+ isSocket : stat . isSocket ( ) ,
17+ isCharDevice : stat . isCharacterDevice ( ) ,
18+ isRegularFile : stat . isFile ( ) ,
19+ } ) ;
20+ }
21+
1222 // isFIFO -> `node a | node b`
1323 // isFile -> `node a < file`
14- return stat . isFIFO ( ) || stat . isFile ( ) ;
24+ // isSocket -> child processes (I think) [but we set a timeout of 50ms to avoid hanging]
25+ return stat . isFIFO ( ) || stat . isFile ( ) || ( stat . isSocket ( ) ? 50 : false ) ;
1526 } )
1627 . catch ( ( ) => false ) ;
1728
29+ if ( process . env . STDIN_DEBUG ) {
30+ console . error ( { isTTY : stdinStream . isTTY , pipedIn, readableEnd : stdinStream . readableEnded } ) ;
31+ }
32+
1833 // The isTTY params will be true if there is no piping into stdin
1934 // pipedIn is set if someone either runs `node a | node b`, or `node a < file`
2035 // if that is the case, isTTY will be undefined (???)
@@ -25,11 +40,39 @@ export async function readStdin(stdinStream: typeof process.stdin = process.stdi
2540
2641 const bufferChunks : Buffer [ ] = [ ] ;
2742
43+ const controller = new AbortController ( ) ;
44+
45+ let timeout : NodeJS . Timeout | null = null ;
46+
47+ if ( typeof pipedIn === 'number' ) {
48+ timeout = setTimeout ( ( ) => {
49+ controller . abort ( ) ;
50+ } , pipedIn ) . unref ( ) ;
51+ }
52+
2853 stdinStream . on ( 'data' , ( chunk ) => {
2954 bufferChunks . push ( chunk ) ;
55+
56+ // If we got some data already, we can clear the timeout, as we will get more
57+ if ( timeout ) {
58+ clearTimeout ( timeout ) ;
59+ timeout = null ;
60+ }
3061 } ) ;
3162
32- await once ( stdinStream , 'end' ) ;
63+ try {
64+ await once ( stdinStream , 'end' , { signal : controller . signal } ) ;
65+ } catch ( error ) {
66+ const casted = error as Error ;
67+
68+ if ( casted . name === 'AbortError' ) {
69+ return ;
70+ }
71+ }
72+
73+ if ( timeout ) {
74+ clearTimeout ( timeout ) ;
75+ }
3376
3477 const concat = Buffer . concat ( bufferChunks ) ;
3578
0 commit comments