Update README and close file descriptors on exit

This commit is contained in:
Utkarsh Verma 2021-10-16 09:32:18 +05:30
parent eaee001006
commit 5a3097a13d
No known key found for this signature in database
GPG Key ID: 817656CF818EFCCC
2 changed files with 40 additions and 27 deletions

View File

@ -78,7 +78,8 @@ The syntax for defining a block is:
```c ```c
static Block blocks[] = { static Block blocks[] = {
... ...
BLOCK("date", 1800, 1) BLOCK("volume", 0, 5)
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
View File

@ -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;
} }