From d55fde9eea105af53242a72de59423cc1590beff Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 31 Jan 2021 07:02:11 +0530 Subject: [PATCH] Use EINTR safe wrappers for open() and shm_open() --- kitty/child-monitor.c | 1 + kitty/child.c | 3 ++- kitty/data-types.c | 3 ++- kitty/data-types.h | 6 ------ kitty/disk-cache.c | 3 ++- kitty/graphics.c | 5 +++-- kitty/loop-utils.c | 1 + kitty/safe-wrappers.h | 36 ++++++++++++++++++++++++++++++++++++ 8 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 kitty/safe-wrappers.h diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 30439e284..b2dc780ce 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -6,6 +6,7 @@ */ #include "loop-utils.h" +#include "safe-wrappers.h" #include "state.h" #include "threading.h" #include "screen.h" diff --git a/kitty/child.c b/kitty/child.c index 500e91dab..886e6a889 100644 --- a/kitty/child.c +++ b/kitty/child.c @@ -6,6 +6,7 @@ */ #include "data-types.h" +#include "safe-wrappers.h" #include #include #include @@ -99,7 +100,7 @@ spawn(PyObject *self UNUSED, PyObject *args) { if (setsid() == -1) exit_on_err("setsid() in child process failed"); // Establish the controlling terminal (see man 7 credentials) - int tfd = open(name, O_RDWR); + int tfd = safe_open(name, O_RDWR, 0); if (tfd == -1) exit_on_err("Failed to open controlling terminal"); #ifdef TIOCSCTTY // On BSD open() does not establish the controlling terminal diff --git a/kitty/data-types.c b/kitty/data-types.c index 746ba8736..3ab7bc3d6 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -12,6 +12,7 @@ #undef _DARWIN_C_SOURCE #endif #include "data-types.h" +#include "safe-wrappers.h" #include "control-codes.h" #include "wcwidth-std.h" #include "wcswidth.h" @@ -110,7 +111,7 @@ open_tty(PyObject *self UNUSED, PyObject *args) { int flags = O_RDWR | O_CLOEXEC | O_NOCTTY; if (!read_with_timeout) flags |= O_NONBLOCK; static char ctty[L_ctermid+1]; - int fd = open(ctermid(ctty), flags); + int fd = safe_open(ctermid(ctty), flags, 0); if (fd == -1) { PyErr_Format(PyExc_OSError, "Failed to open controlling terminal: %s (identified with ctermid()) with error: %s", ctty, strerror(errno)); return NULL; } struct termios *termios_p = calloc(1, sizeof(struct termios)); if (!termios_p) return PyErr_NoMemory(); diff --git a/kitty/data-types.h b/kitty/data-types.h index 889c7ed12..4fb69ed5b 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -329,10 +329,4 @@ SPRITE_MAP_HANDLE alloc_sprite_map(unsigned int, unsigned int); SPRITE_MAP_HANDLE free_sprite_map(SPRITE_MAP_HANDLE); const char* get_hyperlink_for_id(const HYPERLINK_POOL_HANDLE, hyperlink_id_type id, bool only_url); -static inline void safe_close(int fd, const char* file UNUSED, const int line UNUSED) { -#if 0 - printf("Closing fd: %d from file: %s line: %d\n", fd, file, line); -#endif - while(close(fd) != 0 && errno == EINTR); -} void log_event(const char *format, ...) __attribute__((format(printf, 1, 2))); diff --git a/kitty/disk-cache.c b/kitty/disk-cache.c index d361488c9..04688a00f 100644 --- a/kitty/disk-cache.c +++ b/kitty/disk-cache.c @@ -12,6 +12,7 @@ #endif #include "disk-cache.h" +#include "safe-wrappers.h" #include "uthash.h" #include "loop-utils.h" #include "threading.h" @@ -85,7 +86,7 @@ open_cache_file(const char *cache_path) { int fd = -1; #ifdef O_TMPFILE while (fd < 0) { - fd = open(cache_path, O_TMPFILE | O_CLOEXEC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); + fd = safe_open(cache_path, O_TMPFILE | O_CLOEXEC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR); if (fd > -1 || errno != EINTR) break; } #else diff --git a/kitty/graphics.c b/kitty/graphics.c index 8c0c049c8..1877ae170 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -9,6 +9,7 @@ #include "state.h" #include "disk-cache.h" #include "iqsort.h" +#include "safe-wrappers.h" #include #include @@ -371,8 +372,8 @@ load_image_data(GraphicsManager *self, Image *img, const GraphicsCommand *g, con case 's': // POSIX shared memory if (g->payload_sz > 2048) ABRT(EINVAL, "Filename too long"); snprintf(fname, sizeof(fname)/sizeof(fname[0]), "%.*s", (int)g->payload_sz, payload); - if (transmission_type == 's') fd = shm_open(fname, O_RDONLY, 0); - else fd = open(fname, O_CLOEXEC | O_RDONLY); + if (transmission_type == 's') fd = safe_shm_open(fname, O_RDONLY, 0); + else fd = safe_open(fname, O_CLOEXEC | O_RDONLY, 0); if (fd == -1) ABRT(EBADF, "Failed to open file for graphics transmission with error: [%d] %s", errno, strerror(errno)); img->data_loaded = mmap_img_file(self, img, fd, g->data_sz, g->data_offset); safe_close(fd, __FILE__, __LINE__); diff --git a/kitty/loop-utils.c b/kitty/loop-utils.c index 377c26099..abe0faf70 100644 --- a/kitty/loop-utils.c +++ b/kitty/loop-utils.c @@ -6,6 +6,7 @@ */ #include "loop-utils.h" +#include "safe-wrappers.h" #include bool diff --git a/kitty/safe-wrappers.h b/kitty/safe-wrappers.h new file mode 100644 index 000000000..9e57c0e6e --- /dev/null +++ b/kitty/safe-wrappers.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2021 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#pragma once +#include "data-types.h" +#include +#include + + +static inline int safe_open(const char *path, int flags, mode_t mode) { + while (true) { + int fd = open(path, flags, mode); + if (fd == -1 && errno == EINTR) continue; + return fd; + } +} + + +static inline int safe_shm_open(const char *path, int flags, mode_t mode) { + while (true) { + int fd = shm_open(path, flags, mode); + if (fd == -1 && errno == EINTR) continue; + return fd; + } +} + + +static inline void safe_close(int fd, const char* file UNUSED, const int line UNUSED) { +#if 0 + printf("Closing fd: %d from file: %s line: %d\n", fd, file, line); +#endif + while(close(fd) != 0 && errno == EINTR); +}