Skip to content

Commit

Permalink
Fix some issues
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Oct 10, 2023
1 parent 211d5d9 commit 9d372f4
Show file tree
Hide file tree
Showing 29 changed files with 373 additions and 63 deletions.
53 changes: 52 additions & 1 deletion ape/ape-m1.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
#include <sys/uio.h>
#include <time.h>
#include <unistd.h>
#include <semaphore.h>

#define pagesz 16384
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
#define SYSLIB_VERSION 4
#define SYSLIB_VERSION 5

struct Syslib {
int magic;
Expand Down Expand Up @@ -79,6 +80,15 @@ struct Syslib {
long (*pselect)(int, fd_set *, fd_set *, fd_set *, const struct timespec *,
const sigset_t *);
long (*mprotect)(void *, size_t, int);
/* v5 (2023-10-09) */
long (*sigaltstack)(const stack_t *, stack_t *);
long (*getentropy)(void *, size_t);
long (*sem_open)(const char *, int, uint16_t, unsigned);
long (*sem_unlink)(const char *);
long (*sem_close)(int *);
long (*sem_post)(int *);
long (*sem_wait)(int *);
long (*sem_trywait)(int *);
};

#define ELFCLASS32 1
Expand Down Expand Up @@ -350,6 +360,7 @@ static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) {
if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0;
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
MemMove(ps->path + pathlen, ps->name, ps->namelen);
ps->path[pathlen + ps->namelen] = 0;
return !access(ps->path, X_OK);
}

Expand Down Expand Up @@ -795,6 +806,38 @@ static long sys_mprotect(void *data, size_t size, int prot) {
return sysret(mprotect(data, size, prot));
}

static long sys_sigaltstack(const stack_t *ss, stack_t *oss) {
return sysret(sigaltstack(ss, oss));
}

static long sys_getentropy(void *buf, size_t buflen) {
return sysret(getentropy(buf, buflen));
}

static long sys_sem_open(const char *name, int oflags, mode_t mode, unsigned value) {
return sysret((long)sem_open(name, oflags, mode, value));
}

static long sys_sem_unlink(const char *name) {
return sysret(sem_unlink(name));
}

static long sys_sem_close(sem_t *sem) {
return sysret(sem_close(sem));
}

static long sys_sem_post(sem_t *sem) {
return sysret(sem_post(sem));
}

static long sys_sem_wait(sem_t *sem) {
return sysret(sem_wait(sem));
}

static long sys_sem_trywait(sem_t *sem) {
return sysret(sem_trywait(sem));
}

static long sys_write(int fd, const void *data, size_t size) {
return sysret(write(fd, data, size));
}
Expand Down Expand Up @@ -879,6 +922,14 @@ int main(int argc, char **argv, char **envp) {
M->lib.sigaction = sys_sigaction;
M->lib.pselect = sys_pselect;
M->lib.mprotect = sys_mprotect;
M->lib.sigaltstack = sys_sigaltstack;
M->lib.getentropy = sys_getentropy;
M->lib.sem_open = sys_sem_open;
M->lib.sem_unlink = sys_sem_unlink;
M->lib.sem_close = sys_sem_close;
M->lib.sem_post = sys_sem_post;
M->lib.sem_wait = sys_sem_wait;
M->lib.sem_trywait = sys_sem_trywait;

/* getenv("_") is close enough to at_execfn */
execfn = argc > 0 ? argv[0] : 0;
Expand Down
1 change: 1 addition & 0 deletions ape/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) {
if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0;
if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/';
MemMove(ps->path + pathlen, ps->name, ps->namelen);
ps->path[pathlen + ps->namelen] = 0;
return !Access(ps->path, X_OK, ps->os);
}

Expand Down
2 changes: 1 addition & 1 deletion libc/calls/assertfail.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
void __assert_fail(const char *expr, const char *file, int line) {
char ibuf[12];
FormatInt32(ibuf, line);
tinyprint(2, "\n", file, ":", ibuf, ": assert(", expr, ") failed (",
tinyprint(2, file, ":", ibuf, ": assert(", expr, ") failed (",
program_invocation_short_name, " ",
DescribeBacktrace(__builtin_frame_address(0)), ")\n", NULL);
abort();
Expand Down
4 changes: 3 additions & 1 deletion libc/calls/clock_nanosleep-xnu.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/calls/struct/timeval.h"
Expand All @@ -27,6 +28,7 @@
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"

int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
Expand Down Expand Up @@ -74,7 +76,7 @@ int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
}
if (res == -EINTR && //
(_weaken(pthread_testcancel_np) && //
_weaken(pthread_testcancel_np))) {
_weaken(pthread_testcancel_np)())) {
return ecanceled();
}
return _sysret(res);
Expand Down
17 changes: 15 additions & 2 deletions libc/calls/clock_nanosleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/runtime/clktck.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/consts/timer.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/thread.h"

static int sys_clock_nanosleep(int clock, int flags, //
const struct timespec *req,
Expand All @@ -45,6 +48,16 @@ static int sys_clock_nanosleep(int clock, int flags, //
} else {
rc = enosys();
}
if (rc > 0) {
errno = rc;
rc = -1;
}
// system call support might not detect cancelation on bsds
if (rc == -1 && errno == EINTR && //
_weaken(pthread_testcancel_np) && //
_weaken(pthread_testcancel_np)()) {
rc = ecanceled();
}
END_CANCELATION_POINT;
STRACE("sys_clock_nanosleep(%s, %s, %s, [%s]) → %d% m",
DescribeClockName(clock), DescribeSleepFlags(flags),
Expand All @@ -62,11 +75,11 @@ static int cosmo_clock_nanosleep(int clock, int flags,
if (clock == CLOCK_REALTIME || //
clock == CLOCK_REALTIME_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_REALTIME_PRECISE;
sleep_clock = CLOCK_REALTIME;
} else if (clock == CLOCK_MONOTONIC || //
clock == CLOCK_MONOTONIC_PRECISE) {
time_clock = clock;
sleep_clock = CLOCK_MONOTONIC_PRECISE;
sleep_clock = CLOCK_MONOTONIC;
} else if (clock == CLOCK_REALTIME_COARSE || //
clock == CLOCK_REALTIME_FAST) {
return sys_clock_nanosleep(CLOCK_REALTIME, flags, req, rem);
Expand Down
20 changes: 19 additions & 1 deletion libc/calls/sigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/limits.h"
#include "libc/sysv/consts/sa.h"
Expand Down Expand Up @@ -70,6 +71,10 @@ static void sigaction_cosmo2native(union metasigaction *sa) {
sa->linux.sa_restorer = restorer;
sa->linux.sa_mask[0] = masklo;
sa->linux.sa_mask[1] = maskhi;
} else if (IsXnuSilicon()) {
sa->silicon.sa_flags = flags;
sa->silicon.sa_handler = handler;
sa->silicon.sa_mask[0] = masklo;
} else if (IsXnu()) {
sa->xnu_in.sa_flags = flags;
sa->xnu_in.sa_handler = handler;
Expand Down Expand Up @@ -109,6 +114,10 @@ static void sigaction_native2cosmo(union metasigaction *sa) {
restorer = sa->linux.sa_restorer;
masklo = sa->linux.sa_mask[0];
maskhi = sa->linux.sa_mask[1];
} else if (IsXnu()) {
flags = sa->silicon.sa_flags;
handler = sa->silicon.sa_handler;
masklo = sa->silicon.sa_mask[0];
} else if (IsXnu()) {
flags = sa->xnu_out.sa_flags;
handler = sa->xnu_out.sa_handler;
Expand Down Expand Up @@ -142,6 +151,7 @@ static int __sigaction(int sig, const struct sigaction *act,
(sizeof(struct sigaction) >= sizeof(struct sigaction_linux) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_in) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_xnu_out) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_silicon) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_freebsd) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_openbsd) &&
sizeof(struct sigaction) >= sizeof(struct sigaction_netbsd)),
Expand Down Expand Up @@ -193,6 +203,9 @@ static int __sigaction(int sig, const struct sigaction *act,
// mitigate Rosetta signal handling strangeness
// https://github.com/jart/cosmopolitan/issues/455
ap->sa_flags |= SA_SIGINFO;
} else if (IsXnu()) {
sigenter = __sigenter_xnu;
ap->sa_flags |= SA_SIGINFO; // couldn't hurt
} else if (IsNetbsd()) {
sigenter = __sigenter_netbsd;
} else if (IsFreebsd()) {
Expand Down Expand Up @@ -231,7 +244,12 @@ static int __sigaction(int sig, const struct sigaction *act,
arg4 = 8; /* or linux whines */
arg5 = 0;
}
if ((rc = sys_sigaction(sig, ap, oldact, arg4, arg5)) != -1) {
if (!IsXnuSilicon()) {
rc = sys_sigaction(sig, ap, oldact, arg4, arg5);
} else {
rc = _sysret(__syslib->__sigaction(sig, ap, oldact));
}
if (rc != -1) {
sigaction_native2cosmo((union metasigaction *)oldact);
}
} else {
Expand Down
11 changes: 10 additions & 1 deletion libc/calls/sigaltstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/consts/ss.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/tls.h"
Expand Down Expand Up @@ -82,9 +83,17 @@ static textwindows int sigaltstack_cosmo(const struct sigaltstack *neu,

static int sigaltstack_bsd(const struct sigaltstack *neu,
struct sigaltstack *old) {
int rc;
struct sigaltstack_bsd oldbsd, neubsd, *neup = 0;
if (neu) sigaltstack2bsd(&neubsd, neu), neup = &neubsd;
if (sys_sigaltstack(neup, &oldbsd) == -1) return -1;
if (IsXnuSilicon()) {
rc = _sysret(__syslib->__sigaltstack(neup, &oldbsd));
} else {
rc = sys_sigaltstack(neup, &oldbsd);
}
if (rc == -1) {
return -1;
}
if (old) sigaltstack2linux(old, &oldbsd);
return 0;
}
Expand Down
16 changes: 6 additions & 10 deletions libc/calls/sigenter-xnu.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,14 @@ static privileged void linuxssefpustate2xnu(

#endif /* __x86_64__ */

#ifdef __x86_64__
privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
struct siginfo_xnu *xnuinfo,
struct __darwin_ucontext *xnuctx) {
#else
privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
struct __darwin_ucontext *xnuctx) {
#endif
#pragma GCC push_options
#pragma GCC diagnostic ignored "-Wframe-larger-than="
struct Goodies {
Expand Down Expand Up @@ -579,15 +584,6 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
: "=a"(ax)
: "0"(0x20000b8 /* sigreturn */), "D"(xnuctx), "S"(infostyle)
: "rcx", "r11", "memory", "cc");
#else
register long r0 asm("x0") = (long)xnuctx;
register long r1 asm("x1") = (long)infostyle;
asm volatile("mov\tx16,%0\n\t"
"svc\t0"
: /* no outputs */
: "i"(0x0b8 /* sigreturn */), "r"(r0), "r"(r1)
: "x16", "memory");
#endif /* __x86_64__ */

notpossible;
#endif /* __x86_64__ */
}
25 changes: 19 additions & 6 deletions libc/calls/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,45 @@
│ PERFORMANCE OF THIS SOFTWARE. │
╚─────────────────────────────────────────────────────────────────────────────*/
#include "libc/assert.h"
#include "libc/calls/blockcancel.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/limits.h"
#include "libc/sysv/consts/clock.h"
#include "libc/thread/posixthread.internal.h"
#include "libc/thread/thread.h"
#include "libc/time/time.h"

/**
* Sleeps for particular number of seconds.
*
* This function may be canceled except when using masked mode in which
* case cancelation is temporarily disabled, because there is no way to
* report the ECANCELED state.
*
* @return 0 if the full time elapsed, otherwise we assume an interrupt
* was delivered, in which case the errno condition is ignored, and
* this function shall return the number of unslept seconds rounded
* using the ceiling function, and finally `-1u` may be returned if
* thread was cancelled with `PTHREAD_CANCEL_MASKED` in play
* using the ceiling function
* @see clock_nanosleep()
* @cancelationpoint
* @asyncsignalsafe
* @norestart
*/
unsigned sleep(unsigned seconds) {
errno_t rc;
int cs = -1;
errno_t err;
unsigned unslept;
struct timespec tv = {seconds};
if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, &tv, &tv))) return 0;
if (rc == ECANCELED) return -1u;
npassert(rc == EINTR);
if (_pthread_self()->pt_flags & PT_MASKED) {
cs = _pthread_block_cancelation();
}
err = clock_nanosleep(CLOCK_REALTIME, 0, &tv, &tv);
if (cs != -1) {
_pthread_allow_cancelation(cs);
}
if (!err) return 0;
unassert(err == EINTR);
unslept = tv.tv_sec;
if (tv.tv_nsec && unslept < UINT_MAX) {
++unslept;
Expand Down
7 changes: 7 additions & 0 deletions libc/calls/struct/sigaction.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ struct sigaction_netbsd {
uint32_t sa_flags;
};

struct sigaction_silicon {
void *sa_handler;
uint32_t sa_mask[1];
uint32_t sa_flags;
};

struct sigaction_xnu_in {
void *sa_handler;
void *sa_restorer;
Expand All @@ -50,6 +56,7 @@ union metasigaction {
struct sigaction_freebsd freebsd;
struct sigaction_openbsd openbsd;
struct sigaction_netbsd netbsd;
struct sigaction_silicon silicon;
struct sigaction_xnu_in xnu_in;
struct sigaction_xnu_out xnu_out;
};
Expand Down
Loading

0 comments on commit 9d372f4

Please sign in to comment.