Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
e233f6a
Sessions that come back, own keys, pinch zoom, SSH server, web server…
claude Oct 24, 2026
0a52b5c
Native extractor: read a .tar.zst to its end, so that zstd checks its…
claude Oct 24, 2026
575bb78
Emulator test: export ssh_login, which expect runs in a new bash
claude Oct 24, 2026
35abde8
Emulator test: align cortex-emu-runner for 16 KB pages
claude Oct 24, 2026
49164be
Native extractor: decompress a .tar.zst on a thread of its own
claude Oct 24, 2026
ba1a75e
Hook: the app's files are root's in stat(), as the programs are root
claude Oct 24, 2026
6e98a24
Changelog: git's ownership check is fixed, not restored
claude Oct 24, 2026
45ecea3
Hook: accept() as accept4(), the call Android's seccomp filter is mad…
claude Oct 24, 2026
9a61e5b
Emulator test: time limits on adb, no packages on the 16 KB image
claude Oct 24, 2026
cc7e60a
Hook: sshd's privilege-separated user has root's ids
claude Oct 24, 2026
5f7e2fc
Hook: the fortified getgroups and recvfrom go through it too
claude Oct 24, 2026
2f15a34
Changelog: the emulator test's 16 KB run, ownership check and adb limits
claude Oct 24, 2026
1d4ffa7
Hook: sandbox limits that take away descriptors are not applied
claude Oct 24, 2026
c521330
Hook: closefrom() and close_range() leave the ARM translator's memory…
claude Oct 24, 2026
3993d55
Hook: know the ARM translator's memory file by its name
claude Oct 24, 2026
ce61c6e
Emulator test: record what a program sees of its executable and descr…
claude Oct 24, 2026
9054195
Static Go programs see the rootfs: Ubuntu's paths and programs for Go
claude Oct 25, 2026
f3cbede
Merge the Go support onto the branch's merged history (v1.26.38 was s…
claude Oct 25, 2026
fcb2f3b
A new look around the terminal: tabs, themed keys and drawer, seven m…
claude Oct 25, 2026
649be84
Scroll position and a way back to the end, a themed first-start dialo…
claude Oct 25, 2026
545da3c
Go programs patched in normal mode keep working in root mode; README
claude Oct 25, 2026
ce39a5b
Website and README: Go programs no longer need root mode; tabs and co…
claude Oct 25, 2026
ddd5c33
Tests: the tabs, keys, search bar, layouts, first-start dialog and sc…
claude Oct 25, 2026
721e363
Go programs: CORTEX_NO_GOSYS switch and an unpatched control in the e…
claude Oct 25, 2026
7812fe5
Settings theme: the interface's own containers and outline colors, no…
claude Oct 25, 2026
adc951a
Emulator test: a second session is started, and the scheme picker is …
claude Oct 25, 2026
ef79aa8
Scheme picker in the interface's colors; the emulator test retries op…
claude Oct 25, 2026
7b079fa
README and website: screenshots of the new interface, and the scheme …
claude Oct 25, 2026
56e138d
Package compatibility run: apt-get is not started by timeout in the b…
claude Oct 25, 2026
2316c10
Version 1.26.39: Go programs see Ubuntu, session tabs, seven more col…
claude Oct 25, 2026
cd303dd
Hook: Rust programs no longer crash in statx; reading /proc/self/fd o…
claude Oct 25, 2026
7d467e2
Merge the branch's merged history (PR #28 was squashed into main)
claude Oct 25, 2026
c39b5f5
Hook: shadow database and SELinux for Ubuntu's programs, the translat…
claude Oct 25, 2026
af04acc
Fix unclosed Kotlin comment in BaseUsers KDoc
claude Oct 25, 2026
4bc81d7
Version 1.26.40: faster program starts, sudo/su without root, Rust, r…
claude Oct 25, 2026
f98f6a1
Compat run: a MariaDB row; docs say MariaDB and redis run
claude Oct 25, 2026
958bd68
Emulator test: base users and groups, sudo
claude Oct 25, 2026
f1101fc
A color scheme chosen later reaches the cells of the sessions (#29)
claude Oct 25, 2026
29310aa
Review fixes: scheme remap by role, slots of vfork children given bac…
claude Oct 25, 2026
a56e0f4
Merge the branch's merged history (PR #31 was squashed into main)
claude Oct 26, 2026
5fedf73
No more ~/storage link to the shared storage (1.26.41)
claude Oct 26, 2026
bcb86ef
Fix the unclosed comment in the storage-link KDoc; test that no Kotli…
claude Oct 26, 2026
0803909
Test that a ~/storage link to another place is left alone
claude Oct 26, 2026
2474682
Start the next change from main
claude Oct 26, 2026
8cc804b
New app icon, held backspace keeps deleting, copy bar in the right pl…
claude Oct 26, 2026
5c9e1af
Chinese, Japanese, Korean and emoji take two cells instead of overlap…
claude Oct 27, 2026
0d6afc9
Start the next change from main
claude Oct 27, 2026
c5829ae
Fix a half left behind after inserting over a wide character; keep th…
claude Oct 27, 2026
f46bd24
Copy: a selection that ends on the first half of an emoji takes the w…
claude Oct 27, 2026
de3b864
Wide characters: mark the wrap padding, blank halves fully, cut copy;…
claude Oct 27, 2026
c9eb9df
Start the next change from main
claude Oct 27, 2026
4ae2b29
A cleaner drawer and tabs, and a white color scheme; 1.26.44
claude Oct 27, 2026
abc4169
Test the session tabs row by row, and their screen reader labels
claude Oct 27, 2026
515d3c7
Settings: the back arrow follows the color scheme
claude Oct 27, 2026
1d22b55
e2e: scroll the settings list all the way up before choosing the whit…
claude Oct 27, 2026
73f39f1
e2e: give the terminal the focus before typing in the second session
claude Oct 27, 2026
ed8ea5e
Hook: the real path of an open file keeps the rootfs in front of it
claude Oct 27, 2026
a72c5b1
Terminal: a character of the supplementary planes that wcwidth() give…
claude Oct 27, 2026
e6cfa61
Test: compare the colors with the ones the escape codes set
claude Oct 27, 2026
662a6ea
Review: fd links only for fd/N, the root tab says root, a plain curso…
claude Oct 27, 2026
07ce921
e2e: pictures for the README (neofetch, the end of the settings)
claude Oct 27, 2026
0d655de
Merge the earlier history of this branch (squash-merged as #37)
claude Oct 27, 2026
6157483
README and website: the session cards have no directory in their pict…
claude Oct 27, 2026
9b39eb7
e2e: neofetch for the README with the small logo and lines that fit
claude Oct 27, 2026
9d4fb47
tests/e2e: a script that makes the README's pictures from an emulator…
claude Oct 27, 2026
d085168
e2e: neofetch for the README without the emulator's model and archite…
claude Oct 27, 2026
dc33763
README and website pictures from the 1.26.44 emulator run
claude Oct 27, 2026
a342bd2
e2e: the neofetch picture only after a successful install and a finis…
claude Oct 27, 2026
bf700b5
The keyboard's Select all, Copy, Cut and Paste work in the terminal, …
claude Oct 28, 2026
94fc8d4
Merge the earlier history of this branch (squash-merged as #37 and #38)
claude Oct 28, 2026
c09f130
Review: Cut also does what delete does, the selection is the session'…
claude Oct 28, 2026
b3c825a
Review: the selected text is read under the emulator's lock
claude Oct 28, 2026
9855312
Go programs built for Android get Cortex's change, micro no longer ha…
ssfuisu Oct 30, 2026
4a0c199
Merge the earlier history of this branch (squash-merged as #37, #38, …
ssfuisu Oct 30, 2026
08c6397
Review: a clipboard note from the future is ignored, a timed-out clip…
ssfuisu Oct 30, 2026
372d6bc
The clipboard commands keep their deadline inside cortex-api (read -t…
ssfuisu Oct 30, 2026
49e591b
A directory that has lost its owner's rights is repaired when a name …
ssfuisu Oct 31, 2026
b0a4808
Merge the earlier history of this branch (squash-merged as #45)
ssfuisu Oct 31, 2026
2435128
The directory repair test also runs as a user that is not root but ha…
ssfuisu Oct 31, 2026
070181b
Review: the emulated hard link is looked up again after a directory w…
ssfuisu Oct 31, 2026
a108995
Hardware keyboard Ctrl, Alt and Shift reach the terminal; system() an…
ssfuisu Nov 2, 2026
54ad7bb
Review: system(NULL) checks for Ubuntu's shell, concurrent system() c…
ssfuisu Nov 2, 2026
536394a
Keep the branch on main after the 1.26.47 squash merge
claude Nov 2, 2026
b2e5618
Programs a shell starts take fewer page faults: the exec code is prep…
claude Nov 4, 2026
ee332e8
1.26.48: version and changelog
claude Nov 4, 2026
5789211
Review: the fork preparation does not wait for its lock (a signal han…
claude Nov 4, 2026
c134b52
Keep the branch on main after the 1.26.48 squash merge
claude Nov 4, 2026
71bd87b
Servers on a port the kernel picked are no longer connected to by the…
ssfuisu Nov 7, 2026
842ee05
Website: animated redesign
ssfuisu Nov 7, 2026
f4ffbfb
Review: a new socket starts without a chosen port, the qemu test find…
ssfuisu Nov 7, 2026
fdf9341
Pick the test port below the kernel's range, softer button shine in l…
ssfuisu Nov 7, 2026
76ced74
1.26.49
ssfuisu Nov 7, 2026
71394e0
Merge branch after squash
ssfuisu Nov 7, 2026
d549b0f
Website: drawn SVG icons instead of emoji
ssfuisu Nov 7, 2026
ac61da7
Merge branch after squash
ssfuisu Nov 7, 2026
76dade0
README: the phone's files are at /sdcard, near the top
ssfuisu Nov 7, 2026
9b3aa5d
Merge branch after README push
ssfuisu Nov 7, 2026
b9e3275
Programs find libraries through their RUNPATH (adb, fastboot); 1.26.50
ssfuisu Nov 7, 2026
f032f44
RUNPATH: search order as on Linux, any number of headers
ssfuisu Nov 7, 2026
7081ddd
Merge branch after squash
ssfuisu Nov 7, 2026
7bd9964
Desktop (X11) add-on, ld.so.conf.d/ldconfig/ldd, SysV shared memory; …
ssfuisu Nov 8, 2026
776bcb5
Review fixes: ld.so with its own --library-path, ldconfig marks ld.so…
ssfuisu Nov 8, 2026
5cfa504
Desktop and hook review fixes
ssfuisu Nov 8, 2026
e62136c
Merge branch state after #57 [skip ci]
ssfuisu Nov 8, 2026
efc45d6
Drawer: the desktop as a monitor icon next to the update check
ssfuisu Nov 8, 2026
a7e2789
Install: read the archive from the APK file with a CRC check, never m…
ssfuisu Nov 8, 2026
1883d92
installBootstrap: progress stays the last parameter (the trailing lam…
ssfuisu Nov 8, 2026
c6abc3f
Bootstrap reads: close the stream when the header read fails, copy fr…
ssfuisu Nov 8, 2026
c0cdec3
Merge branch state after #59 [skip ci]
ssfuisu Nov 8, 2026
b8d7e2d
SysV shm: a segment marked removed stays attachable for a while (GTK'…
ssfuisu Nov 9, 2026
4363f0b
shm: measure the IPC_RMID grace period with the boot clock
ssfuisu Nov 9, 2026
8d603dc
Merge branch state after 1.27.3
ssfuisu Nov 9, 2026
f7b7bbd
1.27.4: reload the custom terminal font when its file changes (#58)
ssfuisu Nov 9, 2026
42e651b
Merge branch state after 1.27.4
ssfuisu Nov 9, 2026
33acec7
Bug report: the desktop's state and its log
ssfuisu Nov 11, 2026
a4c9d50
1.27.5: XFCE runs (session bus, file type database, libpulse), PulseA…
ssfuisu Nov 11, 2026
4980a6e
Review: loader order and relative paths in dlopen, recvmmsg, desktop …
ssfuisu Nov 11, 2026
06734df
1.27.5.1: libraries' RUNPATH directories, locks on a memfd, fewer rea…
ssfuisu Nov 11, 2026
853aed6
Review: memfd locks by the memfd's inode, RTLD_DEEPBIND, 32-bit names…
ssfuisu Nov 11, 2026
1290602
32-bit: the headers already give these hooks their time64 names
ssfuisu Nov 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up JDK 17
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
uses: actions/setup-java@77dd5b2ce225ea11469928ac317850245a74ae78 # v6.2.0
with:
distribution: 'temurin'
java-version: '17'
Expand Down Expand Up @@ -126,8 +126,7 @@ jobs:
if: steps.cache-hook.outputs.cache-hit != 'true'
run: |
sudo rm -f /etc/apt/sources.list.d/*google* /etc/apt/sources.list.d/*chrome*
sudo apt-get update -o Acquire::Retries=3 -qq
sudo apt-get install -y --no-install-recommends gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf libc6-dev-arm64-cross libc6-dev-armhf-cross dpkg-dev
scripts/ci-apt-install.sh gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf libc6-dev-arm64-cross libc6-dev-armhf-cross dpkg-dev
mkdir -p hook-libs
# The code that is added to static Go programs (gosys/gosys.c), which the 64-bit hook carries
scripts/build-gosys.sh
Expand Down Expand Up @@ -349,8 +348,7 @@ jobs:
CORTEX_REQUIRE_GO_TESTS: 1
CORTEX_GO_TEST_VERSIONS: "1.19.13 1.23.12"
run: |
sudo apt-get update -o Acquire::Retries=3 -qq
sudo apt-get install -y --no-install-recommends qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross binutils-aarch64-linux-gnu
scripts/ci-apt-install.sh qemu-user gcc-aarch64-linux-gnu libc6-dev-arm64-cross binutils-aarch64-linux-gnu
bash tests/scripts/test_go_programs.sh
CORTEX_REQUIRE_QEMU_TESTS=1 bash tests/scripts/test_hook_qemu.sh

Expand Down
47 changes: 47 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,53 @@ What changed in each version of Cortex Terminal, newest first. The release workf
of a GitHub release from the section of its version here. Older versions are described on the
[GitHub releases](https://github.com/ssfuisu/cortex/releases) page.

## 1.27.5.1 (2026-11-11)

### Fixed

- **XFCE: "Unable to contact settings server. The connection is closed".** Every program in Cortex
sees itself as root, but the kernel told a server the app's real user for the program at the other
end of a Unix socket. dbus-daemon compares the two and closed every connection to the session bus,
so XFCE's settings service could not be reached and the session stopped at that message. The other
end is now shown as the user programs see for themselves (SO_PEERCRED, received SCM_CREDENTIALS).
The session bus works for other programs too.
- **XFCE's panel ended at once and the desktop stayed black.** Cortex does not build the database
of file types when packages are installed, and GTK cannot load an icon without it. `cortex-desktop`
now builds it, and the database of the programs that open files, when the desktop is installed or
started and a package has added to them.
- **"Plugin PulseAudio Plugin unexpectedly left the panel".** A library loaded with dlopen() did
not find what one of its dependencies keeps in a directory of its own (libpulse.so.0 and its
libpulsecommon). The same kept programs that load libpulse by name from having sound.

- **Every start of the desktop left a PulseAudio behind.** `pulseaudio --kill` looks for a process
named pulseaudio and found none (Cortex's programs run as ld.so), so the old one was never
stopped and the new one started without its socket: after the desktop was started again its sound
went to a daemon nobody listened to. The desktop now keeps track of its PulseAudio itself, and
ends the ones older versions left.

- **Programs whose libraries name a directory of their own did not start (#67).** fio ended with
"libceph-common.so.2: cannot open shared object file": its librbd.so.1 finds that library through
its RUNPATH (/usr/lib/aarch64-linux-gnu/ceph), which ld.so looked for outside Ubuntu's files. The
directories that libraries name this way are now collected when ldconfig runs (after packages are
installed, as on Linux) into /etc/ld.so.conf.d/zz-cortex-runpath.conf. This also ends the
"libpxbackend-1.0.so: cannot open shared object file" lines of GTK programs.
- **PHP's built-in server: "Cannot create lock - Permission denied (13)" (#69).** PHP keeps the lock
of its opcache in a memory file (memfd), and Android does not let an app lock one. A lock that
Android refuses on a memfd is now taken on a file of Cortex's own, which the program's children
share, so `php -S` and PHP-FPM start.
- **PHP extensions looked for their files in Android's tree.** PHP loads every extension with
RTLD_DEEPBIND, which makes a library call libc directly, past Cortex's library: an extension's
absolute paths (a certificate bundle, a database file) were not Ubuntu's. Libraries are now loaded
without that flag.

### Changed

- lstat() of a link in /usr/lib (libssl.so.3 -> libssl.so.3.0.0 and the like) no longer reads the
link a second time: only a link that can lead into /etc/alternatives is read (#66).
- XFCE starts with its compositor off (shadows and transparency are drawn by the CPU here); it can
be turned on in Settings > Window Manager Tweaks. The desktops install the SVG icon loader.
- A bug report has the desktop's state and the last lines of its log (`~/.cortex/desktop.log`).

## 1.27.4 (2026-11-09)

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ android {
// from the app's writable data directory (filesDir). Android 10+ (targetSdk >= 29)
// enforces SELinux W^X restrictions preventing execution from writable app data storage.
targetSdk = 28
versionCode = 12704
versionName = "1.27.4"
versionCode = 12705
versionName = "1.27.5.1"
// UbuntuOnDeviceTest (app/src/androidTest), on Firebase Test Lab
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
114 changes: 102 additions & 12 deletions app/src/main/assets/scripts/cortex-desktop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ DEFAULT_SIZE="1280x720"

LIGHT_PACKAGES="tigervnc-standalone-server tigervnc-tools dbus-x11 xauth x11-xserver-utils x11-utils
xfonts-base fonts-dejavu-core openbox obconf python3-xdg tint2 pcmanfm lxterminal mousepad lxappearance
adwaita-icon-theme-full pulseaudio pulseaudio-utils xdg-utils"
adwaita-icon-theme-full librsvg2-common pulseaudio pulseaudio-utils xdg-utils"
XFCE_PACKAGES="tigervnc-standalone-server tigervnc-tools dbus-x11 xauth x11-xserver-utils x11-utils
xfonts-base fonts-dejavu-core xfce4 xfce4-terminal thunar mousepad
adwaita-icon-theme-full pulseaudio pulseaudio-utils xdg-utils"
adwaita-icon-theme-full librsvg2-common pulseaudio pulseaudio-utils xdg-utils"

die() {
echo "cortex-desktop: $*" >&2
Expand Down Expand Up @@ -98,6 +98,39 @@ free_display() {
return 1
}

# The real program behind one that Cortex does not run when packages are installed (its stand-in
# does nothing, and the hook answers for a program of that name itself)
real_tool() {
if [ -x "$R/usr/bin/$1.distrib" ]; then
echo "$R/usr/bin/$1.distrib"
elif [ -x "$R/usr/bin/$1" ] && mkdir -p "$STATE" && ln -sf "$R/usr/bin/$1" "$STATE/$1.real" 2>/dev/null; then
echo "$STATE/$1.real"
else
return 1
fi
}

# The databases of file types (/usr/share/mime) and of the programs that open them. Cortex leaves
# them out when packages are installed: they take time and a terminal has no use for them. But GTK
# cannot load a single icon without the first (XFCE's panel ended at once, its desktop stayed
# black), and a file manager does not know what opens a file without the second. They are built
# here: the first (a few seconds) when it is missing or a package added to or took from it (the
# directory of its sources changed: a file dpkg unpacks keeps the date it has in the package, so the
# files' own dates say nothing), the second (a moment) every time.
refresh_databases() {
local dir real
dir="$R/usr/share/mime"
if [ -d "$dir/packages" ] && { [ ! -f "$dir/mime.cache" ] || [ -n "$(find "$dir/packages" -newer "$dir/mime.cache" -print -quit 2>/dev/null)" ]; }; then
if real="$(real_tool update-mime-database)"; then
"$real" "$dir" >/dev/null 2>&1 || echo "cortex-desktop: update-mime-database failed" >&2
fi
fi
dir="$R/usr/share/applications"
if [ -d "$dir" ] && real="$(real_tool update-desktop-database)"; then
"$real" "$dir" >/dev/null 2>&1 || echo "cortex-desktop: update-desktop-database failed" >&2
fi
}

installed_kind() {
local kind
kind="$(conf_value DESKTOP)"
Expand Down Expand Up @@ -133,6 +166,7 @@ cmd_install() {
as_root env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends $packages ||
die "the packages could not be installed"
if [ "$firefox" = 1 ]; then install_firefox || echo "cortex-desktop: Firefox was not installed (see above)." >&2; fi
refresh_databases
set_conf DESKTOP "$kind"
echo "The desktop is installed. Open it from the app's menu (Desktop), or run: cortex-desktop start"
}
Expand Down Expand Up @@ -254,19 +288,53 @@ show_mounts=0
EOF
}

# Ends the desktop's PulseAudio. "pulseaudio --kill" does not find it here: it looks for a process
# named pulseaudio, and Cortex's programs run as ld.so with their name as an argument. So it was
# never stopped, and every start of the desktop left one more behind, the new one without its socket
# (the old one still held it). Ours are known by the pid kept at their start and by their socket.
stop_audio() {
local pid i theirs="module-native-protocol-unix socket=$STATE/pulse.sock"
pid="$(cat "$STATE/pulse.pid" 2>/dev/null)"
pid_is "$pid" pulseaudio && kill "$pid" 2>/dev/null
command -v pkill >/dev/null 2>&1 && pkill -f "$theirs" 2>/dev/null
# all of them gone before the socket is taken away: one that ends later removes it as it goes,
# which would be the next one's
for i in $(seq 1 30); do
if ! pid_is "$pid" pulseaudio && ! { command -v pgrep >/dev/null 2>&1 && pgrep -f "$theirs" >/dev/null 2>&1; }; then break; fi
sleep 0.1
done
if pid_is "$pid" pulseaudio; then kill -9 "$pid" 2>/dev/null; fi
command -v pkill >/dev/null 2>&1 && pkill -9 -f "$theirs" 2>/dev/null
rm -f "$STATE/pulse.pid" "$STATE/pulse.server" "$STATE/pulse.sock"
}

start_audio() {
command -v pulseaudio >/dev/null 2>&1 || return 0
local fifo="$STATE/audio.fifo"
local fifo="$STATE/audio.fifo" pid i
[ -p "$fifo" ] || { rm -f "$fifo"; mkfifo -m 600 "$fifo" 2>/dev/null; } || return 0
pulseaudio --kill >/dev/null 2>&1
stop_audio
# No shared memory between PulseAudio and its programs (they talk over the socket), no realtime
# priority (Android does not give it), and one output: the pipe the app reads and plays
pulseaudio --daemonize=yes --exit-idle-time=-1 --disallow-exit --disable-shm=yes \
# priority (Android does not give it), and one output: the pipe the app reads and plays. Not as
# its own daemon and without its pid file (see stop_audio): in a session of its own, like the X server.
setsid pulseaudio --daemonize=no --use-pid-file=no --exit-idle-time=-1 --disallow-exit --disable-shm=yes \
--realtime=no --high-priority=no --log-target=file:"$LOG_DIR/pulseaudio.log" -n \
-L "module-native-protocol-unix socket=$STATE/pulse.sock auth-anonymous=1" \
-L "module-pipe-sink file=$fifo format=s16le rate=44100 channels=2 sink_name=android" \
-L "module-always-sink" >/dev/null 2>&1 || return 0
echo "unix:$STATE/pulse.sock" >"$STATE/pulse.server"
-L "module-always-sink" </dev/null >/dev/null 2>&1 9>&- &
pid=$!
echo "$pid" >"$STATE/pulse.pid"
# its socket is there within a moment; a desktop without sound is still a desktop
for i in $(seq 1 50); do
[ -S "$STATE/pulse.sock" ] && break
pid_alive "$pid" || break
sleep 0.1
done
if [ -S "$STATE/pulse.sock" ]; then
echo "unix:$STATE/pulse.sock" >"$STATE/pulse.server"
else
# not one that runs on without anyone knowing its socket
stop_audio
fi
}

cmd_start() {
Expand Down Expand Up @@ -325,21 +393,43 @@ cmd_start() {
start_audio
if ! start_session "$display"; then
stop_processes
stop_audio
die "the desktop did not start (log: $LOG)"
fi
echo "The desktop is running: DISPLAY=:$display (programs started from the terminal open on it)."
}

# XFCE's window manager blends the windows together itself (shadows, transparency) unless told
# otherwise, and without a GPU the CPU does that for every change on the screen. Off the first time;
# the file is the user's from then on (Settings > Window Manager Tweaks > Compositor).
ensure_xfce_defaults() {
local dir="${HOME}/.config/xfce4/xfconf/xfce-perchannel-xml"
[ -e "$dir/xfwm4.xml" ] && return 0
mkdir -p "$dir" || return 0
cat >"$dir/xfwm4.xml" <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfwm4" version="1.0">
<property name="general" type="empty">
<property name="use_compositing" type="bool" value="false"/>
</property>
</channel>
EOF
}

# The desktop's session on the X server of display $1; fails when it ends at once
start_session() {
local display="$1" pulse="" current="openbox"
[ "$(conf_value DESKTOP)" = xfce ] || ensure_openbox_autostart
refresh_databases
if [ "$(conf_value DESKTOP)" = xfce ]; then ensure_xfce_defaults; else ensure_openbox_autostart; fi
[ -f "$STATE/pulse.server" ] && pulse="$(cat "$STATE/pulse.server")"
[ "$(conf_value DESKTOP)" = xfce ] && current="XFCE"
(
cd "$HOME" || exit 1
unset SESSION_MANAGER DBUS_SESSION_BUS_ADDRESS
export DISPLAY=":$display" XDG_SESSION_TYPE=x11 XDG_CURRENT_DESKTOP="$current"
# NO_AT_BRIDGE: there is no accessibility bus here, and every GTK program waited for it and
# wrote a warning
export DISPLAY=":$display" XDG_SESSION_TYPE=x11 XDG_CURRENT_DESKTOP="$current" NO_AT_BRIDGE=1
[ -n "$pulse" ] && export PULSE_SERVER="$pulse"
# shellcheck disable=SC2046
exec setsid dbus-launch --exit-with-session $(session_command)
Expand Down Expand Up @@ -375,8 +465,8 @@ cmd_stop() {
take_lock
local stopped=0
stop_processes && stopped=1
command -v pulseaudio >/dev/null 2>&1 && pulseaudio --kill >/dev/null 2>&1
rm -f "$STATE/pulse.server" "$SOCKET"
stop_audio
rm -f "$SOCKET"
if [ "$stopped" = 1 ]; then echo "The desktop was stopped."; else echo "The desktop was not running."; fi
}

Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/cortex-hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@
#include "hook/net.c"
#include "hook/sockets.c"
#include "hook/sysv_shm.c"
#include "hook/memfd_locks.c"
4 changes: 3 additions & 1 deletion app/src/main/cpp/hook/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,13 @@ static int run_execve(orig_execve_f_type f, const char *path, char *const argv[]
return f(path, argv, envp);
}

// ldconfig does nothing in Cortex (its cache is for paths that ld.so opens without the hook), but the
// ldconfig writes no cache in Cortex (its cache is for paths that ld.so opens without the hook), but the
// exec code reads /etc/ld.so.conf(.d) again when /etc/ld.so.cache changes: "sudo ldconfig" after an
// edit of a .conf file marks it changed, as the real ldconfig would by writing it.
static void ldconfig_mark_cache(void) {
if (g_cortex_root[0] == '\0') return;
// what the real one does for its cache: the libraries are read (their RUNPATH), see runpath_conf_refresh()
runpath_conf_refresh();
char path[PATH_MAX];
size_t n = cortex_append(path, sizeof(path), 0, g_cortex_root, g_cortex_root_len);
cortex_append(path, sizeof(path), n, "/etc/ld.so.cache", 16);
Expand Down
Loading
Loading