Detecting the termination of daemons or of all processes
What would happen if you created some processes that subsequently made themselves daemons (i.e., called procmgr_daemon())? As 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. Thus, if you call the function again, the new request replaces the previous one. This means that if multiple threads in a process request different notifications, the first one that issued its request would not receive its notification which is probably not what you want. With procmgr_event_notify_add(), your process can have more than one notification request, so this latter function is the better one to call.
#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, handle;
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 ( chid == -1 )
{
// Was there an error creating the channel?
perror( "ChannelCreate()" ); // Look up the errno code and print
exit( EXIT_FAILURE );
}
SIGEV_PULSE_INIT( &ev, -chid, 10, 1, 0 );
SIGEV_MAKE_UPDATEABLE(&ev);
// Request process death notifications
handle = procmgr_event_notify_add( PROCMGR_EVENT_PROCESS_DEATH, &ev );
if ( handle == -1 ) {
fprintf( stderr,
"procmgr_event_notify_add() failed : %s",
strerror(errno) );
exit( EXIT_FAILURE );
}
while (1)
{
if ( (MsgReceivePulse( chid, &pulse, sizeof pulse, NULL )) == -1 )
{
// Was there an error receiving the pulse?
perror( "MsgReceivePulse" ); // Look up errno code and print
exit( EXIT_FAILURE );
}
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;
}
