diff options
author | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:00 -0500 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-03-07 17:28:32 -0500 |
commit | bd5969fc876a10b18613302db7087ef3c40f18e1 (patch) | |
tree | 7c2b8619afe902abf99570df2873fbdf40a4d1a1 /lib/mlibc/options/linux/generic/utmp-stubs.cpp | |
parent | a95b38b1b92b172e6cc4e8e56a88a30cc65907b0 (diff) |
lib: Add mlibc
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'lib/mlibc/options/linux/generic/utmp-stubs.cpp')
-rw-r--r-- | lib/mlibc/options/linux/generic/utmp-stubs.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/mlibc/options/linux/generic/utmp-stubs.cpp b/lib/mlibc/options/linux/generic/utmp-stubs.cpp new file mode 100644 index 0000000..658dfd3 --- /dev/null +++ b/lib/mlibc/options/linux/generic/utmp-stubs.cpp @@ -0,0 +1,116 @@ +#include <utmp.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +#include <bits/ensure.h> +#include <mlibc/debug.hpp> + +/* + * The code in this file is largely based on glibc. + * This includes: + * - setutent + * - read_last_entry + * - getutent + * - getutent_r + * - endutent + */ +static int fd = -1; +static off_t offset; + +static struct utmp last_entry; + +void setutent(void) { + if(fd < 0) { + fd = open("/run/utmp", O_RDONLY | O_LARGEFILE | O_CLOEXEC); + if(fd == -1) { + return; + } + } + + lseek(fd, 0, SEEK_SET); + offset = 0; +} + +static ssize_t read_last_entry(void) { + struct utmp buf; + ssize_t bytes_read = pread(fd, &buf, sizeof(buf), offset); + + if(bytes_read < 0) { + return -1; + } else if(bytes_read != sizeof(buf)) { + // EOF + return 0; + } else { + last_entry = buf; + offset += sizeof(buf); + return 1; + } +} + +struct utmp *getutent(void) { + struct utmp *result; + static struct utmp *buf; + if(buf == NULL) { + buf = (struct utmp *)malloc(sizeof(struct utmp)); + if(buf == NULL) { + return NULL; + } + } + + if(getutent_r(buf, &result) < 0) { + return NULL; + } + return result; +} + +int getutent_r(struct utmp *buf, struct utmp **res) { + int saved_errno = errno; + + if(fd < 0) { + setutent(); + } + + ssize_t bytes_read = read_last_entry(); + + if(bytes_read <= 0) { + if(bytes_read == 0) { + errno = saved_errno; + *res = NULL; + return -1; + } + } + + memcpy(buf, &last_entry, sizeof(struct utmp)); + *res = buf; + + return 0; +} + +void endutent(void) { + if(fd >= 0) { + close(fd); + fd = -1; + } +} + +struct utmp *pututline(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: pututline() is a stub!\e[39m" << frg::endlog; + return NULL; +} + +struct utmp *getutline(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: getutline() is a stub!\e[39m" << frg::endlog; + return NULL; +} + +int utmpname(const char *) { + mlibc::infoLogger() << "\e[31mmlibc: utmpname() is a stub!\e[39m" << frg::endlog; + return -1; +} + +struct utmp *getutid(const struct utmp *) { + mlibc::infoLogger() << "\e[31mmlibc: getutid() is a stub!\e[39m" << frg::endlog; + return NULL; +} |