user: implement mlibc as the libc, finally.
It's finally done.. Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
#include <mlibc/debug.hpp>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int capset(void *, void *) {
|
||||
mlibc::infoLogger() << "mlibc: capset is a no-op!" << frg::endlog;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int capget(void *, void *) {
|
||||
mlibc::infoLogger() << "mlibc: capget is a no-op!" << frg::endlog;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <limits.h>
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
cpu_set_t *__mlibc_cpu_alloc(int num_cpus) {
|
||||
return reinterpret_cast<cpu_set_t *>(calloc(1, CPU_ALLOC_SIZE(num_cpus)));
|
||||
}
|
||||
|
||||
#define CPU_MASK_BITS (CHAR_BIT * sizeof(__cpu_mask))
|
||||
|
||||
size_t __mlibc_cpu_alloc_size(int num_cpus) {
|
||||
/* calculate the (unaligned) remainder that doesn't neatly fit in one __cpu_mask; 0 or 1 */
|
||||
size_t remainder = ((num_cpus % CPU_MASK_BITS) + CPU_MASK_BITS - 1) / CPU_MASK_BITS;
|
||||
return sizeof(__cpu_mask) * (num_cpus / CPU_MASK_BITS + remainder);
|
||||
}
|
||||
|
||||
void __mlibc_cpu_zero(const size_t setsize, cpu_set_t *set) {
|
||||
memset(set, 0, CPU_ALLOC_SIZE(setsize));
|
||||
}
|
||||
|
||||
void __mlibc_cpu_set(const int cpu, const size_t setsize, cpu_set_t *set) {
|
||||
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *ptr = reinterpret_cast<unsigned char *>(set);
|
||||
size_t off = cpu / CHAR_BIT;
|
||||
size_t mask = 1 << (cpu % CHAR_BIT);
|
||||
|
||||
ptr[off] |= mask;
|
||||
}
|
||||
|
||||
void __mlibc_cpu_clear(const int cpu, const size_t setsize, cpu_set_t *set) {
|
||||
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char *ptr = reinterpret_cast<unsigned char *>(set);
|
||||
size_t off = cpu / CHAR_BIT;
|
||||
size_t mask = 1 << (cpu % CHAR_BIT);
|
||||
|
||||
ptr[off] &= ~mask;
|
||||
}
|
||||
|
||||
|
||||
int __mlibc_cpu_isset(const int cpu, const size_t setsize, const cpu_set_t *set) {
|
||||
if(cpu >= static_cast<int>(setsize * CHAR_BIT)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set);
|
||||
size_t off = cpu / CHAR_BIT;
|
||||
size_t mask = 1 << (cpu % CHAR_BIT);
|
||||
|
||||
return (ptr[off] & mask);
|
||||
}
|
||||
|
||||
int __mlibc_cpu_count(const size_t setsize, const cpu_set_t *set) {
|
||||
size_t count = 0;
|
||||
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(set);
|
||||
|
||||
for(size_t i = 0; i < setsize; i++) {
|
||||
for(size_t bit = 0; bit < CHAR_BIT; bit++) {
|
||||
if((1 << bit) & ptr[i])
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <mlibc/allocator.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <ifaddrs.h>
|
||||
#include <errno.h>
|
||||
|
||||
int getifaddrs(struct ifaddrs **ifap) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getifaddrs, -1);
|
||||
if(int e = sysdep(ifap); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void freeifaddrs(struct ifaddrs *ifa) {
|
||||
while (ifa != nullptr) {
|
||||
ifaddrs *current = ifa;
|
||||
ifa = ifa->ifa_next;
|
||||
getAllocator().free(current);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <bits/linux/linux_unistd.h>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <mlibc/posix-sysdeps.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
int dup3(int oldfd, int newfd, int flags) {
|
||||
if(oldfd == newfd) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_dup2, -1);
|
||||
if(int e = mlibc::sys_dup2(oldfd, flags, newfd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return newfd;
|
||||
}
|
||||
|
||||
int vhangup(void) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
int getdtablesize(void){
|
||||
return sysconf(_SC_OPEN_MAX);
|
||||
}
|
||||
|
||||
int syncfs(int fd) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_syncfs, -1);
|
||||
if(int e = mlibc::sys_syncfs(fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <bits/ensure.h>
|
||||
#include <malloc.h>
|
||||
|
||||
void *memalign(size_t, size_t) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <mntent.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
namespace {
|
||||
|
||||
char *internal_buf;
|
||||
size_t internal_bufsize;
|
||||
|
||||
} // namespace
|
||||
|
||||
#define SENTINEL (char *)&internal_buf
|
||||
|
||||
FILE *setmntent(const char *name, const char *mode) {
|
||||
return fopen(name, mode);
|
||||
}
|
||||
|
||||
struct mntent *getmntent(FILE *f) {
|
||||
static struct mntent mnt;
|
||||
return getmntent_r(f, &mnt, SENTINEL, 0);
|
||||
}
|
||||
|
||||
int addmntent(FILE *f, const struct mntent *mnt) {
|
||||
if(fseek(f, 0, SEEK_END)) {
|
||||
return 1;
|
||||
}
|
||||
return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n",
|
||||
mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
|
||||
mnt->mnt_freq, mnt->mnt_passno) < 0;
|
||||
}
|
||||
|
||||
int endmntent(FILE *f) {
|
||||
if(f) {
|
||||
fclose(f);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *hasmntopt(const struct mntent *mnt, const char *opt) {
|
||||
return strstr(mnt->mnt_opts, opt);
|
||||
}
|
||||
|
||||
/* Adapted from musl */
|
||||
struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen) {
|
||||
int n[8];
|
||||
bool use_internal = (linebuf == SENTINEL);
|
||||
int len;
|
||||
size_t i;
|
||||
|
||||
mnt->mnt_freq = 0;
|
||||
mnt->mnt_passno = 0;
|
||||
|
||||
do {
|
||||
if(use_internal) {
|
||||
getline(&internal_buf, &internal_bufsize, f);
|
||||
linebuf = internal_buf;
|
||||
} else {
|
||||
fgets(linebuf, buflen, f);
|
||||
}
|
||||
if(feof(f) || ferror(f)) {
|
||||
return nullptr;
|
||||
}
|
||||
if(!strchr(linebuf, '\n')) {
|
||||
fscanf(f, "%*[^\n]%*[\n]");
|
||||
errno = ERANGE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
len = strlen(linebuf);
|
||||
if(len > INT_MAX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(i = 0; i < sizeof n / sizeof *n; i++) {
|
||||
n[i] = len;
|
||||
}
|
||||
|
||||
sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
|
||||
n, n + 1, n + 2, n + 3, n + 4, n + 5, n + 6, n + 7,
|
||||
&mnt->mnt_freq, &mnt->mnt_passno);
|
||||
} while(linebuf[n[0]] == '#' || n[1] == len);
|
||||
|
||||
linebuf[n[1]] = 0;
|
||||
linebuf[n[3]] = 0;
|
||||
linebuf[n[5]] = 0;
|
||||
linebuf[n[7]] = 0;
|
||||
|
||||
mnt->mnt_fsname = linebuf + n[0];
|
||||
mnt->mnt_dir = linebuf + n[2];
|
||||
mnt->mnt_type = linebuf + n[4];
|
||||
mnt->mnt_opts = linebuf + n[6];
|
||||
|
||||
return mnt;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <errno.h>
|
||||
#include <module.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int init_module(void *module, unsigned long length, const char *args) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_init_module, -1);
|
||||
if(int e = mlibc::sys_init_module(module, length, args); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int delete_module(const char *name, unsigned flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_delete_module, -1);
|
||||
if(int e = mlibc::sys_delete_module(name, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#include <bits/ensure.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <mlibc/posix-sysdeps.hpp>
|
||||
|
||||
int sched_getcpu(void) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getcpu, -1);
|
||||
int cpu;
|
||||
if(int e = mlibc::sys_getcpu(&cpu); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return cpu;
|
||||
}
|
||||
|
||||
int setns(int fd, int nstype) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setns, -1);
|
||||
if(int e = mlibc::sys_setns(fd, nstype); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sched_getscheduler(pid_t pid) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getscheduler, -1);
|
||||
int policy;
|
||||
if(int e = mlibc::sys_getscheduler(pid, &policy); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getaffinity, -1);
|
||||
if(int e = mlibc::sys_getaffinity(pid, cpusetsize, mask); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unshare(int flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_unshare, -1);
|
||||
if(int e = mlibc::sys_unshare(flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sched_setaffinity(pid_t, size_t, const cpu_set_t *) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
int clone(int (*)(void *), void *, int, void *, ...) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <stddef.h>
|
||||
|
||||
int epoll_create(int) {
|
||||
int fd;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_create, -1);
|
||||
if(int e = mlibc::sys_epoll_create(0, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int epoll_pwait(int epfd, struct epoll_event *evnts, int n, int timeout,
|
||||
const sigset_t *sigmask) {
|
||||
int raised;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_pwait, -1);
|
||||
if(int e = mlibc::sys_epoll_pwait(epfd, evnts, n, timeout, sigmask, &raised)) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return raised;
|
||||
}
|
||||
|
||||
int epoll_create1(int flags) {
|
||||
int fd;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_create, -1);
|
||||
if(int e = mlibc::sys_epoll_create(flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int epoll_ctl(int epfd, int mode, int fd, struct epoll_event *ev) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_ctl, -1);
|
||||
if(int e = mlibc::sys_epoll_ctl(epfd, mode, fd, ev); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int epoll_wait(int epfd, struct epoll_event *evnts, int n, int timeout) {
|
||||
int raised;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_epoll_pwait, -1);
|
||||
if(int e = mlibc::sys_epoll_pwait(epfd, evnts, n, timeout, nullptr, &raised)) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return raised;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include <sys/eventfd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int eventfd(unsigned int initval, int flags) {
|
||||
int fd = 0;
|
||||
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_eventfd_create, -1);
|
||||
if (int e = mlibc::sys_eventfd_create(initval, flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int eventfd_read(int fd, eventfd_t *value) {
|
||||
ssize_t bytes_read;
|
||||
if (int e = mlibc::sys_read(fd, value, 8, &bytes_read); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bytes_read != 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eventfd_write(int fd, eventfd_t value) {
|
||||
ssize_t bytes_written;
|
||||
if (int e = mlibc::sys_write(fd, &value, 8, &bytes_written); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bytes_written != 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <bits/ensure.h>
|
||||
#include <sys/fsuid.h>
|
||||
|
||||
int setfsuid(uid_t) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
int setfsgid(gid_t) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int inotify_init(void) {
|
||||
int fd;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_create, -1);
|
||||
if(int e = mlibc::sys_inotify_create(0, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int inotify_init1(int flags) {
|
||||
int fd;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_create, -1);
|
||||
if(int e = mlibc::sys_inotify_create(flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int inotify_add_watch(int ifd, const char *path, uint32_t mask) {
|
||||
int wd;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_add_watch, -1);
|
||||
if(int e = mlibc::sys_inotify_add_watch(ifd, path, mask, &wd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return wd;
|
||||
}
|
||||
|
||||
int inotify_rm_watch(int ifd, int wd) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_inotify_rm_watch, -1);
|
||||
if(int e = mlibc::sys_inotify_rm_watch(ifd, wd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <errno.h>
|
||||
#include <sys/klog.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int klogctl(int type, char *bufp, int len) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_klogctl, -1);
|
||||
int out;
|
||||
if (int e = mlibc::sys_klogctl(type, bufp, len, &out); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int mount(const char *source, const char *target,
|
||||
const char *fstype, unsigned long flags, const void *data) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_mount, -1);
|
||||
if(int e = mlibc::sys_mount(source, target, fstype, flags, data); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int umount(const char *target) {
|
||||
return umount2(target, 0);
|
||||
}
|
||||
|
||||
int umount2(const char *target, int flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_umount2, -1);
|
||||
if(int e = mlibc::sys_umount2(target, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <bits/ensure.h>
|
||||
#include <errno.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <sys/pidfd.h>
|
||||
|
||||
int pidfd_open(pid_t pid, unsigned int flags) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pidfd_open, -1);
|
||||
int fd = 0;
|
||||
|
||||
if(int e = sysdep(pid, flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
pid_t pidfd_getpid(int fd) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pidfd_getpid, -1);
|
||||
pid_t pid = 0;
|
||||
|
||||
if(int e = sysdep(fd, &pid); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
int pidfd_send_signal(int pidfd, int sig, siginfo_t *info, unsigned int flags) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_pidfd_send_signal, -1);
|
||||
|
||||
if(int e = sysdep(pidfd, sig, info, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <bits/ensure.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#include <mlibc/debug.hpp>
|
||||
|
||||
#include "mlibc/linux-sysdeps.hpp"
|
||||
|
||||
int prctl(int op, ...) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_prctl, -1);
|
||||
|
||||
int val;
|
||||
va_list ap;
|
||||
va_start(ap, op);
|
||||
if(int e = mlibc::sys_prctl(op, ap, &val); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
#include <sys/ptrace.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
long ptrace(int req, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, req);
|
||||
auto pid = va_arg(ap, pid_t);
|
||||
auto addr = va_arg(ap, void *);
|
||||
auto data = va_arg(ap, void *);
|
||||
va_end(ap);
|
||||
|
||||
long ret;
|
||||
if(req > 0 && req < 4) {
|
||||
data = &ret;
|
||||
}
|
||||
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_ptrace, -1);
|
||||
long out;
|
||||
if(int e = mlibc::sys_ptrace(req, pid, addr, data, &out); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
} else if(req > 0 && req < 4) {
|
||||
errno = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#include <bits/ensure.h>
|
||||
#include <sys/quota.h>
|
||||
|
||||
int quotactl(int, const char *, int, caddr_t) {
|
||||
__ensure(!"Not implemented");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
#include <sys/random.h>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/posix-sysdeps.hpp>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
ssize_t getrandom(void *buffer, size_t max_size, unsigned int flags) {
|
||||
if(flags & ~(GRND_RANDOM | GRND_NONBLOCK)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getentropy, -1);
|
||||
if(int e = mlibc::sys_getentropy(buffer, max_size); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return max_size;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <errno.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int reboot(int what) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_reboot, -1);
|
||||
if (int e = mlibc::sys_reboot(what); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <errno.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
ssize_t sendfile(int outfd, int infd, off_t *offset, size_t size) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sendfile, -1);
|
||||
ssize_t out;
|
||||
if(int e = mlibc::sys_sendfile(outfd, infd, offset, size, &out); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/signalfd.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int signalfd(int fd, const sigset_t *mask, int flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_signalfd_create, -1);
|
||||
if(int e = mlibc::sys_signalfd_create(mask, flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int statfs(const char *path, struct statfs *buf) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_statfs, -1);
|
||||
if(int e = mlibc::sys_statfs(path, buf); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fstatfs(int fd, struct statfs *buf) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fstatfs, -1);
|
||||
if (int e = mlibc::sys_fstatfs(fd, buf); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[gnu::alias("fstatfs")]] int fstatfs64(int, struct statfs64 *);
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/posix-sysdeps.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf) {
|
||||
if(!mlibc::sys_statx) {
|
||||
struct stat statbuf;
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_stat, -1);
|
||||
|
||||
if (!(flags & AT_NO_AUTOMOUNT)) {
|
||||
mlibc::infoLogger()
|
||||
<< "mlibc: sys_statx is unavailable, and stat does not support not specifying AT_NO_MOUNTPOINT"
|
||||
<< frg::endlog;
|
||||
}
|
||||
|
||||
// AT_STATX_SYNC_AS_STAT is the default and behaves like good old stat
|
||||
if ((flags & AT_STATX_FORCE_SYNC) || (flags & AT_STATX_DONT_SYNC)) {
|
||||
mlibc::infoLogger()
|
||||
<< "mlibc: sys_statx is unavailable, and stat does not support modes other than AT_STATX_SYNC_AS_STAT"
|
||||
<< frg::endlog;
|
||||
}
|
||||
|
||||
// Mask out flags not appropriate for regular stat
|
||||
flags &= ~(AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT | AT_STATX_FORCE_SYNC | AT_STATX_DONT_SYNC);
|
||||
|
||||
if(int e = mlibc::sys_stat(mlibc::fsfd_target::fd_path, dirfd, pathname, flags, &statbuf); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(statxbuf, 0, sizeof(struct statx));
|
||||
statxbuf->stx_blksize = statbuf.st_blksize;
|
||||
statxbuf->stx_blocks = statbuf.st_blocks;
|
||||
statxbuf->stx_gid = statbuf.st_gid;
|
||||
statxbuf->stx_ino = statbuf.st_ino;
|
||||
statxbuf->stx_mode = statbuf.st_mode;
|
||||
statxbuf->stx_nlink = statbuf.st_nlink;
|
||||
statxbuf->stx_size = statbuf.st_size;
|
||||
statxbuf->stx_uid = statbuf.st_uid;
|
||||
|
||||
statxbuf->stx_atime.tv_sec = statbuf.st_atim.tv_sec;
|
||||
statxbuf->stx_atime.tv_nsec = statbuf.st_atim.tv_nsec;
|
||||
statxbuf->stx_btime.tv_sec = statbuf.st_mtim.tv_sec;
|
||||
statxbuf->stx_btime.tv_nsec = statbuf.st_mtim.tv_nsec;
|
||||
statxbuf->stx_ctime.tv_sec = statbuf.st_ctim.tv_sec;
|
||||
statxbuf->stx_ctime.tv_nsec = statbuf.st_ctim.tv_nsec;
|
||||
statxbuf->stx_mtime.tv_sec = statbuf.st_mtim.tv_sec;
|
||||
statxbuf->stx_mtime.tv_nsec = statbuf.st_mtim.tv_nsec;
|
||||
|
||||
statxbuf->stx_rdev_major = major(statbuf.st_rdev);
|
||||
statxbuf->stx_rdev_minor = minor(statbuf.st_rdev);
|
||||
statxbuf->stx_dev_major = major(statbuf.st_dev);
|
||||
statxbuf->stx_dev_minor = minor(statbuf.st_dev);
|
||||
statxbuf->stx_mask = STATX_BASIC_STATS | STATX_BTIME;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_statx, -1);
|
||||
if(int e = sysdep(dirfd, pathname, flags, mask, statxbuf); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <errno.h>
|
||||
#include <sys/swap.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int swapon(const char *path, int flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_swapon, -1);
|
||||
if(int e = mlibc::sys_swapon(path, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int swapoff(const char *path) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_swapoff, -1);
|
||||
if(int e = mlibc::sys_swapoff(path); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <errno.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <unistd.h>
|
||||
|
||||
int sysinfo(struct sysinfo *info) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_sysinfo, -1);
|
||||
if(int e = mlibc::sys_sysinfo(info); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_nprocs(void) {
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
|
||||
int get_nprocs_conf(void) {
|
||||
return sysconf(_SC_NPROCESSORS_CONF);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/timerfd.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
int timerfd_create(int clockid, int flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timerfd_create, -1);
|
||||
int fd;
|
||||
if(int e = mlibc::sys_timerfd_create(clockid, flags, &fd); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int timerfd_settime(int fd, int flags, const struct itimerspec *value,
|
||||
struct itimerspec *oldvalue) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timerfd_settime, -1);
|
||||
if(int e = mlibc::sys_timerfd_settime(fd, flags, value, oldvalue); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timerfd_gettime(int fd, struct itimerspec *its) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_timerfd_gettime, -1);
|
||||
if(int e = sysdep(fd, its); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include <errno.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
|
||||
ssize_t process_vm_readv(pid_t pid,
|
||||
const struct iovec *local_iov, unsigned long liovcnt,
|
||||
const struct iovec *remote_iov, unsigned long riovcnt,
|
||||
unsigned long flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_process_vm_readv, -1);
|
||||
ssize_t bytes_read;
|
||||
if(int e = mlibc::sys_process_vm_readv(pid, local_iov, liovcnt,
|
||||
remote_iov, riovcnt, flags, &bytes_read); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
ssize_t process_vm_writev(pid_t pid,
|
||||
const struct iovec *local_iov, unsigned long liovcnt,
|
||||
const struct iovec *remote_iov, unsigned long riovcnt,
|
||||
unsigned long flags) {
|
||||
MLIBC_CHECK_OR_ENOSYS(mlibc::sys_process_vm_writev, -1);
|
||||
ssize_t bytes_written;
|
||||
if(int e = mlibc::sys_process_vm_writev(pid, local_iov, liovcnt,
|
||||
remote_iov, riovcnt, flags, &bytes_written); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return bytes_written;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#include <errno.h>
|
||||
#include <sys/xattr.h>
|
||||
|
||||
#include <mlibc/linux-sysdeps.hpp>
|
||||
#include <bits/ensure.h>
|
||||
|
||||
int setxattr(const char *path, const char *name, const void *val, size_t size,
|
||||
int flags) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_setxattr, -1);
|
||||
|
||||
if (int e = sysdep(path, name, val, size, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsetxattr(const char *path, const char *name, const void *val, size_t size,
|
||||
int flags) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lsetxattr, -1);
|
||||
|
||||
if (int e = sysdep(path, name, val, size, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsetxattr(int fd, const char *name, const void *val, size_t size,
|
||||
int flags) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fsetxattr, -1);
|
||||
|
||||
if (int e = sysdep(fd, name, val, size, flags); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t getxattr(const char *path, const char *name, void *val, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_getxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(path, name, val, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t lgetxattr(const char *path, const char *name, void *val, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lgetxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(path, name, val, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t fgetxattr(int fd, const char *name, void *val, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fgetxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(fd, name, val, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
int removexattr(const char *path, const char *name) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_removexattr, -1);
|
||||
return sysdep(path, name);
|
||||
}
|
||||
|
||||
int lremovexattr(const char *path, const char *name) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_lremovexattr, -1);
|
||||
return sysdep(path, name);
|
||||
}
|
||||
|
||||
int fremovexattr(int fd, const char *name) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_fremovexattr, -1);
|
||||
return sysdep(fd, name);
|
||||
}
|
||||
|
||||
ssize_t listxattr(const char *path, char *list, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_listxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(path, list, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t llistxattr(const char *path, char *list, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_llistxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(path, list, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t flistxattr(int fd, char *list, size_t size) {
|
||||
auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_flistxattr, -1);
|
||||
|
||||
ssize_t nread;
|
||||
if (int e = sysdep(fd, list, size, &nread); e) {
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
|
||||
#include <bits/ensure.h>
|
||||
#include <frg/mutex.hpp>
|
||||
#include <frg/spinlock.hpp>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <mlibc/utmp.hpp>
|
||||
#include <mlibc/posix-sysdeps.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr const char *defaultUtmpPath = UTMP_FILE;
|
||||
|
||||
const char *utmpPath = defaultUtmpPath;
|
||||
frg::ticket_spinlock utmpMutex;
|
||||
|
||||
frg::optional<int> utmpFd = frg::null_opt;
|
||||
|
||||
utmp returned;
|
||||
|
||||
} // namespace
|
||||
|
||||
void setutent(void) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd) {
|
||||
int fd;
|
||||
int err = mlibc::sys_open(utmpPath, O_RDWR | O_CREAT | O_CLOEXEC, 0644, &fd);
|
||||
if(err) {
|
||||
mlibc::infoLogger() << "\e[31mmlibc: setutent() failed to open " << utmpPath << ": "
|
||||
<< strerror(err) << "\e[39m" << frg::endlog;
|
||||
utmpFd = frg::null_opt;
|
||||
} else {
|
||||
utmpFd = fd;
|
||||
}
|
||||
} else {
|
||||
off_t discard;
|
||||
mlibc::sys_seek(utmpFd.value(), 0, SEEK_SET, &discard);
|
||||
}
|
||||
}
|
||||
|
||||
struct utmp *getutent(void) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd)
|
||||
setutent();
|
||||
if(!utmpFd) {
|
||||
errno = ENOENT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(int e = mlibc::getUtmpEntry(*utmpFd, &returned); e) {
|
||||
errno = e;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &returned;
|
||||
}
|
||||
|
||||
int getutent_r(struct utmp *buf, struct utmp **res) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd)
|
||||
setutent();
|
||||
if(!utmpFd) {
|
||||
*res = nullptr;
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(int e = mlibc::getUtmpEntry(*utmpFd, buf); e) {
|
||||
*res = nullptr;
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*res = buf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void endutent(void) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(utmpFd) {
|
||||
mlibc::sys_close(utmpFd.value());
|
||||
utmpFd = frg::null_opt;
|
||||
}
|
||||
}
|
||||
|
||||
struct utmp *pututline(const struct utmp *ut) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd)
|
||||
setutent();
|
||||
if(!utmpFd) {
|
||||
errno = ENOENT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(int e = mlibc::putUtmpEntry(*utmpFd, ut); e) {
|
||||
errno = e;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return (utmp *) ut;
|
||||
}
|
||||
|
||||
struct utmp *getutline(const struct utmp *ut) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd)
|
||||
setutent();
|
||||
if(!utmpFd) {
|
||||
errno = ENOENT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(int e = mlibc::getUtmpEntryByType(*utmpFd, ut, &returned); e) {
|
||||
errno = e;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &returned;
|
||||
}
|
||||
|
||||
int utmpname(const char *file) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(strcmp(file, utmpPath)) {
|
||||
if(!strcmp(file, defaultUtmpPath)) {
|
||||
free((void *) utmpPath);
|
||||
utmpPath = defaultUtmpPath;
|
||||
} else {
|
||||
char *name = strdup(file);
|
||||
if(!name)
|
||||
return -1;
|
||||
|
||||
if(utmpPath != defaultUtmpPath)
|
||||
free((void *) utmpPath);
|
||||
|
||||
utmpPath = name;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct utmp *getutid(const struct utmp *ut) {
|
||||
frg::unique_lock lock{utmpMutex};
|
||||
|
||||
if(!utmpFd)
|
||||
setutent();
|
||||
if(!utmpFd) {
|
||||
errno = ENOENT;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(int e = mlibc::getUtmpEntryById(*utmpFd, ut, &returned); e) {
|
||||
errno = e;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &returned;
|
||||
}
|
||||
|
||||
void updwtmp(const char *file, const struct utmp *ut) {
|
||||
int fd;
|
||||
int err = mlibc::sys_open(file, O_RDWR | O_CREAT | O_CLOEXEC | O_APPEND, 0644, &fd);
|
||||
if(err) {
|
||||
mlibc::infoLogger() << "\e[31mmlibc: updwtmp() failed to open " << file << ": "
|
||||
<< strerror(err) << "\e[39m" << frg::endlog;
|
||||
return;
|
||||
}
|
||||
|
||||
mlibc::putUtmpEntry(fd, ut);
|
||||
mlibc::sys_close(fd);
|
||||
}
|
||||
Reference in New Issue
Block a user