@@ -938,33 +938,56 @@ static int run_receive_hook(struct command *commands,
return status;
}
-static int run_update_hook(struct command *cmd)
+static void hook_output_to_sideband(struct strbuf *output, void *cb_data)
{
- const char *argv[5];
- struct child_process proc = CHILD_PROCESS_INIT;
- int code;
+ int keepalive_active = 0;
- argv[0] = find_hook("update");
- if (!argv[0])
- return 0;
+ if (keepalive_in_sec <= 0)
+ use_keepalive = KEEPALIVE_NEVER;
+ if (use_keepalive == KEEPALIVE_ALWAYS)
+ keepalive_active = 1;
- argv[1] = cmd->ref_name;
- argv[2] = oid_to_hex(&cmd->old_oid);
- argv[3] = oid_to_hex(&cmd->new_oid);
- argv[4] = NULL;
+ /* send a keepalive if there is no data to write */
+ if (keepalive_active && !output->len) {
+ static const char buf[] = "0005\1";
+ write_or_die(1, buf, sizeof(buf) - 1);
+ return;
+ }
- proc.no_stdin = 1;
- proc.stdout_to_stderr = 1;
- proc.err = use_sideband ? -1 : 0;
- proc.argv = argv;
- proc.trace2_hook_name = "update";
+ if (use_keepalive == KEEPALIVE_AFTER_NUL && !keepalive_active) {
+ const char *first_null = memchr(output->buf, '\0', output->len);
+ if (first_null) {
+ /* The null bit is excluded. */
+ size_t before_null = first_null - output->buf;
+ size_t after_null = output->len - (before_null + 1);
+ keepalive_active = 1;
+ send_sideband(1, 2, output->buf, before_null, use_sideband);
+ send_sideband(1, 2, first_null + 1, after_null, use_sideband);
+
+ return;
+ }
+ }
+
+ send_sideband(1, 2, output->buf, output->len, use_sideband);
+}
+
+static int run_update_hook(struct command *cmd)
+{
+ struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
+ int code;
+
+ strvec_pushl(&opt.args,
+ cmd->ref_name,
+ oid_to_hex(&cmd->old_oid),
+ oid_to_hex(&cmd->new_oid),
+ NULL);
- code = start_command(&proc);
- if (code)
- return code;
if (use_sideband)
- copy_to_sideband(proc.err, -1, NULL);
- return finish_command(&proc);
+ opt.consume_sideband = hook_output_to_sideband;
+
+ code = run_hooks("update", &opt);
+ run_hooks_opt_clear(&opt);
+ return code;
}
static struct command *find_command_by_refname(struct command *list,