Partial reads and writes when passing file descriptors
I am writing a system that will use Unix domain sockets to pass
descriptors between unrelated processes using the sendmsg() and
recvmsg() functions, as described in Steven's Unix network programming
book.
The book says that it's good practice to send at least one byte of
data with your descriptor so that the caller can distibguish between
eof and an error in the server. In my example I would like to send 8
bytes. However I am not sure what the semantics of partial reads and
writes are wrt passing descriptors.
If I do a sendmsg() with 8 bytes of data and a descriptor, and it
returns 4, does that mean that the descriptor is sent or not? Can
partial writes even occur over Unix domain sockets?
On the receiving side I guess it's easier; I can recvmsg() repeatedly
until I have 8 bytes and hopefully one of those calls will also give
me a descriptor.
Grateful for any insight.
Thanks, Sam
Re: Partial reads and writes when passing file descriptors
[email]sam.jervis@gmail.com[/email] writes:[color=blue]
> I am writing a system that will use Unix domain sockets to pass
> descriptors between unrelated processes using the sendmsg() and
> recvmsg() functions, as described in Steven's Unix network programming
> book.
>
> The book says that it's good practice to send at least one byte of
> data with your descriptor so that the caller can distibguish between
> eof and an error in the server. In my example I would like to send 8
> bytes. However I am not sure what the semantics of partial reads and
> writes are wrt passing descriptors.
>
> If I do a sendmsg() with 8 bytes of data and a descriptor, and it
> returns 4, does that mean that the descriptor is sent or not?[/color]
Assuming the call didn't return an error, you have requested that the
system should send a particular control msg. There is no way the
system could inform you about 'partially sent' control messages and no
way to specify a 'partial, continued control message' (or a 'retry to
send a control message). This means that when the system accepted your
request, a control message will be sent and doing another sendmsg call
with the same control message information would result in a second
control message.
[color=blue]
> Can partial writes even occur over Unix domain sockets?[/color]
Theoretically, sendmsg is supposed to either block until a message can
be sent or return an error indicating that it couldn't when O_NONBLOCK
is set. In practice, this depends on the implementation. At least
for Linux 2.4 PF_UNIX stream sockets, they can: Data is sent as series
of skbs of 'some maximum size' (a little less than 16K) and a partial
write can occur if a memory allocation fails before all of the data
has been handled (or if a copy operation would have resulted in
EFAULT).
[color=blue]
> On the receiving side I guess it's easier; I can recvmsg() repeatedly
> until I have 8 bytes and hopefully one of those calls will also give
> me a descriptor.[/color]
If you are not actually reading a byte stream, but some stream of
'structured messages' (of certain sizes), you could be using a
datagram socket instead (neither partial writes nor partial reads) or
use MSG_WAITALL in the received (tells the kernel that the system call
should not return unless the requested amount of data is available [or
some error occurs]).
Re: Partial reads and writes when passing file descriptors
Thanks - that's the reassurance I was looking for.
I don't think I can use a datagram socket for my system as it needs to
be connection orientated, but MSG_WAITALL could be helpful.