Зарегистрировать имя в пространстве имен и создать канал
#include <sys/iofunc.h>#include <sys/dispatch.h>name_attach_t * name_attach( dispatch_t *dpp,const char *path,unsigned flags );
NULL
или дескриптор диспетчера, возвращаемый dispatch_create() или dispatch_create_channel()./dev/name/[local|global]/
. Данный путь не должен содержать символов .. или начинаться с /
.libc
Функции name_attach(), name_close(), name_detach() и name_open() предоставляют базовое отображение путь к файлу - соединение с сервером без необходимости использования полноценного менеджера ресурсов.
Если структура диспетчера уже создана, следует передать ее как dpp. Если предоставляется собственная dpp, следует установить flags в NAME_FLAG_DETACH_SAVEDPP
при вызове name_detach(); в противном случае, dpp отключается и разрушается автоматически.
Если передать NULL
в качестве dpp, name_attach() вызывает dispatch_create() и resmgr_attach() для создания канала, но никаких флагов канала не устанавливает. Созданный канал будет иметь установленные флаги _NTO_CHF_DISCONNECT
, _NTO_CHF_COID_DISCONNECT
и _NTO_CHF_UNBLOCK
.
Функция name_attach() помещает имя path в пространство имен /dev/name/[local|global]/path
. Имя регистрируется локально по умолчанию или глобально, если в flags установлен NAME_FLAG_ATTACH_GLOBAL
. Зарегистрированные имена можно увидеть в директориях /dev/name/local
и /dev/name/global
.
Приложение, вызывающее name_attach(), получает сообщение _IO_CONNECT
при вызове name_open(). Приложение должно корректно обработать это сообщение с ответом EOK
, чтобы разрешить соединение name_open().
Если буфер приема, предоставляемый сервером, недостаточно велик для получения импульса, MsgReceive() возвращает -1
с установкой errno в EFAULT
.
Информация, обычно требуемая серверу для использования вышеупомянутых сервисов - name_attach_t::chid.
Утилита gns должна быть запущена до вызова приложением name_attach() для глобального объявления или регистрации службы.
Если приложение подключает службу локально, то приложения на других машинах не смогут искать эту службу с помощью утилиты gns. Если приложение подключает службы глобально, то любая машина в сети с запущенным менеджером gns может получить доступ к службе. Приложение может подключать службу локально только в том случае, если нет другого приложения, подключенного локально к той же службе. Ограничений по разрешениям для приложений, подключенных как локальные службы, нет. Приложение может подключить службу глобально только если имеет привилегии суперпользователя. |
Указатель на заполненную структуру name_attach_t.
Если возникла ошибка, функция возвращает NULL
, код ошибки записывается в errno.
NULL
или пустая строка в качестве пути, либо путь, начинающийся с /
или содержащий символы
..). #include <stdio.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <sys/dispatch.h>#define ATTACH_POINT "myname"/* We specify the header as being at least a pulse */typedef struct _pulse msg_header_t;/* Our real data comes after the header */typedef struct _my_data {msg_header_t hdr;int data;} my_data_t;/*** Серверный код ***/int server(){name_attach_t *attach;my_data_t msg;int rcvid;/* Create a local name (/dev/name/local/...) */if ( (attach = name_attach( NULL, ATTACH_POINT, 0 )) == NULL ){return (EXIT_FAILURE);}/* Do your MsgReceive's here now with the chid */while ( 1 ){rcvid = MsgReceive( attach->chid, &msg, sizeof( msg ), NULL );if ( rcvid == -1 ){/* Error condition, exit */break;}if ( rcvid == 0 ){/* Pulse received */switch ( msg.hdr.code ){case _PULSE_CODE_DISCONNECT:/** A client disconnected all its connections (called name_close() for each* name_open() of our name) or terminated*/ConnectDetach( msg.hdr.scoid );break;case _PULSE_CODE_UNBLOCK:/** REPLY blocked client wants to unblock (was hit by a signal or timed out).* It's up to you if you reply now or later.*/break;default:/** A pulse sent by one of your processes or a _PULSE_CODE_COIDDEATH or* _PULSE_CODE_THREADDEATH from the kernel?*/break;}continue;}/* name_open() sends a connect message, must EOK this */if ( msg.hdr.type == _IO_CONNECT ){MsgReply( rcvid, EOK, NULL, 0 );continue;}/* Some other IO message was received; reject it */if ( msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX ){MsgError( rcvid, ENOSYS );continue;}/* A message (presumable ours) received, handle */printf( "Server receive %d \n", msg.data );MsgReply( rcvid, EOK, 0, 0 );}/* Remove the name from the space */name_detach( attach, 0 );return EXIT_SUCCESS;}/*** Клиентский код ***/int client(){my_data_t msg;int server_coid;if ( (server_coid = name_open( ATTACH_POINT, 0 )) == -1 ){return EXIT_FAILURE;}/* We would have pre-defined data to stuff here */msg.hdr.type = 0x00;msg.hdr.subtype = 0x00;/* Do whatever work you wanted with server connection */for ( msg.data = 0; msg.data < 5; msg.data++ ){printf( "Client sending %d \n", msg.data );if ( MsgSend( server_coid, &msg, sizeof( msg ), NULL, 0 ) == -1 ){break;}}/* Close the connection */name_close( server_coid );return EXIT_SUCCESS;}int main( int argc, char **argv ){int ret;if ( argc < 2 ){printf( "Usage %s -s | -c \n", argv[0] );ret = EXIT_FAILURE;} elseif ( strcmp( argv[1], "-c" ) == 0 ){printf( "Running Client ... \n" );ret = client(); /* see name_open() for this code */} elseif ( strcmp( argv[1], "-s" ) == 0 ){printf( "Running Server ... \n" );ret = server(); /* see name_attach() for this code */} else {printf( "Usage %s -s | -c \n", argv[0] );ret = EXIT_FAILURE;}return ret;}
ЗОСРВ «Нейтрино»
Не следует предполагать, что сервер выполняет MsgReceive() для чистого канала. В ЗОСРВ «Нейтрино» (и ЗОСРВ КПДА.00002-01) любой может создать случайное сообщение и отправить его процессу или каналу.
Рекомендуется сделать следующее, чтобы убедиться в безопасном взаимодействии с другими членами системы:
#include <sys/neutrino.h>/* All of your messages should start with this header */typedef struct _pulse msg_header_t;/* Now your real data comes after this */typedef struct _my_data {msg_header_t hdr;int data;} my_data_t;
где:
4
байта интерпретируются как поле типа/подтипа. Это позволяет идентифицировать данные, которые не предназначены для данного сервера. name_attach_t, ChannelCreate(), dispatch_block(), dispatch_context_alloc(), dispatch_context_free(), dispatch_create(), dispatch_create_channel(), dispatch_destroy(), dispatch_handler(), dispatch_timeout(), dispatch_unblock(), MsgReceive(), name_detach(), name_open(), name_close(), struct _pulse, resmgr_attach()
gns в Справочнике по Утилитам
Предыдущий раздел: Описание API системной библиотеки