Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH 1/4] attr: add -h option to operate on symlinks without dereferencing



Since the OSX-style interface doesn't have the l* family, make wrapper
functions that handle the boring details.
---
 Src/Modules/attr.c |  111 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 78 insertions(+), 33 deletions(-)

diff --git a/Src/Modules/attr.c b/Src/Modules/attr.c
index ec3b1e4..cbf3d92 100644
--- a/Src/Modules/attr.c
+++ b/Src/Modules/attr.c
@@ -33,25 +33,79 @@
 #include <sys/types.h>
 #include <sys/xattr.h>

+static ssize_t
+xgetxattr(const char *path, const char *name, void *value, size_t size, int symlink)
+{
+#ifdef XATTR_EXTRA_ARGS
+    return getxattr(path, name, value, size, 0, symlink ? XATTR_NOFOLLOW: 0);
+#else
+    switch (symlink) {
+    case 0:
+        return getxattr(path, name, value, size);
+    case 1:
+        return lgetxattr(path, name, value, size);
+    }
+#endif
+}
+
+static ssize_t
+xlistxattr(const char *path, char *list, size_t size, int symlink)
+{
+#ifdef XATTR_EXTRA_ARGS
+    return listxattr(path, list, size, symlink ? XATTR_NOFOLLOW : 0);
+#else
+    switch (symlink) {
+    case 0:
+        return listxattr(path, list, size);
+    case 1:
+        return llistxattr(path, list, size);
+    }
+#endif
+}
+
+static int
+xsetxattr(const char *path, const char *name, const void *value,
+          size_t size, int flags, int symlink)
+{
+#ifdef XATTR_EXTRA_ARGS
+    return setxattr(path, name, value, size, 0, flags | symlink ? XATTR_NOFOLLOW : 0);
+#else
+    switch (symlink) {
+    case 0:
+        return setxattr(path, name, value, size, flags);
+    case 1:
+        return lsetxattr(path, name, value, size, flags);
+    }
+#endif
+}
+
 static int
-bin_getattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+xremovexattr(const char *path, const char *name, int symlink)
+{
+#ifdef XATTR_EXTRA_ARGS
+    return removexattr(path, name, symlink ? XATTR_NOFOLLOW : 0);
+#else
+    switch (symlink) {
+    case 0:
+        return removexattr(path, name);
+    case 1:
+        return lremovexattr(path, name);
+    }
+#endif
+}
+
+static int
+bin_getattr(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int ret = 0;
     int len, slen;
     char value[256];
+    int symlink = OPT_ISSET(ops, 'h');

     unmetafy(*argv, &slen);
     unmetafy(*(argv+1), NULL);
-    if (listxattr(*argv, NULL, 0
-#ifdef XATTR_EXTRA_ARGS
-		  , 0
-#endif
-		  ) > 0) {
-        if (0 < (len = getxattr(*argv, *(argv+1), value, 255
-#ifdef XATTR_EXTRA_ARGS
-				, 0, 0
-#endif
-				))) {
+    if (xlistxattr(*argv, NULL, 0, symlink) > 0) {
+        if (0 < (len = xgetxattr(*argv, *(argv+1), value, 255, symlink))) {
             if (len < 256) {
                 value[len] = '\0';
                 if (*(argv+2))
@@ -68,18 +122,15 @@ bin_getattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 }

 static int
-bin_setattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+bin_setattr(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int ret = 0, slen;
+    int symlink = OPT_ISSET(ops, 'h');

     unmetafy(*argv, &slen);
     unmetafy(*(argv+1), NULL);
     unmetafy(*(argv+2), NULL);
-    if (setxattr(*argv, *(argv+1), *(argv+2), strlen(*(argv+2)), 0
-#ifdef XATTR_EXTRA_ARGS
-						     , 0
-#endif
-		 )) {
+    if (xsetxattr(*argv, *(argv+1), *(argv+2), strlen(*(argv+2)), 0, symlink)) {
         zwarnnam(nam, "%s: %e", metafy(*argv, slen, META_NOALLOC), errno);
         ret = 1;
     }
@@ -87,17 +138,14 @@ bin_setattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 }

 static int
-bin_delattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+bin_delattr(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int ret = 0, slen;
+    int symlink = OPT_ISSET(ops, 'h');

     unmetafy(*argv, &slen);
     unmetafy(*(argv+1), NULL);
-    if (removexattr(*argv, *(argv+1)
-#ifdef XATTR_EXTRA_ARGS
-		    , 0
-#endif
-		    )) {
+    if (xremovexattr(*argv, *(argv+1), symlink)) {
         zwarnnam(nam, "%s: %e", metafy(*argv, slen, META_NOALLOC), errno);
         ret = 1;
     }
@@ -105,18 +153,15 @@ bin_delattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 }

 static int
-bin_listattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+bin_listattr(char *nam, char **argv, Options ops, UNUSED(int func))
 {
     int ret = 0;
     int len, slen;
     char value[256];
+    int symlink = OPT_ISSET(ops, 'h');

     unmetafy(*argv, &slen);
-    if (0 < (len = listxattr(*argv, value, 256
-#ifdef XATTR_EXTRA_ARGS
-		  , 0
-#endif
-			     ))) {
+    if (0 < (len = xlistxattr(*argv, value, 256, symlink))) {
         if (len < 256) {
             char *p = value;
             if (*(argv+1))
@@ -136,10 +181,10 @@ bin_listattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
 /* module paraphernalia */

 static struct builtin bintab[] = {
-    BUILTIN("zgetattr", 0, bin_getattr, 2, 3, 0, NULL, NULL),
-    BUILTIN("zsetattr", 0, bin_setattr, 3, 3, 0, NULL, NULL),
-    BUILTIN("zdelattr", 0, bin_delattr, 2, 2, 0, NULL, NULL),
-    BUILTIN("zlistattr", 0, bin_listattr, 1, 2, 0, NULL, NULL),
+    BUILTIN("zgetattr", 0, bin_getattr, 2, 3, 0, "h", NULL),
+    BUILTIN("zsetattr", 0, bin_setattr, 3, 3, 0, "h", NULL),
+    BUILTIN("zdelattr", 0, bin_delattr, 2, 2, 0, "h", NULL),
+    BUILTIN("zlistattr", 0, bin_listattr, 1, 2, 0, "h", NULL),
 };

 static struct features module_features = {
--
1.6.5



Messages sorted by: Reverse Date, Date, Thread, Author