Project Home
Project Home
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - recvmsg(): (7 Items)
   
recvmsg()  
Public access to the QNX sources and development process is a wonderful thing.  I truly believe it will be QSSL's 
salvation.

Now on the topic of the Subject line, inspection of recvmsg.c (in lib/socket) shows why passing fds the POSIX way has 
never worked in Neutrino.

Thomas Fletcher has an excellent article at http://community.qnx.com/sf/docman/do/downloadDocument/projects.core_os/
docman.root.articles/doc1227
on what is needed at the QNX message-passing level.

Is anyone planning to apply this to recvmsg.c, or shall I have at it?

Thanks again to everyone at QSSL who has "seen the light" and pushed the idea and implementation of the open development
 process through.

   dB
Re: recvmsg()  
> Now on the topic of the Subject line, inspection of recvmsg.c (in lib/socket) 
> shows why passing fds the POSIX way has never worked in Neutrino.

Can you explain what exactly is not working ?
Re: recvmsg()  
> > Now on the topic of the Subject line, inspection of recvmsg.c (in lib/socket
> ) 
> > shows why passing fds the POSIX way has never worked in Neutrino.
> 
> Can you explain what exactly is not working ?

Sure, I use sendmsg() to pass a file descriptor, and recvmsg() to receive it, but recvmsg() gets an EBADF.

But my point is that you can see a couple of problems in recvmsg.c immediately by code inspection.  The most glaring one
 is that 'dupmsg', which is obviously supposed to contain an _IO_DUP message, never even gets its 'type' field 
initialized before being passed to MsgSendnc() (which is probably where the EBADF is coming from).  And the way 'nfds' 
is being initialized is completely silly (though you might be lucky enough to have it come out to 1 for the important 
special case where you are trying to pass a single fd anyway).

   dB
Re: recvmsg()  
Okay, sorry for the delay. This has been a while so I have to dig a little bit to find out what is happening.

First of all, the attached program showes a simple sending fd through unix domain socket. 

The good news is, it works. The "not so good news" is, while doing this, I also found a bug. If read_fd() pass in a 
smaller control message, it may crash io-pkt. PR53331 is filed for this.

To answer your question for recvmsg(). The "dupmsg" is pointing to a buffer that received from the stack (either in 
cmptr, or in extra tmpbuf). So the detail of the dupmsg is all filled by the stack before it passed to receiver side.

So the idea is, when sendmsg(), the stack queued all the information, when another process comes for recvmsg(), a "
dupmsg()" is returned in control message. The recvmsg() function will then send the _IO_DUP to the real resmgr, to dup 
the fd, and return it.

The only caveat (suppose to be documented somewhere, but I can't find it) is, the sender should not close the fd, before
 the receiver got it (dupped it). 

Does these all make sense now?
Attachment: Text fds.c 4.28 KB
Re: recvmsg()  
> To answer your question for recvmsg(). The "dupmsg" is pointing to a buffer 
> that received from the stack (either in cmptr, or in extra tmpbuf). So the 
> detail of the dupmsg is all filled by the stack before it passed to receiver 
> side.
> 
> So the idea is, when sendmsg(), the stack queued all the information, when 
> another process comes for recvmsg(), a "dupmsg()" is returned in control 
> message. The recvmsg() function will then send the _IO_DUP to the real resmgr,
>  to dup the fd, and return it.
> 
> The only caveat (suppose to be documented somewhere, but I can't find it) is, 
> the sender should not close the fd, before the receiver got it (dupped it). 
> 
> Does these all make sense now?

Thanks, yes, this does all make perfect sense now.  I had indeed foolishly assumed that the message being received by 
recvmsg() was the one being sent by sendmsg(), when in fact as you point out it is really a new one synthesized by the 
stack.

And when I apply your "caveat" (making sure the receiver has actually received the fd before allowing the sender to 
close it), I also find that my code works fine.  This also provides some insight into why my code had worked under 
monolithic kernels but not in Neutrino before now.

You're the best, Xiaodan!

   dB
Re: recvmsg()  
> > To answer your question for recvmsg(). The "dupmsg" is pointing to a buffer 
> 
> > that received from the stack (either in cmptr, or in extra tmpbuf). So the 
> > detail of the dupmsg is all filled by the stack before it passed to receiver
>  
> > side.
> > 
> > So the idea is, when sendmsg(), the stack queued all the information, when 
> > another process comes for recvmsg(), a "dupmsg()" is returned in control 
> > message. The recvmsg() function will then send the _IO_DUP to the real 
> resmgr,
> >  to dup the fd, and return it.
> > 
> > The only caveat (suppose to be documented somewhere, but I can't find it) is
> , 
> > the sender should not close the fd, before the receiver got it (dupped it). 
> 
> > 
> > Does these all make sense now?
> 
> Thanks, yes, this does all make perfect sense now.  I had indeed foolishly 
> assumed that the message being received by recvmsg() was the one being sent by
>  sendmsg(), when in fact as you point out it is really a new one synthesized 
> by the stack.
> 
> And when I apply your "caveat" (making sure the receiver has actually received
>  the fd before allowing the sender to close it), I also find that my code 
> works fine.  This also provides some insight into why my code had worked under
>  monolithic kernels but not in Neutrino before now.
> 
> You're the best, Xiaodan!
> 
>    dB


Good to hear it worked.

The caveat is unfortunatly our limitation. Hopefully that won't be too trouble for you to change the code to apply it. 

We have thought of some other ways to around it, but none are perfect. :(
Re: recvmsg()  
> Good to hear it worked.
> 
> The caveat is unfortunatly our limitation. Hopefully that won't be too trouble
>  for you to change the code to apply it. 
> 
> We have thought of some other ways to around it, but none are perfect. :(

The 1003.1-2001 spec specifically says, "Successful completion of a call to sendmsg() does not guarantee delivery of the
 message."

So the QNX limitation is legitimate POSIX behaviour.  If people like me need a full rendezvous, we have to arrange it 
ourselves.

Thanks again -

  dB