diff --git a/README.md b/README.md index 326ded8..f4c4bce 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ for Linux, written on the kernel's own system-call interface. openkal = "0.17.0" [target.'cfg(os = "linux")'.dependencies] -openkal-linux = "0.18.0" +openkal-linux = "0.18.1" ``` ## Why it does not use a C library diff --git a/mcpp.toml b/mcpp.toml index fd3961b..087ba2f 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-linux" -version = "0.18.0" +version = "0.18.1" description = "The reference implementation of openkal for Linux, written on the kernel's own system-call interface so that it can be placed beneath a C library as well as above one." license = "Apache-2.0" diff --git a/src/process.cpp b/src/process.cpp index 623f58f..81e9b50 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -951,7 +951,11 @@ const kal_u32* kal_process_stop_requested(void) { // caller is told what the first found rather than arming again. int state = __atomic_load_n(&g_stop_armed, __ATOMIC_ACQUIRE); if (state == 0) { - const bool ok = arm_one(15) && arm_one(2); // SIGTERM, SIGINT + // SIGTERM, SIGINT and SIGHUP (0.18.1): the terminal that started a + // program closing is a request to end it as much as the other two, and + // a program that took the requests over and not this one was ended by + // it before it could finish in order. + const bool ok = arm_one(15) && arm_one(2) && arm_one(1); state = ok ? 1 : -1; __atomic_store_n(&g_stop_armed, state, __ATOMIC_RELEASE); } diff --git a/tests/stop_word_take_over.cpp b/tests/stop_word_take_over.cpp index 1134b70..a515108 100644 --- a/tests/stop_word_take_over.cpp +++ b/tests/stop_word_take_over.cpp @@ -25,6 +25,17 @@ void check(bool held, const char* what) { } int main(int argc, char** argv) { + if (argc > 1 && std::strcmp(argv[1], "--hang-up") == 0) { + // 0.18.1: the closing of the terminal is a request to end, taken over + // with the others, and the program ends as it would have. + const kal_u32* word = kal_process_stop_requested(); + if (word == nullptr) return 90; + ::kill(::getpid(), SIGHUP); + for (int i = 0; i < 1000 && *word == 0; ++i) ::usleep(1000); + if (*word == 0) return 91; + kal_process_end_as_requested(); + return 92; + } if (argc > 1 && std::strcmp(argv[1], "--end-as-requested") == 0) { const kal_u32* word = kal_process_stop_requested(); if (word == nullptr) return 90; @@ -58,6 +69,16 @@ int main(int argc, char** argv) { check(WIFSIGNALED(st) && WTERMSIG(st) == SIGTERM, "a program that ends as requested is reported to its starter as ended by the request"); + const pid_t hung = ::fork(); + if (hung == 0) { + ::execl("/proc/self/exe", argv[0], "--hang-up", nullptr); + ::_exit(93); + } + st = 0; + ::waitpid(hung, &st, 0); + check(WIFSIGNALED(st) && WTERMSIG(st) == SIGHUP, + "a hang-up is taken over as a request, and the program ends as it would have"); + if (failures == 0) std::printf("openkal-linux: the stop word is taken over and given back\n"); return failures == 0 ? 0 : 1; }