credential-cache: close stderr in daemon process
PATCH 1/1 credential-cache: close stderr in daemon process
If the stderr of "git credential-cache" is redirected to a pipe, the reader on the other end of a pipe may be surprised that the pipe remains open long after the process exits. This happens because we may auto-spawn a daemon which is long-lived, and which keeps stderr open.
We can solve this by redirecting the daemon's stderr to /dev/null once we are ready to go into our event loop. We would not want to do so before then, because we may want to report errors about the setup (e.g., failure to establish the listening socket).
This does mean that we will not report errors we encounter for specific clients. That's acceptable, as such errors should be rare (e.g., clients sending buggy requests). However, we also provide an escape hatch: if you want to see these later messages, you can provide the "--debug" option to keep stderr open.
--- Documentation/git-credential-cache--daemon.txt | 6 +++++- credential-cache--daemon.c | 23 +++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-)
Documentation/git-credential-cache--daemon.txt +5 -1
@@ -8,7 +8,7 @@ git-credential-cache--daemon - Temporarily store user credentials in memory SYNOPSIS -------- [verse] -git credential-cache--daemon <socket> +git credential-cache--daemon [--debug] <socket> DESCRIPTION -----------
@@ -21,6 +21,10 @@ for `git-credential-cache` clients. Clients may store and retrieve credentials. Each credential is held for a timeout specified by the client; once no credentials are held, the daemon exits. +If the `--debug` option is specified, the daemon does not close its +stderr stream, and may output extra diagnostics to it even after it has +begun listening for clients. + GIT --- Part of the linkgit:git[1] suite
credential-cache--daemon.c +19 -4
@@ -2,6 +2,7 @@#include "credential.h" #include "unix-socket.h" #include "sigchain.h" +#include "parse-options.h" static const char *socket_path;
@@ -201,7 +202,7 @@ static int serve_cache_loop(int fd)return 1 ; } -static void serve_cache (const char *socket_path) +static void serve_cache (const char *socket_path,int debug) {int fd;
@@ -211,6 +212,8 @@ static void serve_cache(const char *socket_path)printf ("ok\n" );fclose (stdout); +if (!debug) +freopen ("/dev/null" ,"w" , stderr);while (serve_cache_loop (fd)) ;/* nothing */
@@ -252,16 +255,28 @@ static void check_socket_directory(const char *path)int main (int argc,const char **argv) { - socket_path = argv[1 ]; +static const char *usage[] = { +"git-credential-cache--daemon [opts] <socket_path>" , +NULL + }; +int debug =0 ; +const struct option options[] = { +OPT_BOOL (0 ,"debug" , &debug, +N_ ("print debugging messages to stderr" )), +OPT_END () + }; + + argc =parse_options (argc, argv,NULL , options, usage,0 ); + socket_path = argv[0 ];if (!socket_path) -die ("usage: git-credential-cache--daemon <socket_path>" ); +usage_with_options (usage, options);check_socket_directory (socket_path);atexit (cleanup_socket);sigchain_push_common (cleanup_socket_on_signal); -serve_cache (socket_path); +serve_cache (socket_path, debug);return 0 ; }
Signature · 1 line
2.1.0.373.g91ca799
credential-cache--daemon.c static void serve_cache(const char *socket_path) · line 216
Quoted 2 lines · Jeff King
credential-cache--daemon.c +2
-0+if (!debug) +freopen ("/dev/null" ,"w" , stderr);
I am getting this:
credential-cache--daemon.c:216:10: error: ignoring return value of 'freopen', declared with attribute warn_unused_result [-Werror=unused-result]
which is somewhat irritating. Even though I am not irritated by this code, but by the compiler and glibc headers, this is apparently the only offending one, so we may want to fix it anyway.
Quoted 10 lines · Junio C Hamano
Review
Quoted 2 lines · Jeff King
(quoted diff) +2
-0+ if (!debug) + freopen("/dev/null", "w", stderr);I am getting this:
credential-cache--daemon.c:216:10: error: ignoring return value of 'freopen', declared with attribute
warn_unused_result[-Werror=unused-result]
Hmph, my glibc does not seem to mark freopen. It's probably sane to check it for error, as we would otherwise probably segfault on the next call to "fprintf(stderr)".
Quoted 1 line
From my reading of freopen(3posix), I do not think we need to do
anything like "stderr = freopen(..., stderr);". The filehandle is repointed, not re-allocated. And anyway, that is the assumption all of our other freopen calls make. :)
Quoted 3 lines
which is somewhat irritating. Even though I am not irritated by this code, but by the compiler and glibc headers, this is apparently the only offending one, so we may want to fix it anyway.
Squash this in?
credential-cache--daemon.c +4 -2
@@ -212,8 +212,10 @@ static void serve_cache(const char *socket_path, int debug)printf ("ok\n" );fclose (stdout); -if (!debug) -freopen ("/dev/null" ,"w" , stderr); +if (!debug) { +if (!freopen ("/dev/null" ,"w" , stderr)) +die_errno ("unable to point stderr to /dev/null" ); + }while (serve_cache_loop (fd)) ;/* nothing */
Quoted 1 line · Jeff King
Squash this in?
Yeah, I did a crude one without _errno() while sending the report; will replace.
Thanks.
Quoted 18 lines
credential-cache--daemon.c +4
-2@@ -212,8 +212,10 @@ static void serve_cache(const char *socket_path, int debug)printf ("ok\n" );fclose (stdout); -if (!debug) -freopen ("/dev/null" ,"w" , stderr); +if (!debug) { +if (!freopen ("/dev/null" ,"w" , stderr)) +die_errno ("unable to point stderr to /dev/null" ); + }while (serve_cache_loop (fd)) ;/* nothing */