commit - 13cc0916743705e32211da7fcf5499197e36e883
commit + e0041ee5139dcd4173fe8f47ff691c0d41951341
blob - ed7bd95c1204a39113a29c6b727504fe3c8a9cc5
blob + 32657d48a66e7b0a1bac2addbf2a5e8efdcbe614
--- parse.y
+++ parse.y
#define SPECIAL(X) ((struct action){.type = (ASPECIAL), .special = (X) })
#define FAKE_KEY(K) ((struct action){.type = (AFAKE), .send_key = (K) })
+#define EXEC(S) ((struct action){.type = (AEXEC), .str = (S) })
%}
%token TMATCH TCLASS
%token TON TDO
-%token TTOGGLE TACTIVATE TDEACTIVATE TIGNORE
+%token TTOGGLE TACTIVATE TDEACTIVATE TIGNORE TEXEC
%token TERR
%token <key> TKEY
| TACTIVATE { $$ = SPECIAL(AACTIVATE); }
| TDEACTIVATE { $$ = SPECIAL(ADEACTIVATE); }
| TIGNORE { $$ = SPECIAL(AIGNORE); }
+ | TEXEC TSTRING { $$ = EXEC($2); }
;
blob - 232d734c950fdfca53cb00a1cac2b6ed52927914
blob + ebe717c4d4a3395fcf52d2aba753bcf331bed9dd
--- star-platinum.c
+++ star-platinum.c
#include "star-platinum.h"
#include <err.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
struct rule *r;
XEvent e;
Window root;
+
+ signal(SIGCHLD, SIG_IGN); /* don't allow zombies */
fname = NULL;
while ((ch = getopt(argc, argv, "c:dn")) != -1) {
XSelectInput(d, root, KeyPressMask);
XFlush(d);
- pledge("stdio", "");
+ pledge("stdio proc exec", NULL);
while (1) {
XNextEvent(d, &e);
}
break;
+ case AEXEC: {
+ pid_t p;
+ const char *sh;
+
+ switch (p = fork()) {
+ case -1:
+ err(1, "fork");
+
+ case 0:
+ if ((sh = getenv("SHELL")) == NULL)
+ sh = "/bin/sh";
+ printf("before exec'ing %s -c '%s'\n", sh, a.str);
+ execlp(sh, sh, "-c", a.str, NULL);
+ err(1, "execlp");
+ }
+
+ break;
+ }
+
default:
/* unreachable */
abort();
}
}
+void
+free_action(struct action a)
+{
+ if (a.type == AEXEC)
+ free(a.str);
+}
+
/* match */
void
printaction(struct action a)
{
- if (a.type == ASPECIAL) {
+ switch (a.type) {
+ case ASPECIAL:
switch (a.special) {
case ATOGGLE: printf("toggle"); break;
case AACTIVATE: printf("activate"); break;
case ADEACTIVATE: printf("deactivate"); break;
case AIGNORE: printf("ignore"); break;
+ default: abort(); /* unreachable */
}
- } else {
+ break;
+
+ case AFAKE:
printf("send key ");
printkey(a.send_key);
+ break;
+
+ case AEXEC:
+ printf("exec %s", a.str);
+ break;
+
+ default:
+ /* unreachable */
+ abort();
}
}
}
printf("match ");
switch (m->prop) {
+ case MANY:
+ printf("all");
+ break;
case MCLASS:
- printf("class");
+ printf("class %s", m->str);
break;
default:
+ /* unreachable */
abort();
}
- printf(" %s", m->str);
if (m->next == NULL)
printf("\n");
blob - 88db9ef46ddebea1d3579a804908d39b992ff23c
blob + f6a752b1d4a5b367add9cb6b943f2d63a5a816d3
--- star-platinum.h
+++ star-platinum.h
struct action {
#define ASPECIAL 1
#define AFAKE 2
+#define AEXEC 3
int type;
union {
-#define ATOGGLE 3
-#define AACTIVATE 4
-#define ADEACTIVATE 5
-#define AIGNORE 6
+#define ATOGGLE 1
+#define AACTIVATE 2
+#define ADEACTIVATE 3
+#define AIGNORE 4
int special;
struct key send_key;
+ char *str;
};
};
void do_action(struct action, Window, int);
+void free_action(struct action);
struct match {
#define MANY 1