* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
- * I/O abstraction interface.
* Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de)
*
*/
#include "portab.h"
-static char UNUSED id[] = "$Id: io.c,v 1.29 2008/03/27 15:47:21 fw Exp $";
+/**
+ * @file
+ * I/O abstraction interface.
+ */
#include <assert.h>
#include <stdlib.h>
#ifdef IO_USE_SELECT
#include "defines.h" /* for conn.h */
-#include "conn.h" /* for CONN_IDX (needed by resolve.h) */
-#include "resolve.h" /* for RES_STAT (needed by conf.h) */
+#include "proc.h" /* for PROC_STAT (needed by conf.h) */
+#include "conn.h" /* for CONN_ID (needed by conf.h) */
#include "conf.h" /* for Conf_MaxConnections */
static fd_set readers;
static fd_set writers;
-static int select_maxfd; /* the select() interface sucks badly */
-static int io_dispatch_select(struct timeval *tv);
+/*
+ * this is the first argument for select(), i.e.
+ * the largest fd registered, plus one.
+ */
+static int select_maxfd;
+static int io_dispatch_select PARAMS((struct timeval *tv));
#ifndef IO_USE_EPOLL
#define io_masterfd -1
static void io_docallback PARAMS((int fd, short what));
#ifdef DEBUG_IO
-static void io_debug(const char *s, int fd, int what)
+static void
+io_debug(const char *s, int fd, int what)
{
Log(LOG_DEBUG, "%s: %d, %d\n", s, fd, what);
}
#else
-static inline void io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b) {/*NOTHING*/}
+static inline void
+io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b)
+{ /* NOTHING */ }
#endif
static io_event *
eventsize, io_masterfd);
}
#else
-static inline void io_close_devpoll(int UNUSED x) {/* NOTHING */}
-static inline void io_library_init_devpoll(unsigned int UNUSED ev) {/*NOTHING*/}
+static inline void
+io_close_devpoll(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_library_init_devpoll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
#endif
}
}
#else
-static inline void io_close_poll(int UNUSED x) {/* NOTHING */}
-static inline void io_library_init_poll(unsigned int UNUSED ev) {/*NOTHING*/}
+static inline void
+io_close_poll(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_library_init_poll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
#endif
static int
io_dispatch_select(struct timeval *tv)
{
- fd_set readers_tmp = readers;
- fd_set writers_tmp = writers;
+ fd_set readers_tmp;
+ fd_set writers_tmp;
short what;
int ret, i;
int fds_ready;
+
+ readers_tmp = readers;
+ writers_tmp = writers;
+
ret = select(select_maxfd + 1, &readers_tmp, &writers_tmp, NULL, tv);
if (ret <= 0)
return ret;
Conf_MaxConnections = FD_SETSIZE - 1;
}
+#else
+ Log(LOG_WARNING,
+ "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
#endif /* FD_SETSIZE */
library_initialized = true;
}
}
}
#else
-static inline void io_library_init_select(int UNUSED x) {/* NOTHING */}
-static inline void io_close_select(int UNUSED x) {/* NOTHING */}
+static inline void
+io_library_init_select(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_close_select(int UNUSED x)
+{ /* NOTHING */ }
#endif /* SELECT */
#endif
}
#else
-static inline void io_library_init_epoll(unsigned int UNUSED ev) {/* NOTHING */}
+static inline void
+io_library_init_epoll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
#endif /* IO_USE_EPOLL */
library_initialized = true;
}
#else
-static inline void io_library_init_kqueue(unsigned int UNUSED ev) {/* NOTHING */}
+static inline void
+io_library_init_kqueue(unsigned int UNUSED ev)
+{ /* NOTHING */ }
#endif
{
if (library_initialized)
return true;
-#ifdef IO_USE_SELECT
-#ifndef FD_SETSIZE
- Log(LOG_WARNING,
- "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
-#else
- if (eventsize >= FD_SETSIZE)
- eventsize = FD_SETSIZE - 1;
-#endif /* FD_SETSIZE */
-#endif /* IO_USE_SELECT */
+
if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
eventsize = 0;
assert(fd >= 0);
#if defined(IO_USE_SELECT) && defined(FD_SETSIZE)
- if (fd >= FD_SETSIZE) {
+ if (io_masterfd < 0 && fd >= FD_SETSIZE) {
Log(LOG_ERR,
"fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)",
fd, FD_SETSIZE);
return fcntl(fd, F_SETFL, flags) == 0;
}
+bool
+io_setcloexec(int fd)
+{
+ int flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ return false;
+#ifdef FD_CLOEXEC
+ flags |= FD_CLOEXEC;
+#endif
+
+ return fcntl(fd, F_SETFD, flags) == 0;
+}
bool
io_close(int fd)