Skip to content

Commit 5d87dd4

Browse files
j6tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f4fa9c commit 5d87dd4

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

daemon.c

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "cache.h"
22
#include "pkt-line.h"
33
#include "exec_cmd.h"
4+
#include "run-command.h"
5+
#include "strbuf.h"
46

57
#include <syslog.h>
68

@@ -343,28 +345,66 @@ static int run_service(char *dir, struct daemon_service *service)
343345
return service->fn();
344346
}
345347

348+
static void copy_to_log(int fd)
349+
{
350+
struct strbuf line = STRBUF_INIT;
351+
FILE *fp;
352+
353+
fp = fdopen(fd, "r");
354+
if (fp == NULL) {
355+
logerror("fdopen of error channel failed");
356+
close(fd);
357+
return;
358+
}
359+
360+
while (strbuf_getline(&line, fp, '\n') != EOF) {
361+
logerror("%s", line.buf);
362+
strbuf_setlen(&line, 0);
363+
}
364+
365+
strbuf_release(&line);
366+
fclose(fp);
367+
}
368+
369+
static int run_service_command(const char **argv)
370+
{
371+
struct child_process cld;
372+
373+
memset(&cld, 0, sizeof(cld));
374+
cld.argv = argv;
375+
cld.git_cmd = 1;
376+
cld.err = -1;
377+
if (start_command(&cld))
378+
return -1;
379+
380+
close(0);
381+
close(1);
382+
383+
copy_to_log(cld.err);
384+
385+
return finish_command(&cld);
386+
}
387+
346388
static int upload_pack(void)
347389
{
348390
/* Timeout as string */
349391
char timeout_buf[64];
392+
const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
350393

351394
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
352-
353-
/* git-upload-pack only ever reads stuff, so this is safe */
354-
execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
355-
return -1;
395+
return run_service_command(argv);
356396
}
357397

358398
static int upload_archive(void)
359399
{
360-
execl_git_cmd("upload-archive", ".", NULL);
361-
return -1;
400+
static const char *argv[] = { "upload-archive", ".", NULL };
401+
return run_service_command(argv);
362402
}
363403

364404
static int receive_pack(void)
365405
{
366-
execl_git_cmd("receive-pack", ".", NULL);
367-
return -1;
406+
static const char *argv[] = { "receive-pack", ".", NULL };
407+
return run_service_command(argv);
368408
}
369409

370410
static struct daemon_service daemon_service[] = {

0 commit comments

Comments
 (0)