diff options
author | Bob Ippolito <bob@redivi.com> | 2010-01-02 23:11:35 +0000 |
---|---|---|
committer | Bob Ippolito <bob@redivi.com> | 2010-01-02 23:11:35 +0000 |
commit | 2219053938529df211440e2b5758bc6ecaf17062 (patch) | |
tree | 762782b4c4c460c91f743f922fa18d570c955120 | |
parent | a4dd71da148892930905d5ffbfe46b33c7daaba1 (diff) | |
download | xattr-2219053938529df211440e2b5758bc6ecaf17062.tar.gz |
experimental solaris support, test suite
-rw-r--r-- | Modules/xattr/_xattr.c | 193 | ||||
-rw-r--r-- | setup.py | 5 |
2 files changed, 195 insertions, 3 deletions
diff --git a/Modules/xattr/_xattr.c b/Modules/xattr/_xattr.c index 5c2b3ba..59ee0b1 100644 --- a/Modules/xattr/_xattr.c +++ b/Modules/xattr/_xattr.c @@ -1,6 +1,12 @@ #include "Python.h" #ifdef __FreeBSD__ #include <sys/extattr.h> +#elif defined(__SUN__) || defined(__sun__) +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <dirent.h> #else #include <sys/xattr.h> #endif @@ -226,6 +232,191 @@ static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) return rv; } +#elif defined(__SUN__) || defined(__sun__) + +/* Solaris 9 and later compatibility API */ +#define XATTR_XATTR_NOFOLLOW 0x0001 +#define XATTR_XATTR_CREATE 0x0002 +#define XATTR_XATTR_REPLACE 0x0004 +#define XATTR_XATTR_NOSECURITY 0x0008 + +#define u_int32_t unsigned int + +static ssize_t xattr_fgetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + int xfd; + ssize_t bytes; + struct stat statbuf; + + /* XXX should check that name does not have / characters in it */ + xfd = openat(fd, name, O_RDONLY | O_XATTR); + close(fd); + if (xfd == -1) { + return -1; + } + if (lseek(xfd, position, SEEK_SET) == -1) { + close(xfd); + return -1; + } + if (value == NULL) { + if (fstat(xfd, &statbuf) == -1) { + close(xfd); + return -1; + } + close(xfd); + return statbuf.st_size; + } + /* XXX should keep reading until the buffer is exhausted or EOF */ + bytes = read(xfd, value, size); + close(xfd); + return bytes; +} + +static ssize_t xattr_getxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + int fd; + ssize_t bytes; + + if (position != 0 || + !(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + + fd = open(path, + O_RDONLY | + ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd == -1) { + return -1; + } + bytes = xattr_fgetxattr(fd, name, value, size, position, options); + close(fd); + return bytes; +} + +static ssize_t xattr_fsetxattr(int fd, const char *name, void *value, + ssize_t size, u_int32_t position, int options) +{ + int xfd; + ssize_t bytes = 0; + + /* XXX should check that name does not have / characters in it */ + xfd = openat(fd, name, O_XATTR | O_TRUNC | + ((options & XATTR_XATTR_CREATE) ? O_EXCL : 0) | + ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0) | + ((options & XATTR_XATTR_REPLACE) ? O_RDWR : O_WRONLY|O_CREAT), + 0644); + if (xfd == -1) { + return -1; + } + while (size > 0) { + bytes = write(xfd, value, size); + if (bytes == -1) { + close(xfd); + return -1; + } + size -= bytes; + value += bytes; + } + close(xfd); + return 0; +} + +static ssize_t xattr_setxattr(const char *path, const char *name, + void *value, ssize_t size, u_int32_t position, + int options) +{ + int fd; + ssize_t bytes; + + if (position != 0) { + return -1; + } + + fd = open(path, + O_RDONLY | (options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0); + if (fd == -1) { + return -1; + } + bytes = xattr_fsetxattr(fd, name, value, size, position, options); + close(fd); + return bytes; +} + +static ssize_t xattr_fremovexattr(int fd, const char *name, int options) +{ + int xfd, status; + /* XXX should check that name does not have / characters in it */ + if (!(options == 0 || options == XATTR_XATTR_NOFOLLOW)) { + return -1; + } + if (options & XATTR_XATTR_NOFOLLOW) { + return -1; + } + xfd = openat(fd, ".", O_XATTR, 0644); + if (xfd == -1) { + return -1; + } + status = unlinkat(xfd, name, 0); + close(xfd); + return status; +} + +static ssize_t xattr_removexattr(const char *path, const char *name, + int options) +{ + int fd; + ssize_t status; + + fd = open(path, + O_RDONLY | ((options & XATTR_XATTR_NOFOLLOW) ? O_NOFOLLOW : 0)); + if (fd == -1) { + return -1; + } + status = xattr_fremovexattr(fd, name, options); + close(fd); + return status; +} + +static ssize_t xattr_xflistxattr(int xfd, char *namebuf, size_t size, int options) +{ + int esize; + DIR *dirp; + struct dirent *entry; + ssize_t nsize = 0; + + dirp = fdopendir(xfd); + while (entry = readdir(dirp)) { + esize = strlen(entry->d_name); + if (nsize + esize + 1 < size) { + strcat(namebuf + nsize, entry->d_name); + nsize += esize + 1; /* +1 for \0 */ + } else { + break; + } + } + closedir(dirp); + return nsize; +} +static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) +{ + int xfd; + + xfd = openat(fd, ".", O_RDONLY); + return xattr_xflistxattr(xfd, namebuf, size, options); +} + +static ssize_t xattr_listxattr(const char *path, char *namebuf, + size_t size, int options) +{ + int xfd; + + xfd = attropen(path, ".", O_RDONLY); + return xattr_xflistxattr(xfd, namebuf, size, options); +} + #elif !defined(XATTR_NOFOLLOW) /* Linux compatibility API */ #define XATTR_XATTR_NOFOLLOW 0x0001 @@ -342,7 +533,7 @@ static ssize_t xattr_flistxattr(int fd, char *namebuf, size_t size, int options) } } -#else +#else /* Mac OS X assumed */ #define xattr_getxattr getxattr #define xattr_fgetxattr fgetxattr #define xattr_removexattr removexattr @@ -12,8 +12,8 @@ Extended attributes extend the basic attributes of files and directories in the file system. They are stored as name:data pairs associated with file system objects (files, directories, symlinks, etc). -Extended attributes are currently only available on Darwin 8.0+ (Max OS X 10.4) -and Linux 2.6+. +Extended attributes are currently only available on Darwin 8.0+ (Mac OS X 10.4) +and Linux 2.6+. Experimental support is included for Solaris and FreeBSD. """ CLASSIFIERS = filter(None, map(str.strip, @@ -50,5 +50,6 @@ setup( "xattr = xattr.tool:main", ], }, + test_suite="xattr.tests.all_tests_suite", zip_safe=False, ) |