123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #include <err.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdint.h>
- #include <stdarg.h>
- #include <string.h>
- #include <unistd.h>
- #include "util.h"
- #include "numfmt.h"
- #include "../components_config.h"
- #ifndef FMT_HUMAN_NUMFMT
- # define FMT_HUMAN_NUMFMT NUMFMT_IEC
- #endif
- static inline int
- evsnprintf(char *str, size_t size, const char *fmt, va_list ap)
- {
- int ret;
- ret = vsnprintf(str, size, fmt, ap);
- if (ret < 0) {
- warn("vsnprintf");
- return -1;
- } else if ((size_t)ret >= size) {
- warnx("vsnprintf: Output truncated");
- return -1;
- }
- return ret;
- }
- void
- bprintf(char *buf, const char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- if (evsnprintf(buf, BUFF_SZ, fmt, ap) < 0) *buf = '\0';
- va_end(ap);
- }
- void
- fmt_human(char *out, uintmax_t num)
- {
- uint8_t i;
- double scaled;
- const char *prefix[] =
- #if FMT_HUMAN_NUMFMT == NUMFMT_IEC
- { "",
- "Ki",
- "Mi",
- "Gi",
- "Ti",
- "Pi",
- "Ei",
- "Zi",
- "Yi" }
- #elif FMT_HUMAN_NUMFMT == NUMFMT_SI
- { "",
- "k",
- "M",
- "G",
- "T",
- "P",
- "E",
- "Z",
- "Y" }
- #else
- # error invalid FMT_HUMAN_NUMFMT
- #endif
- ;
- SAFE_ASSIGN(scaled, num);
- for (i = 0; i < LEN(prefix) && scaled >= FMT_HUMAN_NUMFMT; i++)
- scaled /= FMT_HUMAN_NUMFMT;
- bprintf(out, "%.1f %s", scaled, prefix[i]);
- }
- int
- _sysfs_fd(const char *func,
- const char *path,
- const char *device,
- const char *property)
- {
- uint8_t i;
- int fds[3] = { -1, -1, -1 };
- int *path_fd = &fds[0], *device_fd = &fds[1], *property_fd = &fds[2];
- if ((*path_fd = _eopen(func,
- path,
- WITH_STR(O_RDONLY | O_CLOEXEC | O_DIRECTORY)))
- == -1)
- goto end;
- if ((*device_fd =
- _eopenat(func,
- *path_fd,
- device,
- WITH_STR(O_RDONLY | O_CLOEXEC | O_DIRECTORY)))
- == -1)
- goto end;
- if (!!property) {
- if ((*property_fd = _eopenat(func,
- *device_fd,
- property,
- WITH_STR(O_RDONLY | O_CLOEXEC)))
- == -1)
- goto end;
- } else {
- *property_fd = *device_fd;
- *device_fd = -1;
- }
- end:
- for (i = 0; i < (LEN(fds) - 1 /* except last */); i++)
- if (fds[i] >= 0) _eclose(func, fds[i]);
- return *property_fd;
- }
- uint8_t
- _sysfs_fd_or_rewind(const char *func,
- int * fd,
- const char *path,
- const char *device,
- const char *property)
- {
- if (*fd > 0) return _fd_rewind(func, *fd);
- if ((*fd = _sysfs_fd(func, path, device, property)) != -1) return !0;
- return 0;
- }
- int
- _eopen(const char *func, const char *path, int flags, const char *sflags)
- {
- int fd;
- if ((fd = open(path, flags)) == -1)
- warn("%s: open(" QUOTED("%s") ", %s)", func, path, sflags);
- return fd;
- }
- int
- _eopenat(
- const char *func, int fd, const char *path, int flags, const char *sflags)
- {
- int new_fd;
- if ((new_fd = openat(fd, path, flags)) == -1)
- warn("%s: openat(%d, " QUOTED("%s") ", %s)",
- func,
- fd,
- path,
- sflags);
- return new_fd;
- }
- off_t
- _elseek(const char *func, int fd, off_t offset, int whence)
- {
- off_t ret;
- if ((ret = lseek(fd, offset, whence)) == (off_t)-1)
- warn("%s: lseek(%d, %ld, %d)", func, fd, offset, whence);
- return ret;
- }
- uint8_t
- _fd_rewind(const char *func, int fd)
- {
- return _elseek(func, fd, 0, SEEK_SET) != (off_t)-1;
- }
- ssize_t
- _eread(const char *func, int fd, void *buf, size_t size)
- {
- ssize_t ret;
- if ((ret = read(fd, buf, size)) == -1)
- warn("%s: read(%d, %p, %lu)", func, fd, buf, size);
- return ret;
- }
- uint8_t
- _eclose(const char *func, int fd)
- {
- uint8_t ret;
- if (!(ret = (close(fd) != -1))) warn("%s: close(%d)", func, fd);
- return ret;
- }
- uint8_t
- _esscanf(const char *func,
- int count,
- const char *restrict str,
- const char *restrict fmt,
- ...)
- {
- va_list ap;
- int err;
- __typeof__(count) match = 0;
- va_start(ap, fmt);
- errno = 0;
- match = vsscanf(str, fmt, ap);
- err = errno;
- va_end(ap);
- if (match == count)
- return !0;
- else if (err != 0)
- warn("%s: sscanf(%p, " QUOTED("%s") ", ...)", func, str, fmt);
- else
- warnx("%s: sscnaf(fmt: " QUOTED("%s") "): matched %d of %d",
- func,
- fmt,
- match,
- count);
- return 0;
- }
- void
- fd_cleanup(void *ptr)
- {
- int fd = *((int *)ptr);
- if (fd > 0) eclose(fd);
- }
|