Include endpoint address in accounting dump files.
[l2tpns.git] / fake_epoll.h
diff --git a/fake_epoll.h b/fake_epoll.h
new file mode 100644 (file)
index 0000000..b44f846
--- /dev/null
@@ -0,0 +1,179 @@
+/* kludge up some limited epoll semantics using select for 2.4 kernels */
+/* $Id: fake_epoll.h,v 1.1 2005-06-04 15:42:35 bodea Exp $ */
+
+#ifndef __FAKE_EPOLL_H__
+#define __FAKE_EPOLL_H__
+
+#define EPOLLIN                0x01
+#define EPOLLOUT       0x04
+#define EPOLLERR       0x08
+#define EPOLLHUP       0x10
+
+#define EPOLL_CTL_ADD  1
+#define EPOLL_CTL_DEL  2
+#define EPOLL_CTL_MOD  3
+
+struct epoll_event {
+    uint32_t events;
+    union epoll_data {
+       void *ptr;
+       int fd;
+       uint32_t u32;
+       uint64_t u64;
+    } data;
+};
+
+int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+
+#ifdef FAKE_EPOLL_IMPLEMENTATION
+
+#include <sys/select.h>
+
+static fd_set _epoll_read_set;
+static fd_set _epoll_write_set;
+static int _epoll_fds;
+static struct epoll_event *_epoll_data[128];
+
+static int epoll_create(int size __attribute__ ((unused)))
+{
+    static int once = 0;
+    if (once++)
+    {
+       errno = ENFILE; /* only support one instance */
+       return -1;
+    }
+
+    FD_ZERO(&_epoll_read_set);
+    FD_ZERO(&_epoll_write_set);
+    _epoll_fds = 0;
+
+    memset(_epoll_data, 0, sizeof(_epoll_data));
+
+    return 1; /* "descriptor" */
+}
+
+int epoll_ctl(int epfd __attribute__ ((unused)), int op, int fd,
+    struct epoll_event *event)
+{
+    if (fd > (sizeof(_epoll_data)/sizeof(*_epoll_data)) - 1)
+    {
+       errno = EINVAL;
+       return -1;
+    }
+
+    switch (op)
+    {
+    case EPOLL_CTL_ADD:
+       if (event->events & EPOLLIN)
+           FD_SET(fd, &_epoll_read_set);
+
+       if (event->events & EPOLLOUT)
+           FD_SET(fd, &_epoll_write_set);
+
+       if (fd >= _epoll_fds)
+           _epoll_fds = fd + 1;
+
+       if (_epoll_data[fd])
+           free(_epoll_data[fd]);
+
+       if (!(_epoll_data[fd] = malloc(sizeof(*_epoll_data))))
+       {
+           errno = ENOMEM;
+           return -1;
+       }
+
+       memcpy(_epoll_data[fd], &event->data, sizeof(*_epoll_data));
+       break;
+
+    case EPOLL_CTL_MOD:
+       if (event->events & EPOLLIN)
+           FD_SET(fd, &_epoll_read_set);
+       else
+           FD_CLR(fd, &_epoll_read_set);
+
+       if (event->events & EPOLLOUT)
+           FD_SET(fd, &_epoll_write_set);
+       else
+           FD_CLR(fd, &_epoll_write_set);
+
+       memcpy(_epoll_data[fd], &event->data, sizeof(*_epoll_data));
+       break;
+
+    case EPOLL_CTL_DEL:
+       FD_CLR(fd, &_epoll_read_set);
+       FD_CLR(fd, &_epoll_write_set);
+
+       free(_epoll_data[fd]);
+       _epoll_data[fd] = 0;
+
+       if (fd == _epoll_fds - 1)
+       {
+           _epoll_fds = 0;
+           while (fd-- > 0)
+           {
+               if (FD_ISSET(fd, &_epoll_read_set) ||
+                   FD_ISSET(fd, &_epoll_write_set))
+               {
+                   _epoll_fds = fd + 1;
+                   break;
+               }
+           }
+       }
+
+       break;
+    }
+
+    return 0;
+}
+
+static int epoll_wait(int epfd __attribute__ ((unused)),
+    struct epoll_event *events, int maxevents, int timout)
+{
+    fd_set r;
+    fd_set w;
+    struct timeval t;
+    struct timeval *tp;
+    int n;
+    int e;
+    int i;
+
+    memcpy(&r, &_epoll_read_set, sizeof(r));
+    memcpy(&w, &_epoll_write_set, sizeof(w));
+
+    if (timout >= 0)
+    {
+       t.tv_sec = 0;
+       t.tv_usec = timout * 1000;
+       tp = &t;
+    }
+    else
+       tp = 0;
+
+    n = select(_epoll_fds, &r, &w, 0, tp);
+    if (n > maxevents)
+       n = maxevents;
+
+    for (i = e = 0; n > 0 && i < _epoll_fds; i++)
+    {
+       if (!_epoll_data[i])
+           continue;
+
+       events[e].events = 0;
+       if (FD_ISSET(i, &r))
+           events[e].events |= EPOLLIN;
+
+       if (FD_ISSET(i, &w))
+           events[e].events |= EPOLLOUT;
+
+       if (events[e].events)
+       {
+           memcpy(&events[e++].data, _epoll_data[i], sizeof(events[0].data));
+           n--;
+       }
+    }
+
+    return e;
+}
+
+#endif /* FAKE_EPOLL_IMPLEMENTATION */
+#endif /* __FAKE_EPOLL_H__ */