Skip to content

Commit 6e8a857

Browse files
committed
applied dynamic notification updating patch
dudik/herbe#25
1 parent 876c9cb commit 6e8a857

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
CFLAGS = -Wall -Wextra -pedantic -lX11 -lXft -I/usr/include/freetype2 -pthread
2+
CFLAGS += -lrt
23

34
PREFIX ?= /usr/local
45
CC ?= cc

herbe.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
#include <fcntl.h>
1010
#include <semaphore.h>
1111
#include <poll.h>
12+
#include <sys/file.h>
13+
#include <sys/ipc.h>
14+
#include <sys/shm.h>
15+
#include <unistd.h>
16+
#include <errno.h>
17+
#include <mqueue.h>
1218

1319
#include "config.h"
1420

@@ -24,6 +30,14 @@ char **lines;
2430
static int exit_code = EXIT_DISMISS;
2531
static volatile sig_atomic_t sig_recieved;
2632

33+
struct mq_object {
34+
pid_t pid;
35+
long timestamp;
36+
char buffer[1024];
37+
};
38+
long lastTimestamp;
39+
40+
2741
static void die(const char *format, ...)
2842
{
2943
va_list ap;
@@ -115,11 +129,57 @@ void constructLines(char* strList[], int numberOfStrings) {
115129
}
116130
}
117131

132+
void reload(union sigval sv);
133+
void readAllEvents(mqd_t mqd) {
134+
struct sigevent event = {.sigev_notify=SIGEV_THREAD, .sigev_signo=SIGHUP, .sigev_value.sival_int=mqd, .sigev_notify_function=reload};
135+
136+
if(mq_notify(mqd, &event) == -1) {
137+
perror("mq_notify failed");
138+
exit(1);
139+
}
140+
141+
struct mq_object object;
142+
143+
while(1) {
144+
int ret = mq_receive(mqd, (char*)&object, sizeof(object), NULL);
145+
if(ret==-1) {
146+
if(errno == EAGAIN)
147+
return;
148+
perror("mq_receive");
149+
exit(1);
150+
}
151+
if(object.timestamp && lastTimestamp > object.timestamp)
152+
return;
153+
if(object.timestamp)
154+
lastTimestamp = object.timestamp;
155+
char *buffer = object.buffer;
156+
157+
constructLines(&buffer, 1);
158+
kill(object.pid, SIGTERM);
159+
}
160+
}
161+
void reload(union sigval sv) {
162+
// we've already timed out
163+
if(alarm(duration) == 0)
164+
return;
165+
readAllEvents(sv.sival_int);
166+
XEvent event;
167+
event.type = Expose;
168+
XSendEvent(display, window, 0, 0, &event);
169+
XFlush(display);
170+
}
171+
172+
118173
static void expire(int sig)
119174
{
120175
sig_recieved = sig_recieved ? sig_recieved : sig;
121176
}
122177

178+
179+
void exitSuccess() {
180+
exit(0);
181+
}
182+
123183
int main(int argc, char *argv[])
124184
{
125185
if (argc == 1)
@@ -128,6 +188,44 @@ int main(int argc, char *argv[])
128188
die("Usage: %s body", argv[0]);
129189
}
130190

191+
const char* id =getenv("HERBE_ID");
192+
mqd_t mqd=-1;
193+
if(id) {
194+
struct mq_attr attr = { .mq_maxmsg = 10, .mq_msgsize = sizeof(struct mq_object) };
195+
mqd = mq_open(id, O_RDWR|O_CREAT|O_NONBLOCK, 0722, &attr);
196+
if(mqd==-1){
197+
perror("mq_open");
198+
die("mq_open");
199+
}
200+
while (1) {
201+
if(flock(mqd, LOCK_EX|LOCK_NB) == 0) {
202+
// if we get the lock, register for events
203+
break;
204+
}
205+
if(errno != EWOULDBLOCK) {
206+
perror("flock");
207+
exit(1);
208+
}
209+
// someone else is listening for events
210+
char* ts_str = getenv("NOTIFICATION_ID");
211+
lastTimestamp = ts_str?atol(ts_str):0;
212+
struct mq_object object = {getpid(), lastTimestamp, {0}};
213+
char *buffer=object.buffer;
214+
for(int i=1;i<argc;i++) {
215+
strcat(buffer, argv[i]);
216+
strcat(buffer, "\n");
217+
}
218+
signal(SIGTERM, exitSuccess);
219+
if(mq_send(mqd, (char*)&object, sizeof(object), 1)==-1) {
220+
perror("mq_send");
221+
exit(1);
222+
}
223+
signal(SIGALRM, SIG_IGN);
224+
alarm(1);
225+
pause();
226+
}
227+
}
228+
131229
struct sigaction act_expire, act_ignore;
132230

133231
act_expire.sa_handler = expire;
@@ -202,6 +300,10 @@ int main(int argc, char *argv[])
202300
if (duration != 0)
203301
alarm(duration);
204302

303+
if(id) {
304+
readAllEvents(mqd);
305+
}
306+
205307
for (;;)
206308
{
207309
XEvent event;
@@ -250,5 +352,9 @@ int main(int argc, char *argv[])
250352
XftFontClose(display, font);
251353
XCloseDisplay(display);
252354

355+
if(id) {
356+
mq_close(mqd);
357+
}
358+
253359
return exit_code;
254360
}

0 commit comments

Comments
 (0)