]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/_helpers.c
txstat: fix for python 3
[bup.git] / lib / bup / _helpers.c
index d986895affaeda9cd117b1dc9bc909c470a25f5a..9078be3da723d8e7757662950a7521bdc275754f 100644 (file)
@@ -29,6 +29,9 @@
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
 
 #ifdef HAVE_LINUX_FS_H
 #include <linux/fs.h>
@@ -71,8 +74,10 @@ typedef struct {
 #if PY_MAJOR_VERSION < 3
 static state_t state;
 #  define get_state(x) (&state)
+#  define cstr_argf "s"
 #else
 #  define get_state(x) ((state_t *) PyModule_GetState(x))
+#  define cstr_argf "y"
 #endif // PY_MAJOR_VERSION >= 3
 
 
@@ -740,6 +745,11 @@ struct sha {
     unsigned char bytes[20];
 };
 
+static inline int _cmp_sha(const struct sha *sha1, const struct sha *sha2)
+{
+    return memcmp(sha1->bytes, sha2->bytes, sizeof(sha1->bytes));
+}
+
 
 struct idx {
     unsigned char *map;
@@ -750,17 +760,6 @@ struct idx {
     int name_base;
 };
 
-
-static int _cmp_sha(const struct sha *sha1, const struct sha *sha2)
-{
-    int i;
-    for (i = 0; i < sizeof(struct sha); i++)
-       if (sha1->bytes[i] != sha2->bytes[i])
-           return sha1->bytes[i] - sha2->bytes[i];
-    return 0;
-}
-
-
 static void _fix_idx_order(struct idx **idxs, int *last_i)
 {
     struct idx *idx;
@@ -1251,7 +1250,7 @@ static PyObject *bup_utimensat(PyObject *self, PyObject *args)
     PyObject *access_py, *modification_py;
     struct timespec ts[2];
 
-    if (!PyArg_ParseTuple(args, "is((Ol)(Ol))i",
+    if (!PyArg_ParseTuple(args, "i" cstr_argf "((Ol)(Ol))i",
                           &fd,
                           &path,
                           &access_py, &(ts[0].tv_nsec),
@@ -1293,7 +1292,7 @@ static int bup_parse_xutimes_args(char **path,
     PyObject *access_py, *modification_py;
     long long access_us, modification_us; // POSIX guarantees tv_usec is signed.
 
-    if (!PyArg_ParseTuple(args, "s((OL)(OL))",
+    if (!PyArg_ParseTuple(args, cstr_argf "((OL)(OL))",
                           path,
                           &access_py, &access_us,
                           &modification_py, &modification_us))
@@ -1409,7 +1408,7 @@ static PyObject *bup_stat(PyObject *self, PyObject *args)
     int rc;
     char *filename;
 
-    if (!PyArg_ParseTuple(args, "s", &filename))
+    if (!PyArg_ParseTuple(args, cstr_argf, &filename))
         return NULL;
 
     struct stat st;
@@ -1425,7 +1424,7 @@ static PyObject *bup_lstat(PyObject *self, PyObject *args)
     int rc;
     char *filename;
 
-    if (!PyArg_ParseTuple(args, "s", &filename))
+    if (!PyArg_ParseTuple(args, cstr_argf, &filename))
         return NULL;
 
     struct stat st;
@@ -1479,43 +1478,59 @@ static PyObject *bup_localtime(PyObject *self, PyObject *args)
 #ifdef BUP_MINCORE_BUF_TYPE
 static PyObject *bup_mincore(PyObject *self, PyObject *args)
 {
-    const char *src;
-    Py_ssize_t src_ssize;
-    Py_buffer dest;
+    Py_buffer src, dest;
     PyObject *py_src_n, *py_src_off, *py_dest_off;
-    if (!PyArg_ParseTuple(args, "s#OOw*O",
-                          &src, &src_ssize, &py_src_n, &py_src_off,
+
+    if (!PyArg_ParseTuple(args, cstr_argf "*OOw*O",
+                          &src, &py_src_n, &py_src_off,
                           &dest, &py_dest_off))
        return NULL;
 
-    unsigned long long src_size, src_n, src_off, dest_size, dest_off;
+    PyObject *result = NULL;
+
+    unsigned long long src_n, src_off, dest_off;
     if (!(bup_ullong_from_py(&src_n, py_src_n, "src_n")
           && bup_ullong_from_py(&src_off, py_src_off, "src_off")
           && bup_ullong_from_py(&dest_off, py_dest_off, "dest_off")))
-        return NULL;
+        goto clean_and_return;
 
-    if (!INTEGRAL_ASSIGNMENT_FITS(&src_size, src_ssize))
-        return PyErr_Format(PyExc_OverflowError, "invalid src size");
     unsigned long long src_region_end;
+    if (!uadd(&src_region_end, src_off, src_n)) {
+        result = PyErr_Format(PyExc_OverflowError, "(src_off + src_n) too large");
+        goto clean_and_return;
+    }
+    if (src_region_end > src.len) {
+        result = PyErr_Format(PyExc_OverflowError, "region runs off end of src");
+        goto clean_and_return;
+    }
 
-    if (!uadd(&src_region_end, src_off, src_n))
-        return PyErr_Format(PyExc_OverflowError, "(src_off + src_n) too large");
-    if (src_region_end > src_size)
-        return PyErr_Format(PyExc_OverflowError, "region runs off end of src");
-
-    if (!INTEGRAL_ASSIGNMENT_FITS(&dest_size, dest.len))
-        return PyErr_Format(PyExc_OverflowError, "invalid dest size");
-    if (dest_off > dest_size)
-        return PyErr_Format(PyExc_OverflowError, "region runs off end of dest");
+    unsigned long long dest_size;
+    if (!INTEGRAL_ASSIGNMENT_FITS(&dest_size, dest.len)) {
+        result = PyErr_Format(PyExc_OverflowError, "invalid dest size");
+        goto clean_and_return;
+    }
+    if (dest_off > dest_size) {
+        result = PyErr_Format(PyExc_OverflowError, "region runs off end of dest");
+        goto clean_and_return;
+    }
 
     size_t length;
-    if (!INTEGRAL_ASSIGNMENT_FITS(&length, src_n))
-        return PyErr_Format(PyExc_OverflowError, "src_n overflows size_t");
-    int rc = mincore((void *)(src + src_off), src_n,
+    if (!INTEGRAL_ASSIGNMENT_FITS(&length, src_n)) {
+        result = PyErr_Format(PyExc_OverflowError, "src_n overflows size_t");
+        goto clean_and_return;
+    }
+    int rc = mincore((void *)(src.buf + src_off), src_n,
                      (BUP_MINCORE_BUF_TYPE *) (dest.buf + dest_off));
-    if (rc != 0)
-        return PyErr_SetFromErrno(PyExc_OSError);
-    return Py_BuildValue("O", Py_None);
+    if (rc != 0) {
+        result = PyErr_SetFromErrno(PyExc_OSError);
+        goto clean_and_return;
+    }
+    result = Py_BuildValue("O", Py_None);
+
+ clean_and_return:
+    PyBuffer_Release(&src);
+    PyBuffer_Release(&dest);
+    return result;
 }
 #endif /* def BUP_MINCORE_BUF_TYPE */