Detecting the termination of daemons or of all processes
What would happen if you've created some processes that subsequently made themselves daemons (i.e., called procmgr_daemon())? As we mentioned above, the wait*() functions and sigwaitinfo() won't help.
For these you can give the kernel an event, such as one containing a pulse, and have the kernel deliver that pulse to you whenever a daemon terminates. This request for notification is done by calling procmgr_event_notify() or procmgr_event_notify_add() with PROCMGR_EVENT_DAEMON_DEATH in flags.
The difference between these functions is that with procmgr_event_notify(), your process can have one notification request; if you call the function again, the request replaces the previous one. With procmgr_event_notify_add(), your process can have more than one notification request.
See the documentation for procmgr_event_notify() for an example that uses PROCMGR_EVENT_DAEMON_DEATH.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <process.h>
#include <sys/procmgr.h>
int main(void)
{
int chid, coid;
rcvid_t rcvid;
struct _pulse pulse;
struct sigevent ev;
// Create a channel that's private to this process.
// No other process can connect to it.
chid = ChannelCreate( _NTO_CHF_PRIVATE );
if (-1 == chid)
{
// Was there an error creating the channel?
perror("ChannelCreate()"); // Look up the errno code and print
exit(EXIT_FAILURE);
}
// To ask for pulse delivery, we need a connection to our own channel.
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );
if (-1 == coid)
{
// Was there an error creating the channel?
perror("ConnectAttach()"); // Look up the errno code and print
exit(EXIT_FAILURE);
}
SIGEV_PULSE_INIT( &ev, coid, 10, 1, 0 );
SIGEV_MAKE_UPDATEABLE(&ev);
// Request process death notifications
procmgr_event_notify( PROCMGR_EVENT_PROCESS_DEATH, &ev );
while (1)
{
rcvid = MsgReceive( chid, &pulse, sizeof pulse, NULL );
if (-1 == rcvid)
{
// Was there an error receiving msg?
perror("MsgReceive"); // Look up errno code and print
exit(EXIT_FAILURE); // Give up
}
if( pulse.code == 1 )
{
printf("Process with pid %d died.\n", pulse.value.sival_int );
}
else
{
printf("Unexpected pulse, code: %d\n", pulse.code );
}
}
return 0;
}