Armin Steinhoff <A-Steinhoff@web_.de> wrote:
David Gibbs wrote:
Well, then you have to check:
– has the client opened the fd with O_NONBLOCK?
– if so, reply to the client that you’ve handled 1K
_IO_SET_WRITE_NBYTES( ctp, 1k );
return( _RESMGR_NPARTS(0) );
Does it mean that the client (e.g. cp) will send the rest of the 4k
in messages with the size of 1k … after receiving the first 1k
reply?
The client could, but need not. But, the client should be checking
the return value of write() and if they asked for 4K, and only got
1K written, should try to send the rest of the 4K – either as a 3K
chunk, or as the first 3K of their next 4K chunk. I don’t know how
carefully cp or cat are written – cp may assume this is a “disk full”
situation and fail at that point. (As it is presumed to be writing
to a filesystem, and that would either handle it all, or fail, and
would have O_NONBLOCK set anyway, so would be unlikely to end up in
that situation.)
– if you can’t handle anything, fail the call with EWOULDBLOCK
return( EWOULDBLOCK)
OK … I will switch from EAGAIN to EWOULDBLOCK.
Won’t make any difference, from errno.h :
#define EWOULDBLOCK EAGAIN /* Operation would block */
– if you can block the client, you don’t reply:
– store away rcvid & any info you’ll need
return( RESMGR_NOREPLY )
And, in some other code, when you’re done processing, issue a
MsgReply() to the client directly.
… how to do that MsgReply in the case of a io_write was the
problem.
The status field in the MsgReply becomes the return value from the
clients MsgSendv(), and the write() library routine basically passes
that back up to the client.
The write() library routine basically looks like:
int write( fd, buf,nbytes)
{
iov_t iov[2];
write_hdr hdr;
hdr.nbytes = nbytes;
hdr.type = _IO_WRITE;
SETIOV(&iov[0], &hdr, sizeof(hdr) );
SETIOV(&iov[1], buf, nbytes );
return MsgSendv(fd, iov, 2, NULL, 0 );
}
So, you would:
MsgReply( rcvid, bytes_handled, NULL, 0 );
Once you’ve handled the data.
-David
QNX Training Services
dagibbs@qnx.com