@@ 4,6 4,7 @@
#include <sys/signalfd.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <inttypes.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
@@ 33,6 34,7 @@ struct options {
char sep;
size_t initial_buffer_size;
int hang;
+ const char* pid_file;
};
static int handle_x11_error(Display* d, XErrorEvent* e)
@@ 474,6 476,7 @@ static int signalfd_init(void)
sigset_t m;
sigemptyset(&m);
sigaddset(&m, SIGINT);
+ sigaddset(&m, SIGTERM);
int fd = signalfd(-1, &m, 0);
CHECK(fd, "signalfd");
@@ 509,12 512,42 @@ static void signalfd_handle_event(int fd, struct state* st)
if(si.ssi_signo == SIGINT) {
debug("SIGINT");
st->running = 0;
+ } else if(si.ssi_signo == SIGTERM) {
+ debug("SIGTERM");
+ st->running = 0;
} else {
warning("unhandled signal: %u", si.ssi_signo);
}
}
}
+static void pid_file_init(const char* fn)
+{
+ if(!fn) return;
+
+ int fd = creat(fn, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ CHECK(fd, "creat(%s)", fn);
+
+ char buf[64];
+ int r = snprintf(LIT(buf), "%"PRIdMAX"\n", (intmax_t)getpid());
+ CHECK(r, "snprintf");
+ CHECK_IF(r >= LENGTH(buf), "truncated");
+
+ ssize_t s = write(fd, buf, r);
+ CHECK(s, "write(%s)", fn);
+ CHECK_IF(s != r, "partial write");
+
+ r = close(fd);
+ CHECK(r, "close");
+}
+
+static void pid_file_deinit(const char* fn)
+{
+ if(!fn) return;
+
+ int r = unlink(fn); CHECK(r, "unlink(%s)", fn);
+}
+
static void extend_buf(struct state* st)
{
size_t m = st->buf_n * 2;
@@ 583,6 616,7 @@ static void print_usage(int fd, const char* prog)
dprintf(fd, " -f FONT use FONT\n");
dprintf(fd, " -H don't close the window when stdin closes\n");
dprintf(fd, " -A ACTION run ACTION (like system(3) does) when enter, space or mouse buttons are pressed ($0 is bound to the relevant button)\n");
+ dprintf(fd, " -p FILE write pid to FILE\n");
dprintf(fd, " -h print this message\n");
}
@@ 595,9 629,10 @@ static void parse_options(struct options* o, int argc, char* argv[])
o->font = "sans:pixelsize=34";
o->hang = 0;
o->action = NULL;
+ o->pid_file = NULL;
int res;
- while((res = getopt(argc, argv, "a:0t:f:HA:h")) != -1) {
+ while((res = getopt(argc, argv, "a:0t:f:HA:p:h")) != -1) {
switch(res) {
case 'a':
if(strcmp(optarg, "N") == 0) {
@@ 638,6 673,11 @@ static void parse_options(struct options* o, int argc, char* argv[])
case 'A':
o->action = strdup(optarg);
CHECK_MALLOC(o->action);
+ debug("action: %s", o->action);
+ break;
+ case 'p':
+ o->pid_file = strdup(optarg);
+ CHECK_MALLOC(o->pid_file);
break;
case 'h':
default:
@@ 652,6 692,8 @@ int main(int argc, char* argv[])
struct options opts;
parse_options(&opts, argc, argv);
+ pid_file_init(opts.pid_file);
+
int sfd = signalfd_init();
struct x11_state x11;
@@ 722,6 764,7 @@ int main(int argc, char* argv[])
xft_deinit(&xft);
x11_deinit(&x11);
signalfd_deinit(sfd);
+ pid_file_deinit(opts.pid_file);
return 0;
}