BUG/MINOR: polling: some events were not set in various pollers

fdtab[].ev was only set in ev_sepoll. Unfortunately, some I/O handling
functions now rely on this, so depending on the polling mechanism, some
useless operations might have been performed, such as performing a useless
recv() when a HUP was reported.

This is a very old issue, the flags were only added to the fdtab and not
propagated into any poller. Then they were used in ev_sepoll which needed
them for the cache. It is unsure whether a backport to 1.4 is appropriate
or not.
diff --git a/src/ev_epoll.c b/src/ev_epoll.c
index bc7493b..7026d56 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -242,19 +242,31 @@
 	measure_idle();
 
 	for (count = 0; count < status; count++) {
+		int e = epoll_events[count].events;
 		fd = epoll_events[count].data.fd;
 
+		/* it looks complicated but gcc can optimize it away when constants
+		 * have same values.
+		 */
+		fdtab[fd].ev &= FD_POLL_STICKY;
+		fdtab[fd].ev |=
+			((e & EPOLLIN ) ? FD_POLL_IN  : 0) |
+			((e & EPOLLPRI) ? FD_POLL_PRI : 0) |
+			((e & EPOLLOUT) ? FD_POLL_OUT : 0) |
+			((e & EPOLLERR) ? FD_POLL_ERR : 0) |
+			((e & EPOLLHUP) ? FD_POLL_HUP : 0);
+
 		if ((fd_evts[FD2OFS(fd)] >> FD2BIT(fd)) & DIR2MSK(DIR_RD)) {
 			if (fdtab[fd].state == FD_STCLOSE)
 				continue;
-			if (epoll_events[count].events & ( EPOLLIN | EPOLLERR | EPOLLHUP ))
+			if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
 				fdtab[fd].cb[DIR_RD].f(fd);
 		}
 
 		if ((fd_evts[FD2OFS(fd)] >> FD2BIT(fd)) & DIR2MSK(DIR_WR)) {
 			if (fdtab[fd].state == FD_STCLOSE)
 				continue;
-			if (epoll_events[count].events & ( EPOLLOUT | EPOLLERR | EPOLLHUP ))
+			if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR|FD_POLL_HUP))
 				fdtab[fd].cb[DIR_WR].f(fd);
 		}
 	}
diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c
index b43533a..df4f920 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -142,12 +142,14 @@
 			if (FD_ISSET(fd, fd_evts[DIR_RD])) {
 				if (fdtab[fd].state == FD_STCLOSE)
 					continue;
+				fdtab[fd].ev |= FD_POLL_IN;
 				fdtab[fd].cb[DIR_RD].f(fd);
 			}
 		} else if (kev[count].filter ==  EVFILT_WRITE) {
 			if (FD_ISSET(fd, fd_evts[DIR_WR])) {
 				if (fdtab[fd].state == FD_STCLOSE)
 					continue;
+				fdtab[fd].ev |= FD_POLL_OUT;
 				fdtab[fd].cb[DIR_WR].f(fd);
 			}
 		}
diff --git a/src/ev_poll.c b/src/ev_poll.c
index ec18863..8f2e1d9 100644
--- a/src/ev_poll.c
+++ b/src/ev_poll.c
@@ -143,25 +143,33 @@
 	measure_idle();
 
 	for (count = 0; status > 0 && count < nbfd; count++) {
+		int e = poll_events[count].revents;
 		fd = poll_events[count].fd;
 	  
-		if (!(poll_events[count].revents & ( POLLOUT | POLLIN | POLLERR | POLLHUP )))
+		if (!(e & ( POLLOUT | POLLIN | POLLERR | POLLHUP )))
 			continue;
 
+		fdtab[fd].ev &= FD_POLL_STICKY;
+		fdtab[fd].ev |=
+			((e & POLLIN ) ? FD_POLL_IN  : 0) |
+			((e & POLLOUT) ? FD_POLL_OUT : 0) |
+			((e & POLLERR) ? FD_POLL_ERR : 0) |
+			((e & POLLHUP) ? FD_POLL_HUP : 0);
+
 		/* ok, we found one active fd */
 		status--;
 
 		if (FD_ISSET(fd, fd_evts[DIR_RD])) {
 			if (fdtab[fd].state == FD_STCLOSE)
 				continue;
-			if (poll_events[count].revents & ( POLLIN | POLLERR | POLLHUP ))
+			if (fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP|FD_POLL_ERR))
 				fdtab[fd].cb[DIR_RD].f(fd);
 		}
 	  
 		if (FD_ISSET(fd, fd_evts[DIR_WR])) {
 			if (fdtab[fd].state == FD_STCLOSE)
 				continue;
-			if (poll_events[count].revents & ( POLLOUT | POLLERR | POLLHUP ))
+			if (fdtab[fd].ev & (FD_POLL_OUT|FD_POLL_ERR|FD_POLL_HUP))
 				fdtab[fd].cb[DIR_WR].f(fd);
 		}
 	}
diff --git a/src/ev_select.c b/src/ev_select.c
index 0924e3f..72eca0b 100644
--- a/src/ev_select.c
+++ b/src/ev_select.c
@@ -149,12 +149,14 @@
 			if (FD_ISSET(fd, tmp_evts[DIR_RD])) {
 				if (fdtab[fd].state == FD_STCLOSE)
 					continue;
+				fdtab[fd].ev |= FD_POLL_IN;
 				fdtab[fd].cb[DIR_RD].f(fd);
 			}
 
 			if (FD_ISSET(fd, tmp_evts[DIR_WR])) {
 				if (fdtab[fd].state == FD_STCLOSE)
 					continue;
+				fdtab[fd].ev |= FD_POLL_OUT;
 				fdtab[fd].cb[DIR_WR].f(fd);
 			}
 		}
diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c
index c8444be..b504815 100644
--- a/src/ev_sepoll.c
+++ b/src/ev_sepoll.c
@@ -402,13 +402,13 @@
 		 * have same values.
 		 */
 		fdtab[fd].ev &= FD_POLL_STICKY;
-		fdtab[fd].ev |= 
+		fdtab[fd].ev |=
 			((e & EPOLLIN ) ? FD_POLL_IN  : 0) |
 			((e & EPOLLPRI) ? FD_POLL_PRI : 0) |
 			((e & EPOLLOUT) ? FD_POLL_OUT : 0) |
 			((e & EPOLLERR) ? FD_POLL_ERR : 0) |
 			((e & EPOLLHUP) ? FD_POLL_HUP : 0);
-		
+
 		if ((fdtab[fd].spec.e & FD_EV_MASK_R) == FD_EV_WAIT_R) {
 			if (fdtab[fd].state == FD_STCLOSE || fdtab[fd].state == FD_STERROR)
 				continue;