isomorfeus-speednode 0.2.11 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
1
+ require 'socket'
2
+
3
+ module Isomorfeus
4
+ module Speednode
5
+ class AttachSocket
6
+
7
+ attr_reader :socket
8
+
9
+ def initialize(socket_path, block)
10
+ @socket_path = socket_path
11
+ @run_block = block
12
+ end
13
+
14
+ def run
15
+ @running = true
16
+ client = nil
17
+ ret = nil
18
+ @socket = UNIXServer.new(@socket_path)
19
+
20
+ while @running do
21
+ if ret
22
+ begin
23
+ client = @socket.accept_nonblock
24
+ request = client.gets("\x04")
25
+ result = @run_block.call(request)
26
+ client.write result
27
+ client.flush
28
+ client.close
29
+ rescue Errno::EAGAIN, Errno::EWOULDBLOCK
30
+ end
31
+ end
32
+ sleep 0.005
33
+ ret = begin
34
+ IO.select([@socket], nil, nil, 1) || next
35
+ rescue Errno::EBADF
36
+ end
37
+ end
38
+ end
39
+
40
+ def stop
41
+ @running = false
42
+ @socket.close
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ module Isomorfeus
2
+ class << self
3
+ attr_accessor :node_paths
4
+
5
+ def set_node_paths
6
+ np_sep = Gem.win_platform? ? ';' : ':'
7
+ existing_node_path = ENV['NODE_PATH']
8
+ temp_node_path = ''
9
+ if existing_node_path.nil? || existing_node_path.empty?
10
+ temp_node_path = Isomorfeus.node_paths.join(np_sep)
11
+ else
12
+ if existing_node_path.end_with?(np_sep)
13
+ temp_node_path = existing_node_path + Isomorfeus.node_paths.join(np_sep)
14
+ else
15
+ temp_node_path = existing_node_path + np_sep + Isomorfeus.node_paths.join(np_sep)
16
+ end
17
+ end
18
+ ENV['NODE_PATH'] = temp_node_path.split(np_sep).uniq.join(np_sep)
19
+ end
20
+ end
21
+
22
+ self.node_paths = []
23
+ end
@@ -1,225 +1,326 @@
1
- 'use strict';
2
-
3
- const vm = require('vm');
4
- const net = require('net');
5
- let contexts = {};
6
- let process_exit = false;
7
-
8
- /*** circular-json, originally taken from https://raw.githubusercontent.com/WebReflection/circular-json/
9
- Copyright (C) 2013-2017 by Andrea Giammarchi - @WebReflection
10
-
11
- Permission is hereby granted, free of charge, to any person obtaining a copy
12
- of this software and associated documentation files (the "Software"), to deal
13
- in the Software without restriction, including without limitation the rights
14
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
- copies of the Software, and to permit persons to whom the Software is
16
- furnished to do so, subject to the following conditions:
17
-
18
- The above copyright notice and this permission notice shall be included in
19
- all copies or substantial portions of the Software.
20
-
21
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
- THE SOFTWARE.
28
-
29
- ***
30
-
31
- the original version has been restructured and modified to fit in here,
32
- only stringify is used, unused parts removed.
33
-
34
- */
35
-
36
- const CircularJSON = {};
37
- CircularJSON.specialChar = '~';
38
- CircularJSON.safeSpecialChar = '\\x' + ('0' + CircularJSON.specialChar.charCodeAt(0).toString(16)).slice(-2);
39
- CircularJSON.escapedSafeSpecialChar = '\\' + CircularJSON.safeSpecialChar;
40
- CircularJSON.specialCharRG = new RegExp(CircularJSON.safeSpecialChar, 'g');
41
- CircularJSON.indexOf = [].indexOf || function(v){
42
- for(let i=this.length;i--&&this[i]!==v;);
43
- return i;
44
- };
45
-
46
- CircularJSON.generateReplacer = function (value, replacer, resolve) {
47
- let
48
- doNotIgnore = false,
49
- inspect = !!replacer,
50
- path = [],
51
- all = [value],
52
- seen = [value],
53
- mapp = [resolve ? CircularJSON.specialChar : '[Circular]'],
54
- last = value,
55
- lvl = 1,
56
- i, fn
57
- ;
58
- if (inspect) {
59
- fn = typeof replacer === 'object' ?
60
- function (key, value) {
61
- return key !== '' && CircularJSON.indexOf.call(replacer, key) < 0 ? void 0 : value;
62
- } :
63
- replacer;
64
- }
65
- return function(key, value) {
66
- // the replacer has rights to decide
67
- // if a new object should be returned
68
- // or if there's some key to drop
69
- // let's call it here rather than "too late"
70
- if (inspect) value = fn.call(this, key, value);
71
-
72
- // first pass should be ignored, since it's just the initial object
73
- if (doNotIgnore) {
74
- if (last !== this) {
75
- i = lvl - CircularJSON.indexOf.call(all, this) - 1;
76
- lvl -= i;
77
- all.splice(lvl, all.length);
78
- path.splice(lvl - 1, path.length);
79
- last = this;
80
- }
81
- // console.log(lvl, key, path);
82
- if (typeof value === 'object' && value) {
83
- // if object isn't referring to parent object, add to the
84
- // object path stack. Otherwise it is already there.
85
- if (CircularJSON.indexOf.call(all, value) < 0) {
86
- all.push(last = value);
87
- }
88
- lvl = all.length;
89
- i = CircularJSON.indexOf.call(seen, value);
90
- if (i < 0) {
91
- i = seen.push(value) - 1;
92
- if (resolve) {
93
- // key cannot contain specialChar but could be not a string
94
- path.push(('' + key).replace(CircularJSON.specialCharRG, CircularJSON.safeSpecialChar));
95
- mapp[i] = CircularJSON.specialChar + path.join(CircularJSON.specialChar);
96
- } else {
97
- mapp[i] = mapp[0];
98
- }
99
- } else {
100
- value = mapp[i];
101
- }
102
- } else {
103
- if (typeof value === 'string' && resolve) {
104
- // ensure no special char involved on deserialization
105
- // in this case only first char is important
106
- // no need to replace all value (better performance)
107
- value = value
108
- .replace(CircularJSON.safeSpecialChar, CircularJSON.escapedSafeSpecialChar)
109
- .replace(CircularJSON.specialChar, CircularJSON.safeSpecialChar);
110
- }
111
- }
112
- } else {
113
- doNotIgnore = true;
114
- }
115
- return value;
116
- };
117
- };
118
- CircularJSON.stringify = function stringify(value, replacer, space, doNotResolve) {
119
- return JSON.stringify(
120
- value,
121
- CircularJSON.generateReplacer(value, replacer, !doNotResolve),
122
- space
123
- );
124
- };
125
- /*** end of circular-json ***/
126
-
127
- /*
128
- * Versions of node before 0.12 (notably 0.10) didn't properly propagate
129
- * syntax errors.
130
- * This also regressed in the node 4.0 releases.
131
- *
132
- * To get around this, if it looks like we are missing the location of the
133
- * error, we guess it is (execjs):1
134
- *
135
- * This is obviously not ideal, but only affects syntax errors, and only on
136
- * these versions.
137
- */
138
- function massageStackTrace(stack) {
139
- if (stack && stack.indexOf("SyntaxError") == 0) {
140
- return "(execjs):1\n" + stack;
141
- } else {
142
- return stack;
143
- }
144
- }
145
-
146
- function createCompatibleContext() {
147
- let c = vm.createContext();
148
- vm.runInContext('delete this.console', c, "(execjs)");
149
- return c;
150
- }
151
-
152
- function createPermissiveContext() {
153
- return vm.createContext({ global: {}, process: {release: {name: "node"}}, Buffer, clearTimeout, require, setTimeout });
154
- }
155
-
156
- function getCompatibleContext(uuid) {
157
- return contexts[uuid] || (contexts[uuid] = createCompatibleContext());
158
- }
159
-
160
- function getPermissiveContext(uuid) {
161
- return contexts[uuid] || (contexts[uuid] = createPermissiveContext());
162
- }
163
-
164
- let commands = {
165
- deleteContext: function(uuid) {
166
- delete contexts[uuid];
167
- return [1];
168
- },
169
- exit: function(code) {
170
- process_exit = code;
171
- return ['ok'];
172
- },
173
- execp: function execJS(input) {
174
- let context = getPermissiveContext(input.context);
175
- try {
176
- let program = function(){ return vm.runInContext(input.source, context, "(execjs)"); };
177
- let result = program();
178
- if (typeof result == 'undefined' && result !== null) { return ['ok']; }
179
- else {
180
- try { return ['ok', result]; }
181
- catch (err) { return ['err', '' + err, err.stack]; }
182
- }
183
- } catch (err) { return ['err', '' + err, massageStackTrace(err.stack)]; }
184
- },
185
- exec: function execJS(input) {
186
- let context = getCompatibleContext(input.context);
187
- try {
188
- let program = function(){ return vm.runInContext(input.source, context, "(execjs)"); };
189
- let result = program();
190
- if (typeof result == 'undefined' && result !== null) { return ['ok']; }
191
- else {
192
- try { return ['ok', result]; }
193
- catch (err) { return ['err', '' + err, err.stack]; }
194
- }
195
- } catch (err) { return ['err', '' + err, massageStackTrace(err.stack)]; }
196
- }
197
- };
198
-
199
- let server = net.createServer(function(s) {
200
- let received_data = Buffer.alloc(0);
201
-
202
- s.on('data', function (data) {
203
- received_data = Buffer.concat([received_data, data]);
204
- if (received_data[received_data.length - 1] !== 4) { return; }
205
- let request = received_data.slice(0, received_data.length - 1).toString('utf8');
206
- received_data = Buffer.alloc(0);
207
-
208
- let input = JSON.parse(request);
209
- let result = commands[input.cmd].apply(null, input.args);
210
- let outputJSON = '';
211
-
212
- try { outputJSON = JSON.stringify(result); }
213
- catch(err) {
214
- if (err.message.includes('circular')) {
215
- outputJSON = CircularJSON.stringify(result);
216
- } else { outputJSON = JSON.stringify(['err', '' + err, err.stack]); }
217
- }
218
- s.write(outputJSON + '\x04');
219
- if (process_exit !== false) { process.exit(process_exit); }
220
- });
221
- });
222
-
223
- let socket_path = process.env.SOCKET_PATH;
224
- if (!socket_path) { throw 'No SOCKET_PATH given!'; };
225
- server.listen(socket_path);
1
+ 'use strict';
2
+
3
+ const vm = require('vm');
4
+ const net = require('net');
5
+ const os = require('os');
6
+ const fs = require('fs');
7
+ let contexts = {};
8
+ let process_exit = false;
9
+
10
+ /*** circular-json, originally taken from https://raw.githubusercontent.com/WebReflection/circular-json/
11
+ Copyright (C) 2013-2017 by Andrea Giammarchi - @WebReflection
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in
21
+ all copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
+ THE SOFTWARE.
30
+
31
+ ***
32
+
33
+ the original version has been restructured and modified to fit in here,
34
+ only stringify is used, unused parts removed.
35
+
36
+ */
37
+
38
+ const CircularJSON = {};
39
+ CircularJSON.specialChar = '~';
40
+ CircularJSON.safeSpecialChar = '\\x' + ('0' + CircularJSON.specialChar.charCodeAt(0).toString(16)).slice(-2);
41
+ CircularJSON.escapedSafeSpecialChar = '\\' + CircularJSON.safeSpecialChar;
42
+ CircularJSON.specialCharRG = new RegExp(CircularJSON.safeSpecialChar, 'g');
43
+ CircularJSON.indexOf = [].indexOf || function(v){
44
+ for(let i=this.length;i--&&this[i]!==v;);
45
+ return i;
46
+ };
47
+
48
+ CircularJSON.generateReplacer = function (value, replacer, resolve) {
49
+ let
50
+ doNotIgnore = false,
51
+ inspect = !!replacer,
52
+ path = [],
53
+ all = [value],
54
+ seen = [value],
55
+ mapp = [resolve ? CircularJSON.specialChar : '[Circular]'],
56
+ last = value,
57
+ lvl = 1,
58
+ i, fn
59
+ ;
60
+ if (inspect) {
61
+ fn = typeof replacer === 'object' ?
62
+ function (key, value) {
63
+ return key !== '' && CircularJSON.indexOf.call(replacer, key) < 0 ? void 0 : value;
64
+ } :
65
+ replacer;
66
+ }
67
+ return function(key, value) {
68
+ // the replacer has rights to decide
69
+ // if a new object should be returned
70
+ // or if there's some key to drop
71
+ // let's call it here rather than "too late"
72
+ if (inspect) value = fn.call(this, key, value);
73
+
74
+ // first pass should be ignored, since it's just the initial object
75
+ if (doNotIgnore) {
76
+ if (last !== this) {
77
+ i = lvl - CircularJSON.indexOf.call(all, this) - 1;
78
+ lvl -= i;
79
+ all.splice(lvl, all.length);
80
+ path.splice(lvl - 1, path.length);
81
+ last = this;
82
+ }
83
+ // console.log(lvl, key, path);
84
+ if (typeof value === 'object' && value) {
85
+ // if object isn't referring to parent object, add to the
86
+ // object path stack. Otherwise it is already there.
87
+ if (CircularJSON.indexOf.call(all, value) < 0) {
88
+ all.push(last = value);
89
+ }
90
+ lvl = all.length;
91
+ i = CircularJSON.indexOf.call(seen, value);
92
+ if (i < 0) {
93
+ i = seen.push(value) - 1;
94
+ if (resolve) {
95
+ // key cannot contain specialChar but could be not a string
96
+ path.push(('' + key).replace(CircularJSON.specialCharRG, CircularJSON.safeSpecialChar));
97
+ mapp[i] = CircularJSON.specialChar + path.join(CircularJSON.specialChar);
98
+ } else {
99
+ mapp[i] = mapp[0];
100
+ }
101
+ } else {
102
+ value = mapp[i];
103
+ }
104
+ } else {
105
+ if (typeof value === 'string' && resolve) {
106
+ // ensure no special char involved on deserialization
107
+ // in this case only first char is important
108
+ // no need to replace all value (better performance)
109
+ value = value
110
+ .replace(CircularJSON.safeSpecialChar, CircularJSON.escapedSafeSpecialChar)
111
+ .replace(CircularJSON.specialChar, CircularJSON.safeSpecialChar);
112
+ }
113
+ }
114
+ } else {
115
+ doNotIgnore = true;
116
+ }
117
+ return value;
118
+ };
119
+ };
120
+ CircularJSON.stringify = function stringify(value, replacer, space, doNotResolve) {
121
+ return JSON.stringify(
122
+ value,
123
+ CircularJSON.generateReplacer(value, replacer, !doNotResolve),
124
+ space
125
+ );
126
+ };
127
+ /*** end of circular-json ***/
128
+
129
+ function attachFunctionSource(responder_path, context, func) {
130
+ return func + " = async function(...method_args) {\n\
131
+ let context = \"" + context + "\";\n\
132
+ let func = \"" + func +"\";\n\
133
+ let request = [context, func, method_args];\n\
134
+ let responder_path = '" + responder_path + "';\n\
135
+ if (!global.__responder_socket) {\n\
136
+ return new Promise(function(resolve, reject) {\n\
137
+ setTimeout(function(){\n\
138
+ if (os.platform().indexOf('win') > -1) {\n\
139
+ let socket = net.connect(responder_path);\n\
140
+ socket.on('connect', function(){\n\
141
+ global.__responder_socket = true;\n\
142
+ socket.destroy();\n\
143
+ resolve(" + func + "(...method_args));\n\
144
+ })\n\
145
+ socket.on('error', function (err) {\n\
146
+ resolve(" + func + "(...method_args));\n\
147
+ });\n\
148
+ } else {\n\
149
+ if (fs.existsSync(responder_path)) { global.__responder_socket = true; }\n\
150
+ resolve(" + func + "(...method_args));\n\
151
+ }\n\
152
+ }, 10)\n\
153
+ });\n\
154
+ }\n\
155
+ return new Promise(function(resolve, reject) {\n\
156
+ let request_json = JSON.stringify(request);\n\
157
+ let buffer = Buffer.alloc(0);\n\
158
+ let socket = net.connect(responder_path);\n\
159
+ socket.setTimeout(2000);\n\
160
+ socket.on('error', function (err) {\n\
161
+ if (err.syscall === 'connect') {\n\
162
+ // ignore, close will handle\n\
163
+ } else if (os.platform().indexOf('win') > -1 && err.message.includes('read EPIPE')) {\n\
164
+ // ignore, close will handle\n\
165
+ } else if (os.platform().indexOf('win') > -1 && err.message.includes('write EPIPE')) {\n\
166
+ // ignore, close will handle\n\
167
+ } else { reject(err); }\n\
168
+ });\n\
169
+ socket.on('ready', function () {\n\
170
+ socket.write(request_json + \"\x04\");\n\
171
+ });\n\
172
+ socket.on('data', function (data) {\n\
173
+ buffer = Buffer.concat([buffer, data]);\n\
174
+ });\n\
175
+ socket.on('timeout', function() {\n\
176
+ socket.destroy();\n\
177
+ reject();\n\
178
+ });\n\
179
+ socket.on('close', function() {\n\
180
+ if (buffer.length > 0) {\n\
181
+ let method_result = JSON.parse(buffer.toString('utf8'));\n\
182
+ if (method_result[0] == 'err') {\n\
183
+ reject(method_result);\n\
184
+ } else {\n\
185
+ resolve(method_result[1]);\n\
186
+ }\n\
187
+ } else {\n\
188
+ resolve(null);\n\
189
+ }\n\
190
+ });\n\
191
+ });\n\
192
+ }\n";
193
+ }
194
+
195
+ function createCompatibleContext(uuid, options) {
196
+ let c = vm.createContext();
197
+ vm.runInContext('delete this.console', c, "(execjs)");
198
+ contexts[uuid] = { context: c, options: options };
199
+ return c;
200
+ }
201
+
202
+ function createPermissiveContext(uuid, options) {
203
+ let c = vm.createContext({ global: { __responder_socket: false }, process: { release: { name: "node" }, env: process.env }, Buffer, clearTimeout, fs, net, os, require, setTimeout });
204
+ contexts[uuid] = { context: c, options: options };
205
+ return c;
206
+ }
207
+
208
+ function formatResult(result) {
209
+ if (typeof result === 'undefined' && result !== null) { return ['ok']; }
210
+ else {
211
+ try { return ['ok', result]; }
212
+ catch (err) { return ['err', ['', err].join(''), err.stack]; }
213
+ }
214
+ }
215
+
216
+ function getContext(uuid) {
217
+ if (contexts[uuid]) { return contexts[uuid].context; }
218
+ else { return null; }
219
+ }
220
+
221
+ function getContextOptions(uuid) {
222
+ let options = { filename: "(execjs)", displayErrors: true };
223
+ if (contexts[uuid].options.timeout) {
224
+ options.timeout = contexts[uuid].options.timeout;
225
+ }
226
+ return options;
227
+ }
228
+
229
+ function massageStackTrace(stack) {
230
+ if (stack && stack.indexOf("SyntaxError") == 0) {
231
+ return "(execjs):1\n" + stack;
232
+ } else {
233
+ return stack;
234
+ }
235
+ }
236
+
237
+ let socket_path = process.env.SOCKET_PATH;
238
+ if (!socket_path) { throw 'No SOCKET_PATH given!'; };
239
+
240
+ let commands = {
241
+ attach: function(input) {
242
+ let context = getContext(input.context);
243
+ let responder_path;
244
+ if (os.platform().indexOf('win') > -1) { responder_path = '\\\\\\\\.\\\\pipe\\\\' + socket_path + '_responder'; }
245
+ else { responder_path = socket_path + '_responder' }
246
+ let result = vm.runInContext(attachFunctionSource(responder_path, input.context, input.func), context, { filename: "(execjs)", displayErrors: true });
247
+ return formatResult(result);
248
+ },
249
+ create: function (input) {
250
+ let context = createCompatibleContext(input.context, input.options);
251
+ let result = vm.runInContext(input.source, context, getContextOptions(input.context));
252
+ return formatResult(result);
253
+ },
254
+ createp: function (input) {
255
+ let context = createPermissiveContext(input.context, input.options);
256
+ let result = vm.runInContext(input.source, context, getContextOptions(input.context));
257
+ return formatResult(result);
258
+ },
259
+ deleteContext: function(uuid) {
260
+ delete contexts[uuid];
261
+ return [1];
262
+ },
263
+ exit: function(code) {
264
+ process_exit = code;
265
+ return ['ok'];
266
+ },
267
+ exec: function (input) {
268
+ let result = vm.runInContext(input.source, getContext(input.context), getContextOptions(input.context));
269
+ return formatResult(result);
270
+ },
271
+ eval: function (input) {
272
+ if (input.source.match(/^\s*{/)) { input.source = "(" + input.source + ")"; }
273
+ else if (input.source.match(/^\s*function\s*\(/)) { input.source = "(" + input.source + ")"; }
274
+ let result = vm.runInContext(input.source, getContext(input.context), getContextOptions(input.context));
275
+ return formatResult(result);
276
+ },
277
+ // ctxo: function (input) {
278
+ // return formatResult(getContextOptions(input.context));
279
+ // },
280
+ };
281
+
282
+ let server = net.createServer(function(s) {
283
+ let received_data = [];
284
+
285
+ s.on('data', function (data) {
286
+ received_data.push(data);
287
+ if (data[data.length - 1] !== 4) { return; }
288
+
289
+ let request = received_data.join('').toString('utf8');
290
+ request = request.substr(0, request.length - 1);
291
+ received_data = [];
292
+
293
+ let input, result;
294
+ let outputJSON = '';
295
+
296
+ try { input = JSON.parse(request); }
297
+ catch(err) {
298
+ outputJSON = JSON.stringify(['err', ['', err].join(''), err.stack]);
299
+ s.write([outputJSON, "\x04"].join(''));
300
+ return;
301
+ }
302
+
303
+ try { result = commands[input.cmd].apply(null, input.args); }
304
+ catch (err) {
305
+ outputJSON = JSON.stringify(['err', ['', err].join(''), massageStackTrace(err.stack)]);
306
+ s.write([outputJSON, "\x04"].join(''));
307
+ return;
308
+ }
309
+
310
+ try { outputJSON = JSON.stringify(result); }
311
+ catch(err) {
312
+ if (err.message.includes('circular')) { outputJSON = CircularJSON.stringify(result); }
313
+ else { outputJSON = JSON.stringify([['', err].join(''), err.stack]); }
314
+ s.write([outputJSON, "\x04"].join(''));
315
+ if (process_exit !== false) { process.exit(process_exit); }
316
+ return;
317
+ }
318
+
319
+ try { s.write([outputJSON, "\x04"].join('')); }
320
+ catch (err) {}
321
+ if (process_exit !== false) { process.exit(process_exit); }
322
+ });
323
+ });
324
+
325
+ if (os.platform().indexOf('win') > -1) { server.listen('\\\\.\\pipe\\' + socket_path); }
326
+ else { server.listen(socket_path); }