-/* $Id: catman.c,v 1.14 2017/02/06 19:02:37 schwarze Exp $ */
+/* $Id: catman.c,v 1.21 2017/02/18 12:24:24 schwarze Exp $ */
/*
* Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
* Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
*/
#include "config.h"
+#if HAVE_CMSG_XPG42
+#define _XPG4_2
+#endif
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#include <unistd.h>
int process_manpage(int, int, const char *);
int process_tree(int, int);
void run_mandocd(int, const char *, const char *)
- __attribute__((noreturn));
+ __attribute__((__noreturn__));
ssize_t sock_fd_write(int, int, int, int);
-void usage(void) __attribute__((noreturn));
+void usage(void) __attribute__((__noreturn__));
void
if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)
err(1, "snprintf");
if (defos == NULL)
- execlp("mandocd", "mandocd", "-T", outtype, sockfdstr, NULL);
+ execlp("mandocd", "mandocd", "-T", outtype,
+ sockfdstr, (char *)NULL);
else
execlp("mandocd", "mandocd", "-T", outtype,
- "-I", defos, sockfdstr, NULL);
+ "-I", defos, sockfdstr, (char *)NULL);
err(1, "exec");
}
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 {
} cmsgu;
struct cmsghdr *cmsg;
int *walk;
+ ssize_t sz;
unsigned char dummy[1] = {'\0'};
iov.iov_base = dummy;
*(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
void
usage(void)
{
- fprintf(stderr, "usage: catman [-I os=name] [-T output] "
- "srcdir dstdir\n");
+ fprintf(stderr, "usage: %s [-I os=name] [-T output] "
+ "srcdir dstdir\n", BINM_CATMAN);
exit(1);
}