cwd spawn
This commit is contained in:
36
dwm.c
36
dwm.c
@ -20,6 +20,7 @@
|
|||||||
*
|
*
|
||||||
* To understand everything else, start reading main().
|
* To understand everything else, start reading main().
|
||||||
*/
|
*/
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -28,6 +29,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
@ -1711,6 +1714,7 @@ sigchld(int unused)
|
|||||||
while (0 < waitpid(-1, NULL, WNOHANG));
|
while (0 < waitpid(-1, NULL, WNOHANG));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SPAWN_CWD_DELIM " []{}()<>\"':"
|
||||||
void
|
void
|
||||||
spawn(const Arg *arg)
|
spawn(const Arg *arg)
|
||||||
{
|
{
|
||||||
@ -1719,6 +1723,38 @@ spawn(const Arg *arg)
|
|||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
if (dpy)
|
if (dpy)
|
||||||
close(ConnectionNumber(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();
|
setsid();
|
||||||
execvp(((char **)arg->v)[0], (char **)arg->v);
|
execvp(((char **)arg->v)[0], (char **)arg->v);
|
||||||
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
|
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]);
|
||||||
|
|||||||
Reference in New Issue
Block a user