[svn] assuan - r200 - in trunk: . src tests

svn author wk cvs at cvs.gnupg.org
Wed Sep 13 17:55:26 CEST 2006


Author: wk
Date: 2006-09-13 17:55:25 +0200 (Wed, 13 Sep 2006)
New Revision: 200

Modified:
   trunk/NEWS
   trunk/TODO
   trunk/src/ChangeLog
   trunk/src/assuan-buffer.c
   trunk/src/assuan-client.c
   trunk/src/assuan-defs.h
   trunk/src/assuan-handler.c
   trunk/src/assuan-listen.c
   trunk/src/assuan-pipe-connect.c
   trunk/src/assuan-pipe-server.c
   trunk/src/assuan-socket-connect.c
   trunk/src/assuan-socket-server.c
   trunk/src/assuan-uds.c
   trunk/src/assuan.h
   trunk/src/mkerrors
   trunk/tests/fdpassing.c
Log:
More tweaks for descriptor passing.
gpg-connect-agent may now be used as a test program.


Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/NEWS	2006-09-13 15:55:25 UTC (rev 200)
@@ -17,11 +17,12 @@
    printing of the full data, a new environment variable
    ASSUAN_FULL_LOGGING may be set to any value.
 
- * Removed the assuan_domain fucntions.  Added new function
-   assuan_pipe_connect_ext to allow connections on a socketpair and to
-   pass descriptors.
+ * Removed the assuan_domain functions. 
 
+ * New functions assuan_pipe_connect_ext and assuan_socket_connext_ext
+   to allow connections on a socketpair and to pass descriptors.
 
+
 Noteworthy changes in version 0.6.10 (2005-06-20)
 -------------------------------------------------
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/TODO	2006-09-13 15:55:25 UTC (rev 200)
@@ -10,7 +10,6 @@
   for unknown inquiries, albeit dirmngr itself would handle the
   returns for assuan_inquire gracefully.  We need to check all
   applications whether it is safe to change this.
-* Check the system error to assuan error translation
 * Do a configure test for SO_PEERCRED.
   We already use HAVE_SO_PEERCRED buty it never gets defined.
 * Replace assuan_pipe_connect2 by  assuan_pipe_connect.
\ No newline at end of file

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/ChangeLog	2006-09-13 15:55:25 UTC (rev 200)
@@ -1,5 +1,29 @@
+2006-09-13  Werner Koch  <wk at g10code.com>
+
+	* assuan-client.c (assuan_transact): Need to map the error code.
+	* mkerrors: Need to map ASSUAN_No_Secret_Key.
+
+	* assuan-pipe-server.c (is_valid_socket): New.
+	(assuan_init_pipe_server): Use UDS with the environmet variable is
+	set and a valid descriptor is given.  Ignore FILEDES in this case.
+
+	* assuan-socket-server.c (assuan_init_socket_server_ext): New.
+	Changed other init fucntions to make use of it.
+
+	* assuan-handler.c (assuan_command_parse_fd): Allow for lowercase
+	"fd".
+	(std_handler_reset): Close pending fds.
+	* assuan-uds.c (uds_receivefd): Fixed.
+	(_assuan_uds_close_fds): New.
+
+	* assuan-socket-connect.c (assuan_socket_connect_ext): New. Takes
+	all code of assuan_socket_connect plus an option to use sendmsg.
+	* assuan-pipe-connect.c (assuan_pipe_connect_ext): New arg FLAGS.
+
 2006-09-12  Werner Koch  <wk at g10code.com>
 
+	* assuan-buffer.c (_assuan_write_line): Also log the prefix.
+
 	* assuan-defs.h (DIM, DIMof): New.
 
 	* assuan-domain-server.c: Removed.

Modified: trunk/src/assuan-buffer.c
===================================================================
--- trunk/src/assuan-buffer.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-buffer.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -269,7 +269,11 @@
       if (ctx->confidential)
 	fputs ("[Confidential data not shown]", ctx->log_fp);
       else
-	_assuan_log_print_buffer (ctx->log_fp, line, len);
+        {
+          if (prefixlen)
+            _assuan_log_print_buffer (ctx->log_fp, prefix, prefixlen);
+          _assuan_log_print_buffer (ctx->log_fp, line, len);
+        }
       putc ('\n', ctx->log_fp);
     }
 

Modified: trunk/src/assuan-client.c
===================================================================
--- trunk/src/assuan-client.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-client.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -160,7 +160,7 @@
 
   if (!okay)
     {
-      rc = atoi (line);
+      rc = _assuan_error (atoi (line));
       if (rc < 100)
         rc = ASSUAN_Server_Fault;
     }

Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-defs.h	2006-09-13 15:55:25 UTC (rev 200)
@@ -185,6 +185,7 @@
 void _assuan_release_context (ASSUAN_CONTEXT ctx);
 
 /*-- assuan-uds.c --*/
+void _assuan_uds_close_fds (assuan_context_t ctx);
 void _assuan_uds_deinit (assuan_context_t ctx);
 void _assuan_init_uds_io (assuan_context_t ctx);
 

Modified: trunk/src/assuan-handler.c
===================================================================
--- trunk/src/assuan-handler.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-handler.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -37,20 +37,20 @@
 
 
 static int
-dummy_handler (ASSUAN_CONTEXT ctx, char *line)
+dummy_handler (assuan_context_t ctx, char *line)
 {
   return set_error (ctx, Server_Fault, "no handler registered");
 }
 
 
 static int
-std_handler_nop (ASSUAN_CONTEXT ctx, char *line)
+std_handler_nop (assuan_context_t ctx, char *line)
 {
   return 0; /* okay */
 }
   
 static int
-std_handler_cancel (ASSUAN_CONTEXT ctx, char *line)
+std_handler_cancel (assuan_context_t ctx, char *line)
 {
   if (ctx->cancel_notify_fnc)
     ctx->cancel_notify_fnc (ctx);
@@ -58,7 +58,7 @@
 }
 
 static int
-std_handler_option (ASSUAN_CONTEXT ctx, char *line)
+std_handler_option (assuan_context_t ctx, char *line)
 {
   char *key, *value, *p;
 
@@ -105,7 +105,7 @@
 }
   
 static int
-std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
+std_handler_bye (assuan_context_t ctx, char *line)
 {
   if (ctx->bye_notify_fnc)
     ctx->bye_notify_fnc (ctx);
@@ -115,33 +115,35 @@
 }
   
 static int
-std_handler_auth (ASSUAN_CONTEXT ctx, char *line)
+std_handler_auth (assuan_context_t ctx, char *line)
 {
   return set_error (ctx, Not_Implemented, NULL); 
 }
   
 static int
-std_handler_reset (ASSUAN_CONTEXT ctx, char *line)
+std_handler_reset (assuan_context_t ctx, char *line)
 {
   if (ctx->reset_notify_fnc)
     ctx->reset_notify_fnc (ctx);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
+  _assuan_uds_close_fds (ctx);
   return 0;
 }
   
 static int
-std_handler_end (ASSUAN_CONTEXT ctx, char *line)
+std_handler_end (assuan_context_t ctx, char *line)
 {
   return set_error (ctx, Not_Implemented, NULL); 
 }
 
 assuan_error_t
-assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd)
+assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
 {
   char *endp;
 
-  if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0'))
+  if ( (strncmp (line, "FD", 2) && strncmp (line, "fd", 2))
+       || (line[2] != '=' && line[2] != '\0'))
     return set_error (ctx, Syntax_Error, "FD[=<n>] expected");
   line += 2;
   if (*line == '=')
@@ -150,7 +152,7 @@
       if (!digitp (*line))
 	return set_error (ctx, Syntax_Error, "number required");
       *rfd = strtoul (line, &endp, 10);
-      /* remove that argument so that a notify handler won't see it */
+      /* Remove that argument so that a notify handler won't see it. */
       memset (line, ' ', endp? (endp-line):strlen(line));
 
       if (*rfd == ctx->inbound.fd)
@@ -166,7 +168,7 @@
 
 /* Format is INPUT FD=<n> */
 static int
-std_handler_input (ASSUAN_CONTEXT ctx, char *line)
+std_handler_input (assuan_context_t ctx, char *line)
 {
   int rc, fd;
 
@@ -181,7 +183,7 @@
 
 /* Format is OUTPUT FD=<n> */
 static int
-std_handler_output (ASSUAN_CONTEXT ctx, char *line)
+std_handler_output (assuan_context_t ctx, char *line)
 {
   int rc, fd;
 
@@ -203,7 +205,7 @@
    with default handlers */
 static struct {
   const char *name;
-  int (*handler)(ASSUAN_CONTEXT, char *line);
+  int (*handler)(assuan_context_t, char *line);
   int always; /* always initialize this command */
 } std_cmd_table[] = {
   { "NOP",    std_handler_nop, 1 },
@@ -235,9 +237,9 @@
  * Return value: 0 on success or an error code
  **/
 int
-assuan_register_command (ASSUAN_CONTEXT ctx,
+assuan_register_command (assuan_context_t ctx,
                          const char *cmd_name,
-                         int (*handler)(ASSUAN_CONTEXT, char *))
+                         int (*handler)(assuan_context_t, char *))
 {
   int i;
   const char *s;
@@ -290,7 +292,8 @@
 }
 
 int
-assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
+assuan_register_bye_notify (assuan_context_t ctx,
+                            void (*fnc)(assuan_context_t))
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -299,7 +302,8 @@
 }
 
 int
-assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
+assuan_register_reset_notify (assuan_context_t ctx,
+                              void (*fnc)(assuan_context_t))
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -308,7 +312,8 @@
 }
 
 int
-assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
+assuan_register_cancel_notify (assuan_context_t ctx,
+                               void (*fnc)(assuan_context_t))
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -317,8 +322,8 @@
 }
 
 int
-assuan_register_option_handler (ASSUAN_CONTEXT ctx,
-                               int (*fnc)(ASSUAN_CONTEXT,
+assuan_register_option_handler (assuan_context_t ctx,
+                               int (*fnc)(assuan_context_t,
                                           const char*, const char*))
 {
   if (!ctx)
@@ -328,8 +333,8 @@
 }
 
 int
-assuan_register_input_notify (ASSUAN_CONTEXT ctx,
-                              void (*fnc)(ASSUAN_CONTEXT, const char *))
+assuan_register_input_notify (assuan_context_t ctx,
+                              void (*fnc)(assuan_context_t, const char *))
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -338,8 +343,8 @@
 }
 
 int
-assuan_register_output_notify (ASSUAN_CONTEXT ctx,
-                              void (*fnc)(ASSUAN_CONTEXT, const char *))
+assuan_register_output_notify (assuan_context_t ctx,
+                              void (*fnc)(assuan_context_t, const char *))
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -350,7 +355,7 @@
 
 /* Helper to register the standards commands */
 int
-_assuan_register_std_commands (ASSUAN_CONTEXT ctx)
+_assuan_register_std_commands (assuan_context_t ctx)
 {
   int i, rc;
 
@@ -371,7 +376,7 @@
 /* Process the special data lines.  The "D " has already been removed
    from the line.  As all handlers this function may modify the line.  */
 static int
-handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen)
+handle_data_line (assuan_context_t ctx, char *line, int linelen)
 {
   return set_error (ctx, Not_Implemented, NULL);
 }
@@ -395,7 +400,7 @@
    table, remove leading and white spaces from the arguments, call the
    handler with the argument line and return the error */
 static int 
-dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen)
+dispatch_command (assuan_context_t ctx, char *line, int linelen)
 {
   char *p;
   const char *s;
@@ -442,7 +447,7 @@
 
 
 static int
-process_request (ASSUAN_CONTEXT ctx)
+process_request (assuan_context_t ctx)
 {
   int rc;
 
@@ -553,7 +558,7 @@
  * failed.  Note, that no error is returned for operational errors.
  **/
 int
-assuan_process (ASSUAN_CONTEXT ctx)
+assuan_process (assuan_context_t ctx)
 {
   int rc;
 
@@ -580,7 +585,7 @@
  * Return value: -1 for end of server, 0 on success or an error code
  **/
 int 
-assuan_process_next (ASSUAN_CONTEXT ctx)
+assuan_process_next (assuan_context_t ctx)
 {
   return process_request (ctx);
 }
@@ -604,7 +609,7 @@
  * error which is most likely a too small fdarray.
  **/
 int 
-assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
+assuan_get_active_fds (assuan_context_t ctx, int what,
                        int *fdarray, int fdarraysize)
 {
   int n = 0;
@@ -637,7 +642,7 @@
    implementaion for systems w/o a glibc, a simple implementation
    could use a child process */
 FILE *
-assuan_get_data_fp (ASSUAN_CONTEXT ctx)
+assuan_get_data_fp (assuan_context_t ctx)
 {
 #if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN)
   if (ctx->outbound.data.fp)
@@ -659,7 +664,7 @@
 /* Set the text used for the next OK reponse.  This string is
    automatically reset to NULL after the next command. */
 assuan_error_t
-assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
+assuan_set_okay_line (assuan_context_t ctx, const char *line)
 {
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
@@ -686,7 +691,8 @@
 
 
 assuan_error_t
-assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
+assuan_write_status (assuan_context_t ctx,
+                     const char *keyword, const char *text)
 {
   char buffer[256];
   char *helpbuf;

Modified: trunk/src/assuan-listen.c
===================================================================
--- trunk/src/assuan-listen.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-listen.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include "assuan-defs.h"
 

Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-pipe-connect.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -512,7 +512,7 @@
                     _assuan_error (ASSUAN_Problem_Starting_Server),
                     name, strerror (errno));
           errbuf[sizeof(errbuf)-1] = 0;
-          writen (1, errbuf, strlen (errbuf));
+          writen (fds[1], errbuf, strlen (errbuf));
           _exit (4);
         }
 #ifdef _ASSUAN_USE_DOUBLE_FORK
@@ -842,31 +842,41 @@
 }
 
 
-/* Connect to a server over a socketpair, creating the assuan context
-   and returning it in CTX.  The server filename is NAME, the argument
-   vector in ARGV.  FD_CHILD_LIST is a -1 terminated list of file
-   descriptors not to close in the child.  ATFORK is called in the
-   child right after the fork; ATFORKVALUE is passed as the first
-   argument and 0 is passed as the second argument. The ATFORK
-   function should only act if the second value is 0.  
+/* Connect to a server over a full-duplex socket (i.e. created by
+   socketpair), creating the assuan context and returning it in CTX.
+   The server filename is NAME, the argument vector in ARGV.
+   FD_CHILD_LIST is a -1 terminated list of file descriptors not to
+   close in the child.  ATFORK is called in the child right after the
+   fork; ATFORKVALUE is passed as the first argument and 0 is passed
+   as the second argument. The ATFORK function should only act if the
+   second value is 0.
 
+   For now FLAGS may either take the value 0 to behave like
+   assuan_pipe_connect2 or 1 to enable the described full-duplex
+   socket behaviour.
+
    If NAME as well as ARGV are NULL, no exec is done but the same
    process is continued.  However all file descriptors are closed and
-   some specila environment variables are set. To let the caller
-   detect whether the cild or the parent continues, the child returns
+   some special environment variables are set. To let the caller
+   detect whether the child or the parent continues, the child returns
    a CTX of NULL. */
 assuan_error_t
 assuan_pipe_connect_ext (assuan_context_t *ctx,
                          const char *name, const char *const argv[],
                          int *fd_child_list,
                          void (*atfork) (void *opaque, int reserved),
-                         void *atforkvalue)
+                         void *atforkvalue, unsigned int flags)
 {
+  if ((flags & 1))
+    {
 #ifdef HAVE_W32_SYSTEM
-  return _assuan_error (ASSUAN_Not_Implemented);
+      return _assuan_error (ASSUAN_Not_Implemented);
 #else
-  return socketpair_connect (ctx, name, argv, fd_child_list,
-                             atfork, atforkvalue);
+      return socketpair_connect (ctx, name, argv, fd_child_list,
+                                 atfork, atforkvalue);
 #endif
+    }
+  else
+    return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue);
 }
 

Modified: trunk/src/assuan-pipe-server.c
===================================================================
--- trunk/src/assuan-pipe-server.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-pipe-server.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -22,6 +22,8 @@
 #include <config.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #ifdef HAVE_W32_SYSTEM
 #include <windows.h>
@@ -89,6 +91,18 @@
 }
 
 
+/* Returns true if atoi(S) denotes a valid socket. */
+static int
+is_valid_socket (const char *s)
+{
+  struct stat buf;
+
+  if ( fstat (atoi (s), &buf ) )
+    return 0;
+  return S_ISSOCK (buf.st_mode);
+}
+
+
 int
 assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
 {
@@ -112,7 +126,7 @@
       ctx->outbound.fd = _get_osfhandle (filedes[1]);
 #else
       s = getenv ("_assuan_connection_fd");
-      if (!filedes && s && *s && atoi (s) >= 0 )
+      if (s && *s && is_valid_socket (s) )
         {
           /* Well, we are called with an bi-directional file
              descriptor.  Prepare for using sendmsg/recvmsg.  In this
@@ -121,7 +135,7 @@
           _assuan_init_uds_io (ctx);
           ctx->deinit_handler = _assuan_uds_deinit;
         }
-      else if (filedes)
+      else if (filedes && filedes[0] != -1 && filedes[1] != -1 )
         {
           /* Standard pipe server. */
           ctx->inbound.fd  = filedes[0];

Modified: trunk/src/assuan-socket-connect.c
===================================================================
--- trunk/src/assuan-socket-connect.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-socket-connect.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -55,7 +55,7 @@
 
  
 static int
-do_finish (ASSUAN_CONTEXT ctx)
+do_finish (assuan_context_t ctx)
 {
   if (ctx->inbound.fd != -1)
     {
@@ -67,22 +67,37 @@
 }
 
 static void
-do_deinit (ASSUAN_CONTEXT ctx)
+do_deinit (assuan_context_t ctx)
 {
   do_finish (ctx);
 }
+
+
 /* Make a connection to the Unix domain socket NAME and return a new
    Assuan context in CTX.  SERVER_PID is currently not used but may
    become handy in the future.  */
 assuan_error_t
-assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
+assuan_socket_connect (assuan_context_t *r_ctx,
                        const char *name, pid_t server_pid)
 {
+  return assuan_socket_connect_ext (r_ctx, name, server_pid, 0);
+}
+
+
+/* Make a connection to the Unix domain socket NAME and return a new
+   Assuan context in CTX.  SERVER_PID is currently not used but may
+   become handy in the future.  With flags set to 1 sendmsg and
+   recvmesg are used. */
+assuan_error_t
+assuan_socket_connect_ext (assuan_context_t *r_ctx,
+                           const char *name, pid_t server_pid,
+                           unsigned int flags)
+{
   static struct assuan_io io = { _assuan_simple_read,
 				 _assuan_simple_write };
 
   assuan_error_t err;
-  ASSUAN_CONTEXT ctx;
+  assuan_context_t ctx;
   int fd;
   struct sockaddr_un srvr_addr;
   size_t len;
@@ -92,9 +107,9 @@
     return _assuan_error (ASSUAN_Invalid_Value);
   *r_ctx = NULL;
 
-  /* We require that the name starts with a slash, so that we can
-     alter reuse this function for other socket types.  To make things
-     easier we allow an optional dirver prefix.  */
+  /* We require that the name starts with a slash, so that we
+     eventually can reuse this function for other socket types.  To
+     make things easier we allow an optional dirver prefix.  */
   s = name;
   if (*s && s[1] == ':')
     s += 2;
@@ -107,10 +122,9 @@
   err = _assuan_new_context (&ctx); 
   if (err)
       return err;
-  ctx->deinit_handler = do_deinit;
+  ctx->deinit_handler = ((flags&1))? _assuan_uds_deinit :  do_deinit;
   ctx->finish_handler = do_finish;
 
-
   fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0);
   if (fd == -1)
     {
@@ -138,7 +152,9 @@
   ctx->inbound.fd = fd;
   ctx->outbound.fd = fd;
   ctx->io = &io;
-
+  if ((flags&1))
+    _assuan_init_uds_io (ctx);
+ 
   /* initial handshake */
   {
     int okay, off;
@@ -164,3 +180,5 @@
     *r_ctx = ctx;
   return 0;
 }
+
+

Modified: trunk/src/assuan-socket-server.c
===================================================================
--- trunk/src/assuan-socket-server.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-socket-server.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -114,40 +114,25 @@
 int
 assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd)
 {
-  assuan_context_t ctx;
-  int rc;
-
-  *r_ctx = NULL;
-  ctx = xtrycalloc (1, sizeof *ctx);
-  if (!ctx)
-    return _assuan_error (ASSUAN_Out_Of_Core);
-  ctx->is_server = 1;
-  ctx->input_fd = -1;
-  ctx->output_fd = -1;
-
-  ctx->inbound.fd = -1;
-  ctx->outbound.fd = -1;
-
-  ctx->listen_fd = listen_fd;
-  ctx->connected_fd = -1;
-  ctx->deinit_handler = deinit_socket_server;
-  ctx->accept_handler = accept_connection;
-  ctx->finish_handler = finish_connection;
-
-  ctx->io = &io;
-
-  rc = _assuan_register_std_commands (ctx);
-  if (rc)
-    xfree (ctx);
-  else
-    *r_ctx = ctx;
-  return rc;
+  return assuan_init_socket_server_ext (r_ctx, listen_fd, 0);
 }
 
 /* Initialize a server using the already accepted socket FD. */
 int
 assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
 {
+  return assuan_init_socket_server_ext (r_ctx, fd, 2);
+}
+
+
+/* 
+   Flag bits: 0 - use sendmsg/recvmsg to allow descriptor passing
+              1 - FD has already been accepted.
+*/
+int
+assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
+                               unsigned int flags)
+{
   assuan_context_t ctx;
   int rc;
 
@@ -156,21 +141,34 @@
   if (!ctx)
     return _assuan_error (ASSUAN_Out_Of_Core);
   ctx->is_server = 1;
-  ctx->pipe_mode = 1; /* we want a second accept to indicate EOF */
+  if ((flags & 2))
+    ctx->pipe_mode = 1; /* We want a second accept to indicate EOF. */
   ctx->input_fd = -1;
   ctx->output_fd = -1;
 
   ctx->inbound.fd = -1;
   ctx->outbound.fd = -1;
 
-  ctx->io = &io;
-
-  ctx->listen_fd = -1;
-  ctx->connected_fd = fd;
-  ctx->deinit_handler = deinit_socket_server;
-  ctx->accept_handler = accept_connection_bottom;
+  if ((flags & 2))
+    {
+      ctx->listen_fd = -1;
+      ctx->connected_fd = fd;
+    }
+  else
+    {
+      ctx->listen_fd = fd;
+      ctx->connected_fd = -1;
+    }
+  ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server;
+  ctx->accept_handler = ((flags & 2)
+                         ? accept_connection_bottom 
+                         : accept_connection);
   ctx->finish_handler = finish_connection;
 
+  ctx->io = &io;
+  if ((flags & 1))
+    _assuan_init_uds_io (ctx);
+
   rc = _assuan_register_std_commands (ctx);
   if (rc)
     xfree (ctx);
@@ -178,5 +176,3 @@
     *r_ctx = ctx;
   return rc;
 }
-
-

Modified: trunk/src/assuan-uds.c
===================================================================
--- trunk/src/assuan-uds.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan-uds.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -45,7 +45,10 @@
 #include "assuan-defs.h"
 
 
-/* Read from a unix domain socket using sendmsg.  */
+/* Read from a unix domain socket using sendmsg. 
+
+   FIXME: We don't need the buffering. It is a leftover from the time
+   when we used datagrams. */
 static ssize_t
 uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
 {
@@ -215,16 +218,19 @@
 uds_receivefd (assuan_context_t ctx, int *fd)
 {
 #ifndef HAVE_W32_SYSTEM
-  if (!ctx->uds.pendingfds)
+  int i;
+
+  if (!ctx->uds.pendingfdscount)
     {
       _assuan_log_printf ("no pending file descriptors!\n");
       return _assuan_error (ASSUAN_General_Error);
     }
+  assert (ctx->uds.pendingfdscount <= DIM(ctx->uds.pendingfds));
 
   *fd = ctx->uds.pendingfds[0];
-  if (--ctx->uds.pendingfdscount)
-    memmove (ctx->uds.pendingfds, ctx->uds.pendingfds + 1,
-             ctx->uds.pendingfdscount * sizeof (int));
+  for (i=1; i < ctx->uds.pendingfdscount; i++)
+    ctx->uds.pendingfds[i-1] = ctx->uds.pendingfds[i];
+  ctx->uds.pendingfdscount--;
 
   return 0;
 #else
@@ -233,12 +239,21 @@
 }
 
 
+/* Close all pending fds. */
+void
+_assuan_uds_close_fds (assuan_context_t ctx)
+{
+  int i;
+
+  for (i = 0; i < ctx->uds.pendingfdscount; i++)
+    _assuan_close (ctx->uds.pendingfds[i]);
+  ctx->uds.pendingfdscount = 0;
+}
+
 /* Deinitialize the unix domain socket I/O functions.  */
 void
 _assuan_uds_deinit (assuan_context_t ctx)
 {
-  int i;
-
   /* First call the finish_handler which should close descriptors etc. */
   ctx->finish_handler (ctx);
 
@@ -249,13 +264,10 @@
       xfree (ctx->uds.buffer);
     }
 
-  for (i = 0; i < ctx->uds.pendingfdscount; i++)
-    _assuan_close (ctx->uds.pendingfds[i]);
-  ctx->uds.pendingfdscount = 0;
+  _assuan_uds_close_fds (ctx);
 }
 
 
-
 /* Helper function to initialize a context for domain I/O. */
 void
 _assuan_init_uds_io (assuan_context_t ctx)

Modified: trunk/src/assuan.h
===================================================================
--- trunk/src/assuan.h	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/assuan.h	2006-09-13 15:55:25 UTC (rev 200)
@@ -91,10 +91,12 @@
 #define assuan_init_socket_server _ASSUAN_PREFIX(assuan_init_socket_server)
 #define assuan_init_connected_socket_server \
   _ASSUAN_PREFIX(assuan_init_connected_socket_server)
+#define assuan_init_socket_server_ext \
+  _ASSUAN_PREFIX(assuan_init_socket_server-ext)
 #define assuan_pipe_connect _ASSUAN_PREFIX(assuan_pipe_connect)
+#define assuan_pipe_connect_ext _ASSUAN_PREFIX(assuan_pipe_connect_ext)
 #define assuan_socket_connect _ASSUAN_PREFIX(assuan_socket_connect)
-#define assuan_domain_connect _ASSUAN_PREFIX(assuan_domain_connect)
-#define assuan_init_domain_server _ASSUAN_PREFIX(assuan_init_domain_server)
+#define assuan_socket_connect_ext _ASSUAN_PREFIX(assuan_socket_connect_ext)
 #define assuan_disconnect _ASSUAN_PREFIX(assuan_disconnect)
 #define assuan_get_pid _ASSUAN_PREFIX(assuan_get_pid)
 #define assuan_transact _ASSUAN_PREFIX(assuan_transact)
@@ -365,8 +367,9 @@
 /*-- assuan-socket-server.c --*/
 int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd);
 int assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd);
+int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
+                                   unsigned int flags);
 
-
 /*-- assuan-pipe-connect.c --*/
 assuan_error_t assuan_pipe_connect (assuan_context_t *ctx,
                                     const char *name,
@@ -383,14 +386,18 @@
                                         const char *const argv[],
                                         int *fd_child_list,
                                         void (*atfork) (void *, int),
-                                        void *atforkvalue);
+                                        void *atforkvalue,
+                                        unsigned int flags);
 
 /*-- assuan-socket-connect.c --*/
-assuan_error_t assuan_socket_connect (assuan_context_t *ctx, const char *name,
+assuan_error_t assuan_socket_connect (assuan_context_t *ctx, 
+                                      const char *name,
                                       pid_t server_pid);
+assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx,
+                                          const char *name,
+                                          pid_t server_pid,
+                                          unsigned int flags);
 
-
-
 /*-- assuan-connect.c --*/
 void assuan_disconnect (assuan_context_t ctx);
 pid_t assuan_get_pid (assuan_context_t ctx);

Modified: trunk/src/mkerrors
===================================================================
--- trunk/src/mkerrors	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/src/mkerrors	2006-09-13 15:55:25 UTC (rev 200)
@@ -83,6 +83,7 @@
     case ASSUAN_Unexpected_Command:      n = 274; break;
     case ASSUAN_Unknown_Command:         n = 275; break;
     case ASSUAN_Canceled:                n = 277; break;
+    case ASSUAN_No_Secret_Key:           n =  17; break;
 
     case ASSUAN_Read_Error:
       switch (errno)
@@ -119,8 +120,7 @@
     case -1: n = 16383 /*GPG_ERR_EOF*/; break;
 
     default:
-      assert (!"unmapped error code used in libassuan!!");
-      n = 257; /* Just in case someone compiled with NDEBUG.  */
+      n = 257; 
       break;
     }
 

Modified: trunk/tests/fdpassing.c
===================================================================
--- trunk/tests/fdpassing.c	2006-09-12 11:07:18 UTC (rev 199)
+++ trunk/tests/fdpassing.c	2006-09-13 15:55:25 UTC (rev 200)
@@ -279,7 +279,7 @@
         }
       err = assuan_pipe_connect_ext (&ctx, with_exec? "./fdpassing":NULL,
                                      with_exec? arglist :NULL,
-                                     no_close_fds, NULL, NULL);
+                                     no_close_fds, NULL, NULL, 1);
       if (err)
         {
           log_error ("assuan_pipe_connect failed: %s\n",assuan_strerror (err));




More information about the Gnupg-commits mailing list