Unix Technical Forum

ftpd.c poll() -> kqueue replacement

This is a discussion on ftpd.c poll() -> kqueue replacement within the mailing.openbsd.tech forums, part of the OpenBSD category; --> Hi tech@, Here's a diff that turns the poll() based accept loop with a kevent() based accept loop, it ...


Go Back   Unix Technical Forum > Unix Operating Systems > OpenBSD > mailing.openbsd.tech

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-18-2008, 09:31 AM
Gilles Chehade
 
Posts: n/a
Default ftpd.c poll() -> kqueue replacement

Hi tech@,

Here's a diff that turns the poll() based accept loop with a kevent()
based accept loop, it also replaces two malloc(n * m) with calloc(n, m)

Gilles


Index: ftpd.c
================================================== =================
RCS file: /cvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.179
diff -u -p -r1.179 ftpd.c
--- ftpd.c 2007/07/27 14:12:46 1.179
+++ ftpd.c 2007/07/31 08:42:51
@@ -77,12 +77,15 @@ static const char rcsid[] =
/*
* FTP server.
*/
+#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/event.h>
+#include <sys/time.h>

#include <netinet/in.h>
#include <netinet/in_systm.h>
@@ -115,7 +118,6 @@ static const char rcsid[] =
#include <unistd.h>
#include <util.h>
#include <utmp.h>
-#include <poll.h>

#if defined(TCPWRAPPERS)
#include <tcpd.h>
@@ -280,6 +282,10 @@ usage(void)
int
main(int argc, char *argv[])
{
+ int kq = -1;
+ int *fds;
+ struct kevent kev[1];
+ struct kevent *kevtable = NULL;
socklen_t addrlen;
int ch, on = 1, tos;
char *cp, line[LINE_MAX];
@@ -287,6 +293,7 @@ main(int argc, char *argv[])
struct hostent *hp;
struct sigaction sa;
int error = 0;
+ int n;

tzset(); /* in case no timezone database in ~ftp */
sigfillset(&allsigs); /* used to block signals while root */
@@ -394,10 +401,8 @@ main(int argc, char *argv[])
endpwent();

if (daemon_mode) {
- int *fds, i, fd;
- struct pollfd *pfds;
+ int i, fd;
struct addrinfo hints, *res, *res0;
- nfds_t n;

/*
* Detach from parent.
@@ -420,14 +425,23 @@ main(int argc, char *argv[])
exit(1);
}

+ /*
+ * open kqueue
+ */
+ kq = kqueue();
+ if (kq < 0) {
+ syslog(LOG_ERR, "failed to open kqueue");
+ exit(1);
+ }
+
n = 0;
for (res = res0; res; res = res->ai_next)
n++;

- fds = malloc(n * sizeof(int));
- pfds = malloc(n * sizeof(struct pollfd));
- if (!fds || !pfds) {
- syslog(LOG_ERR, "%s", strerror(errno));
+ fds = calloc(n, sizeof(int));
+ kevtable = calloc(n, sizeof(struct kevent));
+ if (fds == NULL || kevtable == NULL) {
+ syslog(LOG_ERR, "calloc: %m");
exit(1);
}

@@ -437,31 +451,32 @@ main(int argc, char *argv[])
*/
n = 0;
for (res = res0; res; res = res->ai_next) {
- fds[n] = socket(res->ai_family, res->ai_socktype,
+ fd = socket(res->ai_family, res->ai_socktype,
res->ai_protocol);
- if (fds[n] < 0)
+ if (fd < 0)
continue;
-
- if (setsockopt(fds[n], SOL_SOCKET, SO_REUSEADDR,
+ syslog(LOG_ERR, "FD: %d", fd);
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
&on, sizeof(on)) < 0) {
- close(fds[n]);
- fds[n] = -1;
+ close(fd);
continue;
}

- if (bind(fds[n], res->ai_addr, res->ai_addrlen) < 0) {
- close(fds[n]);
- fds[n] = -1;
+ if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) {
+ close(fd);
continue;
}
- if (listen(fds[n], 32) < 0) {
- close(fds[n]);
- fds[n] = -1;
+ if (listen(fd, 32) < 0) {
+ close(fd);
continue;
}

- pfds[n].fd = fds[n];
- pfds[n].events = POLLIN;
+ fds[n] = fd;
+ EV_SET(&kev[0], fd, EVFILT_READ, EV_ADD|EV_CLEAR, NULL, NULL, NULL);
+ syslog(LOG_ERR, "FD: %d/%d", kq, fd);
+ if (kevent(kq, &kev[0], 1, NULL, 0, 0) < 0) {
+ syslog(LOG_ERR, "%m");
+ }
n++;
}
freeaddrinfo(res0);
@@ -479,32 +494,47 @@ main(int argc, char *argv[])
* children to handle them.
*/
while (1) {
- if (poll(pfds, n, INFTIM) < 0) {
+ int ret;
+
+ ret = kevent(kq, NULL, 0, kevtable, n, 0);
+ if (ret < 0) {
if (errno == EINTR)
continue;
- syslog(LOG_ERR, "poll: %m");
+ syslog(LOG_ERR, "kevent: %m");
exit(1);
}
- for (i = 0; i < n; i++)
- if (pfds[i].revents & POLLIN) {
- addrlen = sizeof(his_addr);
- fd = accept(pfds[i].fd,
- (struct sockaddr *)&his_addr,
- &addrlen);
- if (fd != -1) {
- if (fork() == 0)
- goto child;
+ for (i = 0; i < ret; i++) {
+ if (kevtable[i].flags & EV_ERROR) {
+ syslog(LOG_ERR, "kevent: %m");
+ }
+ else {
+ addrlen = sizeof(his_addr);
+ fd = accept(kevtable[i].ident,
+ (struct sockaddr *)&his_addr,
+ &addrlen);
+ if (fd != -1) {
+ if (fork() == 0)
+ goto child;
close(fd);
}
}
+ }
}

child:
/* child */
(void)dup2(fd, STDIN_FILENO);
(void)dup2(fd, STDOUT_FILENO);
- for (i = 0; i < n; i++)
- close(fds[i]);
+
+ if (kevtable != NULL)
+ free(kevtable);
+
+ if (fds != NULL) {
+ for (i = 0; i < n; i++)
+ close(fds[i]);
+ free(fds);
+ }
+
#if defined(TCPWRAPPERS)
/* ..in the child. */
if (!check_host((struct sockaddr *)&his_addr))

--
sysadmin & coder @ http://www.evilkittens.org/
coder @ http://www.exalead.com/

[demime 1.01d removed an attachment of type application/pgp-signature]

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 01:21 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com