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 sigactionpadanya yang memiliki penangan sinyal yang diinginkan disa_sigactiondanSA_SIGINFOtandai disa_flagsmengatur. Dengan bendera ini, penangan sinyal Anda akan menerima tiga argumen, salah satunya adalahsiginfo_tstruktur yang berisi PID dan UID pengirim. -
Hubungi
signalfd()dan bacasignalfd_siginfostruktur 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.