Replying from _IO_MSG.

Hi. I have (yet another) question. My porting project is coming along
very nicely; however, I have run into a real problem here.

The project consists of a resource manager that takes over three devices
(/somepath/snap, /somepath/sample, /somepath/event). An arbitrary
number of clients can then connect to this resource manager and store
data (of type snapshot, sample, or event, depending on the device used)
in it for later retrieval.

The interface is custom; under QNX 4, it was implemented with
qnx_ioctl() calls. Under Neutrino, I’m using the _IO_MSG interface.
When I try to return data, it doesn’t work.

In a nutshell, here is the code. In a common header file:


union reply_union_t {
struct {
unsigned short colls;
unsigned short drops;
unsigned short events;
} record;
// Other structs.
};


On the client side, I have:


io_msg_t msg;
reply_union_t reply;

msg.i.type = _IO_MSG;
msg.i.subtype = RP_RECORD;

// fd is a file descriptor to the resource manager
if (MsgSend(fd, &msg, sizeof(msg),
&reply.record, sizeof(reply.record)) == -1) {
return -1;
}

syslog(LOG_INFO, “%d, %d, %d”, reply.record.colls,

reply.record.drops,
reply.record.evts);


On the resource manager side, I have taken control of the _IO_MSG
request. I handle subtype RP_RECORD as so:


reply_union_t reply;

// Much processing…

// Dummy data, to test return.
reply.record.colls = 42;
reply.record.drops = 84;
reply.record.events = 126;

return (_RESMGR_PTR(ctp, &reply.record, sizeof(reply.record)));


The syslog from the client is:

56426, 45106, 48364

Needless to say, that is not what I’m expecting.

I have traced through the resource manager in the debugger; everything
seems to be working. The client is very simple, and it also appears
correct. However, I do not get back the data. What am I missing?

Also, if I try to return an error from the resource manager, errno is
always set to “No such process” (3) on the client side. Is this related?

As always, any help would be greatly appreciated. Thanks.

Josh Hamacher
FAAC Incorporated

Josh Hamacher <hamacher@faac.com> wrote:

In a nutshell, here is the code. In a common header file:



union reply_union_t {
struct {
unsigned short colls;
unsigned short drops;
unsigned short events;
} record;
// Other structs.
};



On the resource manager side, I have taken control of the _IO_MSG
request. I handle subtype RP_RECORD as so:



reply_union_t reply;

Is the reply variable local to the handler function? If so,
it is on the stack, and will be freed when you return.

// Much processing…

// Dummy data, to test return.
reply.record.colls = 42;
reply.record.drops = 84;
reply.record.events = 126;

return (_RESMGR_PTR(ctp, &reply.record, sizeof(reply.record)));

But the data won’t be sent to the client until after… as the above
only gives the upper level a pointer to the buffer…

Also, if I try to return an error from the resource manager, errno is
always set to “No such process” (3) on the client side. Is this related?

I’d have to see how you are returning an error – it shouldn’t be related.

-David

QNX Training Services
dagibbs@qnx.com

Doh! That was a good catch - it was a stack variable. When I made it
static, everything worked as I anticipated. I knew it had to be
something simple like that - thanks a lot.

As for the error, if I do something like “return ENOMEM;” from the
resource manager, the client’s MsgSend() does fail. But when I print
out errno, it always comes out as “errno 3: No such process”. I’ve
tried that with various errors, and they all seem to be 3.

Josh

Josh Hamacher <hamacher@faac.com> wrote:

Doh! That was a good catch - it was a stack variable. When I made it
static, everything worked as I anticipated. I knew it had to be
something simple like that - thanks a lot.

As for the error, if I do something like “return ENOMEM;” from the
resource manager, the client’s MsgSend() does fail. But when I print
out errno, it always comes out as “errno 3: No such process”. I’ve
tried that with various errors, and they all seem to be 3.

No idea why that would happen. I’ve seen lots and lots of code where
it works as expected.

Are you sure you don’t have a:

if (errno = ESRCH)

instead of:

if (errno == ESRCH)

on the client side?

-David

QNX Training Services
dagibbs@qnx.com

I have an old saying. “There are only two kinds of mistakes. Stupid
mistakes, and ones you can blame on someone else.”

Damn! How often, when I find my problems, I can’t find someone else to
blame them on. ;-}

“Josh Hamacher” <hamacher@faac.com> wrote in message
news:3B79603F.7090607@faac.com

Doh! That was a good catch - it was a stack variable. When I made it
static, everything worked as I anticipated. I knew it had to be
something simple like that - thanks a lot.