Saya juga perlu mengidentifikasi pengirim sinyal dalam suatu program, jadi saya mengambil jawaban grawity, dan menggunakannya dalam program saya, itu berfungsi dengan baik.
Berikut contoh kodenya:
send_signal_raise.c
// send signal to self test - raise()
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
static int int_count = 0, max_int = 5;
static struct sigaction siga;
static void multi_handler(int sig, siginfo_t *siginfo, void *context) {
// get pid of sender,
pid_t sender_pid = siginfo->si_pid;
if(sig == SIGINT) {
int_count++;
printf("INT(%d), from [%d]\n", int_count, (int)sender_pid);
return;
} else if(sig == SIGQUIT) {
printf("Quit, bye, from [%d]\n", (int)sender_pid);
exit(0);
}
return;
}
int raise_test() {
// print pid
printf("process [%d] started.\n", (int)getpid());
// prepare sigaction
siga.sa_sigaction = *multi_handler;
siga.sa_flags |= SA_SIGINFO; // get detail info
// change signal action,
if(sigaction(SIGINT, &siga, NULL) != 0) {
printf("error sigaction()");
return errno;
}
if(sigaction(SIGQUIT, &siga, NULL) != 0) {
printf("error sigaction()");
return errno;
}
// use "ctrl + c" to send SIGINT, and "ctrl + \" to send SIGQUIT,
int sig;
while(1) {
if(int_count < max_int) {
sig = SIGINT;
} else {
sig = SIGQUIT;
}
raise(sig); // send signal to itself,
sleep(1); // sleep a while, note that: SIGINT will interrupt this, and make program wake up,
}
return 0;
}
int main(int argc, char *argv[]) {
raise_test();
return 0;
}
Kompilasi:
gcc -pthread -Wall send_signal_raise.c
Jalankan:
./a.out
Apa fungsinya:
Program mengirimkan SIGINT
ke dirinya sendiri 10 kali, sebelum mengirim SIGQUIT
untuk mengakhiri sendiri.
Juga, selama eksekusi, tekan CTRL +C untuk mengirim SIGINT
, atau CTRL +\ untuk mengirim SIGQUIT
yang akan mengakhiri program dengan tangan.
Program berhasil mengidentifikasi siapa yang mengirim sinyal.
BCC menyertakan killsnoop
kegunaan. Ini membutuhkan kernel dengan dukungan BPF.
Kutipan dari halaman manual killsnoop (8):
killsnoop traces the kill() syscall, to show signals sent via this method. This may be
useful to troubleshoot failing applications, where an unknown mechanism is sending
signals.
This works by tracing the kernel sys_kill() function using dynamic tracing, and will need
updating to match any changes to this function.
This makes use of a Linux 4.5 feature (bpf_perf_event_output()); for kernels older than
4.5, see the version under tools/old, which uses an older mechanism.
Since this uses BPF, only the root user can use this tool.
Dua metode khusus Linux adalah SA_SIGINFO
dan signalfd()
, yang memungkinkan program menerima sangat informasi mendetail tentang sinyal yang dikirim, termasuk PID pengirim.
-
Panggil
sigaction()
dan berikanstruct sigaction
padanya yang memiliki penangan sinyal yang diinginkan disa_sigaction
danSA_SIGINFO
tandai disa_flags
mengatur. Dengan bendera ini, penangan sinyal Anda akan menerima tiga argumen, salah satunya adalahsiginfo_t
struktur yang berisi PID dan UID pengirim. -
Hubungi
signalfd()
dan bacasignalfd_siginfo
struktur dari itu (biasanya dalam beberapa jenis loop pilih/jajak pendapat). Isinya akan mirip dengansiginfo_t
.
Yang mana yang akan digunakan bergantung pada bagaimana aplikasi Anda ditulis; mereka mungkin tidak akan bekerja dengan baik di luar C biasa, dan saya tidak memiliki harapan untuk membuatnya bekerja di Jawa. Mereka juga tidak portabel di luar Linux. Mereka juga kemungkinan besar adalah Cara yang Sangat Salah dalam melakukan apa yang ingin Anda capai.