interactive-wayland: fallback to ftruncate() if needed

Fallback to ftruncate() if the underlying filesystem does not
support posix_fallocate().

Idea by: Jan Beich <jbeich@FreeBSD.org>, Niclas Zeising <zeising@FreeBSD.org>
Inspired by: Wayland cursor/os-compatibility.c
[ran: small adjustments]
Signed-off-by: Ran Benita <ran@unusedvar.com>
master
Evgeniy Khramtsov 2021-04-14 12:56:07 +03:00 committed by Ran Benita
parent 8b603dbe11
commit f04c7e93ce
1 changed files with 24 additions and 11 deletions

View File

@ -130,6 +130,27 @@ create_tmpfile_cloexec(char *tmpname)
}
#endif
static int
os_resize_anonymous_file(int fd, off_t size)
{
int ret;
#ifdef HAVE_POSIX_FALLOCATE
ret = posix_fallocate(fd, 0, size);
if (ret == 0)
return 0;
/*
* Filesystems that do support fallocate will return EINVAL
* or EOPNOTSUPP, fallback to ftruncate() then.
*/
if (ret != EINVAL && ret != EOPNOTSUPP)
return ret;
#endif
ret = ftruncate(fd, size);
if (ret != 0)
return errno;
return 0;
}
/*
* Create a new, unique, anonymous file of the given size, and
* return the file descriptor for it. The file descriptor is set
@ -148,8 +169,8 @@ create_tmpfile_cloexec(char *tmpname)
* If the C library implements posix_fallocate(), it is used to
* guarantee that disk space is available for the file at the
* given size. If disk space is insufficent, errno is set to ENOSPC.
* If posix_fallocate() is not supported, program may receive
* SIGBUS on accessing mmap()'ed file contents instead.
* If posix_fallocate() is not supported, program will fallback
* to ftruncate() instead.
*/
static int
os_create_anonymous_file(off_t size)
@ -180,20 +201,12 @@ os_create_anonymous_file(off_t size)
if (fd < 0)
return -1;
#ifdef HAVE_POSIX_FALLOCATE
ret = posix_fallocate(fd, 0, size);
ret = os_resize_anonymous_file(fd, size);
if (ret != 0) {
close(fd);
errno = ret;
return -1;
}
#else
ret = ftruncate(fd, size);
if (ret < 0) {
close(fd);
return -1;
}
#endif
return fd;
}