3
local $SIG{INT}  = \&handle_sigint;
sub handle_sigint {
    print "received sigint\n";

}

in handle_sigint i would like to print who (pid/process name) sent the signal.
Is there a way to capture that info in perl?

i can do this in C and this is ported to python as a module
I am looking for equivalent in perl

static void csignal_handler(int signum, siginfo_t *siginfo, void *context) {

    char *interrupt_msg[150];
    if (siginfo->si_pid != 0) {
       struct passwd *pwd = getpwuid(siginfo->si_uid);
        if (pwd != 0) {
            sprintf(interrupt_msg, "Received signal '%d' from process '%d' (%s) of user '%s'\n",
                signum, siginfo->si_pid, get_process_name_by_pid(siginfo->si_pid), pwd->pw_name);

        } else {
            sprintf(interrupt_msg, "Received signal '%d' from process '%d' (%s) of user '%d'\n",
               signum, siginfo->si_pid, get_process_name_by_pid(siginfo->si_pid), siginfo->si_uid);

        }

        printf("%s", interrupt_msg);
    }
    if (raise_interrupt) {
        PyGILState_STATE gstate = PyGILState_Ensure();
        PyErr_SetString(PyExc_KeyboardInterrupt, interrupt_msg );
        PyGILState_Release(gstate);
    } else {
        interrupted = 1;
    }
}
Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
ealeon
  • 12,074
  • 24
  • 92
  • 173
  • Pretty sure the answer is 'no', because it's a kernel space thing, but I'm not sure I could find a reference for that. – Sobrique Sep 27 '16 at 08:46
  • im able to capture this info in python because i wrote a c extension module which captures it but idk if it can be port to perl – ealeon Sep 27 '16 at 08:47
  • 2
    OK. Well, at a worst case you can inline C into perl. I didn't honestly think the signal handler passed that information though. – Sobrique Sep 27 '16 at 08:51
  • you mean in perl it doesnt? it works on c/python. ive tested myself. – ealeon Sep 27 '16 at 08:52
  • http://www.perlmonks.org/?node_id=346477 - I suspect the reason may be because perl does 'safe signals' and any C based solution isn't. – Sobrique Sep 27 '16 at 08:52
  • You query the system _very_ heavily here! The info you have does not come from the signal itself. – zdim Sep 27 '16 at 08:55
  • @ealeon, That information is lost. When you install a signal handler, the actual signal handler installed just increments a counter when the signal comes in. Extra information about the signal isn't stored. The signal handler you provided will eventually be called between Perl ops. – ikegami Sep 27 '16 at 17:18

2 Answers2

1

All that our process gets from the kernel is the signal, which I believe is just an integer. Also, a signal may come from all kinds of events, not just another process. The list given by, for example, man 7 signal reveals all kinds of possible sources.

All that is not in the signal.


Update to the question edit

The added C code doesn't exactly use the signal itself, but queries a whole lot more. A similar approach in Perl is discussed in this post, unearthed by Syck in a comment.

As for digging that information up from siginfo_t, the POSIX::SigAction is meant to expose those fields, but it apparently doesn't. It may be that you are best off writing your own extension, or try with Inline::C as suggested by sobrique

Community
  • 1
  • 1
zdim
  • 64,580
  • 5
  • 52
  • 81
1

You can combine SA_SIGINFO and signalfd to find out the pid of process which sent the signal.

See: How can I tell in Linux which process sent my process a signal

Community
  • 1
  • 1
Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133