I have a strange problem. I want to write a simple C programm that outputs "Daytime" repeatedly unless I press Ctrl+C (a SIGINT signal) which makes it to switch to "Nighttime" and vice versa. This part of the programm works. I also want to implement the termination of the programm, which would work over the SIGUSR1 signal. Yet when I type kill -SIGUSR1 <pid>
or kill -10 <pid>
it doesn't work. Why?
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
volatile int termination;
volatile int state;
void handler(int num) {
if (state == 0) {
state = 1;
} else {
state = 0;
}
}
void terminator(int num) {
// kill -SIGUSR1 3289
// kill -USR1 2040
// kill -USR 2040
// kill -10 3289
printf("I work!\n");
termination = 0;
}
int main(void) {
struct sigaction act_int, act_usr;
act_int.sa_handler = handler;
act_usr.sa_handler = terminator;
sigaction(SIGUSR1, &act_usr, NULL);
sigaction(SIGINT, &act_int, NULL);
termination = 1;
state = 1;
printf("My PID is: %d\n", getpid());
while (termination == 1) {
sleep(5);
if (state == 0) {
printf("Daytime\n");
} else {
printf("Nighttime\n");
}
}
printf("Thank you for using my function! :)\n");
return 0;
}
Kind regards
EDIT (My modified new code):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
volatile int termination = 1;
volatile int state = 1;
void handler(int num) {
if (state == 0) {
state = 1;
} else {
state = 0;
}
}
void terminator(int num) {
// kill -SIGUSR1 20560
// kill -10 20560
write(1, "Terminated\n", 10);
termination = 0;
}
int main(void) {
struct sigaction act_int, act_usr;
memset(&act_int, 0, sizeof act_int);
memset(&act_usr, 0, sizeof act_usr);
act_int.sa_handler = handler;
act_usr.sa_handler = terminator;
sigaction(SIGINT, &act_int, NULL);
sigaction(SIGUSR1, &act_usr, NULL);
printf("My PID is: %d\n", getpid());
while (termination == 1) {
if (state == 0) {
printf("Daytime\n");
} else {
printf("Nighttime\n");
}
sleep(5);
}
printf("Thank you for using my function! :)\n");
return 0;
}
EDIT: I ran my program with strace and redirected the output to a file, here are the contents:
execve("./program.x", ["./program.x"], 0x7ffe2fc5b530 /* 58 vars */) = 0
brk(NULL) = 0x55f3ca56b000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd50daca00) = -1 EINVAL (Das Argument ist ungültig)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f586663f000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=114855, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 114855, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5866622000
close(3) = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\237\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0 \0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0"..., 48, 848) = 48
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0i8\235HZ\227\223\333\350s\360\352,\223\340."..., 68, 896) = 68
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2216304, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 2260560, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f58663fa000
mmap(0x7f5866422000, 1658880, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x28000) = 0x7f5866422000
mmap(0x7f58665b7000, 360448, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bd000) = 0x7f58665b7000
mmap(0x7f586660f000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x214000) = 0x7f586660f000
mmap(0x7f5866615000, 52816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5866615000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f58663f7000
arch_prctl(ARCH_SET_FS, 0x7f58663f7740) = 0
set_tid_address(0x7f58663f7a10) = 20560
set_robust_list(0x7f58663f7a20, 24) = 0
rseq(0x7f58663f80e0, 0x20, 0, 0x53053053) = 0
mprotect(0x7f586660f000, 16384, PROT_READ) = 0
mprotect(0x55f3c96a2000, 4096, PROT_READ) = 0
mprotect(0x7f5866679000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f5866622000, 114855) = 0
rt_sigaction(SIGINT, {sa_handler=0x55f3c96a0229, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f586643c520}, NULL, 8) = 0
rt_sigaction(SIGUSR1, {sa_handler=0x55f3c96a0257, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f586643c520}, NULL, 8) = 0
getpid() = 20560
newfstatat(1, "", {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0), ...}, AT_EMPTY_PATH) = 0
getrandom("\x62\x94\x42\xcc\xdf\x17\xbc\x20", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x55f3ca56b000
brk(0x55f3ca58c000) = 0x55f3ca58c000
write(1, "My PID is: 20560\n", 17) = 17
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, {tv_sec=4, tv_nsec=592627880}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Unterbrechung während des Betriebssystemaufrufs)
write(1, "Daytime\n", 8) = 8
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, {tv_sec=3, tv_nsec=876879211}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Unterbrechung während des Betriebssystemaufrufs)
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, {tv_sec=4, tv_nsec=383598465}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Unterbrechung während des Betriebssystemaufrufs)
write(1, "Daytime\n", 8) = 8
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, {tv_sec=4, tv_nsec=611480158}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = -1 EINTR (Unterbrechung während des Betriebssystemaufrufs)
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, 0x7ffd50dac930) = 0
write(1, "Nighttime\n", 10) = 10
clock_nanosleep(CLOCK_REALTIME, 0, {tv_sec=5, tv_nsec=0}, {tv_sec=0, tv_nsec=558127083}) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=20542, si_uid=1000} ---
+++ killed by SIGHUP +++
My platform information (obtained with uname -a):
Linux Luxdragon 5.15.0-76-generic #83-Ubuntu SMP Thu Jun 15 19:16:32 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
So basically Linux Mint 21.1. I tested the code in VSCodium, in the Linux terminal and on Onlinegdb.
EDIT: If I type kill -SIGUSR1 in a separate terminal, then my program terminates as it should. Why can't I terminate it in the same terminal, where the program is run? Why does Ctrl+C then get processed correctly?