public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/tmux] f43: Patch #{pane_current_path} race condition
@ 2026-06-26 14:54 Dridi Boukelmoune
  0 siblings, 0 replies; only message in thread
From: Dridi Boukelmoune @ 2026-06-26 14:54 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/tmux
            Branch : f43
            Commit : c31f4117065295adc25eeea5cf84e40b48b8bde0
            Author : Dridi Boukelmoune <dridi.boukelmoune@gmail.com>
            Date   : 2026-05-05T16:22:49+02:00
            Stats  : +94/-1 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/tmux/c/c31f4117065295adc25eeea5cf84e40b48b8bde0?branch=f43

            Log:
            Patch #{pane_current_path} race condition

Immediately after upgrading to Fedora 44, tmux became useless for my
usage. It involves pane creation followed almost immediately with a
query of the effective pane path.

This bug was already reported and fixed upstream. I have been able to
verify with a local build that this single patch closes the race. My
build was configured with --enable-systemd --enable-cgroups.

I am currently running packages built by koji and can also confirm the
race is gone and tmux is usable again.

---
diff --git a/0001-Setting-working-directory-after-fork-means-there-is-.patch b/0001-Setting-working-directory-after-fork-means-there-is-.patch
new file mode 100644
index 0000000..e3f072a
--- /dev/null
+++ b/0001-Setting-working-directory-after-fork-means-there-is-.patch
@@ -0,0 +1,89 @@
+From f1e4ec1c9fa89f4fc062b5bc4aacc5f93f93f11b Mon Sep 17 00:00:00 2001
+From: nicm <nicm>
+Date: Mon, 8 Dec 2025 08:04:35 +0000
+Subject: [PATCH] Setting working directory after fork means there is a race
+ with pane_current_path (especially on platforms with systemd which have to
+ take time to do some additional faffing around). To avoid this, change it
+ before fork and back in the parent afterwards. GitHub issue 4719.
+
+(cherry picked from commit f58b8d0d6abb2477b584547a4e72cc362ecbbcdb)
+
+Conflicts:
+	spawn.c
+---
+ spawn.c | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+diff --git a/spawn.c b/spawn.c
+index 90cda757..964d0334 100644
+--- a/spawn.c
++++ b/spawn.c
+@@ -211,7 +211,9 @@ spawn_pane(struct spawn_context *sc, char **cause)
+ 	struct environ		 *child;
+ 	struct environ_entry	 *ee;
+ 	char			**argv, *cp, **argvp, *argv0, *cwd, *new_cwd;
+-	const char		 *cmd, *tmp;
++	char			  path[PATH_MAX];
++	const char		 *cmd, *tmp, *home = find_home();
++	const char		 *actual_cwd = NULL;
+ 	int			  argc;
+ 	u_int			  idx;
+ 	struct termios		  now;
+@@ -366,6 +368,16 @@ spawn_pane(struct spawn_context *sc, char **cause)
+ 		goto complete;
+ 	}
+ 
++    /* Store current working directory and change to new one. */
++	if (getcwd(path, sizeof path) != NULL) {
++		if (chdir(new_wp->cwd) == 0)
++			actual_cwd = new_wp->cwd;
++		else if (home != NULL && chdir(home) == 0)
++			actual_cwd = home;
++		else if (chdir("/") == 0)
++			actual_cwd = "/";
++	}
++
+ 	/* Fork the new process. */
+ 	new_wp->pid = fdforkpty(ptm_fd, &new_wp->fd, new_wp->tty, NULL, &ws);
+ 	if (new_wp->pid == -1) {
+@@ -381,8 +393,15 @@ spawn_pane(struct spawn_context *sc, char **cause)
+ 		return (NULL);
+ 	}
+ 
+-	/* In the parent process, everything is done now. */
++	/*
++	 * In the parent process, everything is done now. Change the working
++	 * directory back.
++	 */
+ 	if (new_wp->pid != 0) {
++		if (actual_cwd != NULL &&
++		    chdir(path) != 0 &&
++		    (home == NULL || chdir(home) != 0))
++			chdir("/");
+ 		goto complete;
+ 	}
+ 
+@@ -397,17 +416,10 @@ spawn_pane(struct spawn_context *sc, char **cause)
+ 	}
+ #endif
+ 	/*
+-	 * Child process. Change to the working directory or home if that
+-	 * fails.
++	 * Child process. Set PWD to the working directory.
+ 	 */
+-	if (chdir(new_wp->cwd) == 0)
+-		environ_set(child, "PWD", 0, "%s", new_wp->cwd);
+-	else if ((tmp = find_home()) != NULL && chdir(tmp) == 0)
+-		environ_set(child, "PWD", 0, "%s", tmp);
+-	else if (chdir("/") == 0)
+-		environ_set(child, "PWD", 0, "/");
+-	else
+-		fatal("chdir failed");
++	if (actual_cwd != NULL)
++		environ_set(child, "PWD", 0, "%s", actual_cwd);
+ 
+ 	/*
+ 	 * Update terminal escape characters from the session if available and
+-- 
+2.54.0
+

diff --git a/tmux.spec b/tmux.spec
index c20900c..50c9a9f 100644
--- a/tmux.spec
+++ b/tmux.spec
@@ -2,7 +2,7 @@
 
 Name:           tmux
 Version:        3.6a
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        A terminal multiplexer
 
 License:        ISC AND BSD-2-Clause AND BSD-3-Clause AND SSH-short AND LicenseRef-Fedora-Public-Domain
@@ -10,6 +10,7 @@ URL:            https://tmux.github.io/
 Source0:        https://github.com/tmux/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz
 Source2:        tmux@.service
 Source3:        README.polkit
+Patch0:         0001-Setting-working-directory-after-fork-means-there-is-.patch
 BuildRequires:  byacc
 BuildRequires:  gcc
 BuildRequires:  systemd-devel
@@ -73,6 +74,9 @@ fi
 %{_unitdir}/tmux@.service
 
 %changelog
+* Tue May 05 2026 Dridi Boukelmoune <dridi@fedoraproject.org> - 3.6a-2
+- Patch #{pane_current_path} race condition
+
 * Mon Feb 23 2026 Filipe Rosset <rosset.filipe@gmail.com> - 3.6a-1
 - Update to tmux 3.6a
 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-06-26 14:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-26 14:54 [rpms/tmux] f43: Patch #{pane_current_path} race condition Dridi Boukelmoune

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox