milestone: desktop path Phases 1-5
Phase 1 (Runtime Substrate): 4 check binaries, --probe, POSIX tests Phase 2 (Wayland Compositor): bounded scaffold, zero warnings Phase 3 (KWin Session): preflight checker (KWin stub, gated on Qt6Quick) Phase 4 (KDE Plasma): 18 KF6 enabled, preflight checker Phase 5 (Hardware GPU): DRM/firmware/Mesa preflight checker Build: zero warnings, all scripts syntax-clean. Oracle-verified.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
#TODO: Runtime proof requires executing these binaries inside a Red Bear OS Phase 1 validation target.
|
||||
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = ["relibc"]
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
RELIBC_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage"
|
||||
if [ ! -d "${RELIBC_STAGE}/usr" ]; then
|
||||
RELIBC_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage.tmp"
|
||||
fi
|
||||
|
||||
mkdir -p "${COOKBOOK_SYSROOT}"
|
||||
if [ -d "${RELIBC_STAGE}/usr" ]; then
|
||||
rsync -av "${RELIBC_STAGE}/usr/" "${COOKBOOK_SYSROOT}/"
|
||||
fi
|
||||
|
||||
TARGET_CC="${TARGET}-gcc"
|
||||
if ! command -v "${TARGET_CC}" >/dev/null 2>&1; then
|
||||
TARGET_CC="cc"
|
||||
fi
|
||||
|
||||
rsync -av "${COOKBOOK_SOURCE}/" ./
|
||||
make -j "${COOKBOOK_MAKE_JOBS}" \
|
||||
CC="${CC_WRAPPER} ${TARGET_CC}" \
|
||||
CPPFLAGS="-I${COOKBOOK_SYSROOT}/include" \
|
||||
CFLAGS="-O2 -Wall -Wextra -Werror" \
|
||||
LDFLAGS="--sysroot=${COOKBOOK_SYSROOT} -L${COOKBOOK_SYSROOT}/lib"
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/home/user/relibc-phase1-tests"
|
||||
cp -v test_signalfd_wayland test_timerfd_qt6 test_eventfd_qt6 test_shm_open_qt6 \
|
||||
test_sem_open_qt6 test_waitid_qt6 "${COOKBOOK_STAGE}/home/user/relibc-phase1-tests/"
|
||||
"""
|
||||
|
||||
[package]
|
||||
dependencies = ["gcc13"]
|
||||
@@ -0,0 +1,22 @@
|
||||
PROGRAMS = \
|
||||
test_signalfd_wayland \
|
||||
test_timerfd_qt6 \
|
||||
test_eventfd_qt6 \
|
||||
test_shm_open_qt6 \
|
||||
test_sem_open_qt6 \
|
||||
test_waitid_qt6
|
||||
|
||||
CC ?= cc
|
||||
CPPFLAGS ?=
|
||||
CFLAGS ?= -O2 -Wall -Wextra -Werror
|
||||
LDFLAGS ?=
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(PROGRAMS)
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $< -o $@ $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f $(PROGRAMS)
|
||||
Binary file not shown.
@@ -0,0 +1,45 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __redox__
|
||||
#define EFD_CLOEXEC 0x80000
|
||||
#define EFD_NONBLOCK 0x800
|
||||
int eventfd(unsigned int initval, int flags);
|
||||
#else
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL eventfd: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint64_t expected = 42;
|
||||
uint64_t observed = 0;
|
||||
int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
|
||||
|
||||
if (efd < 0) return fail_step("eventfd");
|
||||
if (write(efd, &expected, sizeof(expected)) != (ssize_t)sizeof(expected)) return fail_step("write first");
|
||||
if (read(efd, &observed, sizeof(observed)) != (ssize_t)sizeof(observed)) return fail_step("read first");
|
||||
if (observed != expected) {
|
||||
printf("FAIL eventfd: first read=%llu\n", (unsigned long long)observed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
expected = 7;
|
||||
if (write(efd, &expected, sizeof(expected)) != (ssize_t)sizeof(expected)) return fail_step("write second");
|
||||
if (read(efd, &observed, sizeof(observed)) != (ssize_t)sizeof(observed)) return fail_step("read second");
|
||||
if (observed != expected) {
|
||||
printf("FAIL eventfd: second read=%llu\n", (unsigned long long)observed);
|
||||
return 1;
|
||||
}
|
||||
if (close(efd) < 0) return fail_step("close");
|
||||
|
||||
printf("PASS eventfd\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL sem_open: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
static const char name[] = "/rb_test_sem";
|
||||
char go = 'G';
|
||||
char ready = 0;
|
||||
int child_value = -1;
|
||||
int parent_value = -1;
|
||||
int parent_to_child[2];
|
||||
int value = -1;
|
||||
int sync_pipe[2];
|
||||
int status;
|
||||
sem_t *sem;
|
||||
pid_t child;
|
||||
|
||||
errno = 0;
|
||||
if (sem_unlink(name) < 0 && errno != ENOENT) return fail_step("sem_unlink pre-clean");
|
||||
sem = sem_open(name, O_CREAT, 0666, 0);
|
||||
if (sem == SEM_FAILED) return fail_step("sem_open create");
|
||||
if (sem_getvalue(sem, &value) < 0 || value != 0) {
|
||||
printf("FAIL sem_open: initial value=%d\n", value);
|
||||
return 1;
|
||||
}
|
||||
if (pipe(sync_pipe) < 0) return fail_step("pipe");
|
||||
if (pipe(parent_to_child) < 0) return fail_step("pipe parent_to_child");
|
||||
|
||||
child = fork();
|
||||
if (child < 0) return fail_step("fork");
|
||||
if (child == 0) {
|
||||
ready = 'R';
|
||||
close(sync_pipe[0]);
|
||||
close(parent_to_child[1]);
|
||||
sem_t *child_sem = sem_open(name, 0);
|
||||
if (child_sem == SEM_FAILED) _Exit(1);
|
||||
if (write(sync_pipe[1], &ready, 1) != 1) _Exit(2);
|
||||
if (read(parent_to_child[0], &go, 1) != 1) _Exit(3);
|
||||
if (sem_wait(child_sem) < 0) _Exit(4);
|
||||
if (sem_getvalue(child_sem, &child_value) < 0 || child_value != 0) _Exit(5);
|
||||
if (sem_post(child_sem) < 0) _Exit(6);
|
||||
if (sem_getvalue(child_sem, &child_value) < 0 || child_value != 1) _Exit(7);
|
||||
if (sem_close(child_sem) < 0) _Exit(8);
|
||||
close(parent_to_child[0]);
|
||||
close(sync_pipe[1]);
|
||||
_Exit(0);
|
||||
}
|
||||
|
||||
close(sync_pipe[1]);
|
||||
close(parent_to_child[0]);
|
||||
if (read(sync_pipe[0], &ready, 1) != 1) return fail_step("child ready read");
|
||||
if (sem_post(sem) < 0) return fail_step("parent sem_post");
|
||||
if (sem_getvalue(sem, &parent_value) < 0 || parent_value != 1) {
|
||||
printf("FAIL sem_open: post value=%d\n", parent_value);
|
||||
return 1;
|
||||
}
|
||||
if (write(parent_to_child[1], &go, 1) != 1) return fail_step("release child");
|
||||
if (close(parent_to_child[1]) < 0) return fail_step("close parent_to_child");
|
||||
if (read(sync_pipe[0], &ready, 1) != 0) return fail_step("child completion pipe");
|
||||
if (sem_getvalue(sem, &parent_value) < 0 || parent_value != 1) {
|
||||
printf("FAIL sem_open: child post value=%d\n", parent_value);
|
||||
return 1;
|
||||
}
|
||||
close(sync_pipe[0]);
|
||||
if (sem_wait(sem) < 0) return fail_step("parent sem_wait");
|
||||
if (waitpid(child, &status, 0) < 0) return fail_step("waitpid");
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
printf("FAIL sem_open: child status=%d\n", status);
|
||||
return 1;
|
||||
}
|
||||
if (sem_getvalue(sem, &value) < 0 || value != 0) {
|
||||
printf("FAIL sem_open: final value=%d\n", value);
|
||||
return 1;
|
||||
}
|
||||
if (sem_close(sem) < 0 || sem_unlink(name) < 0) return fail_step("cleanup");
|
||||
|
||||
printf("PASS sem_open\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL shm_open: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
static const char name[] = "/rb_test_shm";
|
||||
uint32_t *first;
|
||||
uint32_t *second;
|
||||
int fd;
|
||||
int second_fd;
|
||||
|
||||
errno = 0;
|
||||
if (shm_unlink(name) < 0 && errno != ENOENT) return fail_step("shm_unlink pre-clean");
|
||||
fd = shm_open(name, O_CREAT | O_RDWR, 0666);
|
||||
if (fd < 0) return fail_step("shm_open");
|
||||
if (ftruncate(fd, 4096) < 0) return fail_step("ftruncate");
|
||||
second_fd = shm_open(name, O_RDWR, 0666);
|
||||
if (second_fd < 0) return fail_step("shm_open reopen");
|
||||
|
||||
first = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (first == MAP_FAILED) return fail_step("mmap first");
|
||||
second = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, second_fd, 0);
|
||||
if (second == MAP_FAILED) return fail_step("mmap second");
|
||||
*first = 0xDEADBEEFU;
|
||||
if (*second != 0xDEADBEEFU) {
|
||||
printf("FAIL shm_open: observed=0x%08X\n", *second);
|
||||
return 1;
|
||||
}
|
||||
if (munmap(second, 4096) < 0) return fail_step("munmap second");
|
||||
if (munmap(first, 4096) < 0) return fail_step("munmap first");
|
||||
if (close(second_fd) < 0) return fail_step("close second");
|
||||
if (close(fd) < 0) return fail_step("close");
|
||||
if (shm_unlink(name) < 0) return fail_step("shm_unlink");
|
||||
|
||||
printf("PASS shm_open\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __redox__
|
||||
struct signalfd_siginfo {
|
||||
uint32_t ssi_signo;
|
||||
int32_t ssi_errno;
|
||||
int32_t ssi_code;
|
||||
uint32_t ssi_pid;
|
||||
uint32_t ssi_uid;
|
||||
int32_t ssi_fd;
|
||||
uint32_t ssi_tid;
|
||||
uint32_t ssi_band;
|
||||
uint32_t ssi_overrun;
|
||||
uint32_t ssi_trapno;
|
||||
int32_t ssi_status;
|
||||
int32_t ssi_int;
|
||||
uint64_t ssi_ptr;
|
||||
uint64_t ssi_utime;
|
||||
uint64_t ssi_stime;
|
||||
uint64_t ssi_addr;
|
||||
uint16_t ssi_addr_lsb, __pad2;
|
||||
int32_t ssi_syscall;
|
||||
uint64_t ssi_call_addr;
|
||||
uint32_t ssi_arch;
|
||||
unsigned char __pad[28];
|
||||
};
|
||||
int signalfd(int fd, const sigset_t *mask, size_t masksize);
|
||||
_Static_assert(sizeof(struct signalfd_siginfo) == 128, "unexpected signalfd_siginfo size");
|
||||
#else
|
||||
#include <sys/signalfd.h>
|
||||
#endif
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL signalfd: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __redox__
|
||||
#define RB_SIGNALFD(fd, mask) signalfd((fd), (mask), sizeof(*(mask)))
|
||||
#else
|
||||
#define RB_SIGNALFD(fd, mask) signalfd((fd), (mask), 0)
|
||||
#endif
|
||||
|
||||
int main(void) {
|
||||
sigset_t mask;
|
||||
sigset_t oldmask;
|
||||
struct signalfd_siginfo info;
|
||||
int sfd;
|
||||
int status;
|
||||
pid_t child;
|
||||
|
||||
if (sigemptyset(&mask) < 0 || sigaddset(&mask, SIGUSR1) < 0) return fail_step("sigset setup");
|
||||
if (sigprocmask(SIG_BLOCK, &mask, &oldmask) < 0) return fail_step("sigprocmask block");
|
||||
sfd = RB_SIGNALFD(-1, &mask);
|
||||
if (sfd < 0) return fail_step("signalfd");
|
||||
|
||||
child = fork();
|
||||
if (child < 0) return fail_step("fork");
|
||||
if (child == 0) {
|
||||
_Exit(kill(getppid(), SIGUSR1) < 0);
|
||||
}
|
||||
|
||||
if (read(sfd, &info, sizeof(info)) != (ssize_t)sizeof(info)) return fail_step("read");
|
||||
if (waitpid(child, &status, 0) < 0) return fail_step("waitpid");
|
||||
if (close(sfd) < 0) return fail_step("close");
|
||||
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) return fail_step("sigprocmask restore");
|
||||
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
printf("FAIL signalfd: child status=%d\n", status);
|
||||
return 1;
|
||||
}
|
||||
if (info.ssi_signo != (uint32_t)SIGUSR1) {
|
||||
printf("FAIL signalfd: ssi_signo=%u\n", info.ssi_signo);
|
||||
return 1;
|
||||
}
|
||||
if (info.ssi_code != SI_USER) {
|
||||
printf("FAIL signalfd: ssi_code=%d\n", info.ssi_code);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS signalfd\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef __redox__
|
||||
#define TFD_NONBLOCK 0x800
|
||||
int timerfd_create(clockid_t clockid, int flags);
|
||||
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
|
||||
#else
|
||||
#include <sys/timerfd.h>
|
||||
#endif
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL timerfd: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct timespec pause = {.tv_sec = 0, .tv_nsec = 20000000};
|
||||
struct itimerspec spec = {{0, 0}, {0, 100000000}};
|
||||
uint64_t expirations = 0;
|
||||
int tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
||||
|
||||
if (tfd < 0) return fail_step("timerfd_create");
|
||||
if (timerfd_settime(tfd, 0, &spec, NULL) < 0) return fail_step("timerfd_settime");
|
||||
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
ssize_t n = read(tfd, &expirations, sizeof(expirations));
|
||||
if (n == (ssize_t)sizeof(expirations)) {
|
||||
if (expirations >= 1) {
|
||||
if (close(tfd) < 0) return fail_step("close");
|
||||
printf("PASS timerfd\n");
|
||||
return 0;
|
||||
}
|
||||
printf("FAIL timerfd: expirations=%llu\n", (unsigned long long)expirations);
|
||||
return 1;
|
||||
}
|
||||
if (n >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) return fail_step("read");
|
||||
nanosleep(&pause, NULL);
|
||||
}
|
||||
|
||||
printf("FAIL timerfd: timeout waiting for expiration\n");
|
||||
return 1;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int fail_step(const char *step) {
|
||||
printf("FAIL waitid: %s (errno=%d)\n", step, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
siginfo_t info = {0};
|
||||
pid_t child = fork();
|
||||
|
||||
if (child < 0) return fail_step("fork");
|
||||
if (child == 0) _Exit(42);
|
||||
if (waitid(P_PID, child, &info, WEXITED) < 0) return fail_step("waitid");
|
||||
if (info.si_code != CLD_EXITED) {
|
||||
printf("FAIL waitid: si_code=%d\n", info.si_code);
|
||||
return 1;
|
||||
}
|
||||
if (info.si_status != 42) {
|
||||
printf("FAIL waitid: si_status=%d\n", info.si_status);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS waitid\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user