@@ -14,10 +14,10 @@ import product from 'vs/platform/product/common/product';
1414import * as paths from 'vs/base/common/path' ;
1515import { whenDeleted , writeFileSync } from 'vs/base/node/pfs' ;
1616import { findFreePort , randomPort } from 'vs/base/node/ports' ;
17- import { resolveTerminalEncoding } from 'vs/base/node/encoding' ;
1817import { isWindows , isLinux } from 'vs/base/common/platform' ;
1918import { ProfilingSession , Target } from 'v8-inspect-profiler' ;
2019import { isString } from 'vs/base/common/types' ;
20+ import { hasStdinWithoutTty , stdinDataListener , getStdinFilePath , readFromStdin } from 'vs/platform/environment/node/stdin' ;
2121
2222function shouldSpawnCliProcess ( argv : ParsedArgs ) : boolean {
2323 return ! ! argv [ 'install-source' ]
@@ -142,91 +142,55 @@ export async function main(argv: string[]): Promise<any> {
142142 } ) ;
143143 }
144144
145- let stdinWithoutTty : boolean = false ;
146- try {
147- stdinWithoutTty = ! process . stdin . isTTY ; // Via https://twitter.com/MylesBorins/status/782009479382626304
148- } catch ( error ) {
149- // Windows workaround for https://github.com/nodejs/node/issues/11656
150- }
151-
152- const readFromStdin = args . _ . some ( a => a === '-' ) ;
153- if ( readFromStdin ) {
145+ const hasReadStdinArg = args . _ . some ( a => a === '-' ) ;
146+ if ( hasReadStdinArg ) {
154147 // remove the "-" argument when we read from stdin
155148 args . _ = args . _ . filter ( a => a !== '-' ) ;
156149 argv = argv . filter ( a => a !== '-' ) ;
157150 }
158151
159- let stdinFilePath : string ;
160- if ( stdinWithoutTty ) {
152+ let stdinFilePath : string | undefined ;
153+ if ( hasStdinWithoutTty ( ) ) {
161154
162155 // Read from stdin: we require a single "-" argument to be passed in order to start reading from
163156 // stdin. We do this because there is no reliable way to find out if data is piped to stdin. Just
164157 // checking for stdin being connected to a TTY is not enough (https://github.com/Microsoft/vscode/issues/40351)
165- if ( args . _ . length === 0 && readFromStdin ) {
166-
167- // prepare temp file to read stdin to
168- stdinFilePath = paths . join ( os . tmpdir ( ) , `code-stdin-${ Math . random ( ) . toString ( 36 ) . replace ( / [ ^ a - z ] + / g, '' ) . substr ( 0 , 3 ) } .txt` ) ;
169158
170- // open tmp file for writing
171- let stdinFileError : Error | undefined ;
172- let stdinFileStream : fs . WriteStream ;
173- try {
174- stdinFileStream = fs . createWriteStream ( stdinFilePath ) ;
175- } catch ( error ) {
176- stdinFileError = error ;
177- }
159+ if ( args . _ . length === 0 ) {
160+ if ( hasReadStdinArg ) {
161+ stdinFilePath = getStdinFilePath ( ) ;
178162
179- if ( ! stdinFileError ) {
163+ // returns a file path where stdin input is written into (write in progress).
164+ try {
165+ readFromStdin ( stdinFilePath , ! ! verbose ) ; // throws error if file can not be written
180166
181- // Pipe into tmp file using terminals encoding
182- resolveTerminalEncoding ( verbose ) . then ( async encoding => {
183- const iconv = await import ( 'iconv-lite' ) ;
184- const converterStream = iconv . decodeStream ( encoding ) ;
185- process . stdin . pipe ( converterStream ) . pipe ( stdinFileStream ) ;
186- } ) ;
167+ // Make sure to open tmp file
168+ addArg ( argv , stdinFilePath ) ;
187169
188- // Make sure to open tmp file
189- addArg ( argv , stdinFilePath ) ;
190-
191- // Enable --wait to get all data and ignore adding this to history
192- addArg ( argv , '--wait' ) ;
193- addArg ( argv , '--skip-add-to-recently-opened' ) ;
194- args . wait = true ;
195- }
170+ // Enable --wait to get all data and ignore adding this to history
171+ addArg ( argv , '--wait' ) ;
172+ addArg ( argv , '--skip-add-to-recently-opened' ) ;
173+ args . wait = true ;
196174
197- if ( verbose ) {
198- if ( stdinFileError ) {
199- console . error ( `Failed to create file to read via stdin: ${ stdinFileError . toString ( ) } ` ) ;
200- } else {
201175 console . log ( `Reading from stdin via: ${ stdinFilePath } ` ) ;
176+ } catch ( e ) {
177+ console . log ( `Failed to create file to read via stdin: ${ e . toString ( ) } ` ) ;
178+ stdinFilePath = undefined ;
202179 }
203- }
204- }
205-
206- // If the user pipes data via stdin but forgot to add the "-" argument, help by printing a message
207- // if we detect that data flows into via stdin after a certain timeout.
208- else if ( args . _ . length === 0 ) {
209- processCallbacks . push ( child => new Promise ( c => {
210- const dataListener = ( ) => {
211- if ( isWindows ) {
212- console . log ( `Run with '${ product . applicationName } -' to read output from another program (e.g. 'echo Hello World | ${ product . applicationName } -').` ) ;
213- } else {
214- console . log ( `Run with '${ product . applicationName } -' to read from stdin (e.g. 'ps aux | grep code | ${ product . applicationName } -').` ) ;
180+ } else {
181+
182+ // If the user pipes data via stdin but forgot to add the "-" argument, help by printing a message
183+ // if we detect that data flows into via stdin after a certain timeout.
184+ processCallbacks . push ( _ => stdinDataListener ( 1000 ) . then ( dataReceived => {
185+ if ( dataReceived ) {
186+ if ( isWindows ) {
187+ console . log ( `Run with '${ product . applicationName } -' to read output from another program (e.g. 'echo Hello World | ${ product . applicationName } -').` ) ;
188+ } else {
189+ console . log ( `Run with '${ product . applicationName } -' to read from stdin (e.g. 'ps aux | grep code | ${ product . applicationName } -').` ) ;
190+ }
215191 }
216-
217- c ( undefined ) ;
218- } ;
219-
220- // wait for 1s maximum...
221- setTimeout ( ( ) => {
222- process . stdin . removeListener ( 'data' , dataListener ) ;
223-
224- c ( undefined ) ;
225- } , 1000 ) ;
226-
227- // ...but finish early if we detect data
228- process . stdin . once ( 'data' , dataListener ) ;
229- } ) ) ;
192+ } ) ) ;
193+ }
230194 }
231195 }
232196
0 commit comments