forked from microsoft/vscode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstdForkStart.js
More file actions
197 lines (161 loc) · 5.5 KB
/
stdForkStart.js
File metadata and controls
197 lines (161 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const net = require('net');
const fs = require('fs');
// const stream = require('stream');
// const util = require('util');
var ENABLE_LOGGING = false;
var log = (function () {
if (!ENABLE_LOGGING) {
return function () { };
}
var isFirst = true;
var LOG_LOCATION = 'C:\\stdFork.log';
return function log(str) {
if (isFirst) {
isFirst = false;
fs.writeFileSync(LOG_LOCATION, str + '\n');
return;
}
fs.appendFileSync(LOG_LOCATION, str + '\n');
};
})();
var stdInPipeName = process.env['STDIN_PIPE_NAME'];
var stdOutPipeName = process.env['STDOUT_PIPE_NAME'];
var stdErrPipeName = process.env['STDERR_PIPE_NAME'];
log('STDIN_PIPE_NAME: ' + stdInPipeName);
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
log('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']);
// stdout redirection to named pipe
(function () {
log('Beginning stdout redirection...');
// Create a writing stream to the stdout pipe
var stdOutStream = net.connect(stdOutPipeName);
// unref stdOutStream to behave like a normal standard out
stdOutStream.unref();
// handle process.stdout
process.__defineGetter__('stdout', function () { return stdOutStream; });
// Create a writing stream to the stderr pipe
var stdErrStream = net.connect(stdErrPipeName);
// unref stdErrStream to behave like a normal standard out
stdErrStream.unref();
// handle process.stderr
process.__defineGetter__('stderr', function () { return stdErrStream; });
var fsWriteSyncString = function (fd, str, position, encoding) {
// fs.writeSync(fd, string[, position[, encoding]]);
var buf = Buffer.from(str, encoding || 'utf8');
return fsWriteSyncBuffer(fd, buf, 0, buf.length);
};
var fsWriteSyncBuffer = function (fd, buffer, off, len/* , position */) {
off = Math.abs(off | 0);
len = Math.abs(len | 0);
// fs.writeSync(fd, buffer, offset, length[, position]);
var buffer_length = buffer.length;
if (off > buffer_length) {
throw new Error('offset out of bounds');
}
if (len > buffer_length) {
throw new Error('length out of bounds');
}
if (((off + len) | 0) < off) {
throw new Error('off + len overflow');
}
if (buffer_length - off < len) {
// Asking for more than is left over in the buffer
throw new Error('off + len > buffer.length');
}
var slicedBuffer = buffer;
if (off !== 0 || len !== buffer_length) {
slicedBuffer = buffer.slice(off, off + len);
}
if (fd === 1) {
stdOutStream.write(slicedBuffer);
} else {
stdErrStream.write(slicedBuffer);
}
return slicedBuffer.length;
};
// handle fs.writeSync(1, ...) and fs.writeSync(2, ...)
var originalWriteSync = fs.writeSync;
fs.writeSync = function (fd, data/* , position, encoding */) {
if (fd !== 1 && fd !== 2) {
return originalWriteSync.apply(fs, arguments);
}
// usage:
// fs.writeSync(fd, buffer, offset, length[, position]);
// OR
// fs.writeSync(fd, string[, position[, encoding]]);
if (data instanceof Buffer) {
return fsWriteSyncBuffer.apply(null, arguments);
}
// For compatibility reasons with fs.writeSync, writing null will write "null", etc
if (typeof data !== 'string') {
data += '';
}
return fsWriteSyncString.apply(null, arguments);
};
log('Finished defining process.stdout, process.stderr and fs.writeSync');
})();
// stdin redirection to named pipe
(function () {
// Begin listening to stdin pipe
var server = net.createServer(function (stream) {
// Stop accepting new connections, keep the existing one alive
server.close();
log('Parent process has connected to my stdin. All should be good now.');
// handle process.stdin
process.__defineGetter__('stdin', function () {
return stream;
});
// Remove myself from process.argv
process.argv.splice(1, 1);
// Load the actual program
var program = process.argv[1];
log('Loading program: ' + program);
// Unset the custom environmental variables that should not get inherited
delete process.env['STDIN_PIPE_NAME'];
delete process.env['STDOUT_PIPE_NAME'];
delete process.env['STDERR_PIPE_NAME'];
delete process.env['ELECTRON_RUN_AS_NODE'];
require(program);
log('Finished loading program.');
var stdinIsReferenced = true;
var timer = setInterval(function () {
var listenerCount = (
stream.listeners('data').length +
stream.listeners('end').length +
stream.listeners('close').length +
stream.listeners('error').length
);
// log('listenerCount: ' + listenerCount);
if (listenerCount <= 1) {
// No more "actual" listeners, only internal node
if (stdinIsReferenced) {
stdinIsReferenced = false;
// log('unreferencing stream!!!');
stream.unref();
}
} else {
// There are "actual" listeners
if (!stdinIsReferenced) {
stdinIsReferenced = true;
stream.ref();
}
}
// log(
// '' + stream.listeners('data').length +
// ' ' + stream.listeners('end').length +
// ' ' + stream.listeners('close').length +
// ' ' + stream.listeners('error').length
// );
}, 1000);
timer.unref();
});
server.listen(stdInPipeName, function () {
// signal via stdout that the parent process can now begin writing to stdin pipe
process.stdout.write('ready');
});
})();