name_attach, name_open deprecated?

“name_attach” and “name_open” seem to be the standard way
to pass connection info around, but Krten’s book says the’re
deprecated. What’s the story?

I need to establish interprocess communication, but
it’s message-passing, not stream I/O, so a resource
manager is inappropriate. I’d like to do this without
anything running as root. What’s the right way to do this?

John Nagle
Team Overbot

On a related note, can anyone use name_attach, or do you
have to be root, or what?

John Nagle

John Nagle wrote:

“name_attach” and “name_open” seem to be the standard way
to pass connection info around, but Krten’s book says the’re
deprecated. What’s the story?

I need to establish interprocess communication, but
it’s message-passing, not stream I/O, so a resource
manager is inappropriate. I’d like to do this without
anything running as root. What’s the right way to do this?

John Nagle
Team Overbot

John Nagle <nagle@downside.com> wrote:
JN > On a related note, can anyone use name_attach, or do you
JN > have to be root, or what?

JN > John Nagle

JN > John Nagle wrote:

“name_attach” and “name_open” seem to be the standard way
to pass connection info around, but Krten’s book says the’re
deprecated. What’s the story?

I need to establish interprocess communication, but
it’s message-passing, not stream I/O, so a resource
manager is inappropriate. I’d like to do this without
anything running as root. What’s the right way to do this?

John Nagle
Team Overbot

You can use a very stripped down resource manager. It is definitely a
lot more work to set up on the server side then in QNX4 days. But once
you’ve registered a name it is pretty much the same.

Here is a sample server and client sample code that I used as a starting point.

=====================================
/*
#ifdef __USAGE
This is an example Resource Manager using MsgSend() & MsgReply().
It is copied from
http://www.qnx.com/developer/articles/index.html?article=jan2601
#endif
*/

/*

  • ResMgr and Message Server Process
    */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

resmgr_connect_funcs_t ConnectFuncs;
resmgr_io_funcs_t IoFuncs;
iofunc_attr_t IoFuncAttr;


typedef struct
{
uint16_t msg_no;
char msg_data[255];
} server_msg_t;


int other_callback ( resmgr_context_t ctp, void msg )
{
printf( “Server Got OTHER Message\n” );
printf( " ctp
=%p, ctp->msg
=%p, msg*=%p\n", ctp, ctp->msg, msg );
#ifdef DONT_COMPILE
server_msg_t *msg;
int num;
char msg_reply[255];

/* cast a pointer to the message data */
msg = (server_msg_t *)ctp->msg;

/* Print out some usefull information on the message */
printf( “Server Got Message:\n” );
printf( " type: %d\n" , type );
printf( " data: %s\n\n", msg->msg_data );

/* Build the reply message */
num = type - _IO_MAX;
snprintf( msg_reply, 254, “Server Got Message Code: _IO_MAX + %d”, num );

/* Send a reply to the waiting (blocked) client */
MsgReply( ctp->rcvid, EOK, msg_reply, strlen( msg_reply ) + 1 );
#endif
return 0;
}


int message_callback ( message_context_t *ctp, int type, unsigned flags, void *handle )
{
server_msg_t *msg;
int num;
char msg_reply[255];

/* cast a pointer to the message data */
msg = (server_msg_t *)ctp->msg;

/* Print out some usefull information on the message */
printf( “\n\nServer Got Message:\n” );
printf( " type: %d\n" , type );
printf( " data: %s\n\n", msg->msg_data );

/* Build the reply message */
num = type - _IO_MAX;
snprintf( msg_reply, 254, “Server Got Message Code: _IO_MAX + %d”, num );

/* Send a reply to the waiting (blocked) client */
MsgReply( ctp->rcvid, EOK, msg_reply, strlen( msg_reply ) + 1 );

return 0;
}


int main ( int argc, char **argv )
{
resmgr_attr_t resmgr_attr;
message_attr_t message_attr;
dispatch_t *dpp;
dispatch_context_t *ctp, *ctp_ret;
int resmgr_id, message_id;

/* Create the Dispatch Interface */
dpp = dispatch_create();
if( dpp == NULL )
{
fprintf( stderr, “dispatch_create() failed: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}

memset( &resmgr_attr, 0, sizeof( resmgr_attr ) );
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;
// next 2 lines added by Bill
resmgr_attr.other_func = other_callback;
resmgr_attr.flags |= RESMGR_FLAG_ATTACH_OTHERFUNC;

/* Setup the default I/O functions to handle open/read/write/… */
iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &ConnectFuncs,
_RESMGR_IO_NFUNCS, &IoFuncs );

/* Setup the attribute for the entry in the filesystem */
iofunc_attr_init( &IoFuncAttr, S_IFNAM | 0666, 0, 0 );

resmgr_id = resmgr_attach( dpp, &resmgr_attr, “/dev/serv”,
_FTYPE_ANY, 0, &ConnectFuncs, &IoFuncs, &IoFuncAttr );
if( resmgr_id == -1 )
{
fprintf( stderr, “resmgr_attach() failed: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}

/* Setup our private message callback */
memset( &message_attr, 0, sizeof( message_attr ) );
message_attr.nparts_max = 1;
message_attr.msg_max_size = 4096;

/* Attach a callback (handler) for two message types */
// Note: Using this technique, if the server hasn’t registered the message type
// that was sent, it will not receive anything
// unless it also registers an resmgr_attr.other_func and sets
// resmsg_attr.flags |= RESMGR_FLAG_ATTACH_OTHERFUNC;
message_id = message_attach( dpp, &message_attr,
_IO_MAX + 1,_IO_MAX + 2, message_callback, NULL );

if( message_id == -1 )
{
fprintf( stderr, “message_attach() failed: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}

/* Setup a context for the dispatch layer to use /
ctp = dispatch_context_alloc( dpp );
if( ctp == NULL )
{
fprintf( stderr, “dispatch_context_alloc() failed: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}


/
The “Data Pump” - get and process messages */
while( 1 )
{
ctp_ret = dispatch_block( ctp );
if( ctp_ret )
{
printf( “main loop woke up\n” );
ctp = ctp_ret;
dispatch_handler( ctp );
}
else
{
fprintf( stderr, “dispatch_block() failed: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}
}

return EXIT_SUCCESS;
}

#ifdef __USAGE
This is an example Resource Manager Client using
MsgSend() & MsgReply(). It is copied from
http://www.qnx.com/developer/articles/index.html?article=jan2601
#endif

/*

  • Message Client Process
    */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

typedef struct
{
uint16_t msg_no;
char msg_data[255];
} client_msg_t;

int main ( int argc, char **argv )
{
int fd;
int c;
client_msg_t msg;
int ret;
int num;
char msg_reply [255];

num = 1;

/* Process any command line arguments */
while( ( c = getopt( argc, argv, “n:” ) ) != -1 )
{
if( c == ‘n’ )
{
num = strtol( optarg, 0, 0 );
}
}

/* Open a connection to the server (fd == coid) */
fd = open( “/dev/serv”, O_RDWR );
if( fd == -1 )
{
fprintf( stderr, “Unable to open server connection: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}

/* Clear the memory for the msg and the reply */
memset( &msg, 0, sizeof( msg ) );
memset( &msg_reply, 0, sizeof( msg_reply ) );

/* Setup the message data to send to the server */
msg.msg_no = _IO_MAX + num;
snprintf( msg.msg_data, 254, “client %d requesting reply.”, getpid() );

printf( “client: msg_no: _IO_MAX + %d\n”, num );
fflush( stdout );

sleep(10);

/* Send the data to the server and get a reply */
// Note: Using this technique, if the server hasn’t registered the message type
// that was sent, it will not receive anything
ret = MsgSend( fd, &msg, sizeof( msg ), msg_reply, 255 );

sleep(10);

if( ret == -1 )
{
fprintf( stderr, “Unable to MsgSend() to server: %s\n”, strerror( errno ) );
return EXIT_FAILURE;
}

/* Print out the reply data */
printf( “client: server replied: %s\n”, msg_reply );

close( fd );

return EXIT_SUCCESS;
}


Bill Caroselli – Q-TPS Consulting
1-(708) 308-4956 <== Note: New Number
qtps@earthlink.net

Don’t have the book in hand , but the functions are definitly will live:)

name_attach(), name_open() is not “fully implemented” in 6.2.1B,
name_open() a “globally attach” name would fail.

The current rules of name_attach() is: anyuser can do the attach,
but no 2 user can attach to same name.

Once global attach is supported (in 6.3), then “local attach” follow
the same rule (normal user can attach, but the name can’t duplicate),
the “global attach” follow resmgr rule (only root can attach, but
duplicate name is allowed).

-xtang

John Nagle <nagle@downside.com> wrote in message
news:bkifju$sbu$1@inn.qnx.com

On a related note, can anyone use name_attach, or do you
have to be root, or what?

John Nagle

John Nagle wrote:
“name_attach” and “name_open” seem to be the standard way
to pass connection info around, but Krten’s book says the’re
deprecated. What’s the story?

I need to establish interprocess communication, but
it’s message-passing, not stream I/O, so a resource
manager is inappropriate. I’d like to do this without
anything running as root. What’s the right way to do this?

John Nagle
Team Overbot