mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-02 07:28:21 +00:00
syscalls: fchdir, setitimer, getitimer
This commit is contained in:
@@ -66,6 +66,9 @@ extern syscall_uname
|
|||||||
extern syscall_hostname
|
extern syscall_hostname
|
||||||
extern syscall_sync
|
extern syscall_sync
|
||||||
extern syscall_fsync
|
extern syscall_fsync
|
||||||
|
extern syscall_fchdir
|
||||||
|
extern syscall_getitimer
|
||||||
|
extern syscall_setitimer
|
||||||
syscalltab:
|
syscalltab:
|
||||||
dq syscall_print
|
dq syscall_print
|
||||||
dq syscall_mmap
|
dq syscall_mmap
|
||||||
@@ -134,7 +137,10 @@ dq syscall_uname
|
|||||||
dq syscall_hostname
|
dq syscall_hostname
|
||||||
dq syscall_sync
|
dq syscall_sync
|
||||||
dq syscall_fsync
|
dq syscall_fsync
|
||||||
syscallcount equ 67
|
dq syscall_fchdir
|
||||||
|
dq syscall_setitimer
|
||||||
|
dq syscall_getitimer
|
||||||
|
syscallcount equ 70
|
||||||
section .text
|
section .text
|
||||||
global arch_syscall_entry
|
global arch_syscall_entry
|
||||||
; on entry:
|
; on entry:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#ifdef SYSCALL_LOGGING
|
#ifdef SYSCALL_LOGGING
|
||||||
|
|
||||||
#define SYSCALL_COUNT 67
|
#define SYSCALL_COUNT 68
|
||||||
#define LOGSTR(x) arch_e9_puts(x)
|
#define LOGSTR(x) arch_e9_puts(x)
|
||||||
|
|
||||||
static char *name[] = {
|
static char *name[] = {
|
||||||
@@ -75,7 +75,10 @@ static char *name[] = {
|
|||||||
"uname",
|
"uname",
|
||||||
"hostname",
|
"hostname",
|
||||||
"sync",
|
"sync",
|
||||||
"fsync"
|
"fsync",
|
||||||
|
"fchdir",
|
||||||
|
"getitimer",
|
||||||
|
"setitimer"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *args[] = {
|
static char *args[] = {
|
||||||
@@ -145,7 +148,10 @@ static char *args[] = {
|
|||||||
"utsname %p", // uname
|
"utsname %p", // uname
|
||||||
"new %p newsize %lu old %p oldsize %lu", // hostname
|
"new %p newsize %lu old %p oldsize %lu", // hostname
|
||||||
"N/A", // sync
|
"N/A", // sync
|
||||||
"fd %d" // fsync
|
"fd %d", // fsync
|
||||||
|
"fd %d", // fchdir
|
||||||
|
"which %d new %p old %p\n", // setitimer
|
||||||
|
"which %d value %p\n", // getitimer
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _ITIMER_H
|
||||||
|
#define _ITIMER_H
|
||||||
|
|
||||||
|
#include <kernel/dpc.h>
|
||||||
|
#include <kernel/timer.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct cpu_t *cpu;
|
||||||
|
timerentry_t entry;
|
||||||
|
uintmax_t remainingus;
|
||||||
|
uintmax_t repeatus;
|
||||||
|
dpcfn_t fn;
|
||||||
|
dpcarg_t arg;
|
||||||
|
bool paused;
|
||||||
|
spinlock_t lock;
|
||||||
|
} itimer_t;
|
||||||
|
|
||||||
|
void itimer_init(itimer_t *itimer, dpcfn_t fn, dpcarg_t arg);
|
||||||
|
void itimer_pause(itimer_t *itimer, uintmax_t *remainingus, uintmax_t *repeatus);
|
||||||
|
void itimer_set(itimer_t *itimer, uintmax_t timerus, uintmax_t repeatus);
|
||||||
|
void itimer_resume(itimer_t *itimer);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <mutex.h>
|
#include <mutex.h>
|
||||||
#include <kernel/signal.h>
|
#include <kernel/signal.h>
|
||||||
|
#include <kernel/itimer.h>
|
||||||
|
|
||||||
#define SCHED_THREAD_FLAGS_QUEUED 1
|
#define SCHED_THREAD_FLAGS_QUEUED 1
|
||||||
#define SCHED_THREAD_FLAGS_RUNNING 2
|
#define SCHED_THREAD_FLAGS_RUNNING 2
|
||||||
@@ -112,6 +113,13 @@ typedef struct proc_t {
|
|||||||
bool stopunwaited;
|
bool stopunwaited;
|
||||||
bool continueunwaited;
|
bool continueunwaited;
|
||||||
} signals;
|
} signals;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
mutex_t mutex;
|
||||||
|
itimer_t realtime;
|
||||||
|
itimer_t virtualtime;
|
||||||
|
itimer_t profiling;
|
||||||
|
} timer;
|
||||||
} proc_t;
|
} proc_t;
|
||||||
|
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
|||||||
@@ -4,12 +4,18 @@
|
|||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
typedef long time_t;
|
typedef long time_t;
|
||||||
|
typedef long suseconds_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
time_t s;
|
time_t s;
|
||||||
time_t ns;
|
time_t ns;
|
||||||
} timespec_t;
|
} timespec_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
time_t s;
|
||||||
|
suseconds_t us;
|
||||||
|
} timeval_t;
|
||||||
|
|
||||||
static inline timespec_t timespec_add(timespec_t a, timespec_t b) {
|
static inline timespec_t timespec_add(timespec_t a, timespec_t b) {
|
||||||
timespec_t ts;
|
timespec_t ts;
|
||||||
ts.ns = (a.ns + b.ns) % 1000000000;
|
ts.ns = (a.ns + b.ns) % 1000000000;
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
#include <kernel/itimer.h>
|
||||||
|
#include <logging.h>
|
||||||
|
|
||||||
|
static void itimer_dpc(context_t *context, dpcarg_t arg) {
|
||||||
|
itimer_t *itimer = arg;
|
||||||
|
spinlock_acquire(&itimer->lock);
|
||||||
|
if (itimer->paused)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
itimer->remainingus = itimer->repeatus ? itimer->repeatus : 0;
|
||||||
|
itimer->paused = itimer->repeatus == 0;
|
||||||
|
itimer->fn(context, itimer->arg);
|
||||||
|
if (itimer->repeatus) {
|
||||||
|
timer_insert(_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
spinlock_release(&itimer->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void itimer_init(itimer_t *itimer, dpcfn_t fn, dpcarg_t arg) {
|
||||||
|
memset(itimer, 0, sizeof(itimer_t));
|
||||||
|
itimer->fn = fn;
|
||||||
|
itimer->arg = arg;
|
||||||
|
itimer->paused = true;
|
||||||
|
SPINLOCK_INIT(itimer->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void itimer_pause(itimer_t *itimer, uintmax_t *remainingus, uintmax_t *repeatus) {
|
||||||
|
bool intstatus = interrupt_set(false);
|
||||||
|
spinlock_acquire(&itimer->lock);
|
||||||
|
|
||||||
|
while (itimer->cpu && itimer->cpu != _cpu()) {
|
||||||
|
// schedule on the itimer cpu
|
||||||
|
sched_targetcpu(itimer->cpu);
|
||||||
|
spinlock_release(&itimer->lock);
|
||||||
|
sched_yield();
|
||||||
|
sched_targetcpu(NULL);
|
||||||
|
spinlock_acquire(&itimer->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itimer->paused)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
itimer->cpu = NULL;
|
||||||
|
itimer->remainingus = timer_remove(_cpu()->timer, &itimer->entry);
|
||||||
|
if (itimer->remainingus == 0) {
|
||||||
|
// while we were running in the cpu, the timer fired.
|
||||||
|
// the dpc won't be handled because the timer entry
|
||||||
|
// has already been removed from the queue.
|
||||||
|
// this will be handled as a ''timer was one microsecond away from firing''
|
||||||
|
// situation as its the cleanest way of doing this.
|
||||||
|
itimer->remainingus = 1;
|
||||||
|
}
|
||||||
|
itimer->paused = true;
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
spinlock_release(&itimer->lock);
|
||||||
|
interrupt_set(intstatus);
|
||||||
|
if (remainingus)
|
||||||
|
*remainingus = itimer->remainingus;
|
||||||
|
if (repeatus)
|
||||||
|
*repeatus = itimer->repeatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
void itimer_set(itimer_t *itimer, uintmax_t timerus, uintmax_t repeatus) {
|
||||||
|
bool intstatus = interrupt_set(false);
|
||||||
|
spinlock_acquire(&itimer->lock);
|
||||||
|
|
||||||
|
itimer->remainingus = timerus;
|
||||||
|
itimer->repeatus = repeatus;
|
||||||
|
|
||||||
|
spinlock_release(&itimer->lock);
|
||||||
|
interrupt_set(intstatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void itimer_resume(itimer_t *itimer) {
|
||||||
|
bool intstatus = interrupt_set(false);
|
||||||
|
spinlock_acquire(&itimer->lock);
|
||||||
|
|
||||||
|
__assert(itimer->paused && itimer->remainingus);
|
||||||
|
itimer->cpu = _cpu();
|
||||||
|
itimer->paused = false;
|
||||||
|
timer_insert(_cpu()->timer, &itimer->entry, itimer_dpc, itimer, itimer->remainingus, false);
|
||||||
|
|
||||||
|
spinlock_release(&itimer->lock);
|
||||||
|
interrupt_set(intstatus);
|
||||||
|
}
|
||||||
@@ -49,6 +49,27 @@ proc_t *sched_getprocfrompid(int pid) {
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtdpc(context_t *, dpcarg_t arg) {
|
||||||
|
proc_t *proc = arg;
|
||||||
|
// XXX this can sleep and if it does the entire system burns down sooooooo yeah fix this for the love of god
|
||||||
|
__assert(proc->threadtablesize == 1);
|
||||||
|
signal_signalproc(arg, SIGALRM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vtdpc(context_t *, dpcarg_t arg) {
|
||||||
|
proc_t *proc = arg;
|
||||||
|
// XXX this can sleep and if it does the entire system burns down sooooooo yeah fix this for the love of god
|
||||||
|
__assert(proc->threadtablesize == 1);
|
||||||
|
signal_signalproc(arg, SIGVTALRM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profdpc(context_t *, dpcarg_t arg) {
|
||||||
|
proc_t *proc = arg;
|
||||||
|
// XXX this can sleep and if it does the entire system burns down sooooooo yeah fix this for the love of god
|
||||||
|
__assert(proc->threadtablesize == 1);
|
||||||
|
signal_signalproc(arg, SIGPROF);
|
||||||
|
}
|
||||||
|
|
||||||
proc_t *sched_newproc() {
|
proc_t *sched_newproc() {
|
||||||
proc_t *proc = slab_allocate(processcache);
|
proc_t *proc = slab_allocate(processcache);
|
||||||
if (proc == NULL)
|
if (proc == NULL)
|
||||||
@@ -76,6 +97,10 @@ proc_t *sched_newproc() {
|
|||||||
SPINLOCK_INIT(proc->jobctllock);
|
SPINLOCK_INIT(proc->jobctllock);
|
||||||
SPINLOCK_INIT(proc->pgrp.lock);
|
SPINLOCK_INIT(proc->pgrp.lock);
|
||||||
SPINLOCK_INIT(proc->signals.lock);
|
SPINLOCK_INIT(proc->signals.lock);
|
||||||
|
MUTEX_INIT(&proc->timer.mutex);
|
||||||
|
itimer_init(&proc->timer.realtime, rtdpc, proc);
|
||||||
|
itimer_init(&proc->timer.virtualtime, vtdpc, proc);
|
||||||
|
itimer_init(&proc->timer.profiling, profdpc, proc);
|
||||||
|
|
||||||
proc->fd = alloc(sizeof(fd_t) * 3);
|
proc->fd = alloc(sizeof(fd_t) * 3);
|
||||||
if (proc->fd == NULL) {
|
if (proc->fd == NULL) {
|
||||||
@@ -127,7 +152,6 @@ thread_t *sched_newthread(void *ip, size_t kstacksize, int priority, proc_t *pro
|
|||||||
thread->tid = __atomic_fetch_add(&currpid, 1, __ATOMIC_SEQ_CST);
|
thread->tid = __atomic_fetch_add(&currpid, 1, __ATOMIC_SEQ_CST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CTX_INIT(&thread->context, proc != NULL, true);
|
CTX_INIT(&thread->context, proc != NULL, true);
|
||||||
CTX_XINIT(&thread->extracontext, proc != NULL);
|
CTX_XINIT(&thread->extracontext, proc != NULL);
|
||||||
CTX_SP(&thread->context) = proc ? (ctxreg_t)ustack : (ctxreg_t)thread->kernelstacktop;
|
CTX_SP(&thread->context) = proc ? (ctxreg_t)ustack : (ctxreg_t)thread->kernelstacktop;
|
||||||
@@ -291,6 +315,11 @@ void sched_procexit() {
|
|||||||
for (int fd = 0; fd < proc->fdcount; ++fd)
|
for (int fd = 0; fd < proc->fdcount; ++fd)
|
||||||
fd_close(fd);
|
fd_close(fd);
|
||||||
|
|
||||||
|
// turn off interval timers
|
||||||
|
itimer_pause(&proc->timer.realtime, NULL, NULL);
|
||||||
|
itimer_pause(&proc->timer.virtualtime, NULL, NULL);
|
||||||
|
itimer_pause(&proc->timer.profiling, NULL, NULL);
|
||||||
|
|
||||||
// zombify the proc
|
// zombify the proc
|
||||||
MUTEX_ACQUIRE(&proc->mutex, false);
|
MUTEX_ACQUIRE(&proc->mutex, false);
|
||||||
|
|
||||||
@@ -392,7 +421,6 @@ typedef struct {
|
|||||||
// SHOULD NOT BE CALLED WITH THE SCHEDULER STACK
|
// SHOULD NOT BE CALLED WITH THE SCHEDULER STACK
|
||||||
static void userspacecheck(void *_args) {
|
static void userspacecheck(void *_args) {
|
||||||
checkargs_t *args = _args;
|
checkargs_t *args = _args;
|
||||||
__assert(_cpu() >= (cpu_t *)0xffffffff80000000);
|
|
||||||
thread_t *thread = _cpu()->thread;
|
thread_t *thread = _cpu()->thread;
|
||||||
|
|
||||||
if (thread->shouldexit) {
|
if (thread->shouldexit) {
|
||||||
|
|||||||
@@ -42,3 +42,27 @@ syscallret_t syscall_chdir(context_t *, const char *upath) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syscallret_t syscall_fchdir(context_t *, int fd) {
|
||||||
|
syscallret_t ret = {
|
||||||
|
.ret = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
file_t *file = fd_get(fd);
|
||||||
|
if (file == NULL) {
|
||||||
|
ret.errno = EBADF;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file->vnode->type != V_TYPE_DIR) {
|
||||||
|
ret.errno = ENOTDIR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
sched_setcwd(file->vnode);
|
||||||
|
ret.errno = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
fd_release(file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ syscallret_t syscall_futex(context_t *, uint32_t *futexp, int op, uint32_t value
|
|||||||
MUTEX_RELEASE(&futexmutex);
|
MUTEX_RELEASE(&futexmutex);
|
||||||
|
|
||||||
ret.errno = poll_dowait(&desc, us);
|
ret.errno = poll_dowait(&desc, us);
|
||||||
int revents = desc.event->revents;
|
int revents = 0;
|
||||||
|
if (desc.event)
|
||||||
|
revents = desc.event->revents;
|
||||||
|
|
||||||
MUTEX_ACQUIRE(&futexmutex, false);
|
MUTEX_ACQUIRE(&futexmutex, false);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#include <kernel/syscalls.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <kernel/scheduler.h>
|
||||||
|
#include <logging.h>
|
||||||
|
|
||||||
|
#define ITIMER_REAL 0
|
||||||
|
#define ITIMER_VIRTUAL 1
|
||||||
|
#define ITIMER_PROF 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
timeval_t interval;
|
||||||
|
timeval_t value;
|
||||||
|
} itimerval_t;
|
||||||
|
|
||||||
|
static itimer_t *selectitimer(int which) {
|
||||||
|
itimer_t *itimer = NULL;
|
||||||
|
if (which == ITIMER_REAL)
|
||||||
|
itimer = &_cpu()->thread->proc->timer.realtime;
|
||||||
|
else if (which == ITIMER_VIRTUAL)
|
||||||
|
itimer = &_cpu()->thread->proc->timer.virtualtime;
|
||||||
|
else if (which == ITIMER_PROF)
|
||||||
|
itimer = &_cpu()->thread->proc->timer.profiling;
|
||||||
|
|
||||||
|
return itimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallret_t syscall_getitimer(context_t *context, int which, itimerval_t *value) {
|
||||||
|
syscallret_t ret = {
|
||||||
|
.ret = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
__assert(which == ITIMER_REAL);
|
||||||
|
itimer_t *itimer = selectitimer(which);
|
||||||
|
if (itimer == NULL) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
MUTEX_ACQUIRE(&_cpu()->thread->proc->timer.mutex, false);
|
||||||
|
|
||||||
|
uintmax_t oldremaining, oldrepeat;
|
||||||
|
itimer_pause(itimer, &oldremaining, &oldrepeat);
|
||||||
|
if (oldremaining)
|
||||||
|
itimer_resume(itimer);
|
||||||
|
|
||||||
|
MUTEX_RELEASE(&_cpu()->thread->proc->timer.mutex);
|
||||||
|
|
||||||
|
value->interval.s = oldrepeat / 1000000;
|
||||||
|
value->interval.us = oldrepeat % 1000000;
|
||||||
|
value->value.s = oldremaining / 1000000;
|
||||||
|
value->value.us = oldremaining % 1000000;
|
||||||
|
ret.errno = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
syscallret_t syscall_setitimer(context_t *context, int which, itimerval_t *unew, itimerval_t *uold) {
|
||||||
|
syscallret_t ret = {
|
||||||
|
.ret = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
__assert(which == ITIMER_REAL);
|
||||||
|
|
||||||
|
itimer_t *itimer = selectitimer(which);
|
||||||
|
if (itimer == NULL) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
itimerval_t val = {0};
|
||||||
|
if (unew)
|
||||||
|
val = *unew;
|
||||||
|
|
||||||
|
MUTEX_ACQUIRE(&_cpu()->thread->proc->timer.mutex, false);
|
||||||
|
uintmax_t oldremaining, oldrepeat;
|
||||||
|
itimer_pause(itimer, &oldremaining, &oldrepeat);
|
||||||
|
|
||||||
|
// TODO overflow check
|
||||||
|
uintmax_t repeatus = val.interval.s * 1000000 + val.interval.us;
|
||||||
|
uintmax_t newus = val.value.s * 1000000 + val.value.us;
|
||||||
|
itimer_set(itimer, newus, repeatus);
|
||||||
|
|
||||||
|
if (newus)
|
||||||
|
itimer_resume(itimer);
|
||||||
|
|
||||||
|
MUTEX_RELEASE(&_cpu()->thread->proc->timer.mutex);
|
||||||
|
|
||||||
|
if (uold) {
|
||||||
|
uold->interval.s = oldrepeat / 1000000;
|
||||||
|
uold->interval.us = oldrepeat % 1000000;
|
||||||
|
uold->value.s = oldremaining / 1000000;
|
||||||
|
uold->value.us = oldremaining % 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.errno = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -192,10 +192,10 @@ index 0000000..e5b087a
|
|||||||
+
|
+
|
||||||
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
diff --git mlibc-workdir/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..0755fba
|
index 0000000..b150712
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||||
@@ -0,0 +1,714 @@
|
@@ -0,0 +1,724 @@
|
||||||
+#include <bits/ensure.h>
|
+#include <bits/ensure.h>
|
||||||
+#include <mlibc/debug.hpp>
|
+#include <mlibc/debug.hpp>
|
||||||
+#include <mlibc/all-sysdeps.hpp>
|
+#include <mlibc/all-sysdeps.hpp>
|
||||||
@@ -279,9 +279,14 @@ index 0000000..0755fba
|
|||||||
+ return 0;
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ int sys_getitimer(int which, struct itimerval *curr_value) {
|
||||||
|
+ long ret;
|
||||||
|
+ return syscall(SYSCALL_SETITIMER, &ret, which, (uint64_t)curr_value);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ int sys_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) {
|
+ int sys_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) {
|
||||||
+ // TODO unstub
|
+ long ret;
|
||||||
+ return ENOSYS;
|
+ return syscall(SYSCALL_SETITIMER, &ret, which, (uint64_t)new_value, (uint64_t)old_value);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ #ifndef MLIBC_BUILDING_RTLD
|
+ #ifndef MLIBC_BUILDING_RTLD
|
||||||
@@ -728,6 +733,11 @@ index 0000000..0755fba
|
|||||||
+ return syscall(SYSCALL_CHDIR, &ret, (uint64_t)path);
|
+ return syscall(SYSCALL_CHDIR, &ret, (uint64_t)path);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ int sys_fchdir(int fd) {
|
||||||
|
+ long ret;
|
||||||
|
+ return syscall(SYSCALL_FCHDIR, &ret, fd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ int sys_fcntl(int fd, int request, va_list args, int *result) {
|
+ int sys_fcntl(int fd, int request, va_list args, int *result) {
|
||||||
+ long arg = va_arg(args, uint64_t);
|
+ long arg = va_arg(args, uint64_t);
|
||||||
+ long ret;
|
+ long ret;
|
||||||
@@ -929,10 +939,10 @@ index 0000000..990eca0
|
|||||||
+#endif
|
+#endif
|
||||||
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
diff --git mlibc-workdir/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..5148ce4
|
index 0000000..956a10b
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
@@ -0,0 +1,90 @@
|
@@ -0,0 +1,93 @@
|
||||||
+#ifndef _SYSCALL_H_INCLUDE
|
+#ifndef _SYSCALL_H_INCLUDE
|
||||||
+#define _SYSCALL_H_INCLUDE
|
+#define _SYSCALL_H_INCLUDE
|
||||||
+
|
+
|
||||||
@@ -1003,6 +1013,9 @@ index 0000000..5148ce4
|
|||||||
+#define SYSCALL_HOSTNAME 64
|
+#define SYSCALL_HOSTNAME 64
|
||||||
+#define SYSCALL_SYNC 65
|
+#define SYSCALL_SYNC 65
|
||||||
+#define SYSCALL_FSYNC 66
|
+#define SYSCALL_FSYNC 66
|
||||||
|
+#define SYSCALL_FCHDIR 67
|
||||||
|
+#define SYSCALL_SETITIMER 68
|
||||||
|
+#define SYSCALL_GETITIMER 69
|
||||||
+
|
+
|
||||||
+#include <stddef.h>
|
+#include <stddef.h>
|
||||||
+#include <stdint.h>
|
+#include <stdint.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user