diff options
| author | Olivier Fourdan <ofourdan@redhat.com> | 2022-05-30 09:14:04 +0200 |
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2022-06-09 19:18:47 +0000 |
| commit | dd00220b1ef6a4c823632a02b535b40602bfb8d4 (patch) | |
| tree | 856b411bf4cd0d11d2985db9bf10aafd7cbb11b6 /cursor | |
| parent | build: bump to version 1.20.92 for the beta release (diff) | |
| download | wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar.gz wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar.bz2 wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar.lz wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar.xz wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.tar.zst wayland-dd00220b1ef6a4c823632a02b535b40602bfb8d4.zip | |
cursor/os-compatibility: handle EINTR gracefully
If os_resize_anonymous_file() called from os_create_anonymous_file()
fails with EINTR (Interrupted system call), then the buffer allocation
fails.
To avoid that, retry posix_fallocate() on EINTR.
However, in the presence of an alarm, the interrupt may trigger
repeatedly and prevent a large posix_fallocate() to ever complete
successfully, so we need to first block SIGALRM to prevent this.
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Diffstat (limited to 'cursor')
| -rw-r--r-- | cursor/os-compatibility.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/cursor/os-compatibility.c b/cursor/os-compatibility.c index 07452a5..f2445ce 100644 --- a/cursor/os-compatibility.c +++ b/cursor/os-compatibility.c @@ -31,6 +31,7 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> +#include <signal.h> #include <string.h> #include <stdio.h> #include <stdlib.h> @@ -168,11 +169,28 @@ int os_resize_anonymous_file(int fd, off_t size) { #ifdef HAVE_POSIX_FALLOCATE + sigset_t mask; + sigset_t old_mask; + + /* + * posix_fallocate() might be interrupted, so we need to check + * for EINTR and retry in that case. + * However, in the presence of an alarm, the interrupt may trigger + * repeatedly and prevent a large posix_fallocate() to ever complete + * successfully, so we need to first block SIGALRM to prevent + * this. + */ + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + sigprocmask(SIG_BLOCK, &mask, &old_mask); /* - * Filesystems that do support fallocate will return EINVAL or + * Filesystems that do not support fallocate will return EINVAL or * EOPNOTSUPP. In this case we need to fall back to ftruncate */ - errno = posix_fallocate(fd, 0, size); + do { + errno = posix_fallocate(fd, 0, size); + } while (errno == EINTR); + sigprocmask(SIG_SETMASK, &old_mask, NULL); if (errno == 0) return 0; else if (errno != EINVAL && errno != EOPNOTSUPP) |
