In article <m2y2dunwuf....@thuvia.hamartun.priv.no>, Tom Ivar Helbekkmo <t...@hamartun.priv.no> wrote: >Some time last year, probably late summer or autumn, a change was made >that caused transfer of small chunks of data over unix domain sockets to >have a higher chance of resulting in a read() getting only part of the >chunk. > >While there is no guarantee of a one to one relationship between writes >and reads, it seems that some applications expect this. In my case, it >was jack (pkgsrc/audio/jack) that failed. It comes with, among other >things, a daemon, jackd, and a library for use by clients wishing to >connect to it. Communication between jackd and its clients became >impossible with this change, because the code in jack expects to be able >to exchange C structs between server and clients. The jackd server has >a thread that uses poll() to wait for available packets from clients, >and when something arrives, it is read with code like this example: > > if (read (client_fd, &req, sizeof(req)) != sizeof(req)) { > jack_error ("cannot read ACK connection request from client"); > return -1; > } > >The client_fd is an open unix domain stream socket, and it is *not* in >non-blocking mode. The structs being transfered are of various sizes, >and can, from a casual inspection of the header files, be up to a couple >of hundred bytes long. > >Data is written to the sockets using code like this: > > if (write (reply_fd, &req, sizeof(req)) < (ssize_t)sizeof(req)) { > jack_error ("cannot write request result to client"); > return -1; > } > >Meanwhile, in the client library, the code at the other end of this >communication is simply: > > if (write (fd, &req, sizeof(req)) != sizeof(req)) { > jack_error ("cannot write event connect request to server (%s)", > strerror (errno)); > close (fd); > return -1; > } > > if (read (fd, &res, sizeof(res)) != sizeof(res)) { > jack_error ("cannot read event connect result from server (%s)", > strerror (errno)); > close (fd); > return -1; > } > >Obviously, poll() will return, with information about available data, >before the entire chunk written by the other end is available. > >I haven't filed a PR on this, as it isn't technically an error in >NetBSD. However, if there is a wide-spread belief out there that code >such as this will "just work" (I'm guessing it "just works" on Linux, >just like it does on NetBSD < 10), and it's not otherwise detrimental to >have the data from a single write() call all be available to the reader >of the socket before triggering a select() or poll() that's waiting for >it, then maybe such an adjustment should be considered.
Can you please file a PR with an example to keep track of it. It is a behavior change after all and we should understand why it happened. christos