procmgr_event_notify()
Ask to be notified of system-wide events
Synopsis:
#include <sys/procmgr.h>
int procmgr_event_notify (
unsigned flags,
const struct sigevent * event );
Arguments:
- flags
- A bitwise OR of the type of events that you want to be notified of,
or 0 to unarm the sigevent.
The event types include:
- PROCMGR_EVENT_CONFSTR
- PROCMGR_EVENT_CONTIG_ALLOC_FAIL
- PROCMGR_EVENT_DAEMON_DEATH
- PROCMGR_EVENT_PATHSPACE
- PROCMGR_EVENT_PROCESS_CREATE
- PROCMGR_EVENT_PROCESS_DEATH
- PROCMGR_EVENT_SYNC
- PROCMGR_EVENT_SYSCONF
- PROCMGR_EVENT_TOD
For more information, see
Event types,
below. - event
- A pointer to a sigevent structure that specifies how you want to be notified.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The procmgr_event_notify() function requests that the process manager notify the caller of the system-wide events identified by the given flags. The application must register the event by calling MsgRegisterEvent() with SYSMGR_COID passed as the connection ID (coid).
To remove the current notification request, pass a value of 0 for flags.
Event types
The following event types are defined in <sys/procmgr.h>:
- PROCMGR_EVENT_CONFSTR
- A process set a configuration string.
- PROCMGR_EVENT_CONTIG_ALLOC_FAIL
- An attempt to allocate contiguous memory failed.
- PROCMGR_EVENT_DAEMON_DEATH
- A process in session 1 died. This event is most useful for watching for the death of daemon processes that use procmgr_daemon() to put themselves in session 1 as well as close and redirect file descriptors. As a result of this closing and redirecting, the death of daemons is difficult to detect otherwise.
- PROCMGR_EVENT_PATHSPACE
- A resource manager added or removed an entry (i.e., mountpoint) to or from the pathname space. This is generally associated with resource manager calls to resmgr_attach() and resmgr_detach(). Terminating a resource manager process also generates this event if the mountpoints haven't been detached.
- PROCMGR_EVENT_PROCESS_CREATE
- A new process has been created.
- PROCMGR_EVENT_PROCESS_DEATH
- A process died.
- PROCMGR_EVENT_SYNC
- A process called sync() to synchronize the filesystems.
- PROCMGR_EVENT_SYSCONF
- A process set a system configuration string.
- PROCMGR_EVENT_TOD
- A process changed the time of day by calling ClockTime() or clock_settime().
If you set SIGEV_FLAG_UPDATEABLE in the hidden bits in the sigevent structure, the kernel provides some additional information in the sigev_value member:
Event | Information |
---|---|
PROCMGR_EVENT_CONFSTR | The value of the confstr() constant |
PROCMGR_EVENT_DAEMON_DEATH | The process ID of the dying process |
PROCMGR_EVENT_PATHSPACE | The hash of the pathname (see below) |
PROCMGR_EVENT_PROCESS_CREATE | The process ID of the newly created process |
PROCMGR_EVENT_PROCESS_DEATH | The process ID of the dying process |
PROCMGR_EVENT_SYSCONF | The value of the sysconf() constant |
The code for generating the hash of the pathname is as follows:
static unsigned pathspace_hash( const unsigned char *str ) {
unsigned hash, x;
for (x = hash = 0 ; *str ; ++str) {
hash = (hash << 4) + *str;
if ((x = hash & 0xf0000000u) != 0) {
hash ^= (x >> 24);
hash &= ~x;
}
}
// Modification from standard ELFHash so that client can tell that the
// sigev_value field contains a hash if it's non-zero
return hash | 0x80000000u;
}
Returns:
-1 on error (errno is set); any other value indicates success.
Examples:
/*
* This code demonstrates procmgr_event_notify() with the PROCMGR_EVENT_PROCESS_DEATH
* flag, which allows you to be notified if any process in session 1 dies.
*/
#include <ctype.h>
#include <devctl.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/neutrino.h>
#include <sys/procfs.h>
#include <sys/procmgr.h>
#define PROCESS_DIED_CODE (_PULSE_CODE_MINAVAIL + 1)
int main( int argc, char **argv )
{
int chid, coid, rc;
struct sigevent event;
struct _pulse msg;
chid = ChannelCreate( _NTO_CHF_PRIVATE );
if (0 > chid) {
fprintf( stderr, "ChannelCreate() failed : %s", strerror(errno) );
exit( EXIT_FAILURE );
}
coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, _NTO_COF_CLOEXEC );
if (0 > coid) {
fprintf( stderr, "ConnectAttach() failed : %s", strerror(errno) );
exit( EXIT_FAILURE );
}
SIGEV_PULSE_INIT( &event, coid, SIGEV_PULSE_PRIO_INHERIT, PROCESS_DIED_CODE, 0 );
SIGEV_MAKE_UPDATEABLE( &event );
if (0 != MsgRegisterEvent( &event, SYSMGR_COID )) {
fprintf( stderr, "MsgRegisterEvent() failed : %s", strerror(errno) );
exit( EXIT_FAILURE );
}
/*
* Ask to be notified via a pulse whenever a process dies
*/
if (procmgr_event_notify( PROCMGR_EVENT_PROCESS_DEATH, &event ) == -1) {
fprintf( stderr, "procmgr_event_notify() failed : %s", strerror(errno) );
exit( EXIT_FAILURE );
}
for(;;) {
rc = MsgReceivePulse( chid, &msg, sizeof(msg), NULL );
if (rc == -1) {
fprintf( stderr, "MsgReceivePulse() failed : %s", strerror(errno) );
exit( EXIT_FAILURE );
}
switch(msg.code) {
case PROCESS_DIED_CODE:
printf( "process pid:%i is no longer running\n", msg.value.sival_int );
break;
}
}
return 0;
}
Classification:
Safety: | |
---|---|
Cancellation point | No |
Signal handler | Yes |
Thread | Yes |