cwd spawn

This commit is contained in:
2020-08-22 15:45:36 +02:00
parent 9f5a62281b
commit 2baff56a03

36
dwm.c
View File

@ -20,6 +20,7 @@
*
* To understand everything else, start reading main().
*/
#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <signal.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>
@ -1711,6 +1714,7 @@ sigchld(int unused)
while (0 < waitpid(-1, NULL, WNOHANG));
}
#define SPAWN_CWD_DELIM " []{}()<>\"':"
void
spawn(const Arg *arg)
{
@ -1719,6 +1723,38 @@ 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]);