From: Richard D. <ric...@us...> - 2006-08-28 11:45:47
|
Update of /cvsroot/file-extattr/File-ExtAttr In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv8764 Modified Files: Changes extattr_linux.c extattr_solaris.c extattr_solaris.h helpers.c portable.h Added Files: flags.h Log Message: Solaris support for create/replace; Solaris namespace awareness; bugfix: strerror_r different with glibc than POSIX Index: extattr_solaris.h =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/extattr_solaris.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** extattr_solaris.h 14 Aug 2006 22:00:27 -0000 1.2 --- extattr_solaris.h 28 Aug 2006 11:45:40 -0000 1.3 *************** *** 14,22 **** #endif int solaris_setxattr (const char *path, const char *attrname, const char *attrvalue, const size_t slen, ! const int flags); int solaris_fsetxattr (const int fd, --- 14,24 ---- #endif + struct hv; + int solaris_setxattr (const char *path, const char *attrname, const char *attrvalue, const size_t slen, ! struct hv *flags); int solaris_fsetxattr (const int fd, *************** *** 24,50 **** const char *attrvalue, const size_t slen, ! const int flags); int solaris_getxattr (const char *path, const char *attrname, void *attrvalue, ! const size_t slen); int solaris_fgetxattr (const int fd, const char *attrname, void *attrvalue, ! const size_t slen); ! int solaris_removexattr (const char *path, const char *attrname); ! int solaris_fremovexattr (const int fd, const char *attrname); ssize_t solaris_listxattr (const char *path, char *buf, ! const size_t buflen); ssize_t solaris_flistxattr (const int fd, char *buf, ! const size_t buflen); #endif /* EXTATTR_SOLARIS_H */ --- 26,60 ---- const char *attrvalue, const size_t slen, ! struct hv *flags); int solaris_getxattr (const char *path, const char *attrname, void *attrvalue, ! const size_t slen, ! struct hv *flags); int solaris_fgetxattr (const int fd, const char *attrname, void *attrvalue, ! const size_t slen, ! struct hv *flags); ! int solaris_removexattr (const char *path, ! const char *attrname, ! struct hv *flags); ! int solaris_fremovexattr (const int fd, ! const char *attrname, ! struct hv *flags); ssize_t solaris_listxattr (const char *path, char *buf, ! const size_t buflen, ! struct hv *flags); ssize_t solaris_flistxattr (const int fd, char *buf, ! const size_t buflen, ! struct hv *flags); #endif /* EXTATTR_SOLARIS_H */ Index: extattr_linux.c =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/extattr_linux.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** extattr_linux.c 19 Aug 2006 18:27:18 -0000 1.2 --- extattr_linux.c 28 Aug 2006 11:45:39 -0000 1.3 *************** *** 7,10 **** --- 7,12 ---- #include "XSUB.h" + #include "flags.h" + static const char NAMESPACE_DEFAULT[] = "user"; *************** *** 12,17 **** flags2setflags (struct hv *flags) { - static const char CREATE_KEY[] = "create"; - static const char REPLACE_KEY[] = "replace"; const size_t CREATE_KEYLEN = strlen(CREATE_KEY); const size_t REPLACE_KEYLEN = strlen(REPLACE_KEY); --- 14,17 ---- *************** *** 35,39 **** flags2namespace (struct hv *flags) { - static const char NAMESPACE_KEY[] = "namespace"; const size_t NAMESPACE_KEYLEN = strlen(NAMESPACE_KEY); SV **psv_ns; --- 35,38 ---- Index: extattr_solaris.c =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/extattr_solaris.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** extattr_solaris.c 14 Aug 2006 22:00:27 -0000 1.2 --- extattr_solaris.c 28 Aug 2006 11:45:40 -0000 1.3 *************** *** 9,14 **** --- 9,79 ---- #include <sys/types.h> + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + #include "flags.h" + static const mode_t ATTRMODE = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP; + typedef enum { + SET_CREATEIFNEEDED = 0, + SET_CREATE, + SET_REPLACE + } setflags_t; + + static setflags_t + flags2setflags (struct hv *flags) + { + const size_t CREATE_KEYLEN = strlen(CREATE_KEY); + const size_t REPLACE_KEYLEN = strlen(REPLACE_KEY); + SV **psv_ns; + setflags_t ret = SET_CREATEIFNEEDED; + + /* + * ASSUMPTION: Perl layer must ensure that create & replace + * aren't used at the same time. + */ + if (flags && (psv_ns = hv_fetch(flags, CREATE_KEY, CREATE_KEYLEN, 0))) + ret = SvIV(*psv_ns) ? SET_CREATE : SET_CREATEIFNEEDED; + + if (flags && (psv_ns = hv_fetch(flags, REPLACE_KEY, REPLACE_KEYLEN, 0))) + ret = SvIV(*psv_ns) ? SET_REPLACE : SET_CREATEIFNEEDED; + + return ret; + } + + static int + valid_namespace (struct hv *flags) + { + const size_t NAMESPACE_KEYLEN = strlen(NAMESPACE_KEY); + SV **psv_ns; + char *ns = NULL; + int ok = 1; /* Default is valid */ + + if (flags && (psv_ns = hv_fetch(flags, NAMESPACE_KEY, NAMESPACE_KEYLEN, 0))) + { + /* + * Undefined => default. Otherwise treat "user" as if it were valid, + * for compatibility with the default on Linux and *BSD. + * An empty namespace (i.e.: zero-length) is not the same as the default. + */ + if (SvOK(*psv_ns)) + { + char *s; + STRLEN len = 0; + + s = SvPV(*psv_ns, len); + + if (len) + ok = (memcmp("user", s, len) == 0); + else + ok = 0; + } + } + + return ok; + } + static int writexattr (const int attrfd, *************** *** 158,170 **** const char *attrvalue, const size_t slen, ! const int flags) { /* XXX: Support overwrite/no overwrite flags */ int saved_errno = 0; int ok = 1; ! int attrfd = attropen(path, attrname, O_RDWR|O_CREAT, ATTRMODE); /* XXX: More common code? */ ! if (attrfd == -1) ok = 0; if (ok && (writexattr(attrfd, attrvalue, slen) == -1)) --- 223,254 ---- const char *attrvalue, const size_t slen, ! struct hv *flags) { /* XXX: Support overwrite/no overwrite flags */ int saved_errno = 0; int ok = 1; ! setflags_t setflags; ! int openflags = O_RDWR; ! int attrfd = -1; ! ! setflags = flags2setflags(flags); ! switch (setflags) ! { ! case SET_CREATEIFNEEDED: openflags |= O_CREAT; break; ! case SET_CREATE: openflags |= O_CREAT | O_EXCL; break; ! case SET_REPLACE: break; ! } ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrfd = attropen(path, attrname, openflags, ATTRMODE); /* XXX: More common code? */ ! if (ok && (attrfd == -1)) ok = 0; if (ok && (writexattr(attrfd, attrvalue, slen) == -1)) *************** *** 185,197 **** const char *attrvalue, const size_t slen, ! const int flags) { /* XXX: Support overwrite/no overwrite flags */ int saved_errno = 0; int ok = 1; ! int attrfd = openat(fd, attrname, O_RDWR|O_CREAT|O_XATTR, ATTRMODE); /* XXX: More common code? */ ! if (attrfd == -1) ok = 0; if (ok && (writexattr(attrfd, attrvalue, slen) == -1)) --- 269,300 ---- const char *attrvalue, const size_t slen, ! struct hv *flags) { /* XXX: Support overwrite/no overwrite flags */ int saved_errno = 0; int ok = 1; ! int openflags = O_RDWR | O_XATTR; ! setflags_t setflags; ! int attrfd = -1; ! ! setflags = flags2setflags(flags); ! switch (setflags) ! { ! case SET_CREATEIFNEEDED: openflags |= O_CREAT; break; ! case SET_CREATE: openflags |= O_CREAT | O_EXCL; break; ! case SET_REPLACE: break; ! } ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrfd = openat(fd, attrname, openflags, ATTRMODE); /* XXX: More common code? */ ! if (ok && (attrfd == -1)) ok = 0; if (ok && (writexattr(attrfd, attrvalue, slen) == -1)) *************** *** 212,219 **** const char *attrname, void *attrvalue, ! const size_t slen) { ! const int attrfd = attropen(path, attrname, O_RDONLY); ! return readclose(attrfd, attrvalue, slen); } --- 315,334 ---- const char *attrname, void *attrvalue, ! const size_t slen, ! struct hv *flags) { ! int attrfd = -1; ! int ok = 1; ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrfd = attropen(path, attrname, O_RDONLY); ! ! return ok ? readclose(attrfd, attrvalue, slen) : -1; } *************** *** 222,247 **** const char *attrname, void *attrvalue, ! const size_t slen) { ! int attrfd = openat(fd, attrname, O_RDONLY|O_XATTR); ! return readclose(attrfd, attrvalue, slen); } int ! solaris_removexattr (const char *path, const char *attrname) { ! int attrdirfd = attropen(path, ".", O_RDONLY); ! return unlinkclose(attrdirfd, attrname); } int ! solaris_fremovexattr (const int fd, const char *attrname) { ! int attrdirfd = openat(fd, ".", O_RDONLY|O_XATTR); ! return unlinkclose(attrdirfd, attrname); } ssize_t ! solaris_listxattr (const char *path, char *buf, const size_t buflen) { int attrdirfd = attropen(path, ".", O_RDONLY); --- 337,403 ---- const char *attrname, void *attrvalue, ! const size_t slen, ! struct hv *flags) { ! int attrfd = -1; ! int ok = 1; ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrfd = openat(fd, attrname, O_RDONLY|O_XATTR); ! ! return ok ? readclose(attrfd, attrvalue, slen) : -1; } int ! solaris_removexattr (const char *path, ! const char *attrname, ! struct hv *flags) { ! int attrdirfd = -1; ! int ok = 1; ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrdirfd = attropen(path, ".", O_RDONLY); ! ! return ok ? unlinkclose(attrdirfd, attrname) : -1; } int ! solaris_fremovexattr (const int fd, ! const char *attrname, ! struct hv *flags) { ! int attrdirfd = -1; ! int ok = 1; ! ! if (!valid_namespace(flags)) ! { ! errno = ENOATTR; ! ok = 0; ! } ! ! if (ok) ! attrdirfd = openat(fd, ".", O_RDONLY|O_XATTR); ! ! return ok ? unlinkclose(attrdirfd, attrname) : -1; } ssize_t ! solaris_listxattr (const char *path, ! char *buf, ! const size_t buflen, ! struct hv *flags) { int attrdirfd = attropen(path, ".", O_RDONLY); *************** *** 250,254 **** ssize_t ! solaris_flistxattr (const int fd, char *buf, const size_t buflen) { int attrdirfd = openat(fd, ".", O_RDONLY|O_XATTR); --- 406,413 ---- ssize_t ! solaris_flistxattr (const int fd, ! char *buf, ! const size_t buflen, ! struct hv *flags) { int attrdirfd = openat(fd, ".", O_RDONLY|O_XATTR); Index: helpers.c =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/helpers.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** helpers.c 6 Mar 2006 20:04:08 -0000 1.2 --- helpers.c 28 Aug 2006 11:45:40 -0000 1.3 *************** *** 9,20 **** #include "helpers.h" void setattr_warn (const char *funcname, const char *attrname, const int the_errno) { int is_user_xattr; ! char * errstr; is_user_xattr = (strncmp(attrname, "user.", 5) == 0); ! New(1, errstr, 1000, char); // Try to give the user a useful hint of what went wrong. --- 9,46 ---- #include "helpers.h" + #ifdef __GLIBC__ + + static inline char * + my_strerror_r (const int the_errno, char *buf, const size_t buflen) + { + buf[0] = '\0'; + + return strerror_r(the_errno, buf, buflen); + } + + #else + + static inline char * + my_strerror_r (const int the_errno, char *buf, const size_t buflen) + { + buf[0] = '\0'; + strerror_r(the_errno, buf, buflen); + + return buf; + } + + #endif + void setattr_warn (const char *funcname, const char *attrname, const int the_errno) { + static const size_t BUFLEN = 100; int is_user_xattr; ! char *buf; ! char *errstr; is_user_xattr = (strncmp(attrname, "user.", 5) == 0); ! New(1, buf, BUFLEN, char); ! errstr = my_strerror_r(the_errno, buf, BUFLEN); // Try to give the user a useful hint of what went wrong. *************** *** 31,35 **** " needs a \"user.\" prefix?", funcname, ! strerror_r(the_errno,errstr,1000)); } else --- 57,61 ---- " needs a \"user.\" prefix?", funcname, ! errstr); } else *************** *** 39,52 **** " with an option to enable extended attributes?", funcname, ! strerror_r(the_errno,errstr,1000)); } } else { ! warn("%s failed: %s", ! funcname, ! strerror_r(the_errno,errstr,1000)); } ! Safefree(errstr); } --- 65,76 ---- " with an option to enable extended attributes?", funcname, ! errstr); } } else { ! warn("%s failed: %s", funcname, errstr); } ! Safefree(buf); } --- NEW FILE: flags.h --- #ifndef EXTATTR_FLAGS_H #define EXTATTR_FLAGS_H static const char NAMESPACE_KEY[] = "namespace"; static const char CREATE_KEY[] = "create"; static const char REPLACE_KEY[] = "replace"; #endif /* EXTATTR_FLAGS_H */ Index: portable.h =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/portable.h,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** portable.h 19 Aug 2006 14:06:25 -0000 1.8 --- portable.h 28 Aug 2006 11:45:40 -0000 1.9 *************** *** 20,24 **** return bsd_setxattr(path, attrname, attrvalue, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_setxattr(path, attrname, attrvalue, slen, 0 /* XXX: flags? */); #else return linux_setxattr(path, attrname, attrvalue, slen, flags); --- 20,24 ---- return bsd_setxattr(path, attrname, attrvalue, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_setxattr(path, attrname, attrvalue, slen, flags); #else return linux_setxattr(path, attrname, attrvalue, slen, flags); *************** *** 38,42 **** return bsd_fsetxattr(fd, attrname, attrvalue, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_fsetxattr(fd, attrname, attrvalue, slen, 0 /* XXX: flags? */); #else return linux_fsetxattr(fd, attrname, attrvalue, slen, flags); --- 38,42 ---- return bsd_fsetxattr(fd, attrname, attrvalue, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_fsetxattr(fd, attrname, attrvalue, slen, flags); #else return linux_fsetxattr(fd, attrname, attrvalue, slen, flags); *************** *** 57,61 **** return extattr_get_file(path, EXTATTR_NAMESPACE_USER, attrname, attrvalue, slen); #elif defined(EXTATTR_SOLARIS) ! return solaris_getxattr(path, attrname, attrvalue, slen /* XXX: flags? */); #else return linux_getxattr(path, attrname, attrvalue, slen, flags); --- 57,61 ---- return extattr_get_file(path, EXTATTR_NAMESPACE_USER, attrname, attrvalue, slen); #elif defined(EXTATTR_SOLARIS) ! return solaris_getxattr(path, attrname, attrvalue, slen, flags); #else return linux_getxattr(path, attrname, attrvalue, slen, flags); *************** *** 76,80 **** return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, attrname, attrvalue, slen); #elif defined(EXTATTR_SOLARIS) ! return solaris_fgetxattr(fd, attrname, attrvalue, slen /* XXX: flags? */); #else return linux_fgetxattr(fd, attrname, attrvalue, slen, flags); --- 76,80 ---- return extattr_get_fd(fd, EXTATTR_NAMESPACE_USER, attrname, attrvalue, slen); #elif defined(EXTATTR_SOLARIS) ! return solaris_fgetxattr(fd, attrname, attrvalue, slen, flags); #else return linux_fgetxattr(fd, attrname, attrvalue, slen, flags); *************** *** 115,119 **** return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); #elif defined(EXTATTR_SOLARIS) ! return solaris_removexattr(path, name /* XXX: flags? */); #else return linux_removexattr(path, name, flags); --- 115,119 ---- return extattr_delete_file(path, EXTATTR_NAMESPACE_USER, name); #elif defined(EXTATTR_SOLARIS) ! return solaris_removexattr(path, name, flags); #else return linux_removexattr(path, name, flags); *************** *** 130,134 **** return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name); #elif defined(EXTATTR_SOLARIS) ! return solaris_fremovexattr(fd, name /* XXX: flags? */); #else return linux_fremovexattr(fd, name, flags); --- 130,134 ---- return extattr_delete_fd(fd, EXTATTR_NAMESPACE_USER, name); #elif defined(EXTATTR_SOLARIS) ! return solaris_fremovexattr(fd, name, flags); #else return linux_fremovexattr(fd, name, flags); *************** *** 147,151 **** return bsd_listxattr(path, buf, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_listxattr(path, buf, slen /* XXX: flags? */); #else return linux_listxattr(path, buf, slen, flags); --- 147,151 ---- return bsd_listxattr(path, buf, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_listxattr(path, buf, slen, flags); #else return linux_listxattr(path, buf, slen, flags); *************** *** 164,168 **** return bsd_flistxattr(fd, buf, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_flistxattr(fd, buf, slen /* XXX: flags? */); #else return linux_flistxattr(fd, buf, slen, flags); --- 164,168 ---- return bsd_flistxattr(fd, buf, slen /* XXX: flags? */); #elif defined(EXTATTR_SOLARIS) ! return solaris_flistxattr(fd, buf, slen, flags); #else return linux_flistxattr(fd, buf, slen, flags); Index: Changes =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/Changes,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Changes 15 Aug 2006 09:18:04 -0000 1.17 --- Changes 28 Aug 2006 11:45:39 -0000 1.18 *************** *** 1,7 **** Revision history for Perl extension File::ExtAttr. ! 1.00 2006-08-15 - (richdawe) Add support for Solaris 10. - (richdawe) Add support for File::ExtAttr::Tie on *BSD. 0.05 2006-05-27 --- 1,10 ---- Revision history for Perl extension File::ExtAttr. ! 1.00 2006-08-28 - (richdawe) Add support for Solaris 10. - (richdawe) Add support for File::ExtAttr::Tie on *BSD. + - (richdawe) API change: Namespace and the create/replace flag + are now passed via a hash. This breaks API compatibility. + There should be no further API changes. 0.05 2006-05-27 |