git.lucas.co / cce-cloud
cloud storage client
git clone https://git.lucas.co/cce-cloud.git

commit22c0a36f6ed3715420fd9bd0c1272bdc067f9509
parent5877564c5a
authorLucas Galante <[email protected]>
date2026-08-22 10:39
fix: write the spawn log to the per-user runtime dir, not /tmp

spawn_detached logged every launched app to a fixed /tmp/cce-spawn.log and pointed the child's stdout/stderr at the same file. On a shared machine that is both a collision — the first user to log in owns the path, and /tmp's sticky bit denies the rest — and a readable trace of one user's activity, since the file carries every command the launcher ran plus whatever those processes printed. It now lives at $XDG_RUNTIME_DIR/cce/spawn.log via cce_ui::config::cce_runtime_dir() (cce-ui@0f08c0d), which is per-user and mode 0700.

Routed through the shared helper rather than an inline env::var read: hardcoding the resolution here is the same thing the DE-wide path cleanup existed to remove, one indirection later. The daemon carries XDG_RUNTIME_DIR (systemd sets it for user units — verified on the running service), and the compositor's own logs moved to the same directory in cce@522ce13, so the session's runtime files now sit together.

Takes effect on a daemon restart, not an install: ccebuild restart is what swaps it. The file name loses its cce- prefix (spawn.log) now that the directory carries it, matching launch.sh alongside it.

Co-Authored-By: Claude <[email protected]>

 CLAUDE.md   | 4 +++-
 src/main.rs | 6 +++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 1443189..b384843 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -68,7 +68,9 @@ needs-stdin decision, in `run_client()`).
 - `Path` — executables scanned from `$PATH`.
 - `Apps` — `.desktop` files from the standard application dirs, sorted by launch
   frecency persisted in `~/.cache/cce-cloud-apps.json`; selecting spawns the app's
-  `Exec` (spawn output logged to `/tmp/cce-spawn.log`). Each entry's `Icon=` is
+  `Exec` (spawn output logged to `$XDG_RUNTIME_DIR/cce/spawn.log`, via
+  `cce_ui::config::cce_runtime_dir()` — it was `/tmp/cce-spawn.log` before
+  2026-08-22). Each entry's `Icon=` is
   resolved through `cce_ui::icon` and drawn in a gutter left of the label — the
   gutter is applied to every row, so one unresolvable icon doesn't rag the text
   edge. This is the *only* mode with icons: Dmenu/Path items are arbitrary
diff --git a/src/main.rs b/src/main.rs
index cb643f2..f300468 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -522,10 +522,14 @@ fn spawn_detached(program: &str, args: &[&str]) {
     use std::os::unix::process::CommandExt;
     let mut cmd = std::process::Command::new(program);
     cmd.args(args).process_group(0);
+    // Per-user runtime dir, not /tmp: this records every app the launcher
+    // starts and captures their stdout/stderr, so a fixed /tmp path is both a
+    // collision between users and a readable trace of one user's activity.
+    let log_path = cce_ui::config::cce_runtime_dir().join("spawn.log");
     if let Ok(file) = std::fs::OpenOptions::new()
         .create(true)
         .append(true)
-        .open("/tmp/cce-spawn.log")
+        .open(&log_path)
     {
         let mut f = file;
         use std::io::Write;