[前][次][番号順一覧][スレッド一覧]

ruby-changes:72334

From: Nobuyoshi <ko1@a...>
Date: Mon, 27 Jun 2022 22:20:57 +0900 (JST)
Subject: [ruby-changes:72334] b6b9a6190d (master): Check availability of `utimensat` on macOS

https://git.ruby-lang.org/ruby.git/commit/?id=b6b9a6190d

From b6b9a6190def53aa53ac816a51034fa1c96ed70b Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Mon, 27 Jun 2022 13:17:36 +0900
Subject: Check availability of `utimensat` on macOS

---
 file.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/file.c b/file.c
index e92ceeabe1..8ed0789d43 100644
--- a/file.c
+++ b/file.c
@@ -2833,6 +2833,31 @@ utime_failed(struct apply_arg *aa) https://github.com/ruby/ruby/blob/trunk/file.c#L2833
 
 #if defined(HAVE_UTIMES)
 
+# if defined(__APPLE__) && \
+    (!defined(MAC_OS_X_VERSION_13_0) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_13_0))
+
+#   if defined(__has_attribute) && __has_attribute(availability)
+typedef int utimensat_func(int, const char *, const struct timespec [2], int);
+
+RBIMPL_WARNING_PUSH();
+RBIMPL_WARNING_IGNORED(-Wunguarded-availability-new);
+static inline utimensat_func *
+rb_utimensat(void)
+{
+    return &utimensat;
+}
+RBIMPL_WARNING_POP();
+
+#   define utimensat rb_utimensat()
+#   else /* __API_AVAILABLE macro does nothing on gcc */
+__attribute__((weak)) int utimensat(int, const char *, const struct timespec [2], int);
+#   endif
+
+#   define utimensat_available_p() (utimensat != NULL)
+# else
+#   define utimensat_available_p() 1
+# endif
+
 static int
 utime_internal(const char *path, void *arg)
 {
@@ -2841,11 +2866,17 @@ utime_internal(const char *path, void *arg) https://github.com/ruby/ruby/blob/trunk/file.c#L2866
     struct timeval tvbuf[2], *tvp = NULL;
 
 #if defined(HAVE_UTIMENSAT)
+# if defined(__APPLE__)
+    const int try_utimensat = utimensat != NULL;
+    const int try_utimensat_follow = utimensat != NULL;
+# else
+#   define TRY_UTIMENSAT 1
     static int try_utimensat = 1;
 # ifdef AT_SYMLINK_NOFOLLOW
     static int try_utimensat_follow = 1;
 # else
     const int try_utimensat_follow = 0;
+# endif
 # endif
     int flags = 0;
 
@@ -2856,20 +2887,22 @@ utime_internal(const char *path, void *arg) https://github.com/ruby/ruby/blob/trunk/file.c#L2887
 	}
 # endif
 
-	if (utimensat(AT_FDCWD, path, tsp, flags) < 0) {
-            if (errno == ENOSYS) {
+	int result = utimensat(AT_FDCWD, path, tsp, flags);
+# ifdef TRY_UTIMENSAT
+	if (result < 0 && errno == ENOSYS) {
 # ifdef AT_SYMLINK_NOFOLLOW
-		try_utimensat_follow = 0;
+            try_utimensat_follow = 0;
 # endif
-		if (!v->follow)
-		    try_utimensat = 0;
-                goto no_utimensat;
-            }
-            return -1; /* calls utime_failed */
+            if (!v->follow)
+                try_utimensat = 0;
         }
-        return 0;
+        else
+# endif
+            return result;
     }
+# ifdef TRY_UTIMENSAT
 no_utimensat:
+# endif
 #endif
 
     if (tsp) {
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]