Update README and close file descriptors on exit
This commit is contained in:
parent
eaee001006
commit
5a3097a13d
|
@ -78,6 +78,7 @@ The syntax for defining a block is:
|
||||||
```c
|
```c
|
||||||
static Block blocks[] = {
|
static Block blocks[] = {
|
||||||
...
|
...
|
||||||
|
BLOCK("volume", 0, 5)
|
||||||
BLOCK("date", 1800, 1)
|
BLOCK("date", 1800, 1)
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
@ -99,7 +100,7 @@ Most statusbars constantly rerun every script every several seconds to update. T
|
||||||
|
|
||||||
For example, the volume module has the update signal 5 by default. Thus, running `pkill -RTMIN+5 dwmblocks` will update it.
|
For example, the volume module has the update signal 5 by default. Thus, running `pkill -RTMIN+5 dwmblocks` will update it.
|
||||||
|
|
||||||
You can also run `kill -44 $(pidof dwmblocks)` which will have the same effect, but is faster. Just add 34 to your typical signal number.
|
You can also run `kill -39 $(pidof dwmblocks)` which will have the same effect, but is faster. Just add 34 to your typical signal number.
|
||||||
|
|
||||||
My volume module *never* updates on its own, instead I have this command run along side my volume shortcuts in `dwm` to only update it when relevant.
|
My volume module *never* updates on its own, instead I have this command run along side my volume shortcuts in `dwm` to only update it when relevant.
|
||||||
|
|
||||||
|
|
62
main.c
62
main.c
|
@ -2,7 +2,6 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -29,7 +28,7 @@ static char outputs[LEN(blocks)][CMDLENGTH + 2];
|
||||||
static char statusBar[2][LEN(blocks) * ((LEN(outputs[0]) - 1) + (LEN(DELIMITER) - 1)) + 1];
|
static char statusBar[2][LEN(blocks) * ((LEN(outputs[0]) - 1) + (LEN(DELIMITER) - 1)) + 1];
|
||||||
static struct epoll_event event, events[LEN(blocks) + 2];
|
static struct epoll_event event, events[LEN(blocks) + 2];
|
||||||
static int pipes[LEN(blocks)][2];
|
static int pipes[LEN(blocks)][2];
|
||||||
static int timerFD[2];
|
static int timerPipe[2];
|
||||||
static int signalFD;
|
static int signalFD;
|
||||||
static int epollFD;
|
static int epollFD;
|
||||||
void (*writeStatus)();
|
void (*writeStatus)();
|
||||||
|
@ -44,14 +43,20 @@ int gcd(int a, int b) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closePipe(int* pipe) {
|
||||||
|
close(pipe[0]);
|
||||||
|
close(pipe[1]);
|
||||||
|
}
|
||||||
|
|
||||||
void execBlock(int i, const char* button) {
|
void execBlock(int i, const char* button) {
|
||||||
if (fork() == 0) {
|
if (fork() == 0) {
|
||||||
dup2(pipes[i][1], STDOUT_FILENO);
|
|
||||||
close(pipes[i][0]);
|
close(pipes[i][0]);
|
||||||
|
dup2(pipes[i][1], STDOUT_FILENO);
|
||||||
|
|
||||||
if (button)
|
if (button)
|
||||||
setenv("BLOCK_BUTTON", button, 1);
|
setenv("BLOCK_BUTTON", button, 1);
|
||||||
execl("/bin/sh", "sh", "-c", blocks[i].command);
|
execl("/bin/sh", "sh", "-c", blocks[i].command);
|
||||||
|
close(pipes[i][1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +142,8 @@ void signalHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the pipe after each poll to limit number of signals handled
|
// Clear the pipe after each poll to limit number of signals handled
|
||||||
while (read(signalFD, &info, sizeof(info)) != -1);
|
while (read(signalFD, &info, sizeof(info)) != -1)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void termHandler() {
|
void termHandler() {
|
||||||
|
@ -169,35 +175,18 @@ void setupSignals() {
|
||||||
epoll_ctl(epollFD, EPOLL_CTL_ADD, signalFD, &event);
|
epoll_ctl(epollFD, EPOLL_CTL_ADD, signalFD, &event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
|
||||||
epollFD = epoll_create(LEN(blocks) + 1);
|
|
||||||
event.events = EPOLLIN;
|
|
||||||
|
|
||||||
for (int i = 0; i < LEN(blocks); i++) {
|
|
||||||
pipe(pipes[i]);
|
|
||||||
event.data.u32 = i;
|
|
||||||
epoll_ctl(epollFD, EPOLL_CTL_ADD, pipes[i][0], &event);
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe(timerFD);
|
|
||||||
event.data.u32 = LEN(blocks);
|
|
||||||
epoll_ctl(epollFD, EPOLL_CTL_ADD, timerFD[0], &event);
|
|
||||||
|
|
||||||
setupSignals();
|
|
||||||
}
|
|
||||||
|
|
||||||
void statusLoop() {
|
void statusLoop() {
|
||||||
execBlocks(0);
|
execBlocks(0);
|
||||||
|
|
||||||
while (statusContinue) {
|
while (statusContinue) {
|
||||||
int eventCount = epoll_wait(epollFD, events, LEN(events), 10);
|
int eventCount = epoll_wait(epollFD, events, LEN(events), POLL_INTERVAL / 10);
|
||||||
|
|
||||||
for (int i = 0; i < eventCount; i++) {
|
for (int i = 0; i < eventCount; i++) {
|
||||||
unsigned int id = events[i].data.u32;
|
unsigned int id = events[i].data.u32;
|
||||||
|
|
||||||
if (id == LEN(blocks)) {
|
if (id == LEN(blocks)) {
|
||||||
unsigned long long int j = 0;
|
unsigned long long int j = 0;
|
||||||
read(timerFD[0], &j, sizeof(j));
|
read(timerPipe[0], &j, sizeof(j));
|
||||||
execBlocks(j);
|
execBlocks(j);
|
||||||
} else if (id < LEN(blocks)) {
|
} else if (id < LEN(blocks)) {
|
||||||
updateBlock(events[i].data.u32);
|
updateBlock(events[i].data.u32);
|
||||||
|
@ -215,7 +204,7 @@ void statusLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerLoop() {
|
void timerLoop() {
|
||||||
close(timerFD[0]);
|
close(timerPipe[0]);
|
||||||
|
|
||||||
unsigned int sleepInterval = -1;
|
unsigned int sleepInterval = -1;
|
||||||
for (int i = 0; i < LEN(blocks); i++)
|
for (int i = 0; i < LEN(blocks); i++)
|
||||||
|
@ -232,12 +221,31 @@ void timerLoop() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Notify parent to update blocks
|
// Notify parent to update blocks
|
||||||
write(timerFD[1], &i, sizeof(i));
|
write(timerPipe[1], &i, sizeof(i));
|
||||||
|
|
||||||
// After sleep, reset timer and update counter
|
// After sleep, reset timer and update counter
|
||||||
toSleep = sleepTime;
|
toSleep = sleepTime;
|
||||||
i += sleepInterval;
|
i += sleepInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
close(timerPipe[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
epollFD = epoll_create(LEN(blocks) + 1);
|
||||||
|
event.events = EPOLLIN;
|
||||||
|
|
||||||
|
for (int i = 0; i < LEN(blocks); i++) {
|
||||||
|
pipe(pipes[i]);
|
||||||
|
event.data.u32 = i;
|
||||||
|
epoll_ctl(epollFD, EPOLL_CTL_ADD, pipes[i][0], &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe(timerPipe);
|
||||||
|
event.data.u32 = LEN(blocks);
|
||||||
|
epoll_ctl(epollFD, EPOLL_CTL_ADD, timerPipe[0], &event);
|
||||||
|
|
||||||
|
setupSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(const int argc, const char* argv[]) {
|
int main(const int argc, const char* argv[]) {
|
||||||
|
@ -254,5 +262,9 @@ int main(const int argc, const char* argv[]) {
|
||||||
statusLoop();
|
statusLoop();
|
||||||
|
|
||||||
close(epollFD);
|
close(epollFD);
|
||||||
|
close(signalFD);
|
||||||
|
closePipe(timerPipe);
|
||||||
|
for (int i = 0; i < LEN(pipes); i++)
|
||||||
|
closePipe(pipes[i]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue