From: Jonathan Nieder Date: Thu, 27 May 2010 10:10:43 GMT Subject: [PATCH] compat: Add another rudimentary poll() emulation Message-ID: <20100527101043.GA4390@progeny.tock> In-Reply-To: <1274948384-167-2-git-send-email-abcd@gentoo.org> Implement the subset of poll() semantics needed by git in terms of select(), for use by the Interix port. Inspired by commit 6ed807f (Windows: A rudimentary poll() emulation, 2007-12-01). Cc: Johannes Sixt Cc: Jonathan Callen Signed-off-by: Jonathan Nieder --- Jonathan Callen wrote: > Some systems do not have sys/poll.h or poll(2). Maybe this could help. Thanks to DrNick on IRC for the suggestion. Warning: untested. Makefile | 8 ++++++++ compat/poll.c | 33 +++++++++++++++++++++++++++++++++ compat/poll.h | 13 +++++++++++++ git-compat-util.h | 6 +++++- 4 files changed, 59 insertions(+), 1 deletions(-) create mode 100644 compat/poll.c create mode 100644 compat/poll.h diff --git a/Makefile b/Makefile index 2f5d631..6715528 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,9 @@ all:: # # Define NO_PTHREADS if you do not have or do not want to use Pthreads. # +# Define NO_POLL if you have a problem with the poll() system call (e.g. +# Interix). +# # Define NO_PREAD if you have a problem with pread() system call (e.g. # cygwin1.dll before v1.5.22). # @@ -470,6 +473,7 @@ LIB_H += commit.h LIB_H += compat/bswap.h LIB_H += compat/cygwin.h LIB_H += compat/mingw.h +LIB_H += compat/poll.h LIB_H += compat/win32/pthread.h LIB_H += csum-file.h LIB_H += decorate.h @@ -1284,6 +1288,10 @@ endif ifdef OBJECT_CREATION_USES_RENAMES COMPAT_CFLAGS += -DOBJECT_CREATION_MODE=1 endif +ifdef NO_POLL + BASIC_CFLAGS += -DNO_POLL + COMPAT_OBJS += compat/poll.o +endif ifdef NO_PREAD COMPAT_CFLAGS += -DNO_PREAD COMPAT_OBJS += compat/pread.o diff --git a/compat/poll.c b/compat/poll.c new file mode 100644 index 0000000..33c6ae0 --- /dev/null +++ b/compat/poll.c @@ -0,0 +1,33 @@ +#include "../git-compat-util.h" + +int git_poll(struct git_pollfd *ufds, int nfds, int timeout) +{ + int i, maxfd, result; + fd_set fds; + + if (timeout >= 0) { + if (nfds == 0) { + sleep(timeout); + return 0; + } + return errno = EINVAL, error("poll timeout not supported"); + } + + FD_ZERO(&fds); + maxfd = 0; + for (i = 0; i < nfds; i++) { + if (ufds[i].events != POLLIN) + return errno = EINVAL, error("poll: unsupported events"); + maxfd = (ufds[i].fd > maxfd) ? ufds[i].fd : maxfd; + FD_SET(ufds[i].fd, &fds); + } + + result = select(maxfd + 1, &fds, NULL, NULL, NULL); + if (result == -1) + return result; + for (i = 0; i < nfds; i++) { + if (FD_ISSET(ufds[i].fd, &fds)) + ufds[i].revents |= POLLIN; + } + return result; +} diff --git a/compat/poll.h b/compat/poll.h new file mode 100644 index 0000000..65775ab --- /dev/null +++ b/compat/poll.h @@ -0,0 +1,13 @@ +#ifndef POLLIN +#define POLLIN 1 +#define POLLHUP 2 +#endif + +#define pollfd git_pollfd +#define poll git_poll +struct git_pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +extern int git_poll(struct git_pollfd *fds, int nfds, int timeout); diff --git a/git-compat-util.h b/git-compat-util.h index 824c175..2494378 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -94,13 +94,17 @@ #include #ifndef __MINGW32__ #include -#include #include #include #include #ifndef NO_SYS_SELECT_H #include #endif +#ifdef NO_POLL +#include "compat/poll.h" +#else +#include +#endif #include #include #include -- 1.7.1