Files
dwm/patches/dwm-6.0-spawn_cwd.diff
2020-09-14 15:52:07 +02:00

70 lines
1.8 KiB
Diff

https://github.com/sunaku/.dwm/compare/tip...spawn_cwd
---
diff --git a/dwm.c b/dwm.c
index 1d78655..156ee60 100644
--- a/dwm.c
+++ b/dwm.c
@@ -20,6 +20,7 @@
*
* To understand everything else, start reading main().
*/
+#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
@@ -28,6 +29,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <libgen.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
@@ -1661,11 +1664,45 @@ sigchld(int unused) {
while(0 < waitpid(-1, NULL, WNOHANG));
}
+#define SPAWN_CWD_DELIM " []{}()<>\"':"
+
void
spawn(const Arg *arg) {
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
+ if(selmon->sel) {
+ const char* const home = getenv("HOME");
+ assert(home && strchr(home, '/'));
+ const size_t homelen = strlen(home);
+ char *cwd, *pathbuf = NULL;
+ struct stat statbuf;
+
+ cwd = strtok(selmon->sel->name, SPAWN_CWD_DELIM);
+ /* NOTE: strtok() alters selmon->sel->name in-place,
+ * but that does not matter because we are going to
+ * exec() below anyway; nothing else will use it */
+ while(cwd) {
+ if(*cwd == '~') { /* replace ~ with $HOME */
+ if(!(pathbuf = malloc(homelen + strlen(cwd)))) /* ~ counts for NULL term */
+ die("fatal: could not malloc() %u bytes\n", homelen + strlen(cwd));
+ strcpy(strcpy(pathbuf, home) + homelen, cwd + 1);
+ cwd = pathbuf;
+ }
+
+ if(strchr(cwd, '/') && !stat(cwd, &statbuf)) {
+ if(!S_ISDIR(statbuf.st_mode))
+ cwd = dirname(cwd);
+
+ if(!chdir(cwd))
+ break;
+ }
+
+ cwd = strtok(NULL, SPAWN_CWD_DELIM);
+ }
+
+ free(pathbuf);
+ }
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);