340 Commits

Author SHA1 Message Date
Basil Crow
182f8ddd1a Do not resolve the symbolic link for the initial working directory 2025-07-03 07:09:24 -07:00
Mitchell Hashimoto
591ef0f40f Move child exit handling logic to apprt thread
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-27 10:36:23 -07:00
Qwerasd
7cfc906c60 debug: properly set thread names on macOS 2025-06-20 15:18:41 -06:00
Mitchell Hashimoto
a87c68d49a termio: unconditionally show "process exited" message
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-06-09 06:51:17 -07:00
Leorize
b6f120a749 termio, flatpak: support spawning terminals in cwd
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-05-06 13:42:14 -07:00
Mitchell Hashimoto
722d41a359 config: allow commands to specify whether they shell expand or not
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-04-10 13:15:14 -07:00
Leorize
009b53c45e termio, flatpak: implement process watcher with xev
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-15 07:29:13 -07:00
Mitchell Hashimoto
0f4d2bb237 Lots of 0.14 changes 2025-03-12 09:55:52 -07:00
Yorick Peterse
300f4544ef Fix passing EnvMap for Flatpak builds
When using -Dflatpak=true the EnvMap was passed as the incorrect type.
2025-03-09 23:46:24 +01:00
Mitchell Hashimoto
d532a6e260 Update libxev to use dynamic backend, support Linux configurability
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-21 15:04:37 -08:00
Jeffrey C. Ollie
c7971b562e core: add env config option
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-14 20:50:01 -08:00
Mitchell Hashimoto
1fea8028a3 apprt: require envmap for exec-based termio
Supercedes #5726
2025-02-13 12:26:11 -08:00
Mitchell Hashimoto
9ea29dc508 termio: free envmap when able, fix memory leak
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-12 08:48:26 -08:00
Leah Amelia Chen
56ea6c406c gtk(x11): set WINDOWID env var for subprocesses
`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-02-11 13:42:12 -08:00
Mitchell Hashimoto
8475768ad1 termio/exec: if pty fd HUP, end read thread
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-24 09:39:22 -08:00
Mitchell Hashimoto
0d6a1d3fdb Prevent fd leaks to the running shell or command
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-23 22:12:58 -08:00
Mitchell Hashimoto
8ada93d0cb Fix shell-integration-features being ignored with manual shell integration (#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-20 10:28:14 -08:00
Jon Parise
2ee6e005d0 termio: revise macOS-specific .hushlogin note
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)

- 1bca46ecc5
- https://github.com/apple-oss-distributions/distribution-macOS/tree/macos-144
2025-01-18 15:35:23 -05:00
Bryan Lee
8ee4deddb4 Fix shell-integration-features being ignored when shell-integration is none 2025-01-18 05:12:44 +08:00
Mitchell Hashimoto
6ef757a8f8 Revert "termio/exec: fix SIGPIPE crash when reader exits early"
This reverts commit 3e24e96af51fe308705a1f1695e3b9045c54482e.
2025-01-09 12:43:41 -08:00
Danny Lin
3e24e96af5 termio/exec: fix SIGPIPE crash when reader exits early
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-08 13:06:14 -08:00
Jon Parise
29dd5ae605 termio: explain why we're removing VTE_VERSION 2025-01-06 19:11:54 -05:00
Jon Parise
15f82858b7 termio: don't leak VTE_VERSION into child processes
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.
2025-01-06 14:00:38 -05:00
Khang Nguyen Duy
239056c90f avoid asserting working directory is absolute
`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-20 22:41:28 +07:00
Jon Parise
d981ddf128 macos: add our application bundle to XDG_DATA_DIRS
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-12-15 21:24:43 -08:00
Isaac Mills
39fbd7db4b Prevent GTK from initializing Vulkan. This improves startup time 2024-11-26 11:10:00 -07:00
Jon Parise
433b6b4fe2 os: replace PATH_SEP with std.fs.path.delimiter
This standard library symbol is equivalent.
2024-11-19 10:51:02 -05:00
Mitchell Hashimoto
a436bd0af6 move datastructures to dedicated "datastruct" package 2024-11-07 14:39:10 -08:00
Mitchell Hashimoto
f8bdd2b1bb termio: killpg expected to fail on darwin, still go into waitpid loop
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-20 15:29:06 -07:00
FineFindus
6f3db36251 termio: correct comment about windows support
The comment has conflicting information about supporting windows. This
removes the incorrect information that only windows is supported.
2024-09-20 17:42:08 +02:00
Mitchell Hashimoto
e3d528cf0b termio: use surface messages to trigger password input state 2024-09-18 21:14:05 -07:00
Mitchell Hashimoto
42e7cbc475 termio: typos 2024-09-18 20:59:27 -07:00
Mitchell Hashimoto
66a065dcdd termio: always set termios timer running bool to true on focus
Fixes #2265

See comment in diff for details.
2024-09-18 20:56:40 -07:00
Mitchell Hashimoto
1936ef7fee termio: increase termios poller to 200ms 2024-09-18 12:14:55 -07:00
Mitchell Hashimoto
e8bbc987e0 termio: stop the termios poller when not focused 2024-09-18 11:56:07 -07:00
Mitchell Hashimoto
39627e3221 termio: set pw input state on terminal and wake up renderer 2024-09-18 10:47:26 -07:00
Mitchell Hashimoto
4f6995d727 termio: poll termios for changes 2024-09-18 10:34:07 -07:00
Mitchell Hashimoto
f0c4afdf9c termio: set crash threadlocal data for exec reader thread 2024-09-03 14:31:05 -07:00
Mitchell Hashimoto
18419d3589 Clamp initial window size configurations to screen size
Fixes #2145
2024-08-26 10:09:05 -07:00
multifred
72c672adb7 Fix multiple deprecated names for zig lib/std 2024-07-22 00:07:17 +02:00
Mitchell Hashimoto
1100145cf3 tweaks 2024-07-18 15:57:55 -07:00
Łukasz Niemier
255e50124c fix: instead of overriding MANPATHs set by OS, append to them
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`.
2024-07-19 00:36:42 +02:00
Mitchell Hashimoto
835d622baa termio: writer => mailbox 2024-07-15 10:23:09 -07:00
Mitchell Hashimoto
001a6d2624 termio: reader => backend 2024-07-15 10:14:14 -07:00
Mitchell Hashimoto
4a4b9f2411 termio: trying to get Exec to not have access to full Opts 2024-07-15 09:45:58 -07:00
Mitchell Hashimoto
b0cd40d1de termio: fix windows build 2024-07-14 15:16:16 -07:00
Mitchell Hashimoto
a848a53d26 termio: remove a ton of state 2024-07-14 15:10:05 -07:00
Mitchell Hashimoto
af7adedb50 termio: writer abstraction 2024-07-14 14:48:48 -07:00
Mitchell Hashimoto
e30e635bed termio: move all subprocess logic to termio.Exec 2024-07-13 19:24:10 -07:00
Mitchell Hashimoto
b3c2479f87 termio: move subprocess out to its own file 2024-07-13 15:20:38 -07:00