sock_receive_internal() and its (ab)use of uio
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com soreceive(so, NULL, uiop, NULL, NULL, flagsp); My first attempt at a KPI replacement looked like this: size_t bytes = uio->uio_resid; struct msghdr msg = {0}; msg.msg_iov = uiop->uio_iov; msg.msg_iovlen = uiop->uio_iovcnt; error = sock_receive(so, &msg, 0, &bytes); if (!error) { uiop->uio_offset += bytes; uiop->uio_resid -= bytes; ASSERT(uiop->uio_resid >= 0); } Sam _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... I'm trying to clean up the areas in our code where I'm using symbols from mach_kernel instead of the 10.4 KPI. One of these is the use of soreceive() and sosend(). I avoided using the KPI on these two initially because the new interface that uses struct msghdr looked confusing. Now that I've delved into it a bit more it looks pretty much unworkable. Let me use sock_receive() here as an example. When linking directly to the kernel, I can simply pass a uio pointer to soreceive() as follows: I can do this safe in the knowledge that it will use uio_move() to transfer the data it reads into my uio, using and updating my uio_offset and uio_resid fields as appropriate. But it's clearly deficient because the uio_offset isn't being passed into sock_receive(). It's also not clear that it will use my uio_resid value. Sure enough when you run it up, this code asserts pretty quickly, having read more than I wanted it to. The problem as I see it is that the new socket KPI doesn't allow you to specify an offset and a resid along with your iovecs. It's therefore not possible to read into a range of memory somewhere in the middle of the buffers represented by your iovecs. If you use sock_receivembuf(), the data argument to sock_receive_internal() won't be NULL and the value in recvdlen will get used as the uio's resid. This solves one of the problems. Unfortunately the call to uio_createwithbuffer() will still specify 0 for the initial offset of the uio, so this is no good if you want to read into somewhere in the middle of your buffers. The only solution I can see at the moment is to create yet another uio structure before calling sock_receive(). This uio would be given iovecs with data addresses and lengths that represent the region of the original buffers to be received into. This is clearly not an optimal solution, given the extra overhead and unnecessary code to write and debug. It seems odd to me that the shiny new uio KPI wasn't used in the sock_receive() and sock_send() interfaces, since this is exactly the functionality that uios are designed (and were previously used) for. I've raised a radar bug requesting sock_receive_uio() and sock_send_uio() to be added, (#4191646) but I'd be interested to hear other people's opinions on this. This email sent to site_archiver@lists.apple.com
participants (1)
-
Sam Vaughan