Запросить получение уведомлений об общесистемных событиях
#include <sys/procmgr.h>int procmgr_event_notify( unsigned flags,const struct sigevent *event );
0
, чтобы отключить ивент struct sigevent. Типы событий включают в себя: libc
Функция procmgr_event_notify() запрашивает у менеджера процессов получение уведомлений об общесистемных событиях, идентифицированных аргументом flags. Процесс может иметь только один активный запрос на уведомление.
Типы событий
Следующие типы событий определены в <sys/procmgr.h>
:
Уведомление осуществляется через аргумент event, поэтому информация о том, какой процесс завершился, не предоставляется. После того, как было получено уведомление о событии, нужно выполнить дополнительные действия, чтобы определить завершившиеся процессы. Это можно сделать, опросив список всех процессов в поиске конкретных идентификаторов процессов и имен. Если нужный идентификатор процесса не найден – это значит, что процесс завершился. Пример ниже демонстрирует, как можно это сделать. |
/** Пример демонстрирует использование procmgr_event_notify() с флагом PROCMGR_DAEMON_DEATH.* Он позволяет получать уведомления, если какой-либо процесс в сессии 1 завершается.* Демоны — это процессы, которые затрудняют обнаружение своего завершения, вызывая функцию* procmgr_daemon(). Одна из таких мер заключается в том, что демоны завершаются в сессии 1.* В этом и проявляется полезность флага PROCMGR_DAEMON_DEATH.** Уведомление не сообщает какой именно процесс завершился. Получив уведомление, нужно* пройтись по списку процессов, которые все еще работают и определить, все ли искомые* процессы все еще работают. Если известны идентификаторы этих процессов, то это становится* проще. Если они не известны, можно определять процессы по имени. Код ниже выполняет поиск* по имени.*/#include <devctl.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <libgen.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/neutrino.h>#include <sys/procfs.h>#include <sys/procmgr.h>static int check_if_running( char *process );#define DAEMON_DIED_CODE (_PULSE_CODE_MINAVAIL)struct dinfo_s {procfs_debuginfo info;char pathbuffer[PATH_MAX];};int main( int argc, char **argv ){char *daemon_to_watch;int chid, coid, rcvid;struct sigevent event;struct _pulse msg;if ( argc != 2 ){printf( "use: %s process_to_watch_for\n", argv[0] );exit( EXIT_FAILURE );}daemon_to_watch = argv[1]; /* отслеживаемый процесс */chid = ChannelCreate( 0 );coid = ConnectAttach( 0, 0, chid, _NTO_SIDE_CHANNEL, 0 );SIGEV_PULSE_INIT( &event, coid, SIGEV_PULSE_PRIO_INHERIT,DAEMON_DIED_CODE, 0 );/** Запрос получения уведомлений в виде пульсов при завершении демона*/if ( procmgr_event_notify( PROCMGR_EVENT_DAEMON_DEATH, &event ) == -1 ){fprintf( stderr, "procmgr_event_notify() failed" );exit( EXIT_FAILURE );}while ( 1 ){rcvid = MsgReceive( chid, &msg, sizeof(msg), NULL );if ( rcvid != 0 ){/* полученное не является пульсом; возможна ошибка или получение сообщения */exit( EXIT_FAILURE );}if ( check_if_running( daemon_to_watch ) == 0 )printf( "%s is no longer running\n", daemon_to_watch );}return (0);}/** check_if_running - функция производит поиск процесса по имени.*/static int check_if_running( char *process ){DIR *dirp;struct dirent *dire;char buffer[20];int fd, status;pid_t pid;struct dinfo_s dinfo;if ( (dirp = opendir( "/proc" )) == NULL ){perror( "Could not open '/proc'" );return (-1);}while ( 1 ){if ( (dire = readdir( dirp )) == NULL )break;if ( isdigit( dire->d_name[0] ) ){pid = strtoul( dire->d_name, NULL, 0 );sprintf( buffer, "/proc/%d/as", pid );if ( (fd = open( buffer, O_RDONLY )) != NULL ){status = devctl( fd, DCMD_PROC_MAPDEBUG_BASE,&dinfo, sizeof(dinfo), NULL );if ( status == EOK ){if ( !strcmp( process, basename( dinfo.info.path ) ) ){closedir( dirp );/* следует закрыть дескриптор, чтобы избежать утечек памяти */close( fd );return (1);}} /* ветка обработки ошибок */close( fd );}}}closedir( dirp );return (0);}
ЗОСРВ «Нейтрино»
procmgr_daemon(), procmgr_event_trigger(), struct _pulse, struct sigevent
Предыдущий раздел: Описание API системной библиотеки