Skip to content

Commit e7c5a36

Browse files
committed
util.js: Add spawnAsyncIO.
The spawnCommandLineAsyncIO function also accepts an argv instead of a string but its usage is obscure and nearly unused.
1 parent 7190db1 commit e7c5a36

1 file changed

Lines changed: 50 additions & 18 deletions

File tree

js/misc/util.js

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,52 @@ function spawnCommandLineAsync(command_line, callback, errback) {
215215
});
216216
}
217217

218+
function _runSubprocessAsyncIO(subprocess, callback, input, stripBash) {
219+
subprocess.init(null);
220+
let cancellable = new Gio.Cancellable();
221+
222+
subprocess.communicate_utf8_async(input, cancellable, (obj, res) => {
223+
let success, stdout, stderr, exitCode;
224+
// This will throw on cancel with "Gio.IOErrorEnum: Operation was cancelled"
225+
tryFn(() => [success, stdout, stderr] = obj.communicate_utf8_finish(res));
226+
if (typeof callback === 'function' && !cancellable.is_cancelled()) {
227+
if (stripBash && stderr && stderr.indexOf('bash: ') > -1) {
228+
stderr = stderr.replace(/bash: /, '');
229+
}
230+
exitCode = success ? subprocess.get_exit_status() : -1;
231+
callback(stdout, stderr, exitCode);
232+
}
233+
subprocess.cancellable = null;
234+
});
235+
subprocess.cancellable = cancellable;
236+
237+
return subprocess;
238+
}
239+
240+
/**
241+
* spawnAsyncIO:
242+
* @argv: an argument array
243+
* @callback (function): called on success or failure
244+
* @opts (object): options: flags, input
245+
*
246+
* Runs @argv in the background. Callback has three arguments -
247+
* stdout, stderr, and exitCode.
248+
*
249+
* Returns (object): a Gio.Subprocess instance
250+
*/
251+
function spawnAsyncIO(argv, callback, opts = {}) {
252+
let {flags, input} = opts;
253+
if (!input) input = null;
254+
255+
let subprocess = new Gio.Subprocess({
256+
argv: argv,
257+
flags: flags ? flags
258+
: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDERR_PIPE,
259+
});
260+
261+
return _runSubprocessAsyncIO(subprocess, callback, input, false);
262+
}
263+
218264
/**
219265
* spawnCommandLineAsyncIO:
220266
* @command: a command
@@ -224,6 +270,9 @@ function spawnCommandLineAsync(command_line, callback, errback) {
224270
* Runs @command in the background. Callback has three arguments -
225271
* stdout, stderr, and exitCode.
226272
*
273+
* If you have an argument array instead of a command string, use
274+
* spawnAsyncIO() instead.
275+
*
227276
* Returns (object): a Gio.Subprocess instance
228277
*/
229278
function spawnCommandLineAsyncIO(command, callback, opts = {}) {
@@ -235,25 +284,8 @@ function spawnCommandLineAsyncIO(command, callback, opts = {}) {
235284
flags: flags ? flags
236285
: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDERR_PIPE,
237286
});
238-
subprocess.init(null);
239-
let cancellable = new Gio.Cancellable();
240287

241-
subprocess.communicate_utf8_async(input, cancellable, (obj, res) => {
242-
let success, stdout, stderr, exitCode;
243-
// This will throw on cancel with "Gio.IOErrorEnum: Operation was cancelled"
244-
tryFn(() => [success, stdout, stderr] = obj.communicate_utf8_finish(res));
245-
if (typeof callback === 'function' && !cancellable.is_cancelled()) {
246-
if (stderr && stderr.indexOf('bash: ') > -1) {
247-
stderr = stderr.replace(/bash: /, '');
248-
}
249-
exitCode = success ? subprocess.get_exit_status() : -1;
250-
callback(stdout, stderr, exitCode);
251-
}
252-
subprocess.cancellable = null;
253-
});
254-
subprocess.cancellable = cancellable;
255-
256-
return subprocess;
288+
return _runSubprocessAsyncIO(subprocess, callback, input, !argv);
257289
}
258290

259291
function _handleSpawnError(command, err) {

0 commit comments

Comments
 (0)