diff options
author | Lars Wirzenius <liw@liw.fi> | 2013-08-24 08:25:56 +0100 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2013-08-24 08:25:56 +0100 |
commit | a2532321a330ec7edba3230137c6e8739c68b256 (patch) | |
tree | 145324ee106b42f300cb5a8f04666b86e5c9ea39 /_obnammodule.c | |
parent | cb7173f2ab04edea858977c9a23365efde962b1a (diff) | |
download | obnam-a2532321a330ec7edba3230137c6e8739c68b256.tar.gz |
Patches to port Obnam to FreeBSD
By Itamar Turner-Trauring.
Diffstat (limited to '_obnammodule.c')
-rw-r--r-- | _obnammodule.c | 81 |
1 files changed, 72 insertions, 9 deletions
diff --git a/_obnammodule.c b/_obnammodule.c index f3e208bc..a5f93acb 100644 --- a/_obnammodule.c +++ b/_obnammodule.c @@ -45,10 +45,17 @@ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> -#include <sys/xattr.h> #include <unistd.h> #include <stdlib.h> +#ifdef __FreeBSD__ + #include <sys/extattr.h> + #define NO_NANOSECONDS 1 +#else + #include <sys/xattr.h> + #define NO_NANOSECONDS 0 +#endif + static PyObject * fadvise_dontneed(PyObject *self, PyObject *args) @@ -78,8 +85,11 @@ utimensat_wrapper(PyObject *self, PyObject *args) const char *filename; long atime_sec, atime_nsec; long mtime_sec, mtime_nsec; +#if NO_NANOSECONDS + struct timeval tv[2]; +#else struct timespec tv[2]; - +#endif if (!PyArg_ParseTuple(args, "sllll", &filename, &atime_sec, @@ -88,17 +98,41 @@ utimensat_wrapper(PyObject *self, PyObject *args) &mtime_nsec)) return NULL; +#if NO_NANOSECONDS + tv[0].tv_sec = atime_sec; + tv[0].tv_usec = atime_nsec / 1000; + tv[1].tv_sec = mtime_sec; + tv[1].tv_usec = mtime_nsec / 1000; + ret = lutimes(filename, tv); +#else tv[0].tv_sec = atime_sec; tv[0].tv_nsec = atime_nsec; tv[1].tv_sec = mtime_sec; tv[1].tv_nsec = mtime_nsec; ret = utimensat(AT_FDCWD, filename, tv, AT_SYMLINK_NOFOLLOW); +#endif if (ret == -1) ret = errno; return Py_BuildValue("i", ret); } +/* +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. +*/ +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) { @@ -126,11 +160,11 @@ lstat_wrapper(PyObject *self, PyObject *args) (long long) st.st_blksize, (long long) st.st_blocks, (long long) st.st_atim.tv_sec, - (unsigned long long) st.st_atim.tv_nsec, + remove_precision(st.st_atim.tv_nsec), (long long) st.st_mtim.tv_sec, - (unsigned long long) st.st_mtim.tv_nsec, + remove_precision(st.st_mtim.tv_nsec), (long long) st.st_ctim.tv_sec, - (unsigned long long) st.st_ctim.tv_nsec); + remove_precision(st.st_ctim.tv_nsec)); } @@ -140,16 +174,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); @@ -157,7 +213,7 @@ llistxattr_wrapper(PyObject *self, PyObject *args) o = Py_BuildValue("i", errno); free(buf); } while (o == NULL); - +#endif return o; } @@ -178,8 +234,11 @@ 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) @@ -203,7 +262,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); |