dwm-6.0-spawn_cwd.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
dwm-6.0-spawn_cwd.diff (1836B)
---
1 https://github.com/sunaku/.dwm/compare/tip...spawn_cwd
2 ---
3 diff --git a/dwm.c b/dwm.c
4 index 1d78655..156ee60 100644
5 --- a/dwm.c
6 +++ b/dwm.c
7 @@ -20,6 +20,7 @@
8 *
9 * To understand everything else, start reading main().
10 */
11 +#include <assert.h>
12 #include <errno.h>
13 #include <locale.h>
14 #include <stdarg.h>
15 @@ -28,6 +29,8 @@
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 +#include <libgen.h>
20 +#include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <X11/cursorfont.h>
24 @@ -1661,11 +1664,45 @@ sigchld(int unused) {
25 while(0 < waitpid(-1, NULL, WNOHANG));
26 }
27
28 +#define SPAWN_CWD_DELIM " []{}()<>\"':"
29 +
30 void
31 spawn(const Arg *arg) {
32 if(fork() == 0) {
33 if(dpy)
34 close(ConnectionNumber(dpy));
35 + if(selmon->sel) {
36 + const char* const home = getenv("HOME");
37 + assert(home && strchr(home, '/'));
38 + const size_t homelen = strlen(home);
39 + char *cwd, *pathbuf = NULL;
40 + struct stat statbuf;
41 +
42 + cwd = strtok(selmon->sel->name, SPAWN_CWD_DELIM);
43 + /* NOTE: strtok() alters selmon->sel->name in-place,
44 + * but that does not matter because we are going to
45 + * exec() below anyway; nothing else will use it */
46 + while(cwd) {
47 + if(*cwd == '~') { /* replace ~ with $HOME */
48 + if(!(pathbuf = malloc(homelen + strlen(cwd)))) /* ~ counts for NULL term */
49 + die("fatal: could not malloc() %u bytes\n", homelen + strlen(cwd));
50 + strcpy(strcpy(pathbuf, home) + homelen, cwd + 1);
51 + cwd = pathbuf;
52 + }
53 +
54 + if(strchr(cwd, '/') && !stat(cwd, &statbuf)) {
55 + if(!S_ISDIR(statbuf.st_mode))
56 + cwd = dirname(cwd);
57 +
58 + if(!chdir(cwd))
59 + break;
60 + }
61 +
62 + cwd = strtok(NULL, SPAWN_CWD_DELIM);
63 + }
64 +
65 + free(pathbuf);
66 + }
67 setsid();
68 execvp(((char **)arg->v)[0], (char **)arg->v);
69 fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);