static const char pre_receive_hook[] = "hooks/pre-receive";
static const char post_receive_hook[] = "hooks/post-receive";
-static int hook_status(int code, const char *hook_name)
+static int run_status(int code, const char *cmd_name)
{
switch (code) {
case 0:
return 0;
case -ERR_RUN_COMMAND_FORK:
- return error("hook fork failed");
+ return error("fork of %s failed", cmd_name);
case -ERR_RUN_COMMAND_EXEC:
- return error("hook execute failed");
+ return error("execute of %s failed", cmd_name);
case -ERR_RUN_COMMAND_PIPE:
- return error("hook pipe failed");
+ return error("pipe failed");
case -ERR_RUN_COMMAND_WAITPID:
return error("waitpid failed");
case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
return error("waitpid is confused");
case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- return error("%s died of signal", hook_name);
+ return error("%s died of signal", cmd_name);
case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- return error("%s died strangely", hook_name);
+ return error("%s died strangely", cmd_name);
default:
- error("%s exited with error code %d", hook_name, -code);
+ error("%s exited with error code %d", cmd_name, -code);
return -code;
}
}
code = start_command(&proc);
if (code)
- return hook_status(code, hook_name);
+ return run_status(code, hook_name);
for (cmd = commands; cmd; cmd = cmd->next) {
if (!cmd->error_string) {
size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
}
}
close(proc.in);
- return hook_status(finish_command(&proc), hook_name);
+ return run_status(finish_command(&proc), hook_name);
}
static int run_update_hook(struct command *cmd)
argv[3] = sha1_to_hex(cmd->new_sha1);
argv[4] = NULL;
- return hook_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
+ return run_status(run_command_v_opt(argv, RUN_COMMAND_NO_STDIN |
RUN_COMMAND_STDOUT_TO_STDERR),
update_hook);
}
static void run_update_post_hook(struct command *cmd)
{
struct command *cmd_p;
- int argc;
+ int argc, status;
const char **argv;
for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
argc++;
}
argv[argc] = NULL;
- run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
- | RUN_COMMAND_STDOUT_TO_STDERR);
+ status = run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
+ | RUN_COMMAND_STDOUT_TO_STDERR);
+ run_status(status, update_post_hook);
}
static void execute_commands(const char *unpacker_error)
unpacker[i++] = hdr_arg;
unpacker[i++] = NULL;
code = run_command_v_opt(unpacker, RUN_GIT_CMD);
- switch (code) {
- case 0:
+ if (!code)
return NULL;
- case -ERR_RUN_COMMAND_FORK:
- return "unpack fork failed";
- case -ERR_RUN_COMMAND_EXEC:
- return "unpack execute failed";
- case -ERR_RUN_COMMAND_WAITPID:
- return "waitpid failed";
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- return "waitpid is confused";
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- return "unpacker died of signal";
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- return "unpacker died strangely";
- default:
- return "unpacker exited with error code";
- }
+ run_status(code, unpacker[0]);
+ return "unpack-objects abnormal exit";
} else {
const char *keeper[7];
int s, status, i = 0;
ip.argv = keeper;
ip.out = -1;
ip.git_cmd = 1;
- if (start_command(&ip))
+ status = start_command(&ip);
+ if (status) {
+ run_status(status, keeper[0]);
return "index-pack fork failed";
+ }
pack_lockfile = index_pack_lockfile(ip.out);
close(ip.out);
status = finish_command(&ip);
reprepare_packed_git();
return NULL;
}
+ run_status(status, keeper[0]);
return "index-pack abnormal exit";
}
}
#include "cache.h"
#include "pkt-line.h"
#include "exec_cmd.h"
+#include "run-command.h"
+#include "strbuf.h"
#include <syslog.h>
return service->fn();
}
+static void copy_to_log(int fd)
+{
+ struct strbuf line = STRBUF_INIT;
+ FILE *fp;
+
+ fp = fdopen(fd, "r");
+ if (fp == NULL) {
+ logerror("fdopen of error channel failed");
+ close(fd);
+ return;
+ }
+
+ while (strbuf_getline(&line, fp, '\n') != EOF) {
+ logerror("%s", line.buf);
+ strbuf_setlen(&line, 0);
+ }
+
+ strbuf_release(&line);
+ fclose(fp);
+}
+
+static int run_service_command(const char **argv)
+{
+ struct child_process cld;
+
+ memset(&cld, 0, sizeof(cld));
+ cld.argv = argv;
+ cld.git_cmd = 1;
+ cld.err = -1;
+ if (start_command(&cld))
+ return -1;
+
+ close(0);
+ close(1);
+
+ copy_to_log(cld.err);
+
+ return finish_command(&cld);
+}
+
static int upload_pack(void)
{
/* Timeout as string */
char timeout_buf[64];
+ const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
-
- /* git-upload-pack only ever reads stuff, so this is safe */
- execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
- return -1;
+ return run_service_command(argv);
}
static int upload_archive(void)
{
- execl_git_cmd("upload-archive", ".", NULL);
- return -1;
+ static const char *argv[] = { "upload-archive", ".", NULL };
+ return run_service_command(argv);
}
static int receive_pack(void)
{
- execl_git_cmd("receive-pack", ".", NULL);
- return -1;
+ static const char *argv[] = { "receive-pack", ".", NULL };
+ return run_service_command(argv);
}
static struct daemon_service daemon_service[] = {