Blame


1 ae2955a0 2023-12-19 op // This is free and unencumbered software released into the public domain.
2 ae2955a0 2023-12-19 op //
3 ae2955a0 2023-12-19 op // Anyone is free to copy, modify, publish, use, compile, sell, or
4 ae2955a0 2023-12-19 op // distribute this software, either in source code form or as a compiled
5 ae2955a0 2023-12-19 op // binary, for any purpose, commercial or non-commercial, and by any
6 ae2955a0 2023-12-19 op // means.
7 ae2955a0 2023-12-19 op //
8 ae2955a0 2023-12-19 op // In jurisdictions that recognize copyright laws, the author or authors
9 ae2955a0 2023-12-19 op // of this software dedicate any and all copyright interest in the
10 ae2955a0 2023-12-19 op // software to the public domain. We make this dedication for the benefit
11 ae2955a0 2023-12-19 op // of the public at large and to the detriment of our heirs and
12 ae2955a0 2023-12-19 op // successors. We intend this dedication to be an overt act of
13 ae2955a0 2023-12-19 op // relinquishment in perpetuity of all present and future rights to this
14 ae2955a0 2023-12-19 op // software under copyright law.
15 ae2955a0 2023-12-19 op //
16 ae2955a0 2023-12-19 op // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 ae2955a0 2023-12-19 op // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 ae2955a0 2023-12-19 op // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 ae2955a0 2023-12-19 op // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 ae2955a0 2023-12-19 op // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 ae2955a0 2023-12-19 op // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 ae2955a0 2023-12-19 op // OTHER DEALINGS IN THE SOFTWARE.
23 ae2955a0 2023-12-19 op
24 ae2955a0 2023-12-19 op use errors;
25 ae2955a0 2023-12-19 op use io;
26 ae2955a0 2023-12-19 op use rt;
27 ae2955a0 2023-12-19 op use unix::signal;
28 ae2955a0 2023-12-19 op use unix;
29 ae2955a0 2023-12-19 op
30 ae2955a0 2023-12-19 op // In theory we could use TLS to store an event base per-thread and
31 ae2955a0 2023-12-19 op // then we could have a per-thread signal cacher machinery. In
32 ae2955a0 2023-12-19 op // practice, we only provide signal catching for the global event
33 ae2955a0 2023-12-19 op // loop.
34 ae2955a0 2023-12-19 op
35 ae2955a0 2023-12-19 op fn sigcatch(
36 ae2955a0 2023-12-19 op sig: signal::sig,
37 ae2955a0 2023-12-19 op info: *signal::siginfo,
38 ae2955a0 2023-12-19 op ctx: *opaque
39 ae2955a0 2023-12-19 op ) void = {
40 ae2955a0 2023-12-19 op // We should be able to write up to PIPE_BUF bytes without
41 ae2955a0 2023-12-19 op // blocking.
42 ae2955a0 2023-12-19 op let no = sig: u8;
43 ae2955a0 2023-12-19 op
44 ae2955a0 2023-12-19 op // read, write
45 ae2955a0 2023-12-19 op let pipe: (io::file, io::file) = match(global.sigpipe) {
46 ae2955a0 2023-12-19 op case void =>
47 ae2955a0 2023-12-19 op // this can't happen
48 ae2955a0 2023-12-19 op return;
49 ae2955a0 2023-12-19 op case let pipe: (io::file, io::file) =>
50 ae2955a0 2023-12-19 op yield pipe;
51 ae2955a0 2023-12-19 op };
52 ae2955a0 2023-12-19 op
53 ae2955a0 2023-12-19 op // TODO how to save and restore errno?
54 ae2955a0 2023-12-19 op match (rt::write(pipe.1, &no, size(u8))) {
55 ae2955a0 2023-12-19 op case =>
56 ae2955a0 2023-12-19 op // can't do anything about it.
57 ae2955a0 2023-12-19 op return;
58 ae2955a0 2023-12-19 op };
59 ae2955a0 2023-12-19 op };
60 ae2955a0 2023-12-19 op
61 ae2955a0 2023-12-19 op fn sigdispatch(fd: io::file, ev: event, data: nullable *opaque) void = {
62 ae2955a0 2023-12-19 op let no: u8 = 0;
63 ae2955a0 2023-12-19 op
64 ae2955a0 2023-12-19 op // read, write
65 ae2955a0 2023-12-19 op let pipe = global.sigpipe as (io::file, io::file);
66 ae2955a0 2023-12-19 op
67 ae2955a0 2023-12-19 op match (rt::read(pipe.0, &no, size(u8))) {
68 ae2955a0 2023-12-19 op case let err: rt::errno =>
69 ae2955a0 2023-12-19 op // can't do much about.
70 ae2955a0 2023-12-19 op return;
71 ae2955a0 2023-12-19 op case => yield;
72 ae2955a0 2023-12-19 op };
73 ae2955a0 2023-12-19 op
74 ae2955a0 2023-12-19 op let sigcb = global.sigcb as *fn(signal::sig, nullable *opaque) void;
75 ae2955a0 2023-12-19 op sigcb(no: signal::sig, global.sigdata);
76 ae2955a0 2023-12-19 op };
77 ae2955a0 2023-12-19 op
78 ae2955a0 2023-12-19 op export fn signal(
79 ae2955a0 2023-12-19 op sig: signal::sig,
80 ae2955a0 2023-12-19 op cb: *fn(signal::sig, nullable *opaque) void,
81 ae2955a0 2023-12-19 op data: nullable *opaque
82 ae2955a0 2023-12-19 op ) (void | errors::error) = {
83 ae2955a0 2023-12-19 op if (global.sigpipe is void) {
84 ae2955a0 2023-12-19 op // XXX NOCLOEXEC is O_CLOEXEC or means "do not close-on-exec"?
85 ae2955a0 2023-12-19 op // read, write
86 ae2955a0 2023-12-19 op let pipe = unix::pipe(
87 ae2955a0 2023-12-19 op unix::pipe_flag::NONBLOCK | unix::pipe_flag::NOCLOEXEC
88 ae2955a0 2023-12-19 op )?;
89 ae2955a0 2023-12-19 op global.sigpipe = pipe;
90 ae2955a0 2023-12-19 op add(pipe.0, READ, &sigdispatch, null);
91 ae2955a0 2023-12-19 op };
92 ae2955a0 2023-12-19 op
93 ae2955a0 2023-12-19 op global.sigcb = cb;
94 ae2955a0 2023-12-19 op global.sigdata = data;
95 ae2955a0 2023-12-19 op
96 ae2955a0 2023-12-19 op signal::handle(sig, &sigcatch);
97 ae2955a0 2023-12-19 op };