module/battery: using a static buffer in readline_from_fd() isn’t thread safe

This commit is contained in:
Daniel Eklöf 2022-12-26 19:54:32 +01:00
parent 2283647fc7
commit 310c07b03d
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 14 additions and 11 deletions

View file

@ -30,6 +30,7 @@
plugins ([#239][239]). plugins ([#239][239]).
* Documentation for the `cpu` module; `interval` has been renamed to * Documentation for the `cpu` module; `interval` has been renamed to
`poll-interval` ([#241][241]). `poll-interval` ([#241][241]).
* battery: module was not thread safe.
[239]: https://codeberg.org/dnkl/yambar/issues/239 [239]: https://codeberg.org/dnkl/yambar/issues/239
[241]: https://codeberg.org/dnkl/yambar/issues/241 [241]: https://codeberg.org/dnkl/yambar/issues/241

View file

@ -150,20 +150,18 @@ content(struct module *mod)
} }
static const char * static const char *
readline_from_fd(int fd) readline_from_fd(int fd, size_t sz, char buf[static sz])
{ {
static char buf[4096]; ssize_t bytes = read(fd, buf, sz - 1);
ssize_t sz = read(fd, buf, sizeof(buf) - 1);
lseek(fd, 0, SEEK_SET); lseek(fd, 0, SEEK_SET);
if (sz < 0) { if (bytes < 0) {
LOG_WARN("failed to read from FD=%d", fd); LOG_WARN("failed to read from FD=%d", fd);
return NULL; return NULL;
} }
buf[sz] = '\0'; buf[bytes] = '\0';
for (ssize_t i = sz - 1; i >= 0 && buf[i] == '\n'; sz--) for (ssize_t i = bytes - 1; i >= 0 && buf[i] == '\n'; bytes--)
buf[i] = '\0'; buf[i] = '\0';
return buf; return buf;
@ -172,7 +170,8 @@ readline_from_fd(int fd)
static long static long
readint_from_fd(int fd) readint_from_fd(int fd)
{ {
const char *s = readline_from_fd(fd); char buf[512];
const char *s = readline_from_fd(fd, sizeof(buf), buf);
if (s == NULL) if (s == NULL)
return 0; return 0;
@ -189,6 +188,8 @@ readint_from_fd(int fd)
static bool static bool
initialize(struct private *m) initialize(struct private *m)
{ {
char line_buf[512];
int pw_fd = open("/sys/class/power_supply", O_RDONLY); int pw_fd = open("/sys/class/power_supply", O_RDONLY);
if (pw_fd < 0) { if (pw_fd < 0) {
LOG_ERRNO("/sys/class/power_supply"); LOG_ERRNO("/sys/class/power_supply");
@ -210,7 +211,7 @@ initialize(struct private *m)
m->battery, strerror(errno)); m->battery, strerror(errno));
m->manufacturer = NULL; m->manufacturer = NULL;
} else { } else {
m->manufacturer = strdup(readline_from_fd(fd)); m->manufacturer = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf));
close(fd); close(fd);
} }
} }
@ -222,7 +223,7 @@ initialize(struct private *m)
m->battery, strerror(errno)); m->battery, strerror(errno));
m->model = NULL; m->model = NULL;
} else { } else {
m->model = strdup(readline_from_fd(fd)); m->model = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf));
close(fd); close(fd);
} }
} }
@ -338,7 +339,8 @@ update_status(struct module *mod)
long current = current_fd >= 0 ? readint_from_fd(current_fd) : -1; long current = current_fd >= 0 ? readint_from_fd(current_fd) : -1;
long time_to_empty = time_to_empty_fd >= 0 ? readint_from_fd(time_to_empty_fd) : -1; long time_to_empty = time_to_empty_fd >= 0 ? readint_from_fd(time_to_empty_fd) : -1;
const char *status = readline_from_fd(status_fd); char buf[512];
const char *status = readline_from_fd(status_fd, sizeof(buf), buf);
if (status_fd >= 0) if (status_fd >= 0)
close(status_fd); close(status_fd);