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]);