ruby-changes:66754
From: Samuel <ko1@a...>
Date: Mon, 12 Jul 2021 16:16:43 +0900 (JST)
Subject: [ruby-changes:66754] 028441d22f (master): Avoid calling `fstat` on things we already know are valid sockets.
https://git.ruby-lang.org/ruby.git/commit/?id=028441d22f From 028441d22fee121d129126c55938690be38bd3d9 Mon Sep 17 00:00:00 2001 From: Samuel Williams <samuel.williams@o...> Date: Mon, 12 Jul 2021 16:28:43 +1200 Subject: Avoid calling `fstat` on things we already know are valid sockets. --- ext/socket/basicsocket.c | 30 ++++++++++++++++++++++++++++-- ext/socket/init.c | 18 ------------------ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c index 0517210..8477a37 100644 --- a/ext/socket/basicsocket.c +++ b/ext/socket/basicsocket.c @@ -10,6 +10,28 @@ https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L10 #include "rubysocket.h" +#ifdef _WIN32 +#define is_socket(fd) rb_w32_is_socket(fd) +#else +static int +is_socket(int fd) +{ + struct stat sbuf; + + if (fstat(fd, &sbuf) < 0) + rb_sys_fail("fstat(2)"); + return S_ISSOCK(sbuf.st_mode); +} +#endif + +static void +rsock_validate_descriptor(int descriptor) +{ + if (!is_socket(descriptor) || rb_reserved_fd_p(descriptor)) { + rb_syserr_fail(EBADF, "not a socket file descriptor"); + } +} + /* * call-seq: * BasicSocket.for_fd(fd) => basicsocket @@ -22,10 +44,14 @@ https://github.com/ruby/ruby/blob/trunk/ext/socket/basicsocket.c#L44 * */ static VALUE -bsock_s_for_fd(VALUE klass, VALUE fd) +bsock_s_for_fd(VALUE klass, VALUE _descriptor) { rb_io_t *fptr; - VALUE sock = rsock_init_sock(rb_obj_alloc(klass), NUM2INT(fd)); + + int descriptor = RB_NUM2INT(_descriptor); + rsock_validate_descriptor(descriptor); + + VALUE sock = rsock_init_sock(rb_obj_alloc(klass), descriptor); GetOpenFile(sock, fptr); diff --git a/ext/socket/init.c b/ext/socket/init.c index 5859c33..359696e 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -54,20 +54,6 @@ rsock_raise_socket_error(const char *reason, int error) https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L54 #endif } -#ifdef _WIN32 -#define is_socket(fd) rb_w32_is_socket(fd) -#else -static int -is_socket(int fd) -{ - struct stat sbuf; - - if (fstat(fd, &sbuf) < 0) - rb_sys_fail("fstat(2)"); - return S_ISSOCK(sbuf.st_mode); -} -#endif - #if defined __APPLE__ # define do_write_retry(code) do {ret = code;} while (ret == -1 && errno == EPROTOTYPE) #else @@ -79,10 +65,6 @@ rsock_init_sock(VALUE sock, int fd) https://github.com/ruby/ruby/blob/trunk/ext/socket/init.c#L65 { rb_io_t *fp; - if (!is_socket(fd) || rb_reserved_fd_p(fd)) { - rb_syserr_fail(EBADF, "not a socket file descriptor"); - } - rb_update_max_fd(fd); MakeOpenFile(sock, fp); fp->fd = fd; -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/