problems with io_read

Hello,

I have a problem with the following resource manager example from the
qnx website :


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

int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T
*ocb);

static char *buffer = “Hello world\n”;

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL)
{
fprintf(stderr, “%s: Unable to allocate dispatch
handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
io_funcs.read = io_read;

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
attr.nbytes = strlen(buffer)+1;

/* attach our device name */
if((id = resmgr_attach(dpp, &resmgr_attr,
“/dev/sample”, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs,
&attr)) == -1) {
fprintf(stderr, “%s: Unable to attach
name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) ==
NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}

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);

/*

  • On all reads (first and subsequent), calculate
  • how many bytes we can return to the client,
  • based upon the number of bytes available (nleft)
  • and the client’s buffer size
    */

nleft = ocb->attr->nbytes - ocb->offset;
nbytes = min (msg->i.nbytes, nleft);

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 {
/*

  • they’ve asked for zero bytes or they’ve already previously
  • read everything
    */

_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));
}

I can read from /dev/sample with “cat /dev/sample”, but how can I read
from a client process. I tried the following, but len is always -1. If
I try to read only one character, it works.

[code:1:9dd9eeeeb9]
#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <fcntl.h>
#include <devctl.h>
#include <time.h>

int main(void){
int dev;
int len;
char* buf;
char character;
dev=open("/dev/sample",O_RDONLY);
if (dev == -1){
printf(“unable to open
%s\n”,"/dev/sample");
return;
}
printf(“reading … \n”);

//read (dev, &character, 1);
//printf (“Got a character “%c”\n”,
character);

len = read (dev, buf, 4096);
printf(“len : %d \n”,len);
printf(“buf : %s”, buf);
close(dev);
} [/code:1:9dd9eeeeb9]

I hope you can help me, regards.

tobiZI wrote:

Hello,

I have a problem with the following resource manager example from the
qnx website :


#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h
#include <sys/iofunc.h
#include <sys/dispatch.h

int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T
*ocb);

static char *buffer = “Hello world\n”;

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL)
{
fprintf(stderr, “%s: Unable to allocate dispatch
handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
io_funcs.read = io_read;

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
attr.nbytes = strlen(buffer)+1;

/* attach our device name */
if((id = resmgr_attach(dpp, &resmgr_attr,
“/dev/sample”, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs,
&attr)) == -1) {
fprintf(stderr, “%s: Unable to attach
name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) ==
NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}

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);

/*

  • On all reads (first and subsequent), calculate
  • how many bytes we can return to the client,
  • based upon the number of bytes available (nleft)
  • and the client’s buffer size
    */

nleft = ocb->attr->nbytes - ocb->offset;
nbytes = min (msg->i.nbytes, nleft);

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 {
/*

  • they’ve asked for zero bytes or they’ve already previously
  • read everything
    */

_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));
}

I can read from /dev/sample with “cat /dev/sample”, but how can I read
from a client process. I tried the following, but len is always -1. If
I try to read only one character, it works.

[code:1:9dd9eeeeb9]
#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h
#include <sys/iofunc.h
#include <sys/dispatch.h
#include <fcntl.h
#include <devctl.h
#include <time.h

int main(void){
int dev;
int len;
char* buf;
char character;
dev=open("/dev/sample",O_RDONLY);
if (dev == -1){
printf(“unable to open
%s\n”,"/dev/sample");
return;
}
printf(“reading … \n”);

//read (dev, &character, 1);
//printf (“Got a character “%c”\n”,
character);

len = read (dev, buf, 4096);
printf(“len : %d \n”,len);
printf(“buf : %s”, buf);
close(dev);
} [/code:1:9dd9eeeeb9]

I hope you can help me, regards.

If you compile your client code with warnings turned on you’ll be warned

that “‘buf’ might be used uninitialized in this function.” Before you
fix that problem, you might want to print errno when len is -1.

Murf

Murf

tobiZI wrote:

if (msg->i.xtype & _IO_XTYPE_MASK !=
_IO_XTYPE_NONE)
return (ENOSYS);

This, by the way, is an operator precedence error (yes, in the docs),
which will happen to work in most cases; it needs () around the & bit;
but is not your real problem …

char* buf;

You never actually allocate buf to point at valid storage, so I’d say
the error is -1/EFAULT. You need to either do “buf=malloc(4096)” or
declare storage inline as “char buf[4096]”

John Garvey <jgarvey@qnx.com> wrote:

tobiZI wrote:

if (msg->i.xtype & _IO_XTYPE_MASK !=
_IO_XTYPE_NONE)
return (ENOSYS);

This, by the way, is an operator precedence error (yes, in the docs),

The docs have already been corrected.


Steve Reid stever@qnx.com
TechPubs (Technical Publications)
QNX Software Systems