zsh-workers
 help / color / mirror / code / Atom feed
* [wip patch] new zsh/attr module
@ 2009-02-26 21:55 Mikael Magnusson
  2009-02-26 22:36 ` Mikael Magnusson
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Mikael Magnusson @ 2009-02-26 21:55 UTC (permalink / raw)
  To: zsh workers

Hi,

in my .zshrc I have this short function:
#usage, *(e:fattr name:) or *(e:fattr name value:)
function fattr() {
   local val="$(getfattr -n user.$1 --only-values $REPLY 2>/dev/null)"
   [[ -n "$val" && ( -z "$2" || "$val" =~ "$2" ) ]]
}

The problem is it takes a long time when you run it on some significant 
set of files since it forks for every file (~10 seconds for hundreds of 
files). So I cobbled together this module to make three builtins, 
zgetattr, zsetattr and zdelattr.

#usage, *(e:fattr name:) or *(e:fattr name value:)
function fattr() {
   local val
   zgetattr $REPLY user.$1 val 2>/dev/null
   [[ -n "$val" && ( -z "$2" || "$val" =~ "$2" ) ]]
}

This runs in 280ms for the same set of files.

I'm not sure if I should mention it being copied from cap.c since pretty 
much only the skeleton remains. I guess I would have to write some 
documentation too. The builtins should probably handle more than one file 
and parse options in a better way. A builtin for listing attrs on a file 
would be useful too (could at least be used for completion of the second 
argument :) ). Maybe the module should be called xattr instead of just 
attr? I also didn't bother checking what happens when the system doesn't 
support xattrs or doesn't have the includes. I guess something similar to 
what db_gdbm.mdd does is needed? I noticed just now that I was lazy and 
used the ?: extension so that's something to fix too.

Do I need to nul terminate strings I give to metafy() and/or setsparam()?

I think the AC_CHECK_LIB isn't exactly right either, it adds a second -lc 
to $LIBS.

diff --git a/Src/Modules/.distfiles b/Src/Modules/.distfiles
index 40d3114..9231cec 100644
--- a/Src/Modules/.distfiles
+++ b/Src/Modules/.distfiles
@@ -2,6 +2,8 @@ DISTFILES_SRC='
  .cvsignore
  .distfiles
  .exrc
+attr.mdd
+attr.c
  cap.mdd
  cap.c
  clone.mdd
diff --git a/Src/Modules/attr.c b/Src/Modules/attr.c
new file mode 100644
index 0000000..fc9c70a
--- /dev/null
+++ b/Src/Modules/attr.c
@@ -0,0 +1,140 @@
+/*
+ * attr.c - extended attributes (xattr) manipulation
+ * (based on cap.c)
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2009 Mikael Magnusson
+ * Copyright (c) 1997 Andrew Main
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Mikael Magnusson or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Andrew Main and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Mikael Magnusson and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Mikael Magnusson and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "attr.mdh"
+#include "attr.pro"
+
+#include <sys/types.h>
+#include <sys/xattr.h>
+
+static int
+bin_getattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+{
+    int ret = 0;
+    int len;
+    char value[256];
+
+    if (listxattr(*argv, NULL, 0) > 0) {
+        if (0 < (len = getxattr(*argv, *(argv+1), value, 255))) {
+            if (len < 256) {
+                value[len] = '\0';
+                setsparam(*(argv+2) ?: "REPLY", metafy(value, len, META_DUP));
+            }
+        } else {
+            zwarnnam(nam, "%s: %e", *argv, errno);
+            ret = 1;
+        }
+    }
+    return ret;
+}
+
+static int
+bin_setattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+{
+    int ret = 0;
+ 
+    if (setxattr(*argv, *(argv+1), *(argv+2), strlen(*(argv+2)), 0)) {
+        zwarnnam(nam, "%s: %e", *argv, errno);
+        ret = 1;
+    }
+    return ret;
+}
+
+static int
+bin_delattr(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
+{
+    int ret = 0;
+ 
+    if (removexattr(*argv, *(argv+1))) {
+        zwarnnam(nam, "%s: %e", *argv, errno);
+        ret = 1;
+    }
+    return ret;
+}
+
+/* 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),
+};
+
+static struct features module_features = {
+    bintab, sizeof(bintab)/sizeof(*bintab),
+    NULL, 0,
+    NULL, 0,
+    NULL, 0,
+    0
+};
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+    return 0;
+}
+
+/**/
+int
+features_(Module m, char ***features)
+{
+    *features = featuresarray(m, &module_features);
+    return 0;
+}
+
+/**/
+int
+enables_(Module m, int **enables)
+{
+    return handlefeatures(m, &module_features, enables);
+}
+
+/**/
+int
+boot_(UNUSED(Module m))
+{
+    return 0;
+}
+
+/**/
+int
+cleanup_(Module m)
+{
+    return setfeatureenables(m, &module_features, NULL);
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+    return 0;
+}
diff --git a/Src/Modules/attr.mdd b/Src/Modules/attr.mdd
new file mode 100644
index 0000000..fc4f7b9
--- /dev/null
+++ b/Src/Modules/attr.mdd
@@ -0,0 +1,7 @@
+name=zsh/attr
+link=dynamic
+load=no
+
+autofeatures="b:zgetattr b:zsetattr b:zdelattr"
+
+objects="attr.o"
diff --git a/configure.ac b/configure.ac
index 50658e5..fe3f229 100644
--- a/configure.ac
+++ b/configure.ac
@@ -852,6 +852,9 @@ if test x$gdbm != xno; then
    AC_CHECK_LIB(gdbm, gdbm_open)
  fi

+AC_CHECK_HEADERS(sys/xattr.h)
+AC_CHECK_LIB(c, getxattr)
+
  dnl --------------
  dnl CHECK TYPEDEFS
  dnl --------------

--
Mikael Magnusson


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-09-12 11:12 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-26 21:55 [wip patch] new zsh/attr module Mikael Magnusson
2009-02-26 22:36 ` Mikael Magnusson
2009-02-27  0:48 ` Mikael Magnusson
2009-03-03 12:12 ` Peter Stephenson
2009-03-03 14:43   ` Mikael Magnusson
2009-03-03 16:35     ` Peter Stephenson
2009-03-03 16:51       ` Mikael Magnusson
2009-03-03 16:55         ` Peter Stephenson
2009-03-03 17:00           ` Mikael Magnusson
2009-11-03 18:52         ` Mikael Magnusson
2009-11-03 18:55           ` [PATCH 1/4] attr: add -h option to operate on symlinks without dereferencing Mikael Magnusson
2009-11-04 10:48             ` Peter Stephenson
2009-11-04 11:01               ` Mikael Magnusson
2009-11-04 11:36                 ` Peter Stephenson
2010-09-12 11:12             ` Mikael Magnusson
2009-11-03 18:56           ` [PATCH 2/4] attr: Make zlistattr return an array, zdelattr take several attrs Mikael Magnusson
2009-11-05  6:51             ` [PATCH 2/4] attr: Make zlistattr return an array, zdelattr takeseveral attrs Jun T.
2009-11-05  9:48               ` Mikael Magnusson
2009-11-03 18:57           ` [PATCH 3/4] attr: dynamically allocate memory for attributes Mikael Magnusson
2009-11-03 18:57           ` [PATCH 4/4] attr: Use descriptive variables for argv and allow setting values with embedded nuls Mikael Magnusson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).