Skip to content

Commit c62f6e6

Browse files
ptarjangitster
authored andcommitted
fsmonitor: close inherited file descriptors and detach in daemon
When the fsmonitor daemon is spawned as a background process, it may inherit file descriptors from its parent that it does not need. In particular, when the test harness or a CI system captures output through pipes, the daemon can inherit duplicated pipe endpoints. If the daemon holds these open, the parent process never sees EOF and may appear to hang. Set close_fd_above_stderr on the child process at both daemon startup paths: the explicit "fsmonitor--daemon start" command and the implicit spawn triggered by fsmonitor-ipc when a client finds no running daemon. Also suppress stdout and stderr on the implicit spawn path to prevent the background daemon from writing to the client's terminal. Additionally, call setsid() when the daemon starts with --detach to create a new session and process group. This prevents the daemon from being part of the spawning shell's process group, which could cause the shell's "wait" to block until the daemon exits. Signed-off-by: Paul Tarjan <github@paulisageek.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent e7cc48a commit c62f6e6

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

builtin/fsmonitor--daemon.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ static int fsmonitor_run_daemon(void)
14391439
return err;
14401440
}
14411441

1442-
static int try_to_run_foreground_daemon(int detach_console MAYBE_UNUSED)
1442+
static int try_to_run_foreground_daemon(int detach_console)
14431443
{
14441444
/*
14451445
* Technically, we don't need to probe for an existing daemon
@@ -1459,10 +1459,21 @@ static int try_to_run_foreground_daemon(int detach_console MAYBE_UNUSED)
14591459
fflush(stderr);
14601460
}
14611461

1462+
if (detach_console) {
14621463
#ifdef GIT_WINDOWS_NATIVE
1463-
if (detach_console)
14641464
FreeConsole();
1465+
#else
1466+
/*
1467+
* Create a new session so that the daemon is detached
1468+
* from the parent's process group. This prevents
1469+
* shells with job control (e.g. bash with "set -m")
1470+
* from waiting on the daemon when they wait for a
1471+
* foreground command that implicitly spawned it.
1472+
*/
1473+
if (setsid() == -1)
1474+
warning_errno(_("setsid failed"));
14651475
#endif
1476+
}
14661477

14671478
return !!fsmonitor_run_daemon();
14681479
}
@@ -1525,6 +1536,7 @@ static int try_to_start_background_daemon(void)
15251536
cp.no_stdin = 1;
15261537
cp.no_stdout = 1;
15271538
cp.no_stderr = 1;
1539+
cp.close_fd_above_stderr = 1;
15281540

15291541
sbgr = start_bg_command(&cp, bg_wait_cb, NULL,
15301542
fsmonitor__start_timeout_sec);

fsmonitor-ipc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ static int spawn_daemon(void)
6161

6262
cmd.git_cmd = 1;
6363
cmd.no_stdin = 1;
64+
cmd.no_stdout = 1;
65+
cmd.no_stderr = 1;
66+
cmd.close_fd_above_stderr = 1;
6467
cmd.trace2_child_class = "fsmonitor";
6568
strvec_pushl(&cmd.args, "fsmonitor--daemon", "start", NULL);
6669

0 commit comments

Comments
 (0)