Skip to content

Commit fc1b56f

Browse files
Clemens Buchachergitster
authored andcommitted
notice error exit from pager
If the pager fails to run, git produces no output, e.g.: $ GIT_PAGER=not-a-command git log The error reporting fails for two reasons: (1) start_command: There is a mechanism that detects errors during execvp introduced in 2b541bf (start_command: detect execvp failures early). The child writes one byte to a pipe only if execvp fails. The parent waits for either EOF, when the successful execvp automatically closes the pipe (see FD_CLOEXEC in fcntl(1)), or it reads a single byte, in which case it knows that the execvp failed. This mechanism is incompatible with the workaround introduced in 35ce862 (pager: Work around window resizing bug in 'less'), which waits for input from the parent before the exec. Since both the parent and the child are waiting for input from each other, that would result in a deadlock. In order to avoid that, the mechanism is disabled by closing the child_notifier file descriptor. (2) finish_command: The parent correctly detects the 127 exit status from the child, but the error output goes nowhere, since by that time it is already being redirected to the child. No simple solution for (1) comes to mind. Number (2) can be solved by not sending error output to the pager. Not redirecting error output to the pager can result in the pager overwriting error output with standard output, however. Since there is no reliable way to handle error reporting in the parent, produce the output in the child instead. Signed-off-by: Clemens Buchacher <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3bc4181 commit fc1b56f

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

run-command.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@ static int wait_or_whine(pid_t pid, const char *argv0, int silent_exec_failure)
125125
if (code == 127) {
126126
code = -1;
127127
failed_errno = ENOENT;
128-
if (!silent_exec_failure)
129-
error("cannot run %s: %s", argv0,
130-
strerror(ENOENT));
131128
}
132129
} else {
133130
error("waitpid is confused (%s)", argv0);
@@ -282,14 +279,14 @@ int start_command(struct child_process *cmd)
282279
} else {
283280
execvp(cmd->argv[0], (char *const*) cmd->argv);
284281
}
285-
/*
286-
* Do not check for cmd->silent_exec_failure; the parent
287-
* process will check it when it sees this exit code.
288-
*/
289-
if (errno == ENOENT)
282+
if (errno == ENOENT) {
283+
if (!cmd->silent_exec_failure)
284+
error("cannot run %s: %s", cmd->argv[0],
285+
strerror(ENOENT));
290286
exit(127);
291-
else
287+
} else {
292288
die_errno("cannot exec '%s'", cmd->argv[0]);
289+
}
293290
}
294291
if (cmd->pid < 0)
295292
error("cannot fork() for %s: %s", cmd->argv[0],

0 commit comments

Comments
 (0)