Add a request to be notified of system-wide events
#include <sys/procmgr.h> int procmgr_event_notify_add ( unsigned flags, const struct sigevent * event );
For more information, see Event types, below.
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
The procmgr_event_notify_add() function adds a request that the process manager notify the caller of the system-wide events identified by the given flags. You can use this function to set up more than one notification request.
To delete a request, call procmgr_event_notify_delete(), passing it the handle returned by procmgr_event_notify_add().
Event types
The following event types are defined in <sys/procmgr.h>:
In QNX Neutrino 6.6 or later, you can specify SIGEV_FLAG_UPDATEABLE as described below, and then the notification includes the process ID of the process that died.
(QNX Neutrino 6.6 or later) 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_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; }
An integer handle that you can pass to procmgr_event_notify_delete(), or -1 if an error occurred (errno is set).
/* * This code demonstrates procmgr_event_notify_add() 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, rcvid, handle; 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 */ handle = procmgr_event_notify_add( PROCMGR_EVENT_DAEMON_DEATH, &event ); if (handle == -1) { fprintf( stderr, "procmgr_event_notify_add() failed : %s", strerror(errno) ); exit( EXIT_FAILURE ); } for(;;) { rcvid = MsgReceivePulse( chid, &msg, sizeof(msg), NULL ); if (rcvid == -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; } } procmgr_event_notify_delete( handle ); return 0; }
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | Yes |
Thread | Yes |