diff options
Diffstat (limited to 'src/sysdeps/tryokwaitall.c')
-rw-r--r-- | src/sysdeps/tryokwaitall.c | 117 |
1 files changed, 0 insertions, 117 deletions
diff --git a/src/sysdeps/tryokwaitall.c b/src/sysdeps/tryokwaitall.c deleted file mode 100644 index 15721b5..0000000 --- a/src/sysdeps/tryokwaitall.c +++ /dev/null @@ -1,117 +0,0 @@ -/* ISC license. */ - -#undef _POSIX_C_SOURCE -#undef _XOPEN_SOURCE - -#ifndef _XPG4_2 -# define _XPG4_2 -#endif - -#ifndef _BSD_SOURCE -#define _BSD_SOURCE -#endif - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/uio.h> -#if defined(__FreeBSD__) -#include <sys/param.h> -#endif - -#ifndef MSG_NOSIGNAL -#define MSG_NOSIGNAL 0 -#endif - -static int ndelay_on (int fd) -{ - register int got = fcntl(fd, F_GETFL) ; - return (got == -1) ? -1 : fcntl(fd, F_SETFL, got | O_NONBLOCK) ; -} - -static int child (int p, int fd) -{ - char c ; - struct iovec v = { .iov_base = &c, .iov_len = 1 } ; - struct msghdr msg = - { - .msg_name = 0, - .msg_namelen = 0, - .msg_iov = &v, - .msg_iovlen = 1, - .msg_control = 0, - .msg_controllen = 0 - } ; - fd_set rfds ; - if (ndelay_on(fd) < 0) return 111 ; - FD_ZERO(&rfds) ; - FD_SET(fd, &rfds) ; - if (write(p, "", 1) < 1) return 111 ; /* sync with the parent */ - if (select(fd+1, &rfds, 0, 0, 0) < 1) return 111 ; - - /* On buggy systems, the following recvmsg will block, despite - setting the fd non-blocking */ - - if (recvmsg(fd, &msg, MSG_WAITALL) < 1) return 111 ; - if (write(p, "", 1) < 1) return 111 ; - return 0 ; -} - -static int parent (pid_t pid, int p, int fd) -{ - char c ; - struct iovec v = { .iov_base = &c, .iov_len = 1 } ; - struct msghdr msg = - { - .msg_name = 0, - .msg_namelen = 0, - .msg_iov = &v, - .msg_iovlen = 1, - .msg_control = 0, - .msg_controllen = 0 - } ; - struct timeval tv = { .tv_sec = 2, .tv_usec = 0 } ; - fd_set rfds ; - unsigned int n = p > fd ? p : fd ; - int r ; - FD_ZERO(&rfds) ; - FD_SET(p, &rfds) ; - if (read(p, &c, 1) < 1) return 111 ; - if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 1) return 111 ; - for (;;) - { - r = select(n+1, &rfds, 0, 0, &tv) ; - if (r >= 0 || errno != EINTR) break ; - } - if (!r) /* child is still blocking on recvmsg() after 2 seconds */ - { - kill(pid, SIGTERM) ; - return 1 ; - } - if (read(p, &c, 1) < 1) return 111 ; - return 0 ; -} - -int main (void) -{ - pid_t pid ; - int fd[2] ; - int p[2] ; - if (pipe(p) < 0) return 111 ; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0) return 111 ; - pid = fork() ; - if (pid < 0) return 111 ; - if (!pid) - { - close(p[0]) ; - close(fd[0]) ; - return child(p[1], fd[1]) ; - } - close(p[1]) ; - close(fd[1]) ; - return parent(pid, p[0], fd[0]) ; -} |