From bd5969fc876a10b18613302db7087ef3c40f18e1 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 7 Mar 2024 17:28:00 -0500 Subject: lib: Add mlibc Signed-off-by: Ian Moffett --- lib/mlibc/options/linux/generic/utmp-stubs.cpp | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 lib/mlibc/options/linux/generic/utmp-stubs.cpp (limited to 'lib/mlibc/options/linux/generic/utmp-stubs.cpp') 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 +#include +#include +#include +#include + +#include +#include + +/* + * 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; +} -- cgit v1.2.3