summaryrefslogtreecommitdiff
path: root/js/process.ts
diff options
context:
space:
mode:
Diffstat (limited to 'js/process.ts')
-rw-r--r--js/process.ts307
1 files changed, 0 insertions, 307 deletions
diff --git a/js/process.ts b/js/process.ts
deleted file mode 100644
index 0c77929f9..000000000
--- a/js/process.ts
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-import * as dispatch from "./dispatch.ts";
-import { File, close } from "./files.ts";
-import { ReadCloser, WriteCloser } from "./io.ts";
-import { readAll } from "./buffer.ts";
-import { assert, unreachable } from "./util.ts";
-import { build } from "./build.ts";
-
-/** How to handle subprocess stdio.
- *
- * "inherit" The default if unspecified. The child inherits from the
- * corresponding parent descriptor.
- *
- * "piped" A new pipe should be arranged to connect the parent and child
- * subprocesses.
- *
- * "null" This stream will be ignored. This is the equivalent of attaching the
- * stream to /dev/null.
- */
-export type ProcessStdio = "inherit" | "piped" | "null";
-
-// TODO Maybe extend VSCode's 'CommandOptions'?
-// See https://code.visualstudio.com/docs/editor/tasks-appendix#_schema-for-tasksjson
-export interface RunOptions {
- args: string[];
- cwd?: string;
- env?: { [key: string]: string };
- stdout?: ProcessStdio | number;
- stderr?: ProcessStdio | number;
- stdin?: ProcessStdio | number;
-}
-
-interface RunStatusResponse {
- gotSignal: boolean;
- exitCode: number;
- exitSignal: number;
-}
-
-async function runStatus(rid: number): Promise<ProcessStatus> {
- const res = (await sendAsync(dispatch.OP_RUN_STATUS, {
- rid
- })) as RunStatusResponse;
-
- if (res.gotSignal) {
- const signal = res.exitSignal;
- return { signal, success: false };
- } else {
- const code = res.exitCode;
- return { code, success: code === 0 };
- }
-}
-
-/** Send a signal to process under given PID. Unix only at this moment.
- * If pid is negative, the signal will be sent to the process group identified
- * by -pid.
- * Requires the `--allow-run` flag.
- */
-export function kill(pid: number, signo: number): void {
- sendSync(dispatch.OP_KILL, { pid, signo });
-}
-
-export class Process {
- readonly rid: number;
- readonly pid: number;
- readonly stdin?: WriteCloser;
- readonly stdout?: ReadCloser;
- readonly stderr?: ReadCloser;
-
- // @internal
- constructor(res: RunResponse) {
- this.rid = res.rid;
- this.pid = res.pid;
-
- if (res.stdinRid && res.stdinRid > 0) {
- this.stdin = new File(res.stdinRid);
- }
-
- if (res.stdoutRid && res.stdoutRid > 0) {
- this.stdout = new File(res.stdoutRid);
- }
-
- if (res.stderrRid && res.stderrRid > 0) {
- this.stderr = new File(res.stderrRid);
- }
- }
-
- async status(): Promise<ProcessStatus> {
- return await runStatus(this.rid);
- }
-
- /** Buffer the stdout and return it as Uint8Array after EOF.
- * You must set stdout to "piped" when creating the process.
- * This calls close() on stdout after its done.
- */
- async output(): Promise<Uint8Array> {
- if (!this.stdout) {
- throw new Error("Process.output: stdout is undefined");
- }
- try {
- return await readAll(this.stdout);
- } finally {
- this.stdout.close();
- }
- }
-
- /** Buffer the stderr and return it as Uint8Array after EOF.
- * You must set stderr to "piped" when creating the process.
- * This calls close() on stderr after its done.
- */
- async stderrOutput(): Promise<Uint8Array> {
- if (!this.stderr) {
- throw new Error("Process.stderrOutput: stderr is undefined");
- }
- try {
- return await readAll(this.stderr);
- } finally {
- this.stderr.close();
- }
- }
-
- close(): void {
- close(this.rid);
- }
-
- kill(signo: number): void {
- kill(this.pid, signo);
- }
-}
-
-export interface ProcessStatus {
- success: boolean;
- code?: number;
- signal?: number; // TODO: Make this a string, e.g. 'SIGTERM'.
-}
-
-// TODO: this method is only used to validate proper option, probably can be renamed
-function stdioMap(s: string): string {
- switch (s) {
- case "inherit":
- case "piped":
- case "null":
- return s;
- default:
- return unreachable();
- }
-}
-
-function isRid(arg: unknown): arg is number {
- return !isNaN(arg as number);
-}
-
-interface RunResponse {
- rid: number;
- pid: number;
- stdinRid: number | null;
- stdoutRid: number | null;
- stderrRid: number | null;
-}
-/**
- * Spawns new subprocess.
- *
- * Subprocess uses same working directory as parent process unless `opt.cwd`
- * is specified.
- *
- * Environmental variables for subprocess can be specified using `opt.env`
- * mapping.
- *
- * By default subprocess inherits stdio of parent process. To change that
- * `opt.stdout`, `opt.stderr` and `opt.stdin` can be specified independently -
- * they can be set to either `ProcessStdio` or `rid` of open file.
- */
-export function run(opt: RunOptions): Process {
- assert(opt.args.length > 0);
- let env: Array<[string, string]> = [];
- if (opt.env) {
- env = Array.from(Object.entries(opt.env));
- }
-
- let stdin = stdioMap("inherit");
- let stdout = stdioMap("inherit");
- let stderr = stdioMap("inherit");
- let stdinRid = 0;
- let stdoutRid = 0;
- let stderrRid = 0;
-
- if (opt.stdin) {
- if (isRid(opt.stdin)) {
- stdinRid = opt.stdin;
- } else {
- stdin = stdioMap(opt.stdin);
- }
- }
-
- if (opt.stdout) {
- if (isRid(opt.stdout)) {
- stdoutRid = opt.stdout;
- } else {
- stdout = stdioMap(opt.stdout);
- }
- }
-
- if (opt.stderr) {
- if (isRid(opt.stderr)) {
- stderrRid = opt.stderr;
- } else {
- stderr = stdioMap(opt.stderr);
- }
- }
-
- const req = {
- args: opt.args.map(String),
- cwd: opt.cwd,
- env,
- stdin,
- stdout,
- stderr,
- stdinRid,
- stdoutRid,
- stderrRid
- };
-
- const res = sendSync(dispatch.OP_RUN, req) as RunResponse;
- return new Process(res);
-}
-
-// From `kill -l`
-enum LinuxSignal {
- SIGHUP = 1,
- SIGINT = 2,
- SIGQUIT = 3,
- SIGILL = 4,
- SIGTRAP = 5,
- SIGABRT = 6,
- SIGBUS = 7,
- SIGFPE = 8,
- SIGKILL = 9,
- SIGUSR1 = 10,
- SIGSEGV = 11,
- SIGUSR2 = 12,
- SIGPIPE = 13,
- SIGALRM = 14,
- SIGTERM = 15,
- SIGSTKFLT = 16,
- SIGCHLD = 17,
- SIGCONT = 18,
- SIGSTOP = 19,
- SIGTSTP = 20,
- SIGTTIN = 21,
- SIGTTOU = 22,
- SIGURG = 23,
- SIGXCPU = 24,
- SIGXFSZ = 25,
- SIGVTALRM = 26,
- SIGPROF = 27,
- SIGWINCH = 28,
- SIGIO = 29,
- SIGPWR = 30,
- SIGSYS = 31
-}
-
-// From `kill -l`
-enum MacOSSignal {
- SIGHUP = 1,
- SIGINT = 2,
- SIGQUIT = 3,
- SIGILL = 4,
- SIGTRAP = 5,
- SIGABRT = 6,
- SIGEMT = 7,
- SIGFPE = 8,
- SIGKILL = 9,
- SIGBUS = 10,
- SIGSEGV = 11,
- SIGSYS = 12,
- SIGPIPE = 13,
- SIGALRM = 14,
- SIGTERM = 15,
- SIGURG = 16,
- SIGSTOP = 17,
- SIGTSTP = 18,
- SIGCONT = 19,
- SIGCHLD = 20,
- SIGTTIN = 21,
- SIGTTOU = 22,
- SIGIO = 23,
- SIGXCPU = 24,
- SIGXFSZ = 25,
- SIGVTALRM = 26,
- SIGPROF = 27,
- SIGWINCH = 28,
- SIGINFO = 29,
- SIGUSR1 = 30,
- SIGUSR2 = 31
-}
-
-/** Signals numbers. This is platform dependent.
- */
-export const Signal = {};
-
-export function setSignals(): void {
- if (build.os === "mac") {
- Object.assign(Signal, MacOSSignal);
- } else {
- Object.assign(Signal, LinuxSignal);
- }
-}