]> arthur.barton.de Git - bup.git/commitdiff
Depend on python 3 for utime when using 3
authorRob Browning <rlb@defaultvalue.org>
Tue, 24 Nov 2020 00:21:00 +0000 (18:21 -0600)
committerRob Browning <rlb@defaultvalue.org>
Tue, 24 Nov 2020 21:29:43 +0000 (15:29 -0600)
Since python 3.3+ now claims to implement what we need (follow
symlinks, ns resolution), rely on it for utime when possible in
preference to our own C code in _helpers.

This should fix new failures on macos due to changes to the
availability of utimensat, etc.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
config/configure
lib/bup/_helpers.c
lib/bup/xstat.py

index afdfa3880ccb9aead3dd001b1e754bb4e16c74e0..407bd4b29df77d50d075ed8ca36435015c11a5d9 100755 (executable)
@@ -78,8 +78,16 @@ if test -z "$bup_python"; then
     AC_FAIL "ERROR: unable to find python"
 else
     AC_SUB bup_python "$bup_python"
-    AC_SUB bup_python_majver \
-           "$("$bup_python" -c 'import sys; print(sys.version_info[0])')"
+    bup_python_majver=$("$bup_python" -c 'import sys; print(sys.version_info[0])')
+    bup_python_minver=$("$bup_python" -c 'import sys; print(sys.version_info[1])')
+    AC_SUB bup_python_majver "$bup_python_majver"
+fi
+
+# May not be correct yet, i.e. actual requirement may be higher.
+if test "$bup_python_majver" -gt 2 -a "$bup_python_minver" -lt 3; then
+    # utime follow_symlinks >= 3.3
+    bup_version_str=$("$bup_python" --version 2>&1)
+    AC_FAIL "ERROR: found $bup_version_str (must be >= 3.3 if >= 3)"
 fi
 
 bup_git="$(bup_find_prog git '')"
@@ -101,13 +109,16 @@ AC_CHECK_HEADERS sys/mman.h
 AC_CHECK_HEADERS linux/fs.h
 AC_CHECK_HEADERS sys/ioctl.h
 
-# On GNU/kFreeBSD utimensat is defined in GNU libc, but won't work.
-if [ -z "$OS_GNU_KFREEBSD" ]; then
-    AC_CHECK_FUNCS utimensat
+if test "$bup_python_majver" -gt 2; then
+    AC_DEFINE BUP_USE_PYTHON_UTIME 1
+else # Python 2
+    # On GNU/kFreeBSD utimensat is defined in GNU libc, but won't work.
+    if [ -z "$OS_GNU_KFREEBSD" ]; then
+        AC_CHECK_FUNCS utimensat
+    fi
+    AC_CHECK_FUNCS utimes
+    AC_CHECK_FUNCS lutimes
 fi
-AC_CHECK_FUNCS utimes
-AC_CHECK_FUNCS lutimes
-
 
 builtin_mul_overflow_code="
 #include <stddef.h>
index 5f07d446c703444d42edda0376209b3195cfc4e0..2790b07d791ca59ab93e5711c5a276aec2cd411f 100644 (file)
@@ -70,6 +70,7 @@
 #define BUP_HAVE_FILE_ATTRS 1
 #endif
 
+#ifndef BUP_USE_PYTHON_UTIME // just for Python 2 now
 /*
  * Check for incomplete UTIMENSAT support (NetBSD 6), and if so,
  * pretend we don't have it.
@@ -77,6 +78,7 @@
 #if !defined(AT_FDCWD) || !defined(AT_SYMLINK_NOFOLLOW)
 #undef HAVE_UTIMENSAT
 #endif
+#endif // defined BUP_USE_PYTHON_UTIME
 
 #ifndef FS_NOCOW_FL
 // Of course, this assumes it's a bitfield value.
@@ -1406,6 +1408,7 @@ static PyObject *bup_set_linux_file_attr(PyObject *self, PyObject *args)
 #endif /* def BUP_HAVE_FILE_ATTRS */
 
 
+#ifndef BUP_USE_PYTHON_UTIME // just for Python 2 now
 #ifndef HAVE_UTIMENSAT
 #ifndef HAVE_UTIMES
 #error "cannot find utimensat or utimes()"
@@ -1414,6 +1417,7 @@ static PyObject *bup_set_linux_file_attr(PyObject *self, PyObject *args)
 #error "cannot find utimensat or lutimes()"
 #endif
 #endif
+#endif // defined BUP_USE_PYTHON_UTIME
 
 #define ASSIGN_PYLONG_TO_INTEGRAL(dest, pylong, overflow) \
     ({                                                     \
@@ -1450,6 +1454,7 @@ static PyObject *bup_set_linux_file_attr(PyObject *self, PyObject *args)
         })
 
 
+#ifndef BUP_USE_PYTHON_UTIME // just for Python 2 now
 #ifdef HAVE_UTIMENSAT
 
 static PyObject *bup_utimensat(PyObject *self, PyObject *args)
@@ -1567,6 +1572,8 @@ static PyObject *bup_lutimes(PyObject *self, PyObject *args)
 }
 #endif /* def HAVE_LUTIMES */
 
+#endif // defined BUP_USE_PYTHON_UTIME
+
 
 #ifdef HAVE_STAT_ST_ATIM
 # define BUP_STAT_ATIME_NS(st) (st)->st_atim.tv_nsec
@@ -2276,6 +2283,8 @@ static PyMethodDef helper_methods[] = {
     { "set_linux_file_attr", bup_set_linux_file_attr, METH_VARARGS,
       "Set the Linux attributes for the given file." },
 #endif
+
+#ifndef BUP_USE_PYTHON_UTIME // just for Python 2 now
 #ifdef HAVE_UTIMENSAT
     { "bup_utimensat", bup_utimensat, METH_VARARGS,
       "Change path timestamps with nanosecond precision (POSIX)." },
@@ -2289,6 +2298,8 @@ static PyMethodDef helper_methods[] = {
       "Change path timestamps with microsecond precision;"
       " don't follow symlinks." },
 #endif
+#endif // defined BUP_USE_PYTHON_UTIME
+
     { "stat", bup_stat, METH_VARARGS,
       "Extended version of stat." },
     { "lstat", bup_lstat, METH_VARARGS,
@@ -2420,6 +2431,8 @@ static int setup_module(PyObject *m)
         PyObject_SetAttrString(m, "UINT_MAX", value);
         Py_DECREF(value);
     }
+
+#ifndef BUP_USE_PYTHON_UTIME // just for Python 2 now
 #ifdef HAVE_UTIMENSAT
     {
         PyObject *value;
@@ -2434,6 +2447,8 @@ static int setup_module(PyObject *m)
         Py_DECREF(value);
     }
 #endif
+#endif // defined BUP_USE_PYTHON_UTIME
+
 #ifdef BUP_HAVE_MINCORE_INCORE
     {
         PyObject *value;
index 461c932f15865a4611c6342313f9220ae4917bdb..b334ffdee09ca1600fdf3e44cf62328294b4fe92 100644 (file)
@@ -20,6 +20,9 @@ try:
 except AttributeError as e:
     _bup_lutimes = False
 
+assert sys.version_info[0] < 3 \
+    or not (_bup_utimensat or _bup_utimes or _bup_lutimes)
+
 
 def timespec_to_nsecs(ts):
     ts_s, ts_ns = ts
@@ -58,8 +61,14 @@ def fstime_to_sec_bytes(fstime):
     else:
         return b'%d.%09d' % (s, ns)
 
-
-if _bup_utimensat:
+if sys.version_info[0] > 2:
+    def utime(path, times):
+        """Times must be provided as (atime_ns, mtime_ns)."""
+        os.utime(path, ns=times)
+    def lutime(path, times):
+        """Times must be provided as (atime_ns, mtime_ns)."""
+        os.utime(path, ns=times, follow_symlinks=False)
+elif _bup_utimensat:
     def utime(path, times):
         """Times must be provided as (atime_ns, mtime_ns)."""
         atime = nsecs_to_timespec(times[0])