summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-07-12 16:28:43 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-07-12 19:16:22 +1200
commit028441d22fee121d129126c55938690be38bd3d9 (patch)
treec7911aaf9fbcd5c895e4ecf516c701e1072a2bc2 /ext
parent0895d57d3115f162dcb6cff82da1834a7241633e (diff)
Avoid calling `fstat` on things we already know are valid sockets.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4645
Diffstat (limited to 'ext')
-rw-r--r--ext/socket/basicsocket.c30
-rw-r--r--ext/socket/init.c18
2 files changed, 28 insertions, 20 deletions
diff --git a/ext/socket/basicsocket.c b/ext/socket/basicsocket.c
index 05172100c8..8477a37a6d 100644
--- a/ext/socket/basicsocket.c
+++ b/ext/socket/basicsocket.c
@@ -10,6 +10,28 @@
#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 @@
*
*/
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 5859c33e29..359696e626 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -54,20 +54,6 @@ rsock_raise_socket_error(const char *reason, int error)
#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)
{
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;