From "man sendfile" on both OSX and FreeBSD: <<[EINTR] A signal interrupted sendfile() before it could be completed. If specified, the number of bytes successfully sent will be returned in *len.>> Right now we catch EINTR and simply retry. Instead we should only retry is no bytes were sent, else we should return those bytes, similarly to what we do on EAGAIN and EBUSY: https://github.com/python/cpython/blob/2438cdf0e932a341c7613bf4323d06b91ae9f1f1/Modules/posixmodule.c#L8907-L8917
Wasn't the point of PEP475 that all EINTR returns would be explicitly handled by retrying rather than forcing the user to handle it? Seems like the correct solution is still to retry, but on OSX/FreeBSD we'd need to update the offset and count arguments to account for the data that has already been sent.
sendfile() on BSD/OSX is complicated by the headers/trailers args. You'll have to take that into account in the retry logic, adding unnecessary complexity. Since sendfile() may already return fewer bytes than requested (e.g. non-blocking sockets or big files) it's just easier to return the bytes sent thus far (if any). I can work on a patch once I find some time. > Wasn't the point of PEP475 that all EINTR returns would be explicitly handled by retrying rather than forcing the user to handle it? From PEP475: <<[...] to relieve application code from the burden of doing so>>
type: behaviortitle: os.sendfile() on BSD and macOS does not return bytes sent on EINTR -> os.sendfile() on BSD, macOS don't return bytes sent on EINTR
title: os.sendfile() on BSD OSs and macOS does not return bytes sent on EINTR -> os.sendfile() on BSD and macOS does not return bytes sent on EINTR
2019-03-30 19:39:10
ned.deily
set
title: BSD/OSX: os.sendfile() does not return bytes sent on EINTR -> os.sendfile() on BSD OSs and macOS does not return bytes sent on EINTRversions: - Python 3.6