io_read cannot get nbytes count

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]

aryckw wrote:

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

The server’s printf in io_read comes up with 0’s for all values

Where do you set the size of the object to be non-zero? (in this
example a line similar to “IoFuncAttr.nbytes = strlen(buffer);” right
after the iofunc_attr_init() would be a good idea) …

Does the nbytes field represent the size of the device being managed?

aryckw <watz_31337@yahoo-dot-com.no-spam.invalid> wrote:

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.

The problem is in your printf format for ocb->offset – it is a 64
bit integer, you’re formatting it as 32 bit, which means the next
%d grabs the other 32 bits of ocb->offset (all zero) instead of
the contents of msg->i.nbytes as you expected.

Change this:

printf(“serv: io_read, ocb->attr->nbytes= %d,
ocb->offset: %d, msg->i.nbytes: %d\n”,
ocb->attr->nbytes, ocb->offset, msg->i.nbytes);

To:
printf(“serv: io_read, ocb->attr->nbytes= %d,
ocb->offset: %lld, msg->i.nbytes: %d\n”,
ocb->attr->nbytes, ocb->offset, msg->i.nbytes);

-David

David Gibbs
QNX Training Services
dagibbs@qnx.com