Path: blob/main/src/vs/platform/environment/node/stdin.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as fs from 'fs';6import { tmpdir } from 'os';7import { Queue } from '../../../base/common/async.js';8import { randomPath } from '../../../base/common/extpath.js';9import { resolveTerminalEncoding } from '../../../base/node/terminalEncoding.js';1011export function hasStdinWithoutTty() {12try {13return !process.stdin.isTTY; // Via https://twitter.com/MylesBorins/status/78200947938262630414} catch (error) {15// Windows workaround for https://github.com/nodejs/node/issues/1165616}17return false;18}1920export function stdinDataListener(durationinMs: number): Promise<boolean> {21return new Promise(resolve => {22const dataListener = () => resolve(true);2324// wait for 1s maximum...25setTimeout(() => {26process.stdin.removeListener('data', dataListener);2728resolve(false);29}, durationinMs);3031// ...but finish early if we detect data32process.stdin.once('data', dataListener);33});34}3536export function getStdinFilePath(): string {37return randomPath(tmpdir(), 'code-stdin', 3);38}3940async function createStdInFile(targetPath: string) {41await fs.promises.appendFile(targetPath, '');42await fs.promises.chmod(targetPath, 0o600); // Ensure the file is only read/writable by the user: https://github.com/microsoft/vscode-remote-release/issues/904843}4445export async function readFromStdin(targetPath: string, verbose: boolean, onEnd?: Function): Promise<void> {4647let [encoding, iconv] = await Promise.all([48resolveTerminalEncoding(verbose), // respect terminal encoding when piping into file49import('@vscode/iconv-lite-umd'), // lazy load encoding module for usage50createStdInFile(targetPath) // make sure file exists right away (https://github.com/microsoft/vscode/issues/155341)51]);5253if (!iconv.default.encodingExists(encoding)) {54console.log(`Unsupported terminal encoding: ${encoding}, falling back to UTF-8.`);55encoding = 'utf8';56}5758// Use a `Queue` to be able to use `appendFile`59// which helps file watchers to be aware of the60// changes because each append closes the underlying61// file descriptor.62// (https://github.com/microsoft/vscode/issues/148952)6364const appendFileQueue = new Queue();6566const decoder = iconv.default.getDecoder(encoding);6768process.stdin.on('data', chunk => {69const chunkStr = decoder.write(chunk);70appendFileQueue.queue(() => fs.promises.appendFile(targetPath, chunkStr));71});7273process.stdin.on('end', () => {74const end = decoder.end();7576appendFileQueue.queue(async () => {77try {78if (typeof end === 'string') {79await fs.promises.appendFile(targetPath, end);80}81} finally {82onEnd?.();83}84});85});86}878889