Advance redbear-full Wayland, greeter, and Qt integration
Consolidate the active desktop path around redbear-full while landing the greeter/session stack and the runtime fixes needed to keep Wayland and KWin bring-up moving forward.
This commit is contained in:
@@ -7,6 +7,7 @@ patches = [
|
||||
"../../../local/patches/relibc/P3-signalfd.patch",
|
||||
"../../../local/patches/relibc/P3-signalfd-header.patch",
|
||||
"../../../local/patches/relibc/P3-timerfd.patch",
|
||||
"../../../local/patches/relibc/P3-elf64-types.patch",
|
||||
]
|
||||
|
||||
[build]
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../local/recipes/system/redbear-authd
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../local/recipes/system/redbear-greeter
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../local/recipes/system/redbear-session-launch
|
||||
+10
-9
@@ -48,8 +48,9 @@ recipes/wip/
|
||||
│ ├── wlroots/ # wlroots (not compiled/tested)
|
||||
│ ├── sway/ # sway (not compiled/tested)
|
||||
│ ├── hyprland/ # hyprland (not compiled/tested)
|
||||
│ ├── xwayland/ # XWayland (partially patched)
|
||||
│ └── seatd/ # Seat daemon (recipe exists, untested)
|
||||
│ └── xwayland/ # XWayland (partially patched)
|
||||
├── services/
|
||||
│ └── seatd/ # Seat daemon recipe (service category, runtime trust still open)
|
||||
├── kde/ # 9 KDE app recipes
|
||||
│ ├── kde-dolphin/ # File manager (needs kio)
|
||||
│ ├── kdenlive/ # Video editor (needs MLT)
|
||||
@@ -67,21 +68,21 @@ recipes/wip/
|
||||
|
||||
| Task | Location |
|
||||
|------|----------|
|
||||
| Fix Wayland build | `wayland/libwayland/redox.patch` — still carries POSIX compatibility workarounds |
|
||||
| Fix Wayland build | `wayland/libwayland/redox.patch` plus recipe-time source rewrites — residual Redox compatibility and scanner/build handling remain |
|
||||
| Add Wayland compositor | `wayland/<name>/recipe.toml` — use `dependencies = ["libwayland"]` |
|
||||
| Fix cosmic-comp | `wayland/cosmic-comp/` — missing libinput causes no keyboard |
|
||||
| Work on smallvil | `wayland/smallvil/` — Smithay-based, already running |
|
||||
| Inspect cosmic-comp status | `wayland/cosmic-comp/` — historical partial bring-up; not the active forward path |
|
||||
| Inspect smallvil history | `wayland/smallvil/` — historical bounded validation compositor reference only |
|
||||
| Port a KDE app | Copy existing recipe pattern, add `#TODO` header |
|
||||
| Add Qt port | Prefer the newer `local/recipes/qt/` / `local/recipes/kde/` work over this older note |
|
||||
|
||||
## WAYLAND STATUS
|
||||
|
||||
- **libwayland**: Builds with `redox.patch`; several POSIX-dependent code paths are still commented out there
|
||||
- **cosmic-comp**: Partially working, no keyboard input (missing libinput)
|
||||
- **smallvil**: Basic compositor running, poor performance
|
||||
- **libwayland**: Builds with a smaller Redox patch plus recipe-time source rewriting; runtime trust is still incomplete
|
||||
- **cosmic-comp**: Historical partial bring-up note only; current runtime/session status is not trusted enough for support claims
|
||||
- **smallvil**: Historical bounded validation compositor reference only; no longer part of the active forward desktop workflow
|
||||
- **wlroots/sway/hyprland**: Not compiled or tested
|
||||
- **xwayland**: Partially patched
|
||||
- **Blockers**: downstream Wayland patch reduction, libinput/runtime input validation, DRM/KMS hardware/runtime validation
|
||||
- **Blockers**: runtime substrate trust, complete compositor session proof, libinput/seatd runtime validation, and DRM/KMS hardware/runtime validation
|
||||
|
||||
## KDE STATUS
|
||||
|
||||
|
||||
@@ -19,8 +19,39 @@ dependencies = [
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
RELIBC_STAGE_INCLUDE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include"
|
||||
RELIBC_STAGE_LIB="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/lib"
|
||||
RELIBC_STAGE_INCLUDE_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include"
|
||||
RELIBC_STAGE_INCLUDE_TMP="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage.tmp/usr/include"
|
||||
RELIBC_STAGE_LIB_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/lib"
|
||||
RELIBC_STAGE_LIB_TMP="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage.tmp/usr/lib"
|
||||
RELIBC_BUILD_LIB="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/build/target/${TARGET}/release"
|
||||
|
||||
RELIBC_STAGE_INCLUDE="$RELIBC_STAGE_INCLUDE_STAGE"
|
||||
if [ ! -d "$RELIBC_STAGE_INCLUDE" ] && [ -d "$RELIBC_STAGE_INCLUDE_TMP" ]; then
|
||||
RELIBC_STAGE_INCLUDE="$RELIBC_STAGE_INCLUDE_TMP"
|
||||
fi
|
||||
|
||||
choose_relibc_lib_stage() {
|
||||
local candidate="$1"
|
||||
if [ -f "$candidate/libc.so" ] && readelf -Ws "$candidate/libc.so" | grep -q '_Z7strtoldPKcPPc'; then
|
||||
printf '%s\n' "$candidate"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
if RELIBC_STAGE_LIB="$(choose_relibc_lib_stage "$RELIBC_STAGE_LIB_STAGE")"; then
|
||||
:
|
||||
elif RELIBC_STAGE_LIB="$(choose_relibc_lib_stage "$RELIBC_STAGE_LIB_TMP")"; then
|
||||
:
|
||||
elif RELIBC_STAGE_LIB="$(choose_relibc_lib_stage "$RELIBC_BUILD_LIB")"; then
|
||||
:
|
||||
elif [ -d "$RELIBC_STAGE_LIB_STAGE" ]; then
|
||||
RELIBC_STAGE_LIB="$RELIBC_STAGE_LIB_STAGE"
|
||||
elif [ -d "$RELIBC_BUILD_LIB" ]; then
|
||||
RELIBC_STAGE_LIB="$RELIBC_BUILD_LIB"
|
||||
else
|
||||
RELIBC_STAGE_LIB="$RELIBC_STAGE_LIB_TMP"
|
||||
fi
|
||||
if [ -d "${RELIBC_STAGE_INCLUDE}" ]; then
|
||||
mkdir -p "${COOKBOOK_SYSROOT}/include"
|
||||
cp -a "${RELIBC_STAGE_INCLUDE}/." "${COOKBOOK_SYSROOT}/include/"
|
||||
@@ -34,6 +65,24 @@ if [ -d "${RELIBC_STAGE_LIB}" ]; then
|
||||
export LDFLAGS="-L${RELIBC_STAGE_LIB} -Wl,-rpath-link,${RELIBC_STAGE_LIB} ${LDFLAGS}"
|
||||
fi
|
||||
|
||||
cat > strtold_cpp_compat.c <<'EOF'
|
||||
long double strtold(const char *nptr, char **endptr);
|
||||
|
||||
long double relibc_compat_cpp_strtold(const char *nptr, char **endptr)
|
||||
__asm__("_Z7strtoldPKcPPc");
|
||||
|
||||
long double relibc_compat_cpp_strtold(const char *nptr, char **endptr) {
|
||||
return strtold(nptr, endptr);
|
||||
}
|
||||
EOF
|
||||
"${GNU_TARGET}-gcc" \
|
||||
--sysroot="${COOKBOOK_SYSROOT}" \
|
||||
-shared -fPIC strtold_cpp_compat.c \
|
||||
-o "${COOKBOOK_SYSROOT}/lib/libredbear-qt-strtold-compat.so"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib"
|
||||
cp -f "${COOKBOOK_SYSROOT}/lib/libredbear-qt-strtold-compat.so" "${COOKBOOK_STAGE}/usr/lib/"
|
||||
export LDFLAGS="${LDFLAGS} -Wl,--no-as-needed -L${COOKBOOK_SYSROOT}/lib -lredbear-qt-strtold-compat"
|
||||
|
||||
export CFLAGS="${CFLAGS} -fcf-protection=none"
|
||||
export CXXFLAGS="${CXXFLAGS} -fcf-protection=none"
|
||||
|
||||
|
||||
@@ -320,17 +320,76 @@ diff -ruwN source-old/src/corelib/plugin/qelfparser_p.cpp source/src/corelib/plu
|
||||
return header.e_version == EV_CURRENT;
|
||||
}
|
||||
|
||||
@@ -742,7 +752,9 @@
|
||||
|
||||
qEDebug << ElfHeaderDebug{ reinterpret_cast<const uchar *>(data.data()) };
|
||||
|
||||
- auto header = reinterpret_cast<const T::Ehdr *>(data.data());
|
||||
+ typename T::Ehdr headerStorage;
|
||||
+ memcpy(&headerStorage, data.data(), sizeof(headerStorage));
|
||||
+ const auto header = &headerStorage;
|
||||
if (!ElfHeaderCheck<>::checkHeader(*header))
|
||||
return error(ElfHeaderCheck<>::explainCheckFailure(*header));
|
||||
|
||||
diff -ruwN source-old/src/corelib/plugin/qlibrary.cpp source/src/corelib/plugin/qlibrary.cpp
|
||||
--- source-old/src/corelib/plugin/qlibrary.cpp 2024-12-02 05:39:06.000000000 +0000
|
||||
+++ source/src/corelib/plugin/qlibrary.cpp 2026-04-16 00:00:00.000000000 +0000
|
||||
@@ -232,24 +232,37 @@
|
||||
+++ source/src/corelib/plugin/qlibrary.cpp 2026-04-19 00:00:00.000000000 +0000
|
||||
@@ -17,6 +17,10 @@
|
||||
#include <qoperatingsystemversion.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
+#ifdef Q_OS_REDOX
|
||||
+# include <unistd.h>
|
||||
+#endif
|
||||
+
|
||||
#ifdef Q_OS_DARWIN
|
||||
# include <private/qcore_mac_p.h>
|
||||
#endif
|
||||
@@ -176,7 +180,14 @@
|
||||
to it being used in the plugin in the first place.
|
||||
*/
|
||||
#if defined(Q_OF_ELF)
|
||||
+# if defined(Q_OS_REDOX)
|
||||
+ // Redox currently reaches the plugin file successfully but the ELF-specific
|
||||
+ // metadata parser misreads shared plugins inside the guest runtime. Fall
|
||||
+ // back to the generic QTMETADATA search path until the Redox ELF loader /
|
||||
+ // parser path is trustworthy again.
|
||||
+# else
|
||||
return QElfParser::parse({s, s_len}, errMsg);
|
||||
+# endif
|
||||
#elif defined(Q_OF_MACH_O)
|
||||
return QMachOParser::parse(s, s_len, errMsg);
|
||||
#elif defined(Q_OS_WIN) || defined(Q_OS_CYGWIN)
|
||||
@@ -230,7 +234,41 @@
|
||||
Q_INT64_C(1) << (sizeof(qsizetype) > 4 ? 40 : 29);
|
||||
|
||||
qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize);
|
||||
- const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen));
|
||||
+ const char *filedata = nullptr;
|
||||
+ QByteArray data;
|
||||
+
|
||||
+#ifdef Q_OS_REDOX
|
||||
+ data = file.read(qMin<qsizetype>(fdlen, 64 * 1024 * 1024));
|
||||
+ const qsizetype readLimit = qMin<qsizetype>(fdlen, 64 * 1024 * 1024);
|
||||
+ data.resize(readLimit);
|
||||
+ qsizetype total = 0;
|
||||
+ const int fd = file.handle();
|
||||
+ if (fd < 0) {
|
||||
+ qCWarning(qt_lcDebugPlugins, "%ls: failed to acquire file descriptor: %ls",
|
||||
+ qUtf16Printable(library), qUtf16Printable(file.errorString()));
|
||||
+ return {};
|
||||
+ }
|
||||
+ while (total < readLimit) {
|
||||
+ const qint64 chunk = ::pread(fd, data.data() + total, size_t(readLimit - total), off_t(total));
|
||||
+ if (chunk < 0) {
|
||||
+ qCWarning(qt_lcDebugPlugins, "%ls: failed to pread for metadata scan: %ls",
|
||||
+ qUtf16Printable(library), qUtf16Printable(qt_error_string(errno)));
|
||||
+ return {};
|
||||
+ }
|
||||
+ if (chunk == 0)
|
||||
+ break;
|
||||
+ total += chunk;
|
||||
+ }
|
||||
+ data.truncate(total);
|
||||
+ filedata = data.constData();
|
||||
+ fdlen = data.size();
|
||||
+ if (filedata == nullptr || fdlen == 0) {
|
||||
@@ -344,10 +403,7 @@ diff -ruwN source-old/src/corelib/plugin/qlibrary.cpp source/src/corelib/plugin/
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
if (filedata == nullptr) {
|
||||
// If we can't mmap(), then the dynamic loader won't be able to either.
|
||||
// This can't be used as a plugin.
|
||||
qCWarning(qt_lcDebugPlugins, "%ls: failed to map to memory: %ls",
|
||||
qUtf16Printable(library), qUtf16Printable(file.errorString()));
|
||||
@@ -241,7 +279,6 @@
|
||||
return {};
|
||||
}
|
||||
#else
|
||||
@@ -355,14 +411,6 @@ diff -ruwN source-old/src/corelib/plugin/qlibrary.cpp source/src/corelib/plugin/
|
||||
if (filedata == nullptr) {
|
||||
// It's unknown at this point whether Windows supports LoadLibrary() on
|
||||
// files that fail to CreateFileMapping / MapViewOfFile, so we err on
|
||||
// the side of doing a regular read into memory (up to 64 MB).
|
||||
data = file.read(64 * 1024 * 1024);
|
||||
filedata = data.constData();
|
||||
fdlen = data.size();
|
||||
}
|
||||
#endif
|
||||
|
||||
QString errMsg = library;
|
||||
|
||||
diff -ruwN source-old/src/corelib/global/qsimd.cpp source/src/corelib/global/qsimd.cpp
|
||||
--- source-old/src/corelib/global/qsimd.cpp 2024-12-02 05:39:06.000000000 +0000
|
||||
|
||||
@@ -226,4 +226,12 @@ if [ -d "${COOKBOOK_STAGE}/usr/qml" ]; then
|
||||
mkdir -p "${SYSROOT}/qml"
|
||||
cp -a "${COOKBOOK_STAGE}/usr/qml/"* "${SYSROOT}/qml/" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
for stdlib in \
|
||||
"${COOKBOOK_STAGE}/usr/include/stdlib.h" \
|
||||
"${SYSROOT}/include/stdlib.h" \
|
||||
"${SYSROOT}/usr/include/stdlib.h"; do
|
||||
[ -f "$stdlib" ] || continue
|
||||
sed -i '/strtold[[:space:]]*(/d' "$stdlib" 2>/dev/null || true
|
||||
done
|
||||
"""
|
||||
|
||||
@@ -28,9 +28,9 @@ if [ -d "${QTBASE_BUILD_INCLUDE}/6.11.0/QtGui/rhi" ]; then
|
||||
mkdir -p "${COOKBOOK_SYSROOT}/include"
|
||||
cp -a "${QTBASE_BUILD_INCLUDE}/6.11.0/QtGui/rhi" "${COOKBOOK_SYSROOT}/include/"
|
||||
fi
|
||||
export CPPFLAGS="${CPPFLAGS} -I${COOKBOOK_SYSROOT}/include -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
export CFLAGS="${CFLAGS} -I${COOKBOOK_SYSROOT}/include -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
export CXXFLAGS="${CXXFLAGS} -I${COOKBOOK_SYSROOT}/include -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
export CPPFLAGS="${CPPFLAGS} -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
export CFLAGS="${CFLAGS} -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
export CXXFLAGS="${CXXFLAGS} -I${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui"
|
||||
|
||||
python - <<'PY'
|
||||
import os
|
||||
@@ -185,10 +185,10 @@ cmake "${COOKBOOK_SOURCE}" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_PREFIX_PATH="${COOKBOOK_SYSROOT}" \
|
||||
-DCMAKE_C_STANDARD_INCLUDE_DIRECTORIES="${COOKBOOK_SYSROOT}/include;${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui" \
|
||||
-DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES="${COOKBOOK_SYSROOT}/include;${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui" \
|
||||
-DCMAKE_C_STANDARD_INCLUDE_DIRECTORIES="${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui" \
|
||||
-DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES="${COOKBOOK_SYSROOT}/include/QtGui/6.11.0/QtGui" \
|
||||
-DCMAKE_C_FLAGS="${CFLAGS}" \
|
||||
-DCMAKE_CXX_FLAGS="${CXXFLAGS} -I${COOKBOOK_SYSROOT}/include" \
|
||||
-DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
|
||||
-DQT_BUILD_EXAMPLES=OFF \
|
||||
-DQT_BUILD_TESTS=OFF \
|
||||
-DQT_GENERATE_SBOM=OFF \
|
||||
|
||||
@@ -15,10 +15,24 @@ dependencies = [
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
if [ -d "${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include" ]; then
|
||||
RELIBC_INCLUDE_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include"
|
||||
if [ ! -f "${RELIBC_INCLUDE_STAGE}/sys/signalfd.h" ]; then
|
||||
RELIBC_INCLUDE_STAGE="${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage.tmp/usr/include"
|
||||
fi
|
||||
|
||||
if [ -d "${RELIBC_INCLUDE_STAGE}" ]; then
|
||||
mkdir -p "${COOKBOOK_SYSROOT}/include" "${COOKBOOK_SYSROOT}/usr/include"
|
||||
cp -a "${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include/." "${COOKBOOK_SYSROOT}/include/"
|
||||
cp -a "${COOKBOOK_ROOT}/recipes/core/relibc/target/${TARGET}/stage/usr/include/." "${COOKBOOK_SYSROOT}/usr/include/"
|
||||
cp -a "${RELIBC_INCLUDE_STAGE}/." "${COOKBOOK_SYSROOT}/include/"
|
||||
cp -a "${RELIBC_INCLUDE_STAGE}/." "${COOKBOOK_SYSROOT}/usr/include/"
|
||||
mkdir -p "${COOKBOOK_SYSROOT}/include/sys" "${COOKBOOK_SYSROOT}/usr/include/sys"
|
||||
for header in signalfd.h timerfd.h eventfd.h; do
|
||||
if [ -f "${RELIBC_INCLUDE_STAGE}/sys/${header}" ]; then
|
||||
cp -f "${RELIBC_INCLUDE_STAGE}/sys/${header}" \
|
||||
"${COOKBOOK_SYSROOT}/include/sys/${header}"
|
||||
cp -f "${RELIBC_INCLUDE_STAGE}/sys/${header}" \
|
||||
"${COOKBOOK_SYSROOT}/usr/include/sys/${header}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
python - <<'PY'
|
||||
@@ -45,44 +59,159 @@ event_text = event_loop.read_text()
|
||||
event_text = event_text.replace(
|
||||
'''#include <sys/epoll.h>
|
||||
#ifdef __redox__
|
||||
#include <sys/types.h>
|
||||
#ifndef SFD_CLOEXEC
|
||||
#define SFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
#ifndef SFD_NONBLOCK
|
||||
#define SFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
struct signalfd_siginfo {
|
||||
uint8_t pad[128];
|
||||
};
|
||||
int signalfd(int fd, const sigset_t *mask, int flags);
|
||||
#ifndef TFD_CLOEXEC
|
||||
#define TFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
#ifndef TFD_NONBLOCK
|
||||
#define TFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
#ifndef TFD_TIMER_ABSTIME
|
||||
#define TFD_TIMER_ABSTIME TIMER_ABSTIME
|
||||
#endif
|
||||
int timerfd_create(int clockid, int flags);
|
||||
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
#else
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
#endif''',
|
||||
'''#include <sys/epoll.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>''',
|
||||
)
|
||||
event_text = event_text.replace(
|
||||
'''#include <sys/epoll.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>''',
|
||||
'''#include <sys/epoll.h>
|
||||
#ifdef __redox__
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef SFD_CLOEXEC
|
||||
#define SFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
|
||||
#ifndef SFD_NONBLOCK
|
||||
#define SFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
|
||||
struct signalfd_siginfo {
|
||||
uint8_t pad[128];
|
||||
};
|
||||
|
||||
#ifndef TFD_CLOEXEC
|
||||
#define TFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
|
||||
#ifndef TFD_NONBLOCK
|
||||
#define TFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
|
||||
#ifndef TFD_TIMER_ABSTIME
|
||||
#define TFD_TIMER_ABSTIME 0x1
|
||||
#endif
|
||||
|
||||
int signalfd4(int fd, const sigset_t *mask, uintptr_t masksize, int flags);
|
||||
int signalfd(int fd, const sigset_t *mask, uintptr_t masksize);
|
||||
int timerfd_create(int clockid, int flags);
|
||||
int timerfd_gettime(int fd, struct itimerspec *curr);
|
||||
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
|
||||
|
||||
int signalfd4(int fd, const sigset_t *mask, uintptr_t masksize, int flags)
|
||||
{
|
||||
const int supported = SFD_CLOEXEC | SFD_NONBLOCK;
|
||||
int new_fd = fd;
|
||||
|
||||
if ((flags & ~supported) != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (mask == NULL || masksize != sizeof(*mask)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
int oflag = O_RDWR;
|
||||
if (flags & SFD_CLOEXEC)
|
||||
oflag |= O_CLOEXEC;
|
||||
if (flags & SFD_NONBLOCK)
|
||||
oflag |= O_NONBLOCK;
|
||||
new_fd = open("/scheme/event", oflag);
|
||||
if (new_fd < 0)
|
||||
return -1;
|
||||
} else {
|
||||
if ((flags & SFD_CLOEXEC) && fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
|
||||
return -1;
|
||||
if (flags & SFD_NONBLOCK) {
|
||||
int current = fcntl(fd, F_GETFL, 0);
|
||||
if (current < 0)
|
||||
return -1;
|
||||
if (fcntl(fd, F_SETFL, current | O_NONBLOCK) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, mask, NULL) < 0) {
|
||||
if (fd == -1)
|
||||
close(new_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return new_fd;
|
||||
}
|
||||
|
||||
int signalfd(int fd, const sigset_t *mask, uintptr_t masksize)
|
||||
{
|
||||
return signalfd4(fd, mask, masksize, 0);
|
||||
}
|
||||
|
||||
int timerfd_create(int clockid, int flags)
|
||||
{
|
||||
const int supported = TFD_CLOEXEC | TFD_NONBLOCK;
|
||||
int oflag = O_RDWR;
|
||||
char path[64];
|
||||
|
||||
if ((flags & ~supported) != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (flags & TFD_CLOEXEC)
|
||||
oflag |= O_CLOEXEC;
|
||||
if (flags & TFD_NONBLOCK)
|
||||
oflag |= O_NONBLOCK;
|
||||
|
||||
snprintf(path, sizeof(path), "/scheme/time/%d", clockid);
|
||||
return open(path, oflag);
|
||||
}
|
||||
|
||||
int timerfd_gettime(int fd, struct itimerspec *curr)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
|
||||
if (curr == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
curr->it_interval = (struct timespec){0};
|
||||
bytes_read = read(fd, &curr->it_value, sizeof(struct timespec));
|
||||
if (bytes_read != (ssize_t)sizeof(struct timespec)) {
|
||||
if (bytes_read >= 0)
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
|
||||
if (flags & ~TFD_TIMER_ABSTIME) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (new_value == NULL) {
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (old_value != NULL && timerfd_gettime(fd, old_value) < 0)
|
||||
return -1;
|
||||
|
||||
bytes_written = write(fd, &new_value->it_value, sizeof(struct timespec));
|
||||
if (bytes_written != (ssize_t)sizeof(struct timespec)) {
|
||||
if (bytes_written >= 0)
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#include <sys/signalfd.h>
|
||||
#include <sys/timerfd.h>
|
||||
@@ -97,6 +226,45 @@ server_text = server_text.replace(
|
||||
#include <sys/eventfd.h>''',
|
||||
'''#include <fcntl.h>
|
||||
#ifdef __redox__
|
||||
|
||||
#ifndef EFD_CLOEXEC
|
||||
#define EFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
|
||||
#ifndef EFD_NONBLOCK
|
||||
#define EFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
|
||||
#ifndef EFD_SEMAPHORE
|
||||
#define EFD_SEMAPHORE 0x1
|
||||
#endif
|
||||
|
||||
int eventfd(unsigned int initval, int flags)
|
||||
{
|
||||
const int supported = EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE;
|
||||
int oflag = O_RDWR;
|
||||
char path[64];
|
||||
|
||||
if ((flags & ~supported) != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (flags & EFD_CLOEXEC)
|
||||
oflag |= O_CLOEXEC;
|
||||
if (flags & EFD_NONBLOCK)
|
||||
oflag |= O_NONBLOCK;
|
||||
|
||||
snprintf(path, sizeof(path), "/scheme/event/eventfd/%u/%d",
|
||||
initval, (flags & EFD_SEMAPHORE) ? 1 : 0);
|
||||
return open(path, oflag);
|
||||
}
|
||||
#else
|
||||
#include <sys/eventfd.h>
|
||||
#endif''',
|
||||
)
|
||||
server_text = server_text.replace(
|
||||
'''#include <fcntl.h>
|
||||
#ifdef __redox__
|
||||
#ifndef EFD_CLOEXEC
|
||||
#define EFD_CLOEXEC O_CLOEXEC
|
||||
#endif
|
||||
@@ -106,6 +274,32 @@ server_text = server_text.replace(
|
||||
int eventfd(unsigned int initval, int flags);
|
||||
#else
|
||||
#include <sys/eventfd.h>
|
||||
#endif''',
|
||||
'''#include <fcntl.h>
|
||||
#ifdef __redox__
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
int eventfd(unsigned int initval, int flags)
|
||||
{
|
||||
const int supported = EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE;
|
||||
int oflag = O_RDWR;
|
||||
char path[64];
|
||||
|
||||
if ((flags & ~supported) != 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (flags & EFD_CLOEXEC)
|
||||
oflag |= O_CLOEXEC;
|
||||
if (flags & EFD_NONBLOCK)
|
||||
oflag |= O_NONBLOCK;
|
||||
|
||||
snprintf(path, sizeof(path), "/scheme/event/eventfd/%u/%d",
|
||||
initval, (flags & EFD_SEMAPHORE) ? 1 : 0);
|
||||
return open(path, oflag);
|
||||
}
|
||||
#else
|
||||
#include <sys/eventfd.h>
|
||||
#endif''',
|
||||
)
|
||||
server.write_text(server_text)
|
||||
@@ -127,6 +321,42 @@ FILE *open_memstream(char **bufp, size_t *sizep);
|
||||
|
||||
#include "wayland-util.h"''',
|
||||
)
|
||||
connection_text = connection_text.replace(
|
||||
'''void
|
||||
wl_closure_print(struct wl_closure *closure, struct wl_object *target,
|
||||
int send, int discarded, uint32_t (*n_parse)(union wl_argument *arg),
|
||||
const char *queue_name)
|
||||
{
|
||||
int i;''',
|
||||
'''void
|
||||
wl_closure_print(struct wl_closure *closure, struct wl_object *target,
|
||||
int send, int discarded, uint32_t (*n_parse)(union wl_argument *arg),
|
||||
const char *queue_name)
|
||||
{
|
||||
#ifdef __redox__
|
||||
(void)closure;
|
||||
(void)target;
|
||||
(void)send;
|
||||
(void)discarded;
|
||||
(void)n_parse;
|
||||
(void)queue_name;
|
||||
return;
|
||||
#else
|
||||
int i;''',
|
||||
)
|
||||
connection_text = connection_text.replace(
|
||||
''' if (fclose(f) == 0) {
|
||||
fprintf(stderr, "%s", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
}''',
|
||||
''' if (fclose(f) == 0) {
|
||||
fprintf(stderr, "%s", buffer);
|
||||
free(buffer);
|
||||
}
|
||||
#endif
|
||||
}''',
|
||||
)
|
||||
connection.write_text(connection_text)
|
||||
PY
|
||||
|
||||
|
||||
Reference in New Issue
Block a user