summaryrefslogtreecommitdiff
path: root/src/termio/Exec.zig
AgeCommit message (Collapse)Author
2025-10-03Zig 0.15: FlatpakMitchell Hashimoto
2025-10-03Zig 0.15: zig build test macOSMitchell Hashimoto
2025-10-03Zig 0.15: zig build GTK exeMitchell Hashimoto
2025-10-03Zig 0.15: zig build test Mitchell Hashimoto
2025-09-09terminal: fix test w/ freed configCheru Berhanu
this test previously didn't fail when accessing freed members of config because deiniting `command_arena` was a no-op; `command_arena` was derived from `arena`, which allocated memory after `command_arena` was created/used
2025-08-22terminal: test execCommand w/ freed configCheru Berhanu
2025-08-22terminal: fix use-after-free in execCheru Berhanu
This was only an issue on Linux, as MacOS' command is reallocated and rewritten. We hit this using embedded Ghostty w/o a login shell :p
2025-07-03Handle `exec` failures more gracefullyMitchell Hashimoto
Fixes #7792 Our error handling for `exec` failing within the forked process never actually worked! It triggered all sorts of issues. We didn't catch this before because it used to be exceptionally hard to fail an exec because we used to wrap ALL commands in a `/bin/sh -c`. However, we now support direction execution, most notably when you do `ghostty -e <command>` but also via the `direct:` prefix on configured commands. This fixes up our exec failure handling by printing a useful error message and avoiding any errdefers in the child which was causing the double-close.
2025-07-03Do not resolve the symbolic link for the initial working directoryBasil Crow
2025-06-27Move child exit handling logic to apprt threadMitchell Hashimoto
Fixes #7500 Supersedes #7582 This commit moves the child exit handling logic from the IO thead to the apprt thread. The IO thread now only sends a `child_exited` message to the apprt thread with metadata about the exit conditions (exit code, runtime). From there, the apprt thread can handle the exit situation however is necessary. This commit doesn't change the behavior but it does fix the issue #7500. The behavior is: exit immediately, show abnormal exit message, wait for user input, etc. This also gets us closer to #7649.
2025-06-20debug: properly set thread names on macOSQwerasd
2025-06-09termio: unconditionally show "process exited" messageMitchell Hashimoto
We previously only showed this message if the user had `wait-after-command` set to true, since if its false the surface would close anyways. With the latest undo feature on macOS, this is no longer the case; a exited process can be undone and reopened. I considered disallowing undoing an exited surface, but I think there is value in being able to go back and recapture output in scrollback if you wanted to.
2025-05-06termio, flatpak: support spawning terminals in cwdLeorize
Implements path access testing for Flatpak via test spawning. This is required since Flatpak reserves certain paths from being accessible regardless of permissions. Ref: https://docs.flatpak.org/en/latest/sandbox-permissions.html#reserved-paths
2025-04-10config: allow commands to specify whether they shell expand or notMitchell Hashimoto
This introduces a syntax for `command` and `initial-command` that allows the user to specify whether it should be run via `/bin/sh -c` or not. The syntax is a prefix `direct:` or `shell:` prior to the command, with no prefix implying a default behavior as documented. Previously, we unconditionally ran commands via `/bin/sh -c`, primarily to avoid having to do any shell expansion ourselves. We also leaned on it as a crutch for PATH-expansion but this is an easy problem compared to shell expansion. For the principle of least surprise, this worked well for configurations specified via the config file, and is still the default. However, these configurations are also set via the `-e` special flag to the CLI, and it is very much not the principle of least surprise to have the command run via `/bin/sh -c` in that scenario since a shell has already expanded all the arguments and given them to us in a nice separated format. But we had no way to toggle this behavior. This commit introduces the ability to do this, and changes the defaults so that `-e` doesn't shell expand. Further, we also do PATH lookups ourselves for the non-shell expanded case because thats easy (using execvpe style extensions but implemented as part of the Zig stdlib). We don't do path expansion (e.g. `~/`) because thats a shell expansion. So to be clear, there are no two polar opposite behavioes here with clear semantics: 1. Direct commands are passed to `execvpe` directly, space separated. This will not handle quoted strings, environment variables, path expansion (e.g. `~/`), command expansion (e.g. `$()`), etc. 2. Shell commands are passed to `/bin/sh -c` and will be shell expanded as per the shell's rules. This will handle everything that `sh` supports. In doing this work, I also stumbled upon a variety of smaller improvements that could be made: - A number of allocations have been removed from the startup path that only existed to add a null terminator to various strings. We now have null terminators from the beginning since we are almost always on a system that's going to need it anyways. - For bash shell integration, we no longer wrap the new bash command in a shell since we've formed a full parsed command line. - The process of creating the command to execute by termio is now unit tested, so we can test the various complex cases particularly on macOS of wrapping commands in the login command. - `xdg-terminal-exec` on Linux uses the `direct:` method by default since it is also assumed to be executed via a shell environment.
2025-03-15termio, flatpak: implement process watcher with xevLeorize
This allows `termio.Exec` to track processes spawned via `FlatpakHostCommand`, finally allowing Ghostty to function as a Flatpak. Alongside this is a few bug fixes: * Don't add ghostty to PATH when running in flatpak mode since it's unreachable. * Correctly handle exit status returned by Flatpak. Previously this was not processed and contains extra status bits. * Use correct type for PID returned by Flatpak.
2025-03-12Lots of 0.14 changesMitchell Hashimoto
2025-03-09Fix passing EnvMap for Flatpak buildsYorick Peterse
When using -Dflatpak=true the EnvMap was passed as the incorrect type.
2025-02-21Update libxev to use dynamic backend, support Linux configurabilityMitchell Hashimoto
Related to #3224 Previously, Ghostty used a static API for async event handling: io_uring on Linux, kqueue on macOS. This commit changes the backend to be dynamic on Linux so that epoll will be used if io_uring isn't available, or if the user explicitly chooses it. This introduces a new config `async-backend` (default "auto") which can be set by the user to change the async backend in use. This is a best-effort setting: if the user requests io_uring but it isn't available, Ghostty will fall back to something that is and that choice is up to us. Basic benchmarking both in libxev and Ghostty (vtebench) show no noticeable performance differences introducing the dynamic API, nor choosing epoll over io_uring.
2025-02-14core: add `env` config optionJeffrey C. Ollie
Fixes #5257 Specify environment variables to pass to commands launched in a terminal surface. The format is `env=KEY=VALUE`. `env = foo=bar` `env = bar=baz` Setting `env` to an empty string will reset the entire map to default (empty). `env =` Setting a key to an empty string will remove that particular key and corresponding value from the map. `env = foo=bar` `env = foo=` will result in `foo` not being passed to the launched commands. Setting a key multiple times will overwrite previous entries. `env = foo=bar` `env = foo=baz` will result in `foo=baz` being passed to the launched commands. These environment variables _will not_ be passed to commands run by Ghostty for other purposes, like `open` or `xdg-open` used to open URLs in your browser.
2025-02-13apprt: require envmap for exec-based termioMitchell Hashimoto
Supercedes #5726
2025-02-12termio: free envmap when able, fix memory leakMitchell Hashimoto
Caused by #5650 I actually don't understand how this didn't happen before or why we didn't notice it but it seems like the envmap was never freed. In the latest debug builds prior to this build GPA reports the leak. We should free the envmap when the subprocess is deinitialized. But also we can free the env map as soon as we start the subprocess which saves some small amount of memory at runtime. Additionally, we should only be freeing the envmap on error if we created it.
2025-02-11gtk(x11): set `WINDOWID` env var for subprocessesLeah Amelia Chen
`WINDOWID` is the conventional environment variable for scripts that want to know the X11 window ID of the terminal, so that it may call tools like `xprop` or `xdotool`. We already know the window ID for window protocol handling, so we might as well throw this in for convenience.
2025-01-24termio/exec: if pty fd HUP, end read threadMitchell Hashimoto
Fixes #4884 When our command exits, it will close the pty slave fd. This will trigger a HUP on our poll. Previously, we only checked for IN. When a fd is closed, IN triggers forever which would leave to an infinite loop and 100% CPU. Now, detect the HUP and exit the read thread.
2025-01-23Prevent fd leaks to the running shell or commandMitchell Hashimoto
Multiple fixes to prevent file descriptor leaks: - libxev eventfd now uses CLOEXEC - linux: cgroup clone now uses CLOEXEC for the cgroup fd - termio pipe uses pipe2 with CLOEXEC - pty master always sets CLOEXEC because the child doesn't need it - termio exec now closes pty slave fd after fork There still appear to be some fd leaks happening. They seem related to GTK, they aren't things we're accessig directly. I still want to investigate them but this at least cleans up the major sources of fd leakage.
2025-01-20Fix shell-integration-features being ignored with manual shell integration ↵Mitchell Hashimoto
(#5048) ## Descriptions The code was short-circuiting the shell integration setup when `shell-integration = none`, which prevented the feature environment variables from being set. These environment variables are needed even for manual shell integration to work properly. ## Changes - Extracted feature environment variables setup into a separate `setup_features` function - Modified the shell integration initialization to ensure features are set up even when `shell-integration = none` <img width="1126" alt="image" src="https://github.com/user-attachments/assets/ceeb33f5-26ee-4a3b-a6d5-eed57848c96c" /> Fixes https://github.com/ghostty-org/ghostty/issues/5046
2025-01-18termio: revise macOS-specific .hushlogin noteJon Parise
login(1)'s .hushlogin logic was "fixed" in macOS Sonoma 14.4, so this comment (and our workaround) is only relevant for versions earlier than that. The relevant change to login/login.c is part of system_cmds-979.100.8. > login.c: look for .hushlogin in home directory (112854361) - https://github.com/apple-oss-distributions/system_cmds/commit/1bca46ecc5b76432f42eb23ec39fe63e8159f251 - https://github.com/apple-oss-distributions/distribution-macOS/tree/macos-144
2025-01-18Fix `shell-integration-features` being ignored when `shell-integration` is ↵Bryan Lee
`none`
2025-01-09Revert "termio/exec: fix SIGPIPE crash when reader exits early"Mitchell Hashimoto
This reverts commit 3e24e96af51fe308705a1f1695e3b9045c54482e.
2025-01-08termio/exec: fix SIGPIPE crash when reader exits earlyDanny Lin
If the read thread has already exited, it will have closed the read end of the quit pipe. Unless SIGPIPE is masked with signal(SIGPIPE, SIG_IGN), or the macOS-specific fcntl(F_SETNOSIGPIPE), writing to the write end of a broken pipe kills the writer with SIGPIPE instead of returning -EPIPE as an error. This causes a crash if the read thread exits before threadExit. This was already a possible race condition if read() returns error.NotOpenForReading or error.InputOutput, but it's now much easier to trigger due to the recent "termio/exec: fix 100% CPU usage after wait-after-command process exits" fix. Fix this by closing the quit pipe instead of writing to it.
2025-01-06termio: explain why we're removing VTE_VERSIONJon Parise
2025-01-06termio: don't leak VTE_VERSION into child processesJon Parise
This variable is used by gnome-terminal and other VTE-based terminals. We don't want our child processes to think we're running under VTE.
2024-12-20avoid asserting working directory is absoluteKhang Nguyen Duy
`std.fs.accessAbsolute` asserts if the user proposed path is absolute, which we are seemingly passing as-is with no validating that it is. When running with safety checks on, passing non-absolute path to --working-directory will make ghostty crash. I changed it to use `Dir.access`, which is just `accessAbsolute` without the check. This has the side effect of also allowing relative working directory.
2024-12-15macos: add our application bundle to XDG_DATA_DIRSJon Parise
We're packaging more and more application-specific data directories in our application bundle. It's helpful to add that path to XDG_DATA_DIRS so those applications (that support XDG_DATA_DIRS) can locate their data directories without additional user-level configuration. This also fixes a typo ("MATHPATH") in the nearby MANPATH-building code.
2024-11-26Prevent GTK from initializing Vulkan. This improves startup timeIsaac Mills
2024-11-19os: replace PATH_SEP with std.fs.path.delimiterJon Parise
This standard library symbol is equivalent.
2024-11-07move datastructures to dedicated "datastruct" packageMitchell Hashimoto
2024-09-20termio: killpg expected to fail on darwin, still go into waitpid loopMitchell Hashimoto
Fixes #2273 On macOS, killpg is expected to fail with EPERM because of the way we launch a login process around it. Before this commit, this caused us to never call waitpid and reap the child process, which caused the child process to stick around as a zombie. This commit allows killpg to fail with EPERM on macOS and fall through to waitpid.
2024-09-20termio: correct comment about windows supportFineFindus
The comment has conflicting information about supporting windows. This removes the incorrect information that only windows is supported.
2024-09-18termio: use surface messages to trigger password input stateMitchell Hashimoto
2024-09-18termio: typosMitchell Hashimoto
2024-09-18termio: always set termios timer running bool to true on focusMitchell Hashimoto
Fixes #2265 See comment in diff for details.
2024-09-18termio: increase termios poller to 200msMitchell Hashimoto
2024-09-18termio: stop the termios poller when not focusedMitchell Hashimoto
2024-09-18termio: set pw input state on terminal and wake up rendererMitchell Hashimoto
2024-09-18termio: poll termios for changesMitchell Hashimoto
2024-09-03termio: set crash threadlocal data for exec reader threadMitchell Hashimoto
2024-08-26Clamp initial window size configurations to screen sizeMitchell Hashimoto
Fixes #2145
2024-07-22Fix multiple deprecated names for zig lib/stdmultifred
2024-07-18tweaksMitchell Hashimoto
2024-07-19fix: instead of overriding MANPATHs set by OS, append to themŁukasz Niemier
Quoting `man man`: > If MANPATH begins with a colon, it is appended to the default list; Alternatively we can think about: > if it ends with a colon, it is prepended to the default list; To take preference over existing values, but that shouldn't be really a problem, as there rather isn't much of another projects named `ghostty`.