Skip to content

Commit 67f62e4

Browse files
committed
Take up the unit as a handle, and record the SIGPIPE this cannot yet quiet
`kal_spawn.job' and `kal_process_job_enter' are both `setpgid' here: the unit's identity is the first member's, reported back to the caller. `job_terminate' uses the signal that cannot be declined --- a unit contains programs the caller never held a handle to, so a request any member may ignore does not terminate it. ⚠️⚠️ AND A DEFECT IS RECORDED RATHER THAN GUESSED AT. openkal defines no signals, and `kal_stream_write' is required to REPORT that a stream's far end is gone --- while this kernel delivers SIGPIPE, whose default action ends the program. A C library above answers `signal(SIGPIPE, SIG_IGN)' truthfully, having nothing to set, and the program is killed anyway by a mechanism no layer between can name. openkal-linux now ignores it in one call at startup. This kernel's `sigaction' takes a structure carrying a trampoline its C library supplies, and a disposition installed with the wrong shape shows up as a program dying in a way nobody can trace --- which is the defect this note is about, arrived at from the other side. So it waits until it can be MEASURED here, and the consequence is stated in the file rather than discovered by whoever meets it.
1 parent e0634b4 commit 67f62e4

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

src/env.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,35 @@ void record(int argc, char** argv, char** envp) {
1818
} // namespace okm
1919

2020
namespace {
21+
22+
// ⚠️⚠️ A PROGRAM ABOVE openkal SHALL NOT BE ENDED BY SOMETHING openkal NEVER TOLD
23+
// IT ABOUT. openkal defines no signals, and `kal_stream_write' is required to
24+
// REPORT that the far end of a stream is gone --- while this kernel delivers
25+
// SIGPIPE, whose default action ends the program instead.
26+
//
27+
// ⭐ A C library above answers `signal(SIGPIPE, SIG_IGN)' truthfully, because
28+
// openkal has no signals and there is nothing for it to set; the program is then
29+
// killed anyway, by a mechanism no layer between it and here can name. Ignored
30+
// at this level because this is the only level that can. Found on the other
31+
// implementation, fixed on both --- a divergence here would be the same defect
32+
// with a different exit status.
33+
//
34+
// ⚠️ Not a policy about signals in general: this is the one an ordinary openkal
35+
// operation provokes.
36+
//
37+
// ⚠️⚠️ AND IT IS NOT FIXED HERE YET, WHICH IS RECORDED RATHER THAN LEFT TO BE
38+
// DISCOVERED. openkal-linux ignores it in one call. This kernel's `sigaction'
39+
// takes a `struct __sigaction' carrying a TRAMPOLINE that its C library
40+
// supplies, and a disposition installed with the wrong shape is the kind of
41+
// mistake that shows up as a program dying in a way nobody can trace --- which is
42+
// the defect this note is about, arrived at from the other side.
43+
//
44+
// ⇒ It is left until it can be MEASURED on this system. This repository already
45+
// refuses to claim a facility it has not exercised, and a signal disposition
46+
// installed by guesswork is exactly that. The consequence meanwhile is stated:
47+
// a program above this implementation that writes to a stream whose far end has
48+
// gone is ended by SIGPIPE rather than told, and no layer between it and here
49+
// can name what happened.
2150
[[gnu::constructor(101)]] void capture(int argc, char** argv, char** envp) {
2251
if (okm::g_argv == nullptr) okm::record(argc, argv, envp);
2352
}

src/process.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,18 @@ int kal_process_terminate(kal_process h) {
236236
return okm::failed(r) ? okm::translate(r) : kal_ok;
237237
}
238238

239+
// This program itself joins or forms a unit --- what `kal_spawn.job' cannot say,
240+
// because that places a program the caller STARTS and a copy wishing to lead a
241+
// unit must say so about ITSELF before it replaces itself.
242+
int kal_process_job_enter(kal_job* j) {
243+
if (j == nullptr) return kal_err_invalid;
244+
const okm_long join = static_cast<okm_long>(j->h);
245+
const okm_long r = okm::sys(nr_setpgid, 0, join);
246+
if (okm::failed(r)) return okm::translate(r);
247+
if (join == 0) j->h = static_cast<kal_uintptr>(okm::sys(okm::nr_getpid));
248+
return kal_ok;
249+
}
250+
239251
// Every program in the unit, including ones never held as a handle.
240252
//
241253
// ⚠️ A group is named by a process identifier, and those are reused: once the
@@ -244,7 +256,10 @@ int kal_process_terminate(kal_process h) {
244256
// than hidden.
245257
int kal_process_job_terminate(kal_job j) {
246258
if (j.h == 0) return kal_err_invalid;
247-
const okm_long r = okm::sys(okm::nr_kill, -static_cast<okm_long>(j.h), 15 /* SIGTERM */);
259+
// The signal that cannot be declined --- see openkal-linux for the reasoning:
260+
// a unit contains programs the caller never held a handle to, so a request any
261+
// member may ignore does not terminate the unit.
262+
const okm_long r = okm::sys(okm::nr_kill, -static_cast<okm_long>(j.h), 9 /* SIGKILL */);
248263
return okm::failed(r) ? okm::translate(r) : kal_ok;
249264
}
250265

0 commit comments

Comments
 (0)