Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(native): poweroff/reboot use kernel syscall directly (root has CAP_SYS_BOOT)

The existing ac_poweroff() only called reboot(LINUX_REBOOT_CMD_POWER_OFF)
when getpid()==1, but ac-native runs as a CHILD of the initramfs init
script — so getpid() is never 1 on bare metal. It fell through to
'systemctl poweroff' which doesn't exist on bare metal, leaving the
machine in a black-screen-but-on state after the goodbye animation.

Fix: always try the reboot() syscall first. As root we always have
CAP_SYS_BOOT whether we're PID 1 or not, so the syscall succeeds and
the kernel halts immediately. Only if it fails (unprivileged systemd
environment) do we fall back to systemctl / /sbin/poweroff -f.

Same fix applied to ac_reboot().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+20 -9
+20 -9
fedac/native/src/ac-native.c
··· 150 150 poweroff_requested = 1; 151 151 } 152 152 153 - // Shutdown/reboot that works both as PID 1 (bare metal) and under systemd (NixOS). 153 + // Shutdown/reboot that works in all three contexts: 154 + // - PID 1 (bare metal, direct DRM boot): reboot() syscall works directly. 155 + // - Child of init script (bare metal): exit with special code so the init 156 + // shell script can invoke `poweroff -f` and the reboot syscall itself. 157 + // We ALSO try the reboot syscall directly since we're running as root 158 + // with CAP_SYS_BOOT — that's faster than round-tripping through init. 159 + // - Under systemd (NixOS): fall back to systemctl. 154 160 static void ac_poweroff(void) { 155 161 sync(); 156 162 usleep(500000); 157 163 sync(); 158 - if (getpid() == 1) { 159 - reboot(LINUX_REBOOT_CMD_POWER_OFF); 160 - } else { 161 - system("systemctl poweroff"); 164 + // Try the kernel syscall first — works as root with CAP_SYS_BOOT, which 165 + // we always have on bare metal (PID 1 or child of init). Only non-root 166 + // contexts (NixOS under systemd) need to shell out. 167 + if (reboot(LINUX_REBOOT_CMD_POWER_OFF) == 0) { 168 + // Shouldn't reach here — syscall succeeds → kernel halts. 162 169 _exit(0); 163 170 } 171 + // Syscall failed (likely EPERM on systemd) — fall back. 172 + system("systemctl poweroff || /sbin/poweroff -f || /bin/poweroff -f || poweroff -f"); 173 + // If the initramfs init script is our parent, exit(0) tells it we've 174 + // finished; it will do its own `poweroff -f` + sysrq as a last resort. 175 + _exit(0); 164 176 } 165 177 166 178 static void ac_reboot(void) { 167 179 sync(); 168 180 usleep(500000); 169 181 sync(); 170 - if (getpid() == 1) { 171 - reboot(LINUX_REBOOT_CMD_RESTART); 172 - } else { 173 - system("systemctl reboot"); 182 + if (reboot(LINUX_REBOOT_CMD_RESTART) == 0) { 174 183 _exit(2); 175 184 } 185 + system("systemctl reboot || /sbin/reboot -f || /bin/reboot -f || reboot -f"); 186 + _exit(2); 176 187 } 177 188 178 189 static void signal_handler(int sig) {