=================================================================== RCS file: /cvs/mandoc/catman.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -p -r1.14 -r1.15 --- mandoc/catman.c 2017/02/06 19:02:37 1.14 +++ mandoc/catman.c 2017/02/08 14:50:53 1.15 @@ -1,4 +1,4 @@ -/* $Id: catman.c,v 1.14 2017/02/06 19:02:37 schwarze Exp $ */ +/* $Id: catman.c,v 1.15 2017/02/08 14:50:53 schwarze Exp $ */ /* * Copyright (c) 2017 Michael Stapelberg * Copyright (c) 2017 Ingo Schwarze @@ -34,6 +34,7 @@ #include #include #include +#include #include int process_manpage(int, int, const char *); @@ -62,6 +63,7 @@ run_mandocd(int sockfd, const char *outtype, const cha ssize_t sock_fd_write(int fd, int fd0, int fd1, int fd2) { + const struct timespec timeout = { 0, 10000000 }; /* 0.01 s */ struct msghdr msg; struct iovec iov; union { @@ -70,6 +72,7 @@ sock_fd_write(int fd, int fd0, int fd1, int fd2) } cmsgu; struct cmsghdr *cmsg; int *walk; + ssize_t sz; unsigned char dummy[1] = {'\0'}; iov.iov_base = dummy; @@ -93,7 +96,21 @@ sock_fd_write(int fd, int fd0, int fd1, int fd2) *(walk++) = fd1; *(walk++) = fd2; - return sendmsg(fd, &msg, 0); + /* + * It appears that on some systems, sendmsg(3) + * may return EAGAIN even in blocking mode. + * Seen for example on Oracle Solaris 11.2. + * The sleeping time was chosen by experimentation, + * to neither cause more than a handful of retries + * in normal operation nor unnecessary delays. + */ + for (;;) { + if ((sz = sendmsg(fd, &msg, 0)) != -1 || + errno != EAGAIN) + break; + nanosleep(&timeout, NULL); + } + return sz; } int