mirror of
https://github.com/git/git
synced 2024-08-24 18:26:02 +00:00
Merge branch 'pr/use-default-sigpipe-setting'
We used to get confused when a process called us with SIGPIPE ignored; we do want to die with SIGPIPE when the output is not read by default, and do ignore the signal when appropriate. * pr/use-default-sigpipe-setting: mingw.h: add dummy functions for sigset_t operations unblock and unignore SIGPIPE
This commit is contained in:
commit
131f0315c4
|
@ -69,7 +69,6 @@ struct sigaction {
|
||||||
sig_handler_t sa_handler;
|
sig_handler_t sa_handler;
|
||||||
unsigned sa_flags;
|
unsigned sa_flags;
|
||||||
};
|
};
|
||||||
#define sigemptyset(x) (void)0
|
|
||||||
#define SA_RESTART 0
|
#define SA_RESTART 0
|
||||||
|
|
||||||
struct itimerval {
|
struct itimerval {
|
||||||
|
@ -116,6 +115,12 @@ static inline int fcntl(int fd, int cmd, ...)
|
||||||
}
|
}
|
||||||
/* bash cannot reliably detect negative return codes as failure */
|
/* bash cannot reliably detect negative return codes as failure */
|
||||||
#define exit(code) exit((code) & 0xff)
|
#define exit(code) exit((code) & 0xff)
|
||||||
|
#define sigemptyset(x) (void)0
|
||||||
|
static inline int sigaddset(sigset_t *set, int signum)
|
||||||
|
{ return 0; }
|
||||||
|
#define SIG_UNBLOCK 0
|
||||||
|
static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* simple adaptors
|
* simple adaptors
|
||||||
|
|
22
git.c
22
git.c
|
@ -592,6 +592,26 @@ static int run_argv(int *argcp, const char ***argv)
|
||||||
return done_alias;
|
return done_alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Many parts of Git have subprograms communicate via pipe, expect the
|
||||||
|
* upstream of a pipe to die with SIGPIPE when the downstream of a
|
||||||
|
* pipe does not need to read all that is written. Some third-party
|
||||||
|
* programs that ignore or block SIGPIPE for their own reason forget
|
||||||
|
* to restore SIGPIPE handling to the default before spawning Git and
|
||||||
|
* break this carefully orchestrated machinery.
|
||||||
|
*
|
||||||
|
* Restore the way SIGPIPE is handled to default, which is what we
|
||||||
|
* expect.
|
||||||
|
*/
|
||||||
|
static void restore_sigpipe_to_default(void)
|
||||||
|
{
|
||||||
|
sigset_t unblock;
|
||||||
|
|
||||||
|
sigemptyset(&unblock);
|
||||||
|
sigaddset(&unblock, SIGPIPE);
|
||||||
|
sigprocmask(SIG_UNBLOCK, &unblock, NULL);
|
||||||
|
signal(SIGPIPE, SIG_DFL);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **av)
|
int main(int argc, char **av)
|
||||||
{
|
{
|
||||||
|
@ -611,6 +631,8 @@ int main(int argc, char **av)
|
||||||
*/
|
*/
|
||||||
sanitize_stdfds();
|
sanitize_stdfds();
|
||||||
|
|
||||||
|
restore_sigpipe_to_default();
|
||||||
|
|
||||||
git_setup_gettext();
|
git_setup_gettext();
|
||||||
|
|
||||||
trace_command_performance(argv);
|
trace_command_performance(argv);
|
||||||
|
|
|
@ -27,4 +27,26 @@ test_expect_success !MINGW 'signals are propagated using shell convention' '
|
||||||
test_expect_code 143 git sigterm
|
test_expect_code 143 git sigterm
|
||||||
'
|
'
|
||||||
|
|
||||||
|
large_git () {
|
||||||
|
for i in $(test_seq 1 100)
|
||||||
|
do
|
||||||
|
git diff --cached --binary || return
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success 'create blob' '
|
||||||
|
test-genrandom foo 16384 >file &&
|
||||||
|
git add file
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success !MINGW 'a constipated git dies with SIGPIPE' '
|
||||||
|
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 )
|
||||||
|
test "$OUT" -eq 141
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success !MINGW 'a constipated git dies with SIGPIPE even if parent ignores it' '
|
||||||
|
OUT=$( ((trap "" PIPE; large_git; echo $? 1>&3) | :) 3>&1 )
|
||||||
|
test "$OUT" -eq 141
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Loading…
Reference in a new issue