@matheusbsbs / matheus-bagliano / commits / 5d87dd4fca
Fork 0

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>

Johannes Sixt committed Jun 14, 2009 at 22:38 UTC 5d87dd4fcac808fc0f0b993b470644ba7d2d62a2
1 file changed +48 -8
daemon.c
+48 -8
@@ -1,6 +1,8 @@
1 #include "cache.h"
2 #include "pkt-line.h"
3 #include "exec_cmd.h"
4 +#include "run-command.h"
5 +#include "strbuf.h"
6
7 #include <syslog.h>
8
@@ -343,28 +345,66 @@ static int run_service(char *dir, struct daemon_service *service)
345 return service->fn();
346 }
347
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 +
388 static int upload_pack(void)
389 {
390 /* Timeout as string */
391 char timeout_buf[64];
392 + const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
393
394 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);
396 }
397
398 static int upload_archive(void)
399 {
360 - execl_git_cmd("upload-archive", ".", NULL);
361 - return -1;
400 + static const char *argv[] = { "upload-archive", ".", NULL };
401 + return run_service_command(argv);
402 }
403
404 static int receive_pack(void)
405 {
366 - execl_git_cmd("receive-pack", ".", NULL);
367 - return -1;
406 + static const char *argv[] = { "receive-pack", ".", NULL };
407 + return run_service_command(argv);
408 }
409
410 static struct daemon_service daemon_service[] = {