From c90228198bb496fc4033884a8c532f5e5dd87163 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Tue, 1 Oct 2024 11:49:34 -0400 Subject: [PATCH] linux: handle when libuv allocates a file descriptor normally used by stdio (#4558) File descriptors 0 to 2 are used by stdio by default, but are not guaranteed to be in use by stdio, in which case one or more of them may get used by libuv. For example, STDERR can be closed by passing 2>&- on the program command line in the shell. In which case, the file descriptor 2 would be used by libuv libuv should handle this case without aborting --- src/unix/core.c | 3 ++- src/unix/internal.h | 2 ++ src/unix/linux.c | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/unix/core.c b/src/unix/core.c index 1935ba87..4da27247 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -641,7 +641,8 @@ int uv__close_nocheckstdio(int fd) { int uv__close(int fd) { - assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ + if (!uv__low_fd_flag) + assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ #if defined(__MVS__) SAVE_ERRNO(epoll_file_close(fd)); #endif diff --git a/src/unix/internal.h b/src/unix/internal.h index 138685c9..376213f8 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -243,6 +243,8 @@ struct uv__statx { #define uv__nonblock uv__nonblock_fcntl #endif +extern int uv__low_fd_flag; + /* core */ int uv__cloexec(int fd, int set); int uv__nonblock_ioctl(int fd, int set); diff --git a/src/unix/linux.c b/src/unix/linux.c index 803a9a9d..f6603cd7 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c @@ -266,6 +266,8 @@ struct watcher_root { struct watcher_list* rbh_root; }; +int uv__low_fd_flag = 0; + static int uv__inotify_fork(uv_loop_t* loop, struct watcher_list* root); static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, @@ -649,6 +651,9 @@ int uv__platform_loop_init(uv_loop_t* loop) { if (loop->backend_fd == -1) return UV__ERR(errno); + if (loop->backend_fd <= STDERR_FILENO) + uv__low_fd_flag = 1; + uv__iou_init(loop->backend_fd, &lfields->ctl, 256, 0); return 0;