diff mbox series

[uclibc-ng-devel] Implement 'futimesat' function for architectures where Linux does not provide a futimesat syscall.

Message ID R63FRR.RNY40NTCO3AF@midnightspark.net
State Accepted
Headers show
Series [uclibc-ng-devel] Implement 'futimesat' function for architectures where Linux does not provide a futimesat syscall. | expand

Commit Message

Elliot Thomas March 12, 2023, 4:59 p.m. UTC
Recently I tried compiling QEMU user emulation with uClibc on Aarch64, 
and found the 'futimesat' symbol was missing (but still defined in 
headers).

This emulation is similar to the 'lutimesat' emulation.

Regards,
Elliot.

Comments

Waldemar Brodkorb March 13, 2023, 6:54 a.m. UTC | #1
Hi,

thanks, applied and pushed,
 best regards
   Waldemar

Elliot Thomas wrote,

> Recently I tried compiling QEMU user emulation with uClibc on Aarch64, and
> found the 'futimesat' symbol was missing (but still defined in headers).
> 
> This emulation is similar to the 'lutimesat' emulation.
> 
> Regards,
> Elliot.
> 

> From 60d600b56627cceace22da19ea3803aa7ab6bcf2 Mon Sep 17 00:00:00 2001
> From: Elliot Thomas <elliot@midnightspark.net>
> Date: Mon, 6 Mar 2023 01:21:05 +0000
> Subject: [PATCH] Emulate 'futimesat' when __NR_futimesat is not available.
> 
> ---
>  libc/sysdeps/linux/common/futimesat.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c
> index bd73eae7e..fd19fea7c 100644
> --- a/libc/sysdeps/linux/common/futimesat.c
> +++ b/libc/sysdeps/linux/common/futimesat.c
> @@ -11,6 +11,28 @@
>  
>  #ifdef __NR_futimesat
>  _syscall3(int, futimesat, int, fd, const char *, file, const struct timeval *, tvp)
> -#else
> -/* should add emulation with futimes() and /proc/self/fd/ ... */
> +#elif defined __NR_utimensat
> +#include <errno.h>
> +#define __need_NULL
> +#include <stddef.h>
> +
> +int futimesat(int dirfd, const char *file, const struct timeval tvp[2])
> +{
> +	struct timespec ts[2];
> +
> +	if (tvp != NULL)
> +	{
> +		if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
> +		    || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
> +		{
> +			__set_errno(EINVAL);
> +			return -1;
> +		}
> +
> +		TIMEVAL_TO_TIMESPEC(&tvp[0], &ts[0]);
> +		TIMEVAL_TO_TIMESPEC(&tvp[1], &ts[1]);
> +	}
> +
> +	return utimensat(dirfd, file, tvp ? ts : NULL, 0);
> +}
>  #endif
> -- 
> 2.39.2
> 

> _______________________________________________
> devel mailing list -- devel@uclibc-ng.org
> To unsubscribe send an email to devel-leave@uclibc-ng.org
diff mbox series

Patch

From 60d600b56627cceace22da19ea3803aa7ab6bcf2 Mon Sep 17 00:00:00 2001
From: Elliot Thomas <elliot@midnightspark.net>
Date: Mon, 6 Mar 2023 01:21:05 +0000
Subject: [PATCH] Emulate 'futimesat' when __NR_futimesat is not available.

---
 libc/sysdeps/linux/common/futimesat.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c
index bd73eae7e..fd19fea7c 100644
--- a/libc/sysdeps/linux/common/futimesat.c
+++ b/libc/sysdeps/linux/common/futimesat.c
@@ -11,6 +11,28 @@ 
 
 #ifdef __NR_futimesat
 _syscall3(int, futimesat, int, fd, const char *, file, const struct timeval *, tvp)
-#else
-/* should add emulation with futimes() and /proc/self/fd/ ... */
+#elif defined __NR_utimensat
+#include <errno.h>
+#define __need_NULL
+#include <stddef.h>
+
+int futimesat(int dirfd, const char *file, const struct timeval tvp[2])
+{
+	struct timespec ts[2];
+
+	if (tvp != NULL)
+	{
+		if (tvp[0].tv_usec < 0 || tvp[0].tv_usec >= 1000000
+		    || tvp[1].tv_usec < 0 || tvp[1].tv_usec >= 1000000)
+		{
+			__set_errno(EINVAL);
+			return -1;
+		}
+
+		TIMEVAL_TO_TIMESPEC(&tvp[0], &ts[0]);
+		TIMEVAL_TO_TIMESPEC(&tvp[1], &ts[1]);
+	}
+
+	return utimensat(dirfd, file, tvp ? ts : NULL, 0);
+}
 #endif
-- 
2.39.2