diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-10-31 23:26:19 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-10-31 23:26:19 +0000 |
commit | 5dbc3d1e7919f1ee2058baec9555684ee0babed0 (patch) | |
tree | a0a988169f2bde8a12fb41e7b300c6b465cf0a47 /ext/socket/init.c | |
parent | 24176a8d5d98ea7d1eb3971ffb7fad7f9ccd2adb (diff) | |
download | ruby-5dbc3d1e7919f1ee2058baec9555684ee0babed0.tar.gz |
* ext/socket/init.c (cloexec_accept): new function to use accept4 if
available.
(rsock_s_accept_nonblock): use cloexec_accept.
(accept_blocking): ditto.
* ext/socket/extconf.rb: check accept4.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/init.c')
-rw-r--r-- | ext/socket/init.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/ext/socket/init.c b/ext/socket/init.c index 2f6b6eef82..a41f94a38f 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -463,6 +463,30 @@ make_fd_nonblock(int fd) } } +static int +cloexec_accept(int socket, struct sockaddr *address, socklen_t *address_len) +{ + int ret; +#ifdef HAVE_ACCEPT4 + static int try_accept4 = 1; + if (try_accept4) { + ret = accept4(socket, address, address_len, SOCK_CLOEXEC); + /* accept4 is available since Linux 2.6.28, glibc 2.10. */ + if (ret == -1 && errno == ENOSYS) { + try_accept4 = 0; + ret = accept(socket, address, address_len); + } + } + else { + ret = accept(socket, address, address_len); + } +#else + ret = accept(socket, address, address_len); +#endif + return ret; +} + + VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len) { @@ -470,7 +494,7 @@ rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, s rb_secure(3); rb_io_set_nonblock(fptr); - fd2 = accept(fptr->fd, (struct sockaddr*)sockaddr, len); + fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len); if (fd2 < 0) { switch (errno) { case EAGAIN: @@ -500,7 +524,7 @@ static VALUE accept_blocking(void *data) { struct accept_arg *arg = data; - return (VALUE)accept(arg->fd, arg->sockaddr, arg->len); + return (VALUE)cloexec_accept(arg->fd, arg->sockaddr, arg->len); } VALUE |