From fa1cc713ecceee86882b47ed4afa653246d64974 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 25 Aug 2013 11:53:08 +0100 Subject: FreeBSD portability By Itamar Turner-Trauring of HybridCluster. --- NEWS | 6 ++++ _summainmodule.c | 86 +++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/NEWS b/NEWS index 6f6ece7..e1c48aa 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,12 @@ NEWS file for summain ===================== +Version 0.19, released UNRELEASed +--------------------------------- + +* FreeBSD portability fixes by Itamar Turner-Trauring of + HybridCluster. + Version 0.18, released 2013-03-15 --------------------------------- diff --git a/_summainmodule.c b/_summainmodule.c index 998469a..d008fef 100644 --- a/_summainmodule.c +++ b/_summainmodule.c @@ -31,10 +31,32 @@ #include #include #include -#include #include #include +#ifdef __FreeBSD__ + #define NO_NANOSECONDS 1 + #include +#else + #define NO_NANOSECONDS 0 + #include +#endif + +/* + * Since we can't set nanosecond mtime and atimes on some platforms, also + * don't retrieve that level of precision from lstat(), so comparisons + * work. + */ +static unsigned long long +remove_precision(unsigned long long nanoseconds) +{ +#if NO_NANOSECONDS + return nanoseconds - (nanoseconds % 1000); +#else + return nanoseconds; +#endif +} + static PyObject * lstat_wrapper(PyObject *self, PyObject *args) @@ -49,24 +71,25 @@ lstat_wrapper(PyObject *self, PyObject *args) ret = lstat(filename, &st); if (ret == -1) ret = errno; - return Py_BuildValue("iLLLLLLLLLLLLLLLL", + + return Py_BuildValue("iKKKKKKKLLLLKLKLK", ret, - (long long) st.st_dev, - (long long) st.st_ino, - (long long) st.st_mode, - (long long) st.st_nlink, - (long long) st.st_uid, - (long long) st.st_gid, - (long long) st.st_rdev, + (unsigned long long) st.st_dev, + (unsigned long long) st.st_ino, + (unsigned long long) st.st_mode, + (unsigned long long) st.st_nlink, + (unsigned long long) st.st_uid, + (unsigned long long) st.st_gid, + (unsigned long long) st.st_rdev, (long long) st.st_size, (long long) st.st_blksize, (long long) st.st_blocks, (long long) st.st_atim.tv_sec, - (long long) st.st_atim.tv_nsec, + remove_precision(st.st_atim.tv_nsec), (long long) st.st_mtim.tv_sec, - (long long) st.st_mtim.tv_nsec, + remove_precision(st.st_mtim.tv_nsec), (long long) st.st_ctim.tv_sec, - (long long) st.st_ctim.tv_nsec); + remove_precision(st.st_ctim.tv_nsec)); } @@ -76,16 +99,38 @@ llistxattr_wrapper(PyObject *self, PyObject *args) const char *filename; size_t bufsize; PyObject *o; + char* buf; + ssize_t n; if (!PyArg_ParseTuple(args, "s", &filename)) return NULL; +#ifdef __FreeBSD__ + bufsize = extattr_list_link(filename, EXTATTR_NAMESPACE_USER, NULL, 0); + buf = malloc(bufsize); + n = extattr_list_link(filename, EXTATTR_NAMESPACE_USER, buf, bufsize); + if (n >= 0) { + /* Convert from length-prefixed BSD style to '\0'-suffixed + Linux style. */ + size_t i = 0; + while (i < n) { + unsigned char length = (unsigned char) buf[i]; + memmove(buf + i, buf + i + 1, length); + buf[i + length] = '\0'; + i += length + 1; + } + o = Py_BuildValue("s#", buf, (int) n); + } else { + o = Py_BuildValue("i", errno); + } + free(buf); +#else bufsize = 0; o = NULL; do { bufsize += 1024; - char *buf = malloc(bufsize); - ssize_t n = llistxattr(filename, buf, bufsize); + buf = malloc(bufsize); + n = llistxattr(filename, buf, bufsize); if (n >= 0) o = Py_BuildValue("s#", buf, (int) n); @@ -93,7 +138,7 @@ llistxattr_wrapper(PyObject *self, PyObject *args) o = Py_BuildValue("i", errno); free(buf); } while (o == NULL); - +#endif return o; } @@ -114,15 +159,18 @@ lgetxattr_wrapper(PyObject *self, PyObject *args) do { bufsize += 1024; char *buf = malloc(bufsize); +#ifdef __FreeBSD__ + int n = extattr_get_link(filename, EXTATTR_NAMESPACE_USER, attrname, buf, bufsize); +#else ssize_t n = lgetxattr(filename, attrname, buf, bufsize); - +#endif if (n >= 0) o = Py_BuildValue("s#", buf, (int) n); else if (n == -1 && errno != ERANGE) o = Py_BuildValue("i", errno); free(buf); } while (o == NULL); - + return o; } @@ -139,7 +187,11 @@ lsetxattr_wrapper(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "sss#", &filename, &name, &value, &size)) return NULL; +#ifdef __FreeBSD__ + ret = extattr_set_link(filename, EXTATTR_NAMESPACE_USER, name, value, size); +#else ret = lsetxattr(filename, name, value, size, 0); +#endif if (ret == -1) ret = errno; return Py_BuildValue("i", ret); -- cgit v1.2.1