summaryrefslogtreecommitdiff
path: root/dwm-6.2/dwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'dwm-6.2/dwm.c')
-rw-r--r--dwm-6.2/dwm.c142
1 files changed, 57 insertions, 85 deletions
diff --git a/dwm-6.2/dwm.c b/dwm-6.2/dwm.c
index f788759..af6b7f8 100644
--- a/dwm-6.2/dwm.c
+++ b/dwm-6.2/dwm.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
@@ -199,7 +198,6 @@ static void resizeclient(Client *c, int x, int y, int w, int h);
static void resizemouse(const Arg *arg);
static void restack(Monitor *m);
static void run(void);
-static void runautostart(void);
static void scan(void);
static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
@@ -250,13 +248,10 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy(Display *dpy, XErrorEvent *ee);
static int xerrorstart(Display *dpy, XErrorEvent *ee);
static void zoom(const Arg *arg);
+static void autostart_exec(void);
/* variables */
-static const char autostartblocksh[] = "autostart_blocking.sh";
-static const char autostartsh[] = "autostart.sh";
static const char broken[] = "broken";
-static const char dwmdir[] = "dwm";
-static const char localshare[] = ".local/share";
static char stext[256];
static int screen;
static int sw, sh; /* X display screen geometry width, height */
@@ -296,6 +291,34 @@ static Window root, wmcheckwin;
/* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
+/* dwm will keep pid's of processes from autostart array and kill them at quit */
+static pid_t *autostart_pids;
+static size_t autostart_len;
+
+/* execute command from autostart array */
+static void
+autostart_exec() {
+ const char *const *p;
+ size_t i = 0;
+
+ /* count entries */
+ for (p = autostart; *p; autostart_len++, p++)
+ while (*++p);
+
+ autostart_pids = malloc(autostart_len * sizeof(pid_t));
+ for (p = autostart; *p; i++, p++) {
+ if ((autostart_pids[i] = fork()) == 0) {
+ setsid();
+ execvp(*p, (char *const *)p);
+ fprintf(stderr, "dwm: execvp %s\n", *p);
+ perror(" failed");
+ _exit(EXIT_FAILURE);
+ }
+ /* skip arguments */
+ while (*++p);
+ }
+}
+
/* function implementations */
void
applyrules(Client *c)
@@ -1288,6 +1311,16 @@ propertynotify(XEvent *e)
void
quit(const Arg *arg)
{
+ size_t i;
+
+ /* kill child processes */
+ for (i = 0; i < autostart_len; i++) {
+ if (0 < autostart_pids[i]) {
+ kill(autostart_pids[i], SIGTERM);
+ waitpid(autostart_pids[i], NULL, 0);
+ }
+ }
+
running = 0;
}
@@ -1421,83 +1454,6 @@ run(void)
}
void
-runautostart(void)
-{
- char *pathpfx;
- char *path;
- char *xdgdatahome;
- char *home;
- struct stat sb;
-
- if ((home = getenv("HOME")) == NULL)
- /* this is almost impossible */
- return;
-
- /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
- * otherwise use ~/.local/share/dwm as autostart script directory
- */
- xdgdatahome = getenv("XDG_DATA_HOME");
- if (xdgdatahome != NULL && *xdgdatahome != '\0') {
- /* space for path segments, separators and nul */
- pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
-
- if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
- free(pathpfx);
- return;
- }
- } else {
- /* space for path segments, separators and nul */
- pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
- + strlen(dwmdir) + 3);
-
- if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
- free(pathpfx);
- return;
- }
- }
-
- /* check if the autostart script directory exists */
- if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
- /* the XDG conformant path does not exist or is no directory
- * so we try ~/.dwm instead
- */
- char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
- if(pathpfx_new == NULL) {
- free(pathpfx);
- return;
- }
- pathpfx = pathpfx_new;
-
- if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
- free(pathpfx);
- return;
- }
- }
-
- /* try the blocking script first */
- path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
- if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
- free(path);
- free(pathpfx);
- }
-
- if (access(path, X_OK) == 0)
- system(path);
-
- /* now the non-blocking script */
- if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
- free(path);
- free(pathpfx);
- }
-
- if (access(path, X_OK) == 0)
- system(strcat(path, " &"));
-
- free(pathpfx);
- free(path);
-}
-
-void
scan(void)
{
unsigned int i, num;
@@ -1853,9 +1809,25 @@ showhide(Client *c)
void
sigchld(int unused)
{
+ pid_t pid;
+
if (signal(SIGCHLD, sigchld) == SIG_ERR)
die("can't install SIGCHLD handler:");
- while (0 < waitpid(-1, NULL, WNOHANG));
+ while (0 < (pid = waitpid(-1, NULL, WNOHANG))) {
+ pid_t *p, *lim;
+
+ if (!(p = autostart_pids))
+ continue;
+ lim = &p[autostart_len];
+
+ for (; p < lim; p++) {
+ if (*p == pid) {
+ *p = -1;
+ break;
+ }
+ }
+
+ }
}
void
@@ -2364,13 +2336,13 @@ main(int argc, char *argv[])
if (!(dpy = XOpenDisplay(NULL)))
die("dwm: cannot open display");
checkotherwm();
+ autostart_exec();
setup();
#ifdef __OpenBSD__
if (pledge("stdio rpath proc exec", NULL) == -1)
die("pledge");
#endif /* __OpenBSD__ */
scan();
- runautostart();
run();
cleanup();
XCloseDisplay(dpy);