isomorfeus-speednode 0.2.12 → 0.4.2

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,224 +1,327 @@
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 = [];
201
-
202
- s.on('data', function (data) {
203
- received_data.push(data);
204
- if (data[data.length - 1] !== 4) { return; }
205
- let request = received_data.join('').toString('utf8');
206
- request = request.substr(0, request.length - 1);
207
- received_data = [];
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')) { outputJSON = CircularJSON.stringify(result); }
215
- else { outputJSON = JSON.stringify(['err', '' + err, err.stack]); }
216
- }
217
- s.write(outputJSON + '\x04');
218
- if (process_exit !== false) { process.exit(process_exit); }
219
- });
220
- });
221
-
222
- let socket_path = process.env.SOCKET_PATH;
223
- if (!socket_path) { throw 'No SOCKET_PATH given!'; };
224
- 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({ __responder_socket: false, process: { release: { name: "node" }, env: process.env }, Buffer, clearTimeout, fs, net, os, require, setTimeout });
204
+ vm.runInContext('global = globalThis;', c);
205
+ contexts[uuid] = { context: c, options: options };
206
+ return c;
207
+ }
208
+
209
+ function formatResult(result) {
210
+ if (typeof result === 'undefined' && result !== null) { return ['ok']; }
211
+ else {
212
+ try { return ['ok', result]; }
213
+ catch (err) { return ['err', ['', err].join(''), err.stack]; }
214
+ }
215
+ }
216
+
217
+ function getContext(uuid) {
218
+ if (contexts[uuid]) { return contexts[uuid].context; }
219
+ else { return null; }
220
+ }
221
+
222
+ function getContextOptions(uuid) {
223
+ let options = { filename: "(execjs)", displayErrors: true };
224
+ if (contexts[uuid].options.timeout) {
225
+ options.timeout = contexts[uuid].options.timeout;
226
+ }
227
+ return options;
228
+ }
229
+
230
+ function massageStackTrace(stack) {
231
+ if (stack && stack.indexOf("SyntaxError") == 0) {
232
+ return "(execjs):1\n" + stack;
233
+ } else {
234
+ return stack;
235
+ }
236
+ }
237
+
238
+ let socket_path = process.env.SOCKET_PATH;
239
+ if (!socket_path) { throw 'No SOCKET_PATH given!'; };
240
+
241
+ let commands = {
242
+ attach: function(input) {
243
+ let context = getContext(input.context);
244
+ let responder_path;
245
+ if (os.platform().indexOf('win') > -1) { responder_path = '\\\\\\\\.\\\\pipe\\\\' + socket_path + '_responder'; }
246
+ else { responder_path = socket_path + '_responder' }
247
+ let result = vm.runInContext(attachFunctionSource(responder_path, input.context, input.func), context, { filename: "(execjs)", displayErrors: true });
248
+ return formatResult(result);
249
+ },
250
+ create: function (input) {
251
+ let context = createCompatibleContext(input.context, input.options);
252
+ let result = vm.runInContext(input.source, context, getContextOptions(input.context));
253
+ return formatResult(result);
254
+ },
255
+ createp: function (input) {
256
+ let context = createPermissiveContext(input.context, input.options);
257
+ let result = vm.runInContext(input.source, context, getContextOptions(input.context));
258
+ return formatResult(result);
259
+ },
260
+ deleteContext: function(uuid) {
261
+ delete contexts[uuid];
262
+ return [1];
263
+ },
264
+ exit: function(code) {
265
+ process_exit = code;
266
+ return ['ok'];
267
+ },
268
+ exec: function (input) {
269
+ let result = vm.runInContext(input.source, getContext(input.context), getContextOptions(input.context));
270
+ return formatResult(result);
271
+ },
272
+ eval: function (input) {
273
+ if (input.source.match(/^\s*{/)) { input.source = "(" + input.source + ")"; }
274
+ else if (input.source.match(/^\s*function\s*\(/)) { input.source = "(" + input.source + ")"; }
275
+ let result = vm.runInContext(input.source, getContext(input.context), getContextOptions(input.context));
276
+ return formatResult(result);
277
+ },
278
+ // ctxo: function (input) {
279
+ // return formatResult(getContextOptions(input.context));
280
+ // },
281
+ };
282
+
283
+ let server = net.createServer(function(s) {
284
+ let received_data = [];
285
+
286
+ s.on('data', function (data) {
287
+ received_data.push(data);
288
+ if (data[data.length - 1] !== 4) { return; }
289
+
290
+ let request = received_data.join('').toString('utf8');
291
+ request = request.substr(0, request.length - 1);
292
+ received_data = [];
293
+
294
+ let input, result;
295
+ let outputJSON = '';
296
+
297
+ try { input = JSON.parse(request); }
298
+ catch(err) {
299
+ outputJSON = JSON.stringify(['err', ['', err].join(''), err.stack]);
300
+ s.write([outputJSON, "\x04"].join(''));
301
+ return;
302
+ }
303
+
304
+ try { result = commands[input.cmd].apply(null, input.args); }
305
+ catch (err) {
306
+ outputJSON = JSON.stringify(['err', ['', err].join(''), massageStackTrace(err.stack)]);
307
+ s.write([outputJSON, "\x04"].join(''));
308
+ return;
309
+ }
310
+
311
+ try { outputJSON = JSON.stringify(result); }
312
+ catch(err) {
313
+ if (err.message.includes('circular')) { outputJSON = CircularJSON.stringify(result); }
314
+ else { outputJSON = JSON.stringify([['', err].join(''), err.stack]); }
315
+ s.write([outputJSON, "\x04"].join(''));
316
+ if (process_exit !== false) { process.exit(process_exit); }
317
+ return;
318
+ }
319
+
320
+ try { s.write([outputJSON, "\x04"].join('')); }
321
+ catch (err) {}
322
+ if (process_exit !== false) { process.exit(process_exit); }
323
+ });
324
+ });
325
+
326
+ if (os.platform().indexOf('win') > -1) { server.listen('\\\\.\\pipe\\' + socket_path); }
327
+ else { server.listen(socket_path); }