Hi,

I've attached a patch that allows dwm to exec rc-style paths, e.g.
"local/foo". This is of limited usefulness, but it's handy if you're
running rc and want to bind other directories into /bin instead of
messing with PATH. Any input would be appreciated.

-Matt Stickney
-- 
On Mr. Dibbler's excellent sausages: "And then you bit into them, and
learned once again that Cut-me-own-Throat Dibbler could find a use for
bits of an animal that the animal didn't know it had got. Dibbler had
worked out that with enough fried onions and mustard people would eat
*anything*."
 — (Terry Pratchett, Moving Pictures)
diff -r 406003e3a01f dwm.c
--- a/dwm.c	Mon Sep 27 07:53:44 2010 +0000
+++ b/dwm.c	Sat Oct 23 23:03:38 2010 -0400
@@ -1587,13 +1587,59 @@
 	while(0 < waitpid(-1, NULL, WNOHANG));
 }
 
+int
+rcexec(const char *file, char *const argv[])
+{
+	char path[1024];
+	char *epath, *p, *fp;
+	size_t len;
+
+	if (*file == '/')
+		return execv(file, argv);
+
+	epath = getenv("PATH");
+	if (epath == NULL) {
+		epath = "/bin";
+	}
+
+	p = epath;
+	while (*p) {
+		len=0;
+		memset(path, 0, 1024);
+		fp = path;
+		while (*p && *p != ':' && len < 1024) {
+			*fp++ = *p++;
+			len++;
+		}
+		if (*p == ':')
+			p++;
+		len = fp - path;
+		if (len < 1024) {
+			if (path[0]) {
+				fp--;
+				strcat(fp, "/");
+				len++;
+			}
+			if (len+strlen(file) < 1024) {
+				strcat(fp, file);
+				execv(path, argv);
+			} else {
+				fprintf(stderr, "rcexec: command name too long\n");
+				errno = E2BIG;
+				return -1;
+			}
+		}
+	}
+	return -1;
+}
+
 void
 spawn(const Arg *arg) {
 	if(fork() == 0) {
 		if(dpy)
 			close(ConnectionNumber(dpy));
 		setsid();
-		execvp(((char **)arg->v)[0], (char **)arg->v);
+		rcexec(((char **)arg->v)[0], (char **)arg->v);
 		fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
 		perror(" failed");
 		exit(0);

Reply via email to