Capture the pid of signal sender [duplicate] - perl

This question already has an answer here:
How, in Perl 5, can I get the pid of the process who sent me a signal?
(1 answer)
Closed 6 years ago.
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;
}
}

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

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

Related

C select is overwriting timeout value [duplicate]

This question already has answers here:
Is timeout changed after a call to select in c?
(5 answers)
Closed 25 days ago.
In a very simple C program, using select() to check any new read data on a socket, when I use the optional timeout parameter, it is being overwritten by select(). It looks like it resets it to values of seconds and microseconds it actually waited, so when data is coming sooner than the timeout, it will have much smaller values, leading to smaller and smaller timeouts unless timeout is reset, when select() is called in a loop.
I could not find any information on this behavior in select() description. I am using Linux Ubuntu 18.04 in my testing. It looks like I have to reset the timeout value every time before calling select() to keep the same timeout?
The code snippet is this:
void *main_udp_loop(void *arg)
{
struct UDP_CTX *ctx = (UDP_CTX*)arg;
fd_set readfds = {};
struct sockaddr peer_addr = { 0 };
int peer_addr_len = sizeof(peer_addr);
while (1)
{
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 850000; // wait 0.85 second.
FD_ZERO(&readfds);
FD_SET(ctx->udp_socketfd, &readfds);
int activity = select( ctx->udp_socketfd + 1 , &readfds , NULL , NULL , &timeout);
if ((activity < 0) && (errno != EINTR))
{
printf("Select error: Exiting main thread\n");
return NULL;
}
if (timeout.tv_usec != 850000)
{
printf ("Timeout changed: %ld %ld\n", (long)timeout.tv_sec, (long)timeout.tv_usec);
}
if (activity == 0)
{
printf ("No activity from select: %ld \n", (long)time(0));
continue;
}
...
}
This is documented behavior in the Linux select() man page:
On Linux, select() modifies timeout to reflect the amount of time not slept; most other implementations do not do this. (POSIX.1 permits either behavior.) This causes problems both when Linux code which reads timeout is ported to other operating systems, and when code is ported to Linux that reuses a struct timeval for multiple select()s in a loop without reinitializing it. Consider timeout to be undefined after select() returns.
So, yes, you have to reset the timeout value every time you call select().

MIKMIDI: writing events on a track produces a warning

I'm trying to write a program to shift the key of a midi file. Basically, I just need to shift every note event by a given amount and live the rest unchanged. I found it easy to use MIKMIDI to read, parse, modify and write back the stream.
Unfortunately, I have a problem that I'm unable to solve. I've a loop in which I select the note events and add/subtract the desired shift value, but when I append the event in the output track I get a message from the MIKMIDI library:
"Warning: attempted to insert a NULL event".
The code I wrote is the following:
for event in inputTrack.events {
if event.eventType == .midiNoteMessage {
var tmpData = event.data
if (event.data[0] != 9) { // skip percussion channel
tmpData[1] = event.data[1] - shift
}
let outEvent = MIKMIDIEvent(timeStamp: event.timeStamp, midiEventType: .midiNoteMessage, data: tmpData)!
outputSeq.tracks[i].events.append(outEvent)
}
else {
outSeq.tracks[i].events.append(event)
}
}
BTW, the code works perfectly (the midi file is plays as expected), it is just that it takes minutes to execute in debugging mode due to the infinite sequence of warning messages printed in the debug screen.
Thanks!

perl code structure for post-processing

The question I have is a bit abstract, but I'll attempt to be clear in my statement. (This is something of a "rubber duck effect" post, so I'll be thankful if just typing it out gets me somewhere. Replies, however, would be brilliant!)
I have old fortran code that I can't change (at least not yet) so I'm stuck with its awkward output.
I'm using perl to post-process poorly annotated ascii output files, which, as you might imagine, are a very specialized mixture of text and numbers. "Ah, the perfect perl objective," you say. Yes, it is. But what I've come up with is pretty terrible coding, I've recently concluded.
My question is about the generic structure that folks prefer to use to achieve such an objective. As I've said, I'm not happy with the one I've chosen.
Here's some pseudocode of the structure that I've arrived at:
flag1 = 0;
flag2 = 0;
while (<INPUT>) {
if (cond1) {
do something [like parse and set a header];
flag1 = 1;
} else {
next;
}
if (flag1 == 1 && cond2) {
do something else [like process a block of data];
} else {
next;
}
}
The objective of the above code is to be able to break the processing into blocks corresponding to the poorly partitioned ascii file -- there isn't much by way of "tags" in the file, so the conditions (cond1, cond2, etc.) are involved. The purpose of having the flags set is, among other reasons, to track the progress of the code through the file.
It occurs to me now that a better structure might be
while (<INPUT>) {
do stuff;
}
while (<INPUT>) {
do other stuff;
}
In any event, if my rambling inspires any thoughts I'd appreciate hearing them.
Thank you
Your original structure is perfectly fine. You're building a state machine, and doing it in a completely reasonable way that can't really be made any more idiomatic.
The only thing you can possibly do if you wish is to modularize the code a wee bit:
our %state = (last => 0, current => 0, next => 0);
our %extra_flags = ();
sub cond1($line) { return $next_state } # Returns 0 if cond==false
sub cond2($line) { return $next_state } # Returns 0 if cond==false
our %conditions = (
0 => \&cond1
1 => \&cond2 # flag1 is set
);
while (<INPUT>) {
my $state = $state->{current};
if ($state->{next} = $conditions{$state}->($_, $state)) {
$do_stuff{$state}->{$next_state}->($line);
$state->{last} = $state->{current};
$state->{current} = $state->{next};
next;
}
}
If the file does indeed lend itself to being processed in multiple loops, that would be a much clearer way to do it than emulating that with conditionals, IMO.
If not, even if there are just a few exceptions to code around, it's probably better to stick with the original approach you describe.

NodeJS: What is the proper way to handling TCP socket streams ? Which delimiter should I use?

From what I understood here, "V8 has a generational garbage collector. Moves objects aound randomly. Node can’t get a pointer to raw string data to write to socket." so I shouldn't store data that comes from a TCP stream in a string, specially if that string becomes bigger than Math.pow(2,16) bytes. (hope I'm right till now..)
What is then the best way to handle all the data that's comming from a TCP socket ? So far I've been trying to use _:_:_ as a delimiter because I think it's somehow unique and won't mess around other things.
A sample of the data that would come would be something_:_:_maybe a large text_:_:_ maybe tons of lines_:_:_more and more data
This is what I tried to do:
net = require('net');
var server = net.createServer(function (socket) {
socket.on('connect',function() {
console.log('someone connected');
buf = new Buffer(Math.pow(2,16)); //new buffer with size 2^16
socket.on('data',function(data) {
if (data.toString().search('_:_:_') === -1) { // If there's no separator in the data that just arrived...
buf.write(data.toString()); // ... write it on the buffer. it's part of another message that will come.
} else { // if there is a separator in the data that arrived
parts = data.toString().split('_:_:_'); // the first part is the end of a previous message, the last part is the start of a message to be completed in the future. Parts between separators are independent messages
if (parts.length == 2) {
msg = buf.toString('utf-8',0,4) + parts[0];
console.log('MSG: '+ msg);
buf = (new Buffer(Math.pow(2,16))).write(parts[1]);
} else {
msg = buf.toString() + parts[0];
for (var i = 1; i <= parts.length -1; i++) {
if (i !== parts.length-1) {
msg = parts[i];
console.log('MSG: '+msg);
} else {
buf.write(parts[i]);
}
}
}
}
});
});
});
server.listen(9999);
Whenever I try to console.log('MSG' + msg), it will print out the whole buffer, so it's useless to see if something worked.
How can I handle this data the proper way ? Would the lazy module work, even if this data is not line oriented ? Is there some other module to handle streams that are not line oriented ?
It has indeed been said that there's extra work going on because Node has to take that buffer and then push it into v8/cast it to a string. However, doing a toString() on the buffer isn't any better. There's no good solution to this right now, as far as I know, especially if your end goal is to get a string and fool around with it. Its one of the things Ryan mentioned # nodeconf as an area where work needs to be done.
As for delimiter, you can choose whatever you want. A lot of binary protocols choose to include a fixed header, such that you can put things in a normal structure, which a lot of times includes a length. In this way, you slice apart a known header and get information about the rest of the data without having to iterate over the entire buffer. With a scheme like that, one can use a tool like:
node-buffer - https://github.com/substack/node-binary
node-ctype - https://github.com/rmustacc/node-ctype
As an aside, buffers can be accessed via array syntax, and they can also be sliced apart with .slice().
Lastly, check here: https://github.com/joyent/node/wiki/modules -- find a module that parses a simple tcp protocol and seems to do it well, and read some code.
You should use the new stream2 api. http://nodejs.org/api/stream.html
Here are some very useful examples: https://github.com/substack/stream-handbook
https://github.com/lvgithub/stick

simple parallel processing in perl

I have a few blocks of code, inside a function of some object, that can run in parallel and speed things up for me.
I tried using subs::parallel in the following way (all of this is in a body of a function):
my $is_a_done = parallelize {
# block a, do some work
return 1;
};
my $is_b_done = parallelize {
# block b, do some work
return 1;
};
my $is_c_done = parallelize {
# block c depends on a so let's wait (block)
if ($is_a_done) {
# do some work
};
return 1;
};
my $is_d_done = parallelize {
# block d, do some work
return 1;
};
if ($is_a_done && $is_b_done && $is_c_done && $is_d_done) {
# just wait for all to finish before the function returns
}
First, notice I use if to wait for threads to block and wait for previous thread to finish when it's needed (a better idea? the if is quite ugly...).
Second, I get an error:
Thread already joined at /usr/local/share/perl/5.10.1/subs/parallel.pm line 259.
Perl exited with active threads:
1 running and unjoined
-1 finished and unjoined
3 running and detached
I haven't seen subs::parallel before, but given that it's doing all of the thread handling for you, and it seems to be doing it wrong, based on the error message, I think it's a bit suspect.
Normally I wouldn't just suggest throwing it out like that, but what you're doing really isn't any harder with the plain threads interface, so why not give that a shot, and simplify the problem a bit? At the same time, I'll give you an answer to the other part of your question.
use threads;
my #jobs;
push #jobs, threads->create(sub {
# do some work
});
push #jobs, threads->create(sub {
# do some other work
});
# Repeat as necessary :)
$_->join for #jobs; # Wait for everything to finish.
You need something a little bit more intricate if you're using the return values from those subs (simply switching to a hash would help a good deal) but in the code sample you provided, you're ignoring them, which makes things easy.