Reputation: 329
If one program sendS a signal to the second program, can the second program figure out what the pid of the first program is just by the signal sent by it?
First Program: (Code is incomplete, signals is the main focus)
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<time.h>
void my_handler(int);
int main(int argc, char *argv[]){
FILE *fp;
fp=fopen(argv[1], "w");
kill(atol(argv[2]),SIGUSR1);
}
Second Program:
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<time.h>
void my_handler(int signum){
if (signum == SIGUSR1)
{
printf("Received SIGUSR1!\n");
}
}
int main(int argc, char *argv[]){
int pid;
pid=getpid();
printf("PID: %d\n", pid);
signal(SIGUSR1, my_handler);
pause();
}
Is there a way? Or should i put the pid of the first program in SIGUSR1
somehow and the second program can figure out the pid?
Upvotes: 4
Views: 2540
Reputation: 754880
Assuming you are on a sufficiently POSIX-compatible system, then you can get the information if you set the signal handling with sigaction()
, if you specify a signal handler that takes a siginfo_t
pointer, and you specify SA_SIGINFO as one of the flags:
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static siginfo_t sig_info;
static volatile sig_atomic_t sig_num;
static void *sig_ctxt;
static void catcher(int signum, siginfo_t *info, void *vp)
{
sig_num = signum;
sig_info = *info;
sig_ctxt = vp;
}
static void set_handler(int signum)
{
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = catcher;
sigemptyset(&sa.sa_mask);
if (sigaction(signum, &sa, 0) != 0)
{
int errnum = errno;
fprintf(stderr, "Failed to set signal handler (%d: %s)\n", errnum, strerror(errnum));
exit(1);
}
}
static void prt_interrupt(FILE *fp)
{
if (sig_num != 0)
{
fprintf(fp, "Signal %d from PID %d\n", sig_info.si_signo, (int)sig_info.si_pid);
sig_num = 0;
}
}
int main(void)
{
set_handler(SIGINT);
pause();
prt_interrupt(stdout);
return(0);
}
Compile as 'catch' and run:
$ ./catch &
[1] 31165
$ kill -2 31165
Signal 2 from PID 26983
$ echo $$
26983
[1]+ Done ./catch
$
Upvotes: 1
Reputation: 5836
You can create a shared memory between the two process. From the 1st process , obtain the pid using getpid() , and save it to the shared memory area.
ShmID = shmget(PidKey, sizeof(pid_t), IPC_CREAT | 0666);
ShmPTR = (pid_t *) shmat(ShmID, NULL, 0);
In the second process , inside your handler just attach your c program to the shared memory area
void my_handler(int signum)
{
if (signum == SIGUSR1)
{
ShmID = shmget(PidKey, sizeof(pid_t), 0666);
ShmPTR = (pid_t *) shmat(ShmID, NULL, 0);
pid = *ShmPTR
}
}
At the end of the program , do clean up the shared memory
shmdt(ShmPTR);
shmctl(ShmID, IPC_RMID, NULL);
Note - The code above is far from complete , no semaphores are used and no other measures are taken against race conditions in a multiprocessor environment.
Upvotes: -1
Reputation: 179687
Assuming you mean POSIX signals, then yes. You can access the sender's PID through the si_pid
member of siginfo_t
, though you will need to use sigaction
and the SA_SIGINFO
flag to define your handler.
Non-POSIX systems (e.g. Windows) may not even have the concept of a signal (at least not in the POSIX sense), so none of this will apply.
Upvotes: 1