2020-01-24 08:15:31 -05:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
2020-03-09 10:18:02 -04:00
|
|
|
import { bindSignal, pollSignal, unbindSignal } from "./ops/signal.ts";
|
2020-01-24 08:15:31 -05:00
|
|
|
import { build } from "./build.ts";
|
|
|
|
|
2020-03-11 10:49:53 -04:00
|
|
|
// 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,
|
2020-03-28 13:03:49 -04:00
|
|
|
SIGSYS = 31,
|
2020-03-11 10:49:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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,
|
2020-03-28 13:03:49 -04:00
|
|
|
SIGUSR2 = 31,
|
2020-03-11 10:49:53 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export const Signal: { [key: string]: number } = {};
|
|
|
|
|
|
|
|
export function setSignals(): void {
|
|
|
|
if (build.os === "mac") {
|
|
|
|
Object.assign(Signal, MacOSSignal);
|
|
|
|
} else {
|
|
|
|
Object.assign(Signal, LinuxSignal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-24 08:15:31 -05:00
|
|
|
export function signal(signo: number): SignalStream {
|
|
|
|
if (build.os === "win") {
|
|
|
|
throw new Error("not implemented!");
|
|
|
|
}
|
|
|
|
return new SignalStream(signo);
|
|
|
|
}
|
|
|
|
|
|
|
|
export const signals = {
|
|
|
|
alarm(): SignalStream {
|
|
|
|
return signal(Signal.SIGALRM);
|
|
|
|
},
|
|
|
|
child(): SignalStream {
|
|
|
|
return signal(Signal.SIGCHLD);
|
|
|
|
},
|
|
|
|
hungup(): SignalStream {
|
|
|
|
return signal(Signal.SIGHUP);
|
|
|
|
},
|
|
|
|
interrupt(): SignalStream {
|
|
|
|
return signal(Signal.SIGINT);
|
|
|
|
},
|
|
|
|
io(): SignalStream {
|
|
|
|
return signal(Signal.SIGIO);
|
|
|
|
},
|
|
|
|
pipe(): SignalStream {
|
|
|
|
return signal(Signal.SIGPIPE);
|
|
|
|
},
|
|
|
|
quit(): SignalStream {
|
|
|
|
return signal(Signal.SIGQUIT);
|
|
|
|
},
|
|
|
|
terminate(): SignalStream {
|
|
|
|
return signal(Signal.SIGTERM);
|
|
|
|
},
|
|
|
|
userDefined1(): SignalStream {
|
|
|
|
return signal(Signal.SIGUSR1);
|
|
|
|
},
|
|
|
|
userDefined2(): SignalStream {
|
|
|
|
return signal(Signal.SIGUSR2);
|
|
|
|
},
|
|
|
|
windowChange(): SignalStream {
|
|
|
|
return signal(Signal.SIGWINCH);
|
2020-03-28 13:03:49 -04:00
|
|
|
},
|
2020-01-24 08:15:31 -05:00
|
|
|
};
|
|
|
|
|
2020-02-07 01:53:15 -05:00
|
|
|
export class SignalStream
|
|
|
|
implements AsyncIterableIterator<void>, PromiseLike<void> {
|
2020-03-28 13:03:49 -04:00
|
|
|
#disposed = false;
|
|
|
|
#pollingPromise: Promise<boolean> = Promise.resolve(false);
|
|
|
|
#rid: number;
|
|
|
|
|
2020-01-24 08:15:31 -05:00
|
|
|
constructor(signo: number) {
|
2020-03-28 13:03:49 -04:00
|
|
|
this.#rid = bindSignal(signo).rid;
|
|
|
|
this.#loop();
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
2020-03-28 13:03:49 -04:00
|
|
|
#pollSignal = async (): Promise<boolean> => {
|
|
|
|
const res = await pollSignal(this.#rid);
|
2020-03-09 10:18:02 -04:00
|
|
|
return res.done;
|
2020-03-28 13:03:49 -04:00
|
|
|
};
|
2020-01-24 08:15:31 -05:00
|
|
|
|
2020-03-28 13:03:49 -04:00
|
|
|
#loop = async (): Promise<void> => {
|
2020-01-24 08:15:31 -05:00
|
|
|
do {
|
2020-03-28 13:03:49 -04:00
|
|
|
this.#pollingPromise = this.#pollSignal();
|
|
|
|
} while (!(await this.#pollingPromise) && !this.#disposed);
|
|
|
|
};
|
2020-01-24 08:15:31 -05:00
|
|
|
|
|
|
|
then<T, S>(
|
|
|
|
f: (v: void) => T | Promise<T>,
|
|
|
|
g?: (v: Error) => S | Promise<S>
|
|
|
|
): Promise<T | S> {
|
2020-03-28 13:03:49 -04:00
|
|
|
return this.#pollingPromise.then(() => {}).then(f, g);
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
async next(): Promise<IteratorResult<void>> {
|
2020-03-28 13:03:49 -04:00
|
|
|
return { done: await this.#pollingPromise, value: undefined };
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
2020-02-07 01:53:15 -05:00
|
|
|
[Symbol.asyncIterator](): AsyncIterableIterator<void> {
|
2020-01-24 08:15:31 -05:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
dispose(): void {
|
2020-03-28 13:03:49 -04:00
|
|
|
if (this.#disposed) {
|
2020-01-24 08:15:31 -05:00
|
|
|
throw new Error("The stream has already been disposed.");
|
|
|
|
}
|
2020-03-28 13:03:49 -04:00
|
|
|
this.#disposed = true;
|
|
|
|
unbindSignal(this.#rid);
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
}
|