561
return 0;
562
}
563
564
+/*
565
+ * Start an async thread which redirects hook stderr over the sideband.
566
+ * The original stderr fd is saved to `saved_stderr` and STDERR_FILENO is
567
+ * redirected to the async's input pipe.
568
+ */
569
+static void prepare_sideband_async(struct async *sideband_async, int *saved_stderr, int *started)
570
+{
571
+ *started = 0;
572
+
573
+ if (!use_sideband)
574
+ return;
575
+
576
+ memset(sideband_async, 0, sizeof(*sideband_async));
577
+ sideband_async->proc = copy_to_sideband;
578
+ sideband_async->in = -1;
579
+
580
+ if (!start_async(sideband_async)) {
581
+ *started = 1;
582
+ *saved_stderr = dup(STDERR_FILENO);
583
+ if (*saved_stderr >= 0)
584
+ dup2(sideband_async->in, STDERR_FILENO);
585
+ close(sideband_async->in);
586
+ }
587
+}
588
+
589
+/*
590
+ * Restore the original stderr and wait for the async sideband thread to finish.
591
+ */
592
+static void finish_sideband_async(struct async *sideband_async, int saved_stderr, int started)
593
+{
594
+ if (!use_sideband)
595
+ return;
596
+
597
+ if (saved_stderr >= 0) {
598
+ dup2(saved_stderr, STDERR_FILENO);
599
+ close(saved_stderr);
600
+ }
601
+
602
+ if (started)
603
+ finish_async(sideband_async);
604
+}
605
+
606
static void hmac_hash(unsigned char *out,
607
const char *key_in, size_t key_len,
608
const char *text, size_t text_len)
983
984
static int run_update_hook(struct command *cmd)
985
{
944
- struct child_process proc = CHILD_PROCESS_INIT;
986
+ struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
987
+ struct async sideband_async;
988
+ int sideband_async_started = 0;
989
+ int saved_stderr = -1;
990
int code;
946
- const char *hook_path = find_hook(the_repository, "update");
991
948
- if (!hook_path)
949
- return 0;
992
+ strvec_pushl(&opt.args,
993
+ cmd->ref_name,
994
+ oid_to_hex(&cmd->old_oid),
995
+ oid_to_hex(&cmd->new_oid),
996
+ NULL);
997
951
- strvec_push(&proc.args, hook_path);
952
- strvec_push(&proc.args, cmd->ref_name);
953
- strvec_push(&proc.args, oid_to_hex(&cmd->old_oid));
954
- strvec_push(&proc.args, oid_to_hex(&cmd->new_oid));
998
+ prepare_sideband_async(&sideband_async, &saved_stderr, &sideband_async_started);
999
956
- proc.no_stdin = 1;
957
- proc.stdout_to_stderr = 1;
958
- proc.err = use_sideband ? -1 : 0;
959
- proc.trace2_hook_name = "update";
1000
+ code = run_hooks_opt(the_repository, "update", &opt);
1001
961
- code = start_command(&proc);
962
- if (code)
963
- return code;
964
- if (use_sideband)
965
- copy_to_sideband(proc.err, -1, NULL);
966
- return finish_command(&proc);
1002
+ finish_sideband_async(&sideband_async, saved_stderr, sideband_async_started);
1003
+
1004
+ return code;
1005
}
1006
1007
static struct command *find_command_by_refname(struct command *list,
1677
1678
static void run_update_post_hook(struct command *commands)
1679
{
1680
+ struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
1681
+ struct async sideband_async;
1682
struct command *cmd;
1643
- struct child_process proc = CHILD_PROCESS_INIT;
1644
- const char *hook;
1645
-
1646
- hook = find_hook(the_repository, "post-update");
1647
- if (!hook)
1648
- return;
1683
+ int sideband_async_started = 0;
1684
+ int saved_stderr = -1;
1685
1686
for (cmd = commands; cmd; cmd = cmd->next) {
1687
if (cmd->error_string || cmd->did_not_exist)
1688
continue;
1653
- if (!proc.args.nr)
1654
- strvec_push(&proc.args, hook);
1655
- strvec_push(&proc.args, cmd->ref_name);
1689
+ strvec_push(&opt.args, cmd->ref_name);
1690
}
1657
- if (!proc.args.nr)
1691
+ if (!opt.args.nr)
1692
return;
1693
1660
- proc.no_stdin = 1;
1661
- proc.stdout_to_stderr = 1;
1662
- proc.err = use_sideband ? -1 : 0;
1663
- proc.trace2_hook_name = "post-update";
1694
+ prepare_sideband_async(&sideband_async, &saved_stderr, &sideband_async_started);
1695
1665
- if (!start_command(&proc)) {
1666
- if (use_sideband)
1667
- copy_to_sideband(proc.err, -1, NULL);
1668
- finish_command(&proc);
1669
- }
1696
+ run_hooks_opt(the_repository, "post-update", &opt);
1697
+
1698
+ finish_sideband_async(&sideband_async, saved_stderr, sideband_async_started);
1699
}
1700
1701
static void check_aliased_update_internal(struct command *cmd,