mirror of
https://github.com/git/git
synced 2024-10-02 14:45:21 +00:00
daemon: send stderr of service programs to the syslog
If git-daemon is run with --detach or --inetd, then stderr is explicitly redirected to /dev/null. But notice that the service programs were spawned via execl_git_cmd(), in particular, the stderr channel is inherited from the daemon. This means that errors that the programs wrote to stderr (for example, via die()), went to /dev/null. This patch arranges that the daemon does not merely exec the service program, but forks it and monitors stderr of the child; it writes the errors that it produces to the daemons log via logerror(). A consequence is that the daemon process remains in memory for the full duration of the service program, but this cannot be avoided. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
4f4fa9c228
commit
5d87dd4fca
56
daemon.c
56
daemon.c
|
@ -1,6 +1,8 @@
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
#include "exec_cmd.h"
|
#include "exec_cmd.h"
|
||||||
|
#include "run-command.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
|
@ -343,28 +345,66 @@ static int run_service(char *dir, struct daemon_service *service)
|
||||||
return service->fn();
|
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)
|
static int upload_pack(void)
|
||||||
{
|
{
|
||||||
/* Timeout as string */
|
/* Timeout as string */
|
||||||
char timeout_buf[64];
|
char timeout_buf[64];
|
||||||
|
const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
|
||||||
|
|
||||||
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
|
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
|
||||||
|
return run_service_command(argv);
|
||||||
/* git-upload-pack only ever reads stuff, so this is safe */
|
|
||||||
execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int upload_archive(void)
|
static int upload_archive(void)
|
||||||
{
|
{
|
||||||
execl_git_cmd("upload-archive", ".", NULL);
|
static const char *argv[] = { "upload-archive", ".", NULL };
|
||||||
return -1;
|
return run_service_command(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int receive_pack(void)
|
static int receive_pack(void)
|
||||||
{
|
{
|
||||||
execl_git_cmd("receive-pack", ".", NULL);
|
static const char *argv[] = { "receive-pack", ".", NULL };
|
||||||
return -1;
|
return run_service_command(argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct daemon_service daemon_service[] = {
|
static struct daemon_service daemon_service[] = {
|
||||||
|
|
Loading…
Reference in a new issue