Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1952844

Browse filesBrowse files
committed
child_process: support options in send()
This commit adds an options object to process.send(). The same object is propagated to process._send(), the _handleQueue, and the send() and postSend() functions of the handle converter. Fixes: #4271 PR-URL: #5283 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 18abb3c commit 1952844
Copy full SHA for 1952844

File tree

Expand file treeCollapse file tree

4 files changed

+66
-17
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+66
-17
lines changed
Open diff view settings
Collapse file

‎doc/api/child_process.markdown‎

Copy file name to clipboardExpand all lines: doc/api/child_process.markdown
+5-1Lines changed: 5 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -750,10 +750,11 @@ console.log(`Spawned child pid: ${grep.pid}`);
750750
grep.stdin.end();
751751
```
752752

753-
### child.send(message[, sendHandle][, callback])
753+
### child.send(message[, sendHandle[, options]][, callback])
754754

755755
* `message` {Object}
756756
* `sendHandle` {Handle}
757+
* `options` {Object}
757758
* `callback` {Function}
758759
* Return: {Boolean}
759760

@@ -801,6 +802,9 @@ passing a TCP server or socket object to the child process. The child will
801802
receive the object as the second argument passed to the callback function
802803
registered on the `process.on('message')` event.
803804

805+
The `options` argument, if present, is an object used to parameterize the
806+
sending of certain types of handles.
807+
804808
The optional `callback` is a function that is invoked after the message is
805809
sent but before the child may have received it. The function is called with a
806810
single argument: `null` on success, or an [`Error`][] object on failure.
Collapse file

‎doc/api/process.markdown‎

Copy file name to clipboardExpand all lines: doc/api/process.markdown
+2-1Lines changed: 2 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -825,10 +825,11 @@ In custom builds from non-release versions of the source tree, only the
825825
`name` property may be present. The additional properties should not be
826826
relied upon to exist.
827827

828-
## process.send(message[, sendHandle][, callback])
828+
## process.send(message[, sendHandle[, options]][, callback])
829829

830830
* `message` {Object}
831831
* `sendHandle` {Handle object}
832+
* `options` {Object}
832833
* `callback` {Function}
833834
* Return: {Boolean}
834835

Collapse file

‎lib/internal/child_process.js‎

Copy file name to clipboardExpand all lines: lib/internal/child_process.js
+34-15Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const handleConversion = {
3535
'net.Native': {
3636
simultaneousAccepts: true,
3737

38-
send: function(message, handle) {
38+
send: function(message, handle, options) {
3939
return handle;
4040
},
4141

@@ -47,7 +47,7 @@ const handleConversion = {
4747
'net.Server': {
4848
simultaneousAccepts: true,
4949

50-
send: function(message, server) {
50+
send: function(message, server, options) {
5151
return server._handle;
5252
},
5353

@@ -60,7 +60,7 @@ const handleConversion = {
6060
},
6161

6262
'net.Socket': {
63-
send: function(message, socket) {
63+
send: function(message, socket, options) {
6464
if (!socket._handle)
6565
return;
6666

@@ -90,7 +90,7 @@ const handleConversion = {
9090
return handle;
9191
},
9292

93-
postSend: function(handle) {
93+
postSend: function(handle, options) {
9494
// Close the Socket handle after sending it
9595
if (handle)
9696
handle.close();
@@ -117,7 +117,7 @@ const handleConversion = {
117117
'dgram.Native': {
118118
simultaneousAccepts: false,
119119

120-
send: function(message, handle) {
120+
send: function(message, handle, options) {
121121
return handle;
122122
},
123123

@@ -129,7 +129,7 @@ const handleConversion = {
129129
'dgram.Socket': {
130130
simultaneousAccepts: false,
131131

132-
send: function(message, socket) {
132+
send: function(message, socket, options) {
133133
message.dgramType = socket.type;
134134

135135
return socket._handle;
@@ -466,7 +466,7 @@ function setupChannel(target, channel) {
466466
target._handleQueue = null;
467467

468468
queue.forEach(function(args) {
469-
target._send(args.message, args.handle, false, args.callback);
469+
target._send(args.message, args.handle, args.options, args.callback);
470470
});
471471

472472
// Process a pending disconnect (if any).
@@ -498,13 +498,23 @@ function setupChannel(target, channel) {
498498
});
499499
});
500500

501-
target.send = function(message, handle, callback) {
501+
target.send = function(message, handle, options, callback) {
502502
if (typeof handle === 'function') {
503503
callback = handle;
504504
handle = undefined;
505+
options = undefined;
506+
} else if (typeof options === 'function') {
507+
callback = options;
508+
options = undefined;
509+
} else if (options !== undefined &&
510+
(options === null || typeof options !== 'object')) {
511+
throw new TypeError('"options" argument must be an object');
505512
}
513+
514+
options = Object.assign({swallowErrors: false}, options);
515+
506516
if (this.connected) {
507-
return this._send(message, handle, false, callback);
517+
return this._send(message, handle, options, callback);
508518
}
509519
const ex = new Error('channel closed');
510520
if (typeof callback === 'function') {
@@ -515,12 +525,17 @@ function setupChannel(target, channel) {
515525
return false;
516526
};
517527

518-
target._send = function(message, handle, swallowErrors, callback) {
528+
target._send = function(message, handle, options, callback) {
519529
assert(this.connected || this._channel);
520530

521531
if (message === undefined)
522532
throw new TypeError('"message" argument cannot be undefined');
523533

534+
// Support legacy function signature
535+
if (typeof options === 'boolean') {
536+
options = {swallowErrors: options};
537+
}
538+
524539
// package messages with a handle object
525540
if (handle) {
526541
// this message will be handled by an internalMessage event handler
@@ -549,6 +564,7 @@ function setupChannel(target, channel) {
549564
this._handleQueue.push({
550565
callback: callback,
551566
handle: handle,
567+
options: options,
552568
message: message.msg,
553569
});
554570
return this._handleQueue.length === 1;
@@ -557,8 +573,10 @@ function setupChannel(target, channel) {
557573
var obj = handleConversion[message.type];
558574

559575
// convert TCP object to native handle object
560-
handle =
561-
handleConversion[message.type].send.call(target, message, handle);
576+
handle = handleConversion[message.type].send.call(target,
577+
message,
578+
handle,
579+
options);
562580

563581
// If handle was sent twice, or it is impossible to get native handle
564582
// out of it - just send a text without the handle.
@@ -575,6 +593,7 @@ function setupChannel(target, channel) {
575593
this._handleQueue.push({
576594
callback: callback,
577595
handle: null,
596+
options: options,
578597
message: message,
579598
});
580599
return this._handleQueue.length === 1;
@@ -593,7 +612,7 @@ function setupChannel(target, channel) {
593612
if (this.async === true)
594613
control.unref();
595614
if (obj && obj.postSend)
596-
obj.postSend(handle);
615+
obj.postSend(handle, options);
597616
if (typeof callback === 'function')
598617
callback(null);
599618
};
@@ -605,9 +624,9 @@ function setupChannel(target, channel) {
605624
} else {
606625
// Cleanup handle on error
607626
if (obj && obj.postSend)
608-
obj.postSend(handle);
627+
obj.postSend(handle, options);
609628

610-
if (!swallowErrors) {
629+
if (!options.swallowErrors) {
611630
const ex = errnoException(err, 'write');
612631
if (typeof callback === 'function') {
613632
process.nextTick(callback, ex);
Collapse file
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const cp = require('child_process');
5+
6+
function noop() {}
7+
8+
function fail(proc, args) {
9+
assert.throws(() => {
10+
proc.send.apply(proc, args);
11+
}, /"options" argument must be an object/);
12+
}
13+
14+
let target = process;
15+
16+
if (process.argv[2] !== 'child')
17+
target = cp.fork(__filename, ['child']);
18+
19+
fail(target, ['msg', null, null]);
20+
fail(target, ['msg', null, '']);
21+
fail(target, ['msg', null, 'foo']);
22+
fail(target, ['msg', null, 0]);
23+
fail(target, ['msg', null, NaN]);
24+
fail(target, ['msg', null, 1]);
25+
fail(target, ['msg', null, null, noop]);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.