]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
kill: (test) add a case for testing -l 0xSIGMASK and -d $PID options
authorMasatake YAMATO <yamato@redhat.com>
Sun, 7 Jul 2024 17:53:52 +0000 (02:53 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Mon, 8 Jul 2024 08:55:37 +0000 (17:55 +0900)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
meson.build
tests/commands.sh
tests/expected/kill/decode [new file with mode: 0644]
tests/helpers/Makemodule.am
tests/helpers/test_sigstate.c [new file with mode: 0644]
tests/ts/kill/decode [new file with mode: 0755]

index 883e79ad607c389e88c5467e36ac5d188174cab5..85c91e1c15b82f29b68b3e1df632005737e5d398 100644 (file)
@@ -3649,6 +3649,14 @@ exe = executable(
   build_by_default: program_tests)
 exes += exe
 
+exe = executable(
+  'test_sigstate',
+  'tests/helpers/test_sigstate.c',
+  include_directories : includes,
+  link_with : lib_common,
+  build_by_default: program_tests)
+exes += exe
+
 exe = executable(
   'test_tiocsti',
   'tests/helpers/test_tiocsti.c',
index 3af675962ac8f958f9b5d9f05e4c9871c59b6244..3febcbc6321327e1622c5df4cef29dcb4a2f34b7 100644 (file)
@@ -47,6 +47,7 @@ TS_HELPER_PARTITIONS="${ts_helpersdir}sample-partitions"
 TS_HELPER_PATHS="${ts_helpersdir}test_pathnames"
 TS_HELPER_SCRIPT="${ts_helpersdir}test_script"
 TS_HELPER_SIGRECEIVE="${ts_helpersdir}test_sigreceive"
+TS_HELPER_SIGSTATE="${ts_helpersdir}test_sigstate"
 TS_HELPER_STRERROR="${ts_helpersdir}test_strerror"
 TS_HELPER_STRUTILS="${ts_helpersdir}test_strutils"
 TS_HELPER_SYSINFO="${ts_helpersdir}test_sysinfo"
diff --git a/tests/expected/kill/decode b/tests/expected/kill/decode
new file mode 100644 (file)
index 0000000..74783ad
--- /dev/null
@@ -0,0 +1,20 @@
+decode "0x00000000000044aa":
+INT
+ILL
+ABRT
+FPE
+SEGV
+TERM
+decode "0x0000000000003015":
+HUP
+QUIT
+TRAP
+PIPE
+ALRM
+decode "0x0000000000000200":
+USR1
+Pending (thread): INT ILL 
+Pending (process): USR1 
+Blocked: INT ILL ABRT FPE USR1 SEGV TERM 
+Ignored: HUP QUIT TRAP PIPE ALRM 
+Caught: ILL USR1 
index 67a1d3d096161680455f83afcd16468927d40e29..fac8608cd28c8162e938074e468975a06d36bbbf 100644 (file)
@@ -24,6 +24,10 @@ check_PROGRAMS += test_sigreceive
 test_sigreceive_SOURCES = tests/helpers/test_sigreceive.c
 test_sigreceive_LDADD = $(LDADD) libcommon.la
 
+check_PROGRAMS += test_sigstate
+test_sigstate_SOURCES = tests/helpers/test_sigstate.c
+test_sigstate_LDADD = $(LDADD) libcommon.la
+
 check_PROGRAMS += test_tiocsti
 test_tiocsti_SOURCES = tests/helpers/test_tiocsti.c
 
diff --git a/tests/helpers/test_sigstate.c b/tests/helpers/test_sigstate.c
new file mode 100644 (file)
index 0000000..52c7dcb
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * test_sigstate - ...
+ *
+ * Written by Masatake YAMATO <yamato@redhat.com>
+ */
+
+#include "c.h"
+
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <err.h>
+
+#define _U_ __attribute__((__unused__))
+
+static enum {
+       HANDLER_NONE,
+       HANDLER_WRITE,
+       HANDLER_READ
+} handler_state = HANDLER_NONE;
+
+static int ERRNO;
+
+static void handler(int signum _U_)
+{
+       char c;
+
+       if (write(1, "USR1\n", 5) == -1) {
+               handler_state = HANDLER_WRITE;
+               goto out;
+       }
+
+       if (read(0, &c, 1) != -1)
+               _exit(0);
+       handler_state = HANDLER_READ;
+
+ out:
+       ERRNO = errno;
+}
+
+int main(int argc _U_, char **argv _U_)
+{
+       sigset_t block_set;
+
+       sigemptyset(&block_set);
+       sigaddset(&block_set, SIGINT);
+       sigaddset(&block_set, SIGILL);
+       sigaddset(&block_set, SIGABRT);
+       sigaddset(&block_set, SIGFPE);
+       sigaddset(&block_set, SIGSEGV);
+       sigaddset(&block_set, SIGTERM);
+
+       if (sigprocmask(SIG_SETMASK, &block_set, NULL) == -1)
+               err(EXIT_FAILURE, "failed to mask signals");
+
+       raise(SIGINT);
+       raise(SIGILL);
+
+#define sigignore(S) if (signal(S, SIG_IGN) == SIG_ERR) \
+               err(EXIT_FAILURE, "failed to make " #S "ignored")
+
+       sigignore(SIGHUP);
+       sigignore(SIGQUIT);
+       sigignore(SIGTRAP);
+       sigignore(SIGPIPE);
+       sigignore(SIGALRM);
+
+       signal(SIGBUS, SIG_DFL);
+       signal(SIGFPE, SIG_DFL);
+       signal(SIGSEGV, SIG_DFL);
+       signal(32, SIG_DFL);
+       signal(33, SIG_DFL);
+
+       if (signal(SIGUSR1, handler) == SIG_ERR)
+               err(EXIT_FAILURE, "failed to set a signal handler for SIGUSR1");
+       if (signal(SIGILL, handler) == SIG_ERR)
+               err(EXIT_FAILURE, "failed to set a signal handler for SIGILL");
+
+       printf("%d\n", getpid());
+       if (fflush(stdout) == EOF)
+               err(EXIT_FAILURE, "failed to flush stdout");
+
+       pause();
+       if (ERRNO == 0)
+               errx(EXIT_FAILURE, "caught an unexpected signal");
+       errno = ERRNO;
+       errx(EXIT_FAILURE, "failed in %s an ack from the command invoker",
+            handler_state == HANDLER_WRITE? "writing": "reading");
+
+       return 0;               /* UNREACHABLE */
+}
diff --git a/tests/ts/kill/decode b/tests/ts/kill/decode
new file mode 100755 (executable)
index 0000000..03bc25f
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+# This file is part of util-linux.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="decode functions"
+
+. "$TS_TOPDIR/functions.sh"
+ts_init "$*"
+
+ts_skip_qemu_user
+
+ts_check_test_command "$TS_CMD_KILL"
+ts_check_test_command "$TS_HELPER_SIGSTATE"
+
+. "$TS_SELF/kill_functions.sh"
+
+decode()
+{
+    echo decode "\"$1\":"
+    "$TS_CMD_KILL" -l "$1"
+}
+
+PID=
+ACK=
+{
+    for d in 0x00000000000044aa \
+                0x0000000000003015 \
+                0x0000000000000200; do
+       decode "$d"
+    done
+
+    coproc SIGSTATE { "$TS_HELPER_SIGSTATE" ; }
+    if read -u ${SIGSTATE[0]} PID; then
+       "$TS_CMD_KILL" -USR1 "$PID"
+       if read -u ${SIGSTATE[0]} ACK; then
+           # The taget process is in its signal handler for USR1.
+           # Sending one more USR1 is for making the signal pending state.
+           "$TS_CMD_KILL" -USR1 "$PID"
+           "$TS_CMD_KILL" -d "$PID" | {
+               if [[ $("$TS_CMD_KILL" --list=34) == RT0 ]]; then
+                   # See man signal(7).
+                   #   The  Linux  kernel  supports a range of 33 different real-time signals,
+                   #   numbered 32 to 64.  However, the glibc POSIX threads implementation in‐
+                   #   ternally uses two (for NPTL) or three (for LinuxThreads) real-time sig‐
+                   #   nals (see pthreads(7)), and adjusts the value of SIGRTMIN suitably  (to
+                   #   34 or 35).
+                   sed -e s/' 32 33'// -e s/' 34'//
+               else
+                   cat
+               fi
+           }
+       fi
+       echo DONE >&"${SIGSTATE[1]}"
+    fi
+    wait ${SIGSTATE_PID}
+} > "$TS_OUTPUT" 2>&1
+
+ts_finalize