@@ -10,6 +10,9 @@ namespace okm {
1010int g_argc = 0 ;
1111char ** g_argv = nullptr ;
1212char ** g_envp = nullptr ;
13+ // Whether SIGPIPE was ignored HERE, at the default this program was started
14+ // with: a program it starts is given the default back (process.cpp).
15+ bool g_pipe_ignored_here = false ;
1316
1417void record (int argc, char ** argv, char ** envp) {
1518 g_argc = argc; g_argv = argv; g_envp = envp;
@@ -41,14 +44,33 @@ namespace {
4144// mistake that shows up as a program dying in a way nobody can trace --- which is
4245// the defect this note is about, arrived at from the other side.
4346//
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.
47+ // ⇒ MEASURED SINCE (0.15): the stop word installs a handler through this
48+ // kernel's `sigaction' with this implementation's own trampoline, and the
49+ // conformance suite raises the signal and returns from it. Ignoring needs no
50+ // trampoline at all --- the kernel never enters one for an ignored signal ---
51+ // so the shape is the measured one and the trampoline field is left empty.
52+ //
53+ // ONLY WHERE NOTHING ELSE HAS CHOSEN. A program whose own runtime installed a
54+ // handler for SIGPIPE keeps it; a disposition still at its default is the one
55+ // that ends the program without telling it, and that is the one replaced.
56+ //
57+ // AND IT IS THIS PROGRAM'S, NOT PASSED ON. An ignored disposition survives
58+ // `execve', so a program started from here would begin with SIGPIPE ignored and
59+ // a shell it runs could not undo it. `kal_process_spawn' gives the default back
60+ // to the program it starts when the ignore was made here (process.cpp).
61+ void ignore_sigpipe () {
62+ struct { void (*handler)(int ); void * tramp; unsigned int mask; int flags; } act{};
63+ struct { void (*handler)(int ); unsigned int mask; int flags; } old{};
64+ if (okm::failed (okm::sys (46 /* sigaction */ , 13 /* SIGPIPE */ , 0 , reinterpret_cast <okm_long>(&old))))
65+ return ;
66+ if (old.handler != nullptr ) return ; // not SIG_DFL
67+ act.handler = reinterpret_cast <void (*)(int )>(1 ); // SIG_IGN
68+ if (!okm::failed (okm::sys (46 /* sigaction */ , 13 , reinterpret_cast <okm_long>(&act), 0 )))
69+ okm::g_pipe_ignored_here = true ;
70+ }
5071[[gnu::constructor(101)]] void capture (int argc, char ** argv, char ** envp) {
5172 if (okm::g_argv == nullptr ) okm::record (argc, argv, envp);
73+ ignore_sigpipe ();
5274}
5375} // namespace
5476
@@ -108,4 +130,42 @@ kal_intptr kal_env_var_at(kal_uintptr index, char* out, kal_uintptr cap) {
108130 return -kal_err_not_found;
109131}
110132
133+ // THE IMAGE THE KERNEL STARTED (0.17): what `proc_pidpath' answers, the
134+ // kernel's record of the file it mapped (`proc_info', PROC_PIDPATHINFO);
135+ // where that is refused, `executable_path=' from the vector this kernel passes
136+ // after the environment, which is the name the kernel was given.
137+ // A program built for its environment was loaded by nothing the interface
138+ // names (clause 12: only an image has a loader to name).
139+ kal_intptr kal_env_loader (char * out, kal_uintptr cap) {
140+ (void )out; (void )cap;
141+ return -kal_err_not_found;
142+ }
143+
144+ kal_intptr kal_env_image (char * out, kal_uintptr cap) {
145+ char buf[4096 ];
146+ const okm_long n = okm::sys (okm::nr_proc_info, 2 /* PROC_INFO_CALL_PIDINFO */ ,
147+ okm::sys (okm::nr_getpid), 11 /* PROC_PIDPATHINFO */ , 0 ,
148+ reinterpret_cast <okm_long>(buf), sizeof buf);
149+ if (!okm::failed (n) && n > 0 ) {
150+ kal_uintptr len = 0 ; while (len < sizeof buf && buf[len] != ' \0 ' ) ++len;
151+ if (len > 0 ) return give (buf, len, out, cap);
152+ }
153+ if (okm::g_envp != nullptr ) {
154+ char ** a = okm::g_envp;
155+ while (*a) ++a;
156+ for (++a; *a; ++a) {
157+ const char key[] = " executable_path=" ;
158+ kal_uintptr i = 0 ;
159+ while (key[i] != ' \0 ' && (*a)[i] == key[i]) ++i;
160+ if (key[i] == ' \0 ' ) return give (*a + i, okm::length (*a + i), out, cap);
161+ }
162+ }
163+ return -kal_err_not_found;
164+ }
165+
166+ // For conventions only, as the declaration restricts it.
167+ kal_intptr kal_env_system (char * out, kal_uintptr cap) {
168+ return give (" macos" , 5 , out, cap);
169+ }
170+
111171}
0 commit comments