Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/platform/environment/node/stdin.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as fs from 'fs';
7
import { tmpdir } from 'os';
8
import { Queue } from '../../../base/common/async.js';
9
import { randomPath } from '../../../base/common/extpath.js';
10
import { resolveTerminalEncoding } from '../../../base/node/terminalEncoding.js';
11
12
export function hasStdinWithoutTty() {
13
try {
14
return !process.stdin.isTTY; // Via https://twitter.com/MylesBorins/status/782009479382626304
15
} catch (error) {
16
// Windows workaround for https://github.com/nodejs/node/issues/11656
17
}
18
return false;
19
}
20
21
export function stdinDataListener(durationinMs: number): Promise<boolean> {
22
return new Promise(resolve => {
23
const dataListener = () => resolve(true);
24
25
// wait for 1s maximum...
26
setTimeout(() => {
27
process.stdin.removeListener('data', dataListener);
28
29
resolve(false);
30
}, durationinMs);
31
32
// ...but finish early if we detect data
33
process.stdin.once('data', dataListener);
34
});
35
}
36
37
export function getStdinFilePath(): string {
38
return randomPath(tmpdir(), 'code-stdin', 3);
39
}
40
41
async function createStdInFile(targetPath: string) {
42
await fs.promises.appendFile(targetPath, '');
43
await fs.promises.chmod(targetPath, 0o600); // Ensure the file is only read/writable by the user: https://github.com/microsoft/vscode-remote-release/issues/9048
44
}
45
46
export async function readFromStdin(targetPath: string, verbose: boolean, onEnd?: Function): Promise<void> {
47
48
let [encoding, iconv] = await Promise.all([
49
resolveTerminalEncoding(verbose), // respect terminal encoding when piping into file
50
import('@vscode/iconv-lite-umd'), // lazy load encoding module for usage
51
createStdInFile(targetPath) // make sure file exists right away (https://github.com/microsoft/vscode/issues/155341)
52
]);
53
54
if (!iconv.default.encodingExists(encoding)) {
55
console.log(`Unsupported terminal encoding: ${encoding}, falling back to UTF-8.`);
56
encoding = 'utf8';
57
}
58
59
// Use a `Queue` to be able to use `appendFile`
60
// which helps file watchers to be aware of the
61
// changes because each append closes the underlying
62
// file descriptor.
63
// (https://github.com/microsoft/vscode/issues/148952)
64
65
const appendFileQueue = new Queue();
66
67
const decoder = iconv.default.getDecoder(encoding);
68
69
process.stdin.on('data', chunk => {
70
const chunkStr = decoder.write(chunk);
71
appendFileQueue.queue(() => fs.promises.appendFile(targetPath, chunkStr));
72
});
73
74
process.stdin.on('end', () => {
75
const end = decoder.end();
76
77
appendFileQueue.queue(async () => {
78
try {
79
if (typeof end === 'string') {
80
await fs.promises.appendFile(targetPath, end);
81
}
82
} finally {
83
onEnd?.();
84
}
85
});
86
});
87
}
88
89