Hello all,
I am posting this because I’m having a tough time with some basic
resource manager code. (Source code is listed below.) In the io_read
handler code, I am unable to see the number of bytes requested by the
user (msg.i->nbytes). I have taken an entire project and stripped
it down to a basic server, client, and io_read function(s), and still
the msg.i->nbytes value is zero… assuming here that something is
wrong in either the io_read or the resource manager’s main() method.
I have a simple client program that connects to the server and does a
read, as follows:
…
int fd = open(“serv”, O_RDWR);
char buff[255];
read(fd, buff, sizeof(buff));
…
The server’s printf in io_read comes up with 0’s for all values.
Has anyone seen this before? Your help/suggestions are greatly
appreciated.
Respectfully,
Eric Watz
Here is the io_read function
#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <sys/resmgr.h>
static char *buffer = “Hello world\n”;
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T
*ocb)
{
int nleft;
int nbytes;
int nparts;
int status;
if ((status = iofunc_read_verify (ctp, msg, ocb,
NULL)) != EOK)
return (status);
if (msg->i.xtype & _IO_XTYPE_MASK !=
_IO_XTYPE_NONE)
return (ENOSYS);
// calculate #bytes to return
nleft = ocb->attr->nbytes - ocb->offset;
nbytes = min (msg->i.nbytes, nleft);
printf(“serv: io_read, ocb->attr->nbytes= %d,
ocb->offset: %d, msg->i.nbytes: %d\n”,
ocb->attr->nbytes, ocb->offset, msg->i.nbytes);
if (nbytes > 0) {
/* set up the return data IOV /
SETIOV (ctp->iov, buffer + ocb->offset,
nbytes);
/ set up the number of bytes (returned by client’s
read()) /
_IO_SET_READ_NBYTES (ctp, nbytes);
// advance the offset by the number of bytes returned to the
client.
ocb->offset += nbytes;
nparts = 1;
} else {
_IO_SET_READ_NBYTES (ctp, 0);
nparts = 0;
}
/ mark the access time as invalid (we just accessed it)
*/
if (msg->i.nbytes > 0)
ocb->attr->flags |= IOFUNC_ATTR_ATIME;
return (_RESMGR_NPARTS (nparts));
}
[b:821cb8c323]Here is the main server function[/b:821cb8c323]
[code:1:821cb8c323]
/*
- 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>
#include <sys/resmgr.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;
extern int io_read (resmgr_context_t *ctp, io_read_t *msg,
RESMGR_OCB_T *ocb);
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;
/* Setup the default I/O functions to handle open/read/write/…
*/
iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &ConnectFuncs,
_RESMGR_IO_NFUNCS, &IoFuncs );
IoFuncs.read = io_read;
/* 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,
“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 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 */
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 )
{
dispatch_handler( ctp );
}
else
{
fprintf( stderr, “dispatch_block()
failed: %s\n”,
strerror( errno ) );
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
[/code:1:821cb8c323]