]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
Save and restore errno on signal handlers
authorCristian Rodríguez <cristian@rodriguez.im>
Sun, 11 Feb 2024 18:53:30 +0000 (15:53 -0300)
committerCristian Rodríguez <cristian@rodriguez.im>
Mon, 12 Feb 2024 12:56:25 +0000 (09:56 -0300)
"Fetching and setting the value of errno is async-signal-safe
provided that the signal handler saves errno on entry and
       restores its value before returning."

save and restore errno on cases where it is needed.

include/c.h
lib/pager.c
misc-utils/hardlink.c
text-utils/pg.c

index 61b95ab2dc5b90e76dbe7b2b3f8e11d76a335432..3b921ab33b15d570f3faf5ba8efe341e75228a97 100644 (file)
@@ -595,4 +595,13 @@ static inline void *reallocarray(void *ptr, size_t nmemb, size_t size)
 }
 #endif
 
+static inline void ul_reset_errno(int *saved_errno) {
+        if (*saved_errno < 0)
+                return;
+
+        errno = *saved_errno;
+}
+
+#define UL_PROTECT_ERRNO __attribute__((__cleanup__(ul_reset_errno))) \
+                         __attribute__((__unused__)) int __ul_saved_errno = errno
 #endif /* UTIL_LINUX_C_H */
index 98814b54922ad4304e889d5c1e47f9fb799b1a45..14bf071dbee2dec5674ca5da16411faa11ea4d18 100644 (file)
@@ -173,6 +173,7 @@ static void wait_for_pager(void)
 
 static void wait_for_pager_signal(int signo)
 {
+       UL_PROTECT_ERRNO;
        wait_for_pager();
        raise(signo);
 }
index f9d3d09ac6bfa0ef021066a891f5f60b4b5fb5e5..89046a9f75194a11841f744b871f55289406c7f5 100644 (file)
@@ -1378,6 +1378,7 @@ static void to_be_called_atexit(void)
 */
 static void sighandler(int i)
 {
+       UL_PROTECT_ERRNO;
        if (last_signal != SIGINT)
                last_signal = i;
        if (i == SIGINT)
index 30ed04660ba5dc6948a83f29c86b95b37b9be625..8e01a9a5bd2ed210b1b4eb8e5c4087f6f1c4b15d 100644 (file)
@@ -371,6 +371,7 @@ static void skip(int direction)
 /* Signal handler while reading from input file. */
 static void sighandler(int signum)
 {
+       UL_PROTECT_ERRNO;
        if (canjump && (signum == SIGINT || signum == SIGQUIT))
                longjmp(jmpenv, signum);
        tcsetattr(STDOUT_FILENO, TCSADRAIN, &otio);