Am Wed, Apr 13, 2022 at 09:51:31PM -0000 schrieb Christos Zoulas: > In article <Ylcr/ndudne2a...@bec.de>, Joerg Sonnenberger <jo...@bec.de> > wrote: > >Am Tue, Apr 12, 2022 at 04:56:05PM -0000 schrieb Christos Zoulas: > > >splice(2) as a concept is much older than the current Linux implementation. > >There is no reason why zero-copying for sockets should require a > >different system call for zero-copying from/to pipes. There are valid > >reasons for other combinations, too. Consider /bin/cp for example. > > You don't need two system calls because the kernel knows the type of > the file descriptors and can dispatch to different implementations. > One of the questions is do you provide the means to pass an additional > header/trailer to the output data like FreeBSD does for its sendfile(2) > implementation? > > int > splice(int infd, off_t *inoff, int outfd, off_t *outoff, size_t len, > const struct { > struct iov *head; > size_t headcnt; > struct iov *tail; > size_t tailcnt; > } *ht, int flags);
There are essentially two use cases here: (1) I want a simple interface to transfer data from one fd to another without extra copies. (2) I wanto avoid copies AND I want to avoid system calls. For the former: int splice(int dstfd, int srcfd, off_t *len); is more than good enough. "Transfer up to [*len] octets from srcfd to dstfd, updating [len] with the actually transferred amount and returning the first error if any. For the second category, an interface more like the posix_spawn interface (but without all the extra allocations) would be useful. > >I was saying that the Linux system call can be implemented without a > >kernel backend, because I don't consider zero copy a necessary part of > >the interface contract. It's a perfectly valid, if a bit slower > >implementation to do allocate a kernel buffer and do IO via that. > > Of course, but how do you make an existing binary use it? LD_PRELOAD > a binary to override the symbol in the linux glibc? By that logic you > don't need an in kernel linux emulation, you can do it all in userland :-) You still provide the system call as front end, but internally implement it on top of regular read/write to a temporary buffer. Joerg