gpg-agent --daemon running in foreground

Ciprian Dorin, Craciun ciprian.craciun at gmail.com
Mon Oct 12 15:57:49 CEST 2009


On Mon, Oct 12, 2009 at 4:08 PM, David Shaw <dshaw at jabberwocky.com> wrote:
> On Oct 12, 2009, at 7:58 AM, Ciprian Dorin, Craciun wrote:
>
>>   Hello all!
>>
>>   I'm facing the following problem: I need to run gpg-agent, but
>> without him going into background. Is there any solution to this one?
>
> I'm not sure exactly what you're trying to do, but you can run gpg-agent
> without it backgrounding by leaving off the "--daemon" option.
>
> David

    So I have the following situation: I want to be able to run
gpg-agent inside a runsv process (part of runit package), that
monitors the process, and in case it breaks, it shall restart it.
Unfortunately gpg-agent forks into background, and thus I cannot
monitor if it's running from inside runsv.

    Thus I need to make gpg-agent behave just like `gpg-agent
--server` (not forking into background), but using the sockets (just
like --daemon).

    Anyway, I've modified the latest source code (2.0.13), file
agent/gpg-agent.c, to add another option --daemon-fg, that shall not
fork in background. (The patch is attached.) (I'm not very proud of
the patch but it does the job. Hope I've not broken anything... :) )

    So I would like to ask the maintainer of gpg-agent to look upon
it, and either include it, either (if time allows him) provide such an
option.

    Thanks,
    Ciprian.
-------------- next part --------------
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 2e81567..ac2dfdb 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -74,6 +74,7 @@ enum cmd_and_opt_values
   oLogFile,
   oServer,
   oDaemon,
+  oDaemonFg,
   oBatch,
 
   oPinentryProgram,
@@ -120,6 +121,7 @@ static ARGPARSE_OPTS opts[] = {
 
   { oServer,   "server",     0, N_("run in server mode (foreground)") },
   { oDaemon,   "daemon",     0, N_("run in daemon mode (background)") },
+  { oDaemonFg, "daemon-fg",  0, N_("run in daemon mode (foreground)") },
   { oVerbose, "verbose",     0, N_("verbose") },
   { oQuiet,	"quiet",     0, N_("be somewhat more quiet") },
   { oSh,	"sh",        0, N_("sh-style command output") },
@@ -743,6 +745,7 @@ main (int argc, char **argv )
         case oSh: csh_style = 0; break;
         case oServer: pipe_server = 1; break;
         case oDaemon: is_daemon = 1; break;
+        case oDaemonFg: is_daemon = 2; break;
 
         case oDisplay: default_display = xstrdup (pargs.r.ret_str); break;
         case oTTYname: default_ttyname = xstrdup (pargs.r.ret_str); break;
@@ -996,7 +999,10 @@ main (int argc, char **argv )
       pid = getpid ();
       printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid);
 #else /*!HAVE_W32_SYSTEM*/
-      pid = fork ();
+      if (is_daemon == 1)
+          pid = fork ();
+      else
+          pid = getpid ();
       if (pid == (pid_t)-1) 
         {
           log_fatal ("fork failed: %s\n", strerror (errno) );
@@ -1007,7 +1013,8 @@ main (int argc, char **argv )
           char *infostr, *infostr_ssh_sock, *infostr_ssh_pid;
 
           /* Close the socket FD. */
-          close (fd);
+          if (is_daemon == 1)
+              close (fd);
 
           /* Note that we used a standard fork so that Pth runs in
              both the parent and the child.  The pth_fork would
@@ -1019,18 +1026,21 @@ main (int argc, char **argv )
              right now and thus we restore it.  That is not strictly
              necessary but some programs falsely assume a cleared
              signal mask.  */
-          if ( !pth_kill () )
-            log_error ("pth_kill failed in forked process\n");
+          if (is_daemon == 1)
+             if ( !pth_kill () )
+                log_error ("pth_kill failed in forked process\n");
             
 #ifdef HAVE_SIGPROCMASK
-          if (startup_signal_mask_valid)
-            {
-              if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
-                log_error ("error restoring signal mask: %s\n",
-                           strerror (errno));
-            }
-          else
-            log_info ("no saved signal mask\n");
+          if (is_daemon == 1) {
+              if (startup_signal_mask_valid)
+                {
+                  if (sigprocmask (SIG_SETMASK, &startup_signal_mask, NULL))
+                    log_error ("error restoring signal mask: %s\n",
+                               strerror (errno));
+                }
+              else
+                log_info ("no saved signal mask\n");
+          }
 #endif /*HAVE_SIGPROCMASK*/          
 
           /* Create the info string: <name>:<pid>:<protocol_version> */
@@ -1090,6 +1100,10 @@ main (int argc, char **argv )
 
           if (argc) 
             { /* Run the program given on the commandline.  */
+              if (is_daemon != 1) {
+                  log_error ("no command expected.\n");
+                  exit (1);
+              }
               if (putenv (infostr))
                 {
                   log_error ("failed to set environment: %s\n",
@@ -1128,7 +1142,7 @@ main (int argc, char **argv )
             {
               /* Print the environment string, so that the caller can use
                  shell's eval to set it */
-              if (csh_style)
+              if (is_daemon == 1 && csh_style)
                 {
                   *strchr (infostr, '=') = ' ';
                   printf ("setenv %s\n", infostr);
@@ -1140,7 +1154,7 @@ main (int argc, char **argv )
 		      printf ("setenv %s\n", infostr_ssh_pid);
 		    }
                 }
-              else
+              else if (is_daemon == 1)
                 {
                   printf ( "%s; export GPG_AGENT_INFO;\n", infostr);
 		  if (opt.ssh_support)
@@ -1155,7 +1169,8 @@ main (int argc, char **argv )
 		  xfree (infostr_ssh_sock);
 		  xfree (infostr_ssh_pid);
 		}
-              exit (0); 
+              if (is_daemon == 1)
+                  exit (0);
             }
           /*NOTREACHED*/
         } /* End parent */
@@ -1185,7 +1200,7 @@ main (int argc, char **argv )
                     }
                 }
             }
-          if (setsid() == -1)
+          if (is_daemon == 1 && setsid() == -1)
             {
               log_error ("setsid() failed: %s\n", strerror(errno) );
               cleanup ();


More information about the Gnupg-users mailing list