=================================================================== RCS file: /cvs/mandoc/catman.c,v retrieving revision 1.14 retrieving revision 1.16 diff -u -p -r1.14 -r1.16 --- mandoc/catman.c 2017/02/06 19:02:37 1.14 +++ mandoc/catman.c 2017/02/08 16:11:40 1.16 @@ -1,4 +1,4 @@ -/* $Id: catman.c,v 1.14 2017/02/06 19:02:37 schwarze Exp $ */ +/* $Id: catman.c,v 1.16 2017/02/08 16:11:40 schwarze Exp $ */ /* * Copyright (c) 2017 Michael Stapelberg * Copyright (c) 2017 Ingo Schwarze @@ -17,6 +17,10 @@ */ #include "config.h" +#if HAVE_CMSG_XPG42 +#define _XPG4_2 +#endif + #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include int process_manpage(int, int, const char *); @@ -62,6 +67,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 +76,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 +100,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