From a7705355e87583c888b5b1f54f404d90c0f3a56b Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sun, 30 May 2010 15:18:15 -0400 Subject: [PATCH] Give up on implementing proglist portably in sh and do it in C. Fixes issue #42. --- cmd/wmii.rc.rc | 5 +---- cmd/wmii.sh.sh | 4 +--- cmd/wmiir.c | 38 ++++++++++++++++++++++++++++++++++++++ man/wmiir.1 | 47 ++++++++++++++++++++++++++++++++++++++++++++++- man/wmiir.man1 | 26 +++++++++++++++++++++++++- 5 files changed, 111 insertions(+), 9 deletions(-) diff --git a/cmd/wmii.rc.rc b/cmd/wmii.rc.rc index 392a0d7c..3da4f58b 100755 --- a/cmd/wmii.rc.rc +++ b/cmd/wmii.rc.rc @@ -58,10 +58,7 @@ fn wi_fn-p { } fn wi_proglist { - # XXX: maxdepth is not POSIX compliant. - ifs=: { find -L `{echo -n $*} -type f -a -maxdepth 1 \ - '(' -perm -0100 -o -perm -0010 -o -perm -0001 ')' >[2]/dev/null \ - | sed 's,.*/,,' | sort | uniq} + ifs=: { wmiir proglist -- `{echo -n $*} | sort | uniq } } fn wi_actions { diff --git a/cmd/wmii.sh.sh b/cmd/wmii.sh.sh index 07d0bd76..8d10abfd 100755 --- a/cmd/wmii.sh.sh +++ b/cmd/wmii.sh.sh @@ -135,9 +135,7 @@ wi_fnmenu() { } wi_proglist() { - ls -lL $(echo $* | sed 'y/:/ /') 2>/dev/null \ - | awk '$1 ~ /^[^d].*x/ { print $NF }' \ - | sort | uniq + wmiir proglist -- $(echo $* | sed 'y/:/ /') | sort | uniq } wi_actions() { diff --git a/cmd/wmiir.c b/cmd/wmiir.c index 4fd5acae..1b5cab22 100644 --- a/cmd/wmiir.c +++ b/cmd/wmiir.c @@ -3,6 +3,7 @@ */ #define IXP_NO_P9_ #define IXP_P9_STRUCTS +#include #include #include #include @@ -328,15 +329,44 @@ xnamespace(int argc, char *argv[]) { return 0; } +static int +xproglist(int argc, char *argv[]) { + DIR *d; + struct dirent *de; + char *dir; + + quotefmtinstall(); + + ARGBEGIN{ + default: + usage(); + }ARGEND; + + while((dir = ARGF())) + if((d = opendir(dir))) { + while((de = readdir(d))) + if(access(de->d_name, X_OK)) + print("%q\n", de->d_name); + closedir(d); + } + + return 0; /* NOTREACHED */ +} + static int xsetsid(int argc, char *argv[]) { char *av0; + bool dofork; av0 = nil; + dofork = false; ARGBEGIN{ case '0': av0 = EARGF(usage()); break; + case 'f': + dofork = true; + break; default: usage(); }ARGEND; @@ -346,6 +376,13 @@ xsetsid(int argc, char *argv[]) { return 1; setsid(); + if(dofork) + switch(fork()) { + case 0: break; + case -1: fatal("can't fork: %r\n"); + default: return 0; + } + execvp(av0, argv); fatal("setsid: can't exec: %r"); return 1; /* NOTREACHED */ @@ -368,6 +405,7 @@ struct exectab { }, utiltab[] = { {"namespace", xnamespace}, {"ns", xnamespace}, + {"proglist", xproglist}, {"setsid", xsetsid}, {0, } }; diff --git a/man/wmiir.1 b/man/wmiir.1 index acf658d9..a83b99cc 100644 --- a/man/wmiir.1 +++ b/man/wmiir.1 @@ -25,6 +25,9 @@ configuration scripts. The address at which to connect to \fBwmii\fR. .SH COMMANDS +.P +The following commands deal with 9P filesystems. + .TP create \fI\fR Creates a new file or directory in the filesystem. Permissions and @@ -57,7 +60,7 @@ Synonyms: \fBcat\fR remove \fI\fR Removes \fI\fR from the filesystem. -Synonyms: rm +Synonyms: \fBrm\fR .TP write \fI\fR Writes the contents of the standard input to \fI\fR. @@ -66,6 +69,48 @@ xwrite \fI\fR \fI\fR ... Writes each argument after \fI\fR to the latter. +.P +Additionally, wmiir provides the following utility commands relevant +to scripting wmii: + +.TP +namespace + +.RS +Prints the current wmii namespace directory, usually +equivalent to /tmp/ns.\fB$USER\fR.\fB${DISPLAY\fR%.0\fB}\fR, but possibly +different depending on the value of \fB$NAMESPACE\fR and +\fB$WMII_NAMESPACE\fR. +.RE + +.RS +Synonyms: \fBns\fR +.RE +.TP +setsid \fI[\-0 \fI\fR]\fR \fI[\-f]\fR \fI\fR + +.RS +Executes the given command after setting the session id (see +setsid(2)). If \fI\-0\fR is given, the command is run with the +given value as argv\fI[0]\fR. For instance, to run sh as a login +shell, one might run +.RE + +.nf + wmiir setsid -0 -sh sh +.fi + +.RS +If \fI\-f\fR is given, wmiir will fork into the background before +executing the command. +.RE +.TP +proglist \fI[\-\-]\fR \fI\fR ... + +.RS +Lists all executable commands in the given directories. +.RE + .SH ENVIRONMENT .TP \fB$WMII_ADDRESS\fR diff --git a/man/wmiir.man1 b/man/wmiir.man1 index 8ea04edf..83f5f926 100644 --- a/man/wmiir.man1 +++ b/man/wmiir.man1 @@ -28,6 +28,8 @@ configuration scripts. : = COMMANDS = +The following commands deal with 9P filesystems. + : create Creates a new file or directory in the filesystem. Permissions and file type are inferred by `wmii`. The contents of the standard input @@ -53,13 +55,35 @@ configuration scripts. : remove Removes from the filesystem. - Synonyms: rm + Synonyms: `rm` : write Writes the contents of the standard input to . : xwrite ... Writes each argument after to the latter. : +Additionally, wmiir provides the following utility commands relevant +to scripting wmii: + +: namespace + Prints the current wmii namespace directory, usually + equivalent to /tmp/ns.$USER.${DISPLAY%.0}, but possibly + different depending on the value of $NAMESPACE and + $WMII_NAMESPACE. + + Synonyms: `ns` +: setsid [-0 ] [-f] + Executes the given command after setting the session id (see + setsid(2)). If _-0_ is given, the command is run with the + given value as argv[0]. For instance, to run sh as a login + shell, one might run + +``` wmiir setsid -0 -sh sh + If _-f_ is given, wmiir will fork into the background before + executing the command. +: proglist [--] ... + Lists all executable commands in the given directories. + = ENVIRONMENT = : $WMII_ADDRESS