[svn] assuan - r196 - in trunk: . doc src tests

svn author wk cvs at cvs.gnupg.org
Wed Sep 6 18:36:47 CEST 2006


Author: wk
Date: 2006-09-06 18:36:45 +0200 (Wed, 06 Sep 2006)
New Revision: 196

Added:
   trunk/tests/
   trunk/tests/Makefile.am
   trunk/tests/common.h
   trunk/tests/fdpassing.c
Modified:
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/NEWS
   trunk/TODO
   trunk/configure.ac
   trunk/doc/assuan.texi
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/assuan-buffer.c
   trunk/src/assuan-client.c
   trunk/src/assuan-defs.h
   trunk/src/assuan-domain-connect.c
   trunk/src/assuan-domain-server.c
   trunk/src/assuan-handler.c
   trunk/src/assuan-inquire.c
   trunk/src/assuan-listen.c
   trunk/src/assuan-logging.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.h
   trunk/src/mkerrors
Log:
Changes to support gpg-error style error codes.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/ChangeLog	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,3 +1,7 @@
+2006-09-05  Werner Koch  <wk at g10code.com>
+
+	* configure.ac (AH_BOTTOM): Define _ASSUAN_IN_LIBASSUAN.
+
 2005-10-24  Werner Koch  <wk at g10code.com>
 
 	* COPYING.LESSER: Added.

Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/Makefile.am	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,6 +1,8 @@
-SUBDIRS = src doc 
+
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = dist-bzip2
 
 EXTRA_DIST = config.rpath  config.rpath autogen.sh README.SVN
 
+SUBDIRS = src doc tests
+

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/NEWS	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,4 +1,4 @@
-Noteworthy changes in version 0.6.11
+Noteworthy changes in version 0.9.0
 -------------------------------------------------
 
  * Internal cleanups to make inclusion of the code into libraries
@@ -6,7 +6,14 @@
 
  * Made clear that the software is under the LGPL.
 
+ * New function assuan_set_assuan_err_source.  All gpg-error enabled
+   software should call this right at startup to switch libassuan into
+   the gpg-error style mode.  All error codes are then returned as
+   gpg-error style codes (GPG_ERR_ASS_* as well as others).
+   If the new macro _ASSUAN_ONLY_GPG_ERRORS is defned all old
+   definitions are excluded from assuan.h.
 
+
 Noteworthy changes in version 0.6.10 (2005-06-20)
 -------------------------------------------------
 

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/TODO	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,3 +1,4 @@
+                                                           -*- outline -*-
 * waitpid is used instead of pth_waitpid as well as some  other
   functions.
 * When turning libassuan into a shared library, provide a general
@@ -3,8 +4,11 @@
   version as well as a Pth-enabled one.
 * Need API documentation.
-* assuan_transact returns immetitely on an error in the callback
-  function.  It might be Better to return the error to the caller. As
-  an example see dirmngr-client, where we need to send empty reponses
+* assuan_transact returns immediately on an error in the callback
+  function.  It might be better to return the error to the caller. As
+  an example see dirmngr-client, where we need to send empty responses
   for unknown inquiries, albeit dirmngr itself would handle the
-  returns for assuan_inquire gracefully.  We need to chekc all
+  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.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/configure.ac	2006-09-06 16:36:45 UTC (rev 196)
@@ -23,7 +23,7 @@
 
 # Version number: Remember to change it immediately *after* a release.
 #                 Add a "-cvs" prefix for non-released code.
-AC_INIT(libassuan, 0.6.11-cvs, gnupg-devel at gnupg.org)
+AC_INIT(libassuan, 0.9.0-cvs, gnupg-devel at gnupg.org)
 # Note, that this is not yet available as a shared library.
 
 PACKAGE=$PACKAGE_NAME
@@ -68,6 +68,11 @@
 fi
 
 
+AH_BOTTOM([
+#define _ASSUAN_IN_LIBASSUAN 1
+])
+
+
 # 
 # Options depending on the host OS.
 # 
@@ -160,6 +165,7 @@
 AC_CONFIG_FILES([Makefile])
 AC_CONFIG_FILES([src/Makefile])
 AC_CONFIG_FILES([doc/Makefile])
+AC_CONFIG_FILES([tests/Makefile])
 AC_CONFIG_FILES([src/libassuan-config], [chmod +x src/libassuan-config])
 
 AC_OUTPUT

Modified: trunk/doc/assuan.texi
===================================================================
--- trunk/doc/assuan.texi	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/doc/assuan.texi	2006-09-06 16:36:45 UTC (rev 196)
@@ -175,7 +175,7 @@
 @item Easy module testing
 @item Extendible
 @item Optional authentication and encryption facility
- at item Usable by access external hardware
+ at item Usable to access external hardware
 @end itemize
 
 
@@ -261,7 +261,7 @@
 over to the next token (except for data lines where the raw data starts
 exactly after 2 bytes).  Lines larger than 1000 bytes should be
 treated as a communication error. (The rationale for having a line
-length limit is to allow for easier multiplexing of multiple channels).
+length limit is to allow for easier multiplexing of several channels).
 
 
 @node Client requests
@@ -405,7 +405,7 @@
 @end table
 
 For historical reasons a few more error codes are defined in
- at file{assuan.h}; they should not be used be new applications.
+ at file{assuan.h}; they should not be used by new applications.
 
 Errror codes in the range @var{ASSUAN_USER_ERROR_FIRST} to
 @var{ASSUAN_USER_ERROR_LAST} may be used at the applications own

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/ChangeLog	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,3 +1,37 @@
+2006-09-06  Werner Koch  <wk at g10code.com>
+
+	* assuan.h (_ASSUAN_ONLY_GPG_ERRORS): New.
+
+	* assuan-handler.c (dispatch_command): Use Syntax_Error instead of
+	Invalid_Command.
+
+	* assuan-domain-connect.c: Changed alloc malloc/free/realloc to
+	xtrymalloc et al.
+	(read_int, write_int): Make args void pointers.
+	(domain_receivefd): Take care of realloc shrinking failure.
+
+	* assuan-buffer.c (_assuan_read_line, _assuan_write_line)
+	(assuan_write_line, _assuan_cookie_write_data)
+	(_assuan_cookie_write_flush): Print the inbound fd instead of the
+	address of the context when logging I/0.  This makes it more
+	readable.
+
+2006-09-05  Werner Koch  <wk at g10code.com>
+
+	* assuan-defs.h (err_code, err_is_eof): New.
+
+	* mkerrors (_assuan_error): New.  Wrapped all error code
+	assignments in a call to this.
+	(assuan_strerror): Map gpg-style error codes back. Also print a
+	string for the old EOF code.
+	(assuan_set_assuan_err_source): New.
+
+	* assuan-logging.c (_assuan_log_printf): Do not change ERRNO and
+	print the pid.
+
+	* assuan-domain-connect.c (domain_reader): Replaced plain printf
+	by assuan_log function.
+
 2005-10-24  Werner Koch  <wk at g10code.com>
 
 	* putc_unlocked.c, memrchr.c, isascii.c, funopen.c: Changed

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/Makefile.am	2006-09-06 16:36:45 UTC (rev 196)
@@ -54,5 +54,5 @@
 
 libassuan_a_LIBADD = @LIBOBJS@
 
-assuan-errors.c : assuan.h
+assuan-errors.c : assuan.h mkerrors
 	$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c

Modified: trunk/src/assuan-buffer.c
===================================================================
--- trunk/src/assuan-buffer.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-buffer.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -31,6 +31,9 @@
 #endif
 #include "assuan-defs.h"
 
+
+/* Extended version of write(2) to guarantee that all bytes are
+   written.  Returns 0 on success or -1 and ERRNO on failure. */
 static int
 writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
 {
@@ -50,7 +53,9 @@
   return 0;  /* okay */
 }
 
-/* Read an entire line.  */
+/* Read an entire line. Returns 0 on success or -1 and ERRNo on
+   failure.  EOF is indictated by setting the integer at address
+   R_EOF.  */
 static int
 readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
 	  int *r_nread, int *r_eof)
@@ -89,6 +94,7 @@
 }
 
 
+/* Function returns an Assuan error. */
 int
 _assuan_read_line (ASSUAN_CONTEXT ctx)
 {
@@ -129,19 +135,20 @@
   if (rc)
     {
       if (ctx->log_fp)
-	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
+	fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n",
 		 assuan_get_assuan_log_prefix (),
-                 (unsigned int)getpid (), ctx, strerror (errno));
-      return ASSUAN_Read_Error;
+                 (unsigned int)getpid (), ctx->inbound.fd,
+                 strerror (errno));
+      return _assuan_error (ASSUAN_Read_Error);
     }
   if (!nread)
     {
       assert (ctx->inbound.eof);
       if (ctx->log_fp)
-	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
+	fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [EOF]\n",
 		 assuan_get_assuan_log_prefix (),
-                 (unsigned int)getpid (), ctx);
-      return -1;
+                 (unsigned int)getpid (), ctx->inbound.fd);
+      return _assuan_error (-1);
     }
 
   ctx->inbound.attic.pending = 0;
@@ -171,9 +178,9 @@
       ctx->inbound.linelen = endp - line;
       if (ctx->log_fp)
 	{
-	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
+	  fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ",
 		   assuan_get_assuan_log_prefix (),
-                   (unsigned int)getpid (), ctx);
+                   (unsigned int)getpid (), ctx->inbound.fd);
 	  if (ctx->confidential)
 	    fputs ("[Confidential data not shown]", ctx->log_fp);
 	  else
@@ -187,13 +194,14 @@
   else
     {
       if (ctx->log_fp)
-	fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
+	fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Invalid line]\n",
 		 assuan_get_assuan_log_prefix (),
-                 (unsigned int)getpid (), ctx);
+                 (unsigned int)getpid (), ctx->inbound.fd);
       *line = 0;
       ctx->inbound.linelen = 0;
-      return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
-	: ASSUAN_Line_Too_Long;
+      return _assuan_error (ctx->inbound.eof 
+                            ? ASSUAN_Line_Not_Terminated
+                            : ASSUAN_Line_Too_Long);
     }
 }
 
@@ -213,7 +221,7 @@
   assuan_error_t err;
 
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   err = _assuan_read_line (ctx);
   *line = ctx->inbound.line;
@@ -242,10 +250,10 @@
   if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
     {
       if (ctx->log_fp)
-        fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
+        fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
                  "[supplied line too long -truncated]\n",
                  assuan_get_assuan_log_prefix (),
-                 (unsigned int)getpid (), ctx);
+                 (unsigned int)getpid (), ctx->inbound.fd);
       if (prefixlen > 5)
         prefixlen = 5;
       if (len > ASSUAN_LINELENGTH - prefixlen - 2)
@@ -255,9 +263,9 @@
   /* Fixme: we should do some kind of line buffering.  */
   if (ctx->log_fp)
     {
-      fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
+      fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
 	       assuan_get_assuan_log_prefix (),
-               (unsigned int)getpid (), ctx);
+               (unsigned int)getpid (), ctx->inbound.fd);
       if (ctx->confidential)
 	fputs ("[Confidential data not shown]", ctx->log_fp);
       else
@@ -269,18 +277,18 @@
     {
       rc = writen (ctx, prefix, prefixlen);
       if (rc)
-        rc = ASSUAN_Write_Error;
+        rc = _assuan_error (ASSUAN_Write_Error);
     }
   if (!rc)
     {
       rc = writen (ctx, line, len);
       if (rc)
-        rc = ASSUAN_Write_Error;
+        rc = _assuan_error (ASSUAN_Write_Error);
       if (!rc)
         {
           rc = writen (ctx, "\n", 1);
           if (rc)
-            rc = ASSUAN_Write_Error;
+            rc = _assuan_error (ASSUAN_Write_Error);
         }
     }
   return rc;
@@ -294,7 +302,7 @@
   const char *s;
 
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   /* Make sure that we never take a LF from the user - this might
      violate the protocol. */
@@ -302,10 +310,10 @@
   len = s? (s-line) : strlen (line);
 
   if (ctx->log_fp && s)
-    fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
-             "[supplied line contained a LF -truncated]\n",
+    fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
+             "[supplied line contained a LF - truncated]\n",
              assuan_get_assuan_log_prefix (),
-             (unsigned int)getpid (), ctx);
+             (unsigned int)getpid (), ctx->inbound.fd);
 
   return _assuan_write_line (ctx, NULL, line, len);
 }
@@ -360,9 +368,9 @@
         {
           if (ctx->log_fp)
             {
-	      fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
+	      fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
 		       assuan_get_assuan_log_prefix (),
-                       (unsigned int)getpid (), ctx);
+                       (unsigned int)getpid (), ctx->inbound.fd);
 
               if (ctx->confidential)
                 fputs ("[Confidential data not shown]", ctx->log_fp);
@@ -376,7 +384,7 @@
           linelen++;
           if (writen (ctx, ctx->outbound.data.line, linelen))
             {
-              ctx->outbound.data.error = ASSUAN_Write_Error;
+              ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
               return 0;
             }
           line = ctx->outbound.data.line;
@@ -408,9 +416,9 @@
     {
       if (ctx->log_fp)
 	{
-	  fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
+	  fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
 		   assuan_get_assuan_log_prefix (),
-                   (unsigned int)getpid (), ctx);
+                   (unsigned int)getpid (), ctx->inbound.fd);
 	  if (ctx->confidential)
 	    fputs ("[Confidential data not shown]", ctx->log_fp);
 	  else
@@ -422,7 +430,7 @@
       linelen++;
       if (writen (ctx, ctx->outbound.data.line, linelen))
         {
-          ctx->outbound.data.error = ASSUAN_Write_Error;
+          ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
           return 0;
         }
       ctx->outbound.data.linelen = 0;
@@ -453,9 +461,9 @@
 assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   if (!buffer && length)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   if (!buffer)
     { /* flush what we have */

Modified: trunk/src/assuan-client.c
===================================================================
--- trunk/src/assuan-client.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-client.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -104,7 +104,7 @@
       *off = 3;
     }
   else
-    rc = ASSUAN_Invalid_Response;
+    rc = _assuan_error (ASSUAN_Invalid_Response);
   return rc;
 }
 
@@ -113,7 +113,7 @@
 /**
  * assuan_transact:
  * @ctx: The Assuan context
- * @command: Coimmand line to be send to server
+ * @command: Command line to be send to the server
  * @data_cb: Callback function for data lines
  * @data_cb_arg: first argument passed to @data_cb
  * @inquire_cb: Callback function for a inquire response
@@ -167,7 +167,7 @@
   else if (okay == 2)
     {
       if (!data_cb)
-        rc = ASSUAN_No_Data_Callback;
+        rc = _assuan_error (ASSUAN_No_Data_Callback);
       else 
         {
           char *s, *d;
@@ -196,7 +196,7 @@
         {
           assuan_write_line (ctx, "END"); /* get out of inquire mode */
           _assuan_read_from_server (ctx, &okay, &off); /* dummy read */
-          rc = ASSUAN_No_Inquire_Callback;
+          rc = _assuan_error (ASSUAN_No_Inquire_Callback);
         }
       else
         {
@@ -217,7 +217,7 @@
   else if (okay == 5)
     {
       if (!data_cb)
-        rc = ASSUAN_No_Data_Callback;
+        rc = _assuan_error (ASSUAN_No_Data_Callback);
       else 
         {
           rc = data_cb (data_cb_arg, NULL, 0);

Modified: trunk/src/assuan-defs.h
===================================================================
--- trunk/src/assuan-defs.h	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-defs.h	2006-09-06 16:36:45 UTC (rev 196)
@@ -16,7 +16,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA. 
+ * USA.
  */
 
 #ifndef ASSUAN_DEFS_H
@@ -63,12 +63,16 @@
 
 #define LINELENGTH ASSUAN_LINELENGTH
 
+
 struct cmdtbl_s
 {
   const char *name;
   int (*handler)(ASSUAN_CONTEXT, char *line);
 };
 
+
+/* A structure to dispatch I/O functions.  All these functions need to
+   return 0 on success and set ERRNO on failure.  */
 struct assuan_io
 {
   /* Routine to read from input_fd.  */
@@ -79,8 +83,10 @@
   assuan_error_t (*sendfd) (ASSUAN_CONTEXT, int);
   /* Receive a file descriptor.  */
   assuan_error_t (*receivefd) (ASSUAN_CONTEXT, int *);
-};  
+};
 
+
+/* The context we use with most functions. */
 struct assuan_context_s
 {
   assuan_error_t err_no;
@@ -89,17 +95,17 @@
                          error codes. */
 
   /* Context specific flags (cf. assuan_flag_t). */
-  struct 
+  struct
   {
     unsigned int no_waitpid:1; /* See ASSUAN_NO_WAITPID. */
-  } flags; 
+  } flags;
 
   int confidential;
   int is_server;      /* Set if this is context belongs to a server */
   int in_inquire;
   char *hello_line;
   char *okay_line;    /* See assuan_set_okay_line() */
-  
+
   void *user_pointer;  /* For assuan_get_pointer and assuan-set_pointer (). */
 
   FILE *log_fp;
@@ -123,14 +129,14 @@
     struct {
       FILE *fp;
       char line[LINELENGTH];
-      int linelen; 
+      int linelen;
       int error;
-    } data; 
+    } data;
   } outbound;
 
   int pipe_mode;  /* We are in pipe mode, i.e. we can handle just one
                      connection and must terminate then */
-  pid_t pid;	  /* The the pid of the peer. */
+  pid_t pid;	  /* The pid of the peer. */
   int listen_fd;  /* The fd we are listening on (used by socket servers) */
   int connected_fd; /* helper */
 
@@ -152,7 +158,7 @@
   int *pendingfds;
   int pendingfdscount;
 
-  void (*deinit_handler)(ASSUAN_CONTEXT);  
+  void (*deinit_handler)(ASSUAN_CONTEXT);
   int (*accept_handler)(ASSUAN_CONTEXT);
   int (*finish_handler)(ASSUAN_CONTEXT);
 
@@ -183,8 +189,8 @@
    Assuan context in CTX.  SERVER_PID is currently not used but may
    become handy in the future.  */
 assuan_error_t _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
-				 int rendezvousfd,
-				 pid_t peer);
+                                    int rendezvousfd,
+                                    pid_t peer);
 
 /*-- assuan-handler.c --*/
 int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
@@ -199,7 +205,24 @@
 /*-- assuan-client.c --*/
 assuan_error_t _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
 
+/*-- assuan-error.c --*/
 
+
+/* Map error codes as used in this implementaion to the libgpg-error
+   codes. */
+int _assuan_error (int oldcode);
+
+/* Extrac the erro code from A.  This works for both the old and the
+   new style error codes. This needs to be whenever an error code is
+   compared. */
+#define err_code(a) ((a) & 0x00ffffff)
+
+/* Check whether A is the erro code for EOF.  We allow forold and new
+   style EOF error codes here.  */
+#define err_is_eof(a) ((a) == (-1) || err_code (a) == 16383)
+
+
+
 /*-- assuan-util.c --*/
 void *_assuan_malloc (size_t n);
 void *_assuan_calloc (size_t n, size_t m);
@@ -211,7 +234,8 @@
 #define xtryrealloc(a,b) _assuan_realloc((a),(b))
 #define xfree(a)         _assuan_free ((a))
 
-#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t))
+#define set_error(c,e,t) \
+        assuan_set_error ((c), _assuan_error (ASSUAN_ ## e), (t))
 
 void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t  length);
 void _assuan_log_sanitized_string (const char *string);
@@ -267,4 +291,3 @@
 #endif
 
 #endif /*ASSUAN_DEFS_H*/
-

Modified: trunk/src/assuan-domain-connect.c
===================================================================
--- trunk/src/assuan-domain-connect.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-domain-connect.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -60,7 +60,7 @@
 /* Read an integer from byte address ADDR.  Works even if ADDR is
    misaligned.  */
 static int
-read_int (const char *addr)
+read_int (const void *addr)
 {
   int val;
 
@@ -73,7 +73,7 @@
 /* Write the integer VAL to byte address ADDR.  Works even if ADDR is
    misaligned.  */
 static void
-write_int (char *addr, int val)
+write_int (void *addr, int val)
 {
   memcpy (addr, &val, sizeof (int));
 }
@@ -90,7 +90,7 @@
   if (ctx->domainbuffer)
     {
       assert (ctx->domainbufferallocated);
-      free (ctx->domainbuffer);
+      xfree (ctx->domainbuffer);
     }
 
   if (ctx->pendingfds)
@@ -101,7 +101,7 @@
       for (i = 0; i < ctx->pendingfdscount; i ++)
 	_assuan_close (ctx->pendingfds[i]);
 
-      free (ctx->pendingfds);
+      xfree (ctx->pendingfds);
     }
 
   unlink (ctx->myaddr.sun_path);
@@ -126,8 +126,7 @@
       {
 	struct cmsghdr hdr;
 	int fd;
-      }
-      cmsg;
+      } cmsg;
 
       memset (&msg, 0, sizeof (msg));
 
@@ -147,7 +146,7 @@
 	  len = recvmsg (ctx->inbound.fd, &msg, MSG_PEEK);
 	  if (len < 0)
 	    {
-	      printf ("domain_reader: %m\n");
+	      _assuan_log_printf ("domain_reader: %s\n", strerror (errno));
 	      return -1;
 	    }
 
@@ -171,11 +170,11 @@
 	      else
 		size *= 2;
 
-	      tmp = malloc (size);
+	      tmp = xtrymalloc (size);
 	      if (! tmp)
 		return -1;
 
-	      free (ctx->domainbuffer);
+	      xfree (ctx->domainbuffer);
 	      ctx->domainbuffer = tmp;
 	      ctx->domainbufferallocated = size;
 	    }
@@ -221,8 +220,8 @@
 	{
 	  void *tmp;
 
-	  tmp = realloc (ctx->pendingfds,
-			 sizeof (int) * (ctx->pendingfdscount + 1));
+	  tmp = xtryrealloc (ctx->pendingfds,
+                             sizeof (int) * (ctx->pendingfdscount + 1));
 	  if (! tmp)
 	    {
 	      _assuan_log_printf ("domain_reader: %s\n", strerror (errno));
@@ -303,8 +302,7 @@
   {
     struct cmsghdr hdr;
     int fd;
-  }
-  cmsg;
+  } cmsg;
   int len;
 
   memset (&msg, 0, sizeof (msg));
@@ -329,7 +327,7 @@
   if (len < 0)
     {
       _assuan_log_printf ("domain_sendfd: %s\n", strerror (errno));
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
   else
     return 0;
@@ -345,22 +343,28 @@
   if (ctx->pendingfds == 0)
     {
       _assuan_log_printf ("no pending file descriptors!\n");
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
 
   *fd = ctx->pendingfds[0];
   if (-- ctx->pendingfdscount == 0)
     {
-      free (ctx->pendingfds);
+      xfree (ctx->pendingfds);
       ctx->pendingfds = 0;
     }
-  else
-    /* Fix the array.  */
+  else /* Fix the array.  */
     {
+      void *tmp;
+
       memmove (ctx->pendingfds, ctx->pendingfds + 1,
 	       ctx->pendingfdscount * sizeof (int));
-      ctx->pendingfds = realloc (ctx->pendingfds,
-				 ctx->pendingfdscount * sizeof (int));
+      tmp = xtryrealloc (ctx->pendingfds,
+                         ctx->pendingfdscount * sizeof (int));
+      if (tmp)
+        ctx->pendingfds = tmp;
+      /* Note: we ignore an shrinking error here thus the next realloc
+         to increase the size will succeed as the block is already of
+         the then requested size. */
     }
 #endif
   return 0;
@@ -368,9 +372,6 @@
 
 
 
-/* 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_domain_init (assuan_context_t *r_ctx, int rendezvousfd, pid_t peer)
 {
@@ -384,7 +385,7 @@
   int tries;
 
   if (!r_ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   *r_ctx = NULL;
 
   err = _assuan_new_context (&ctx); 
@@ -404,7 +405,7 @@
     {
       _assuan_log_printf ("can't create socket: %s\n", strerror (errno));
       _assuan_release_context (ctx);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
   
   ctx->inbound.fd = fd;
@@ -438,7 +439,7 @@
             "name.  DoS in progress?\n");
 	  _assuan_release_context (ctx);
 	  _assuan_close (fd);
-	  return ASSUAN_General_Error;
+	  return _assuan_error (ASSUAN_General_Error);
 	}
 
       memset (&ctx->myaddr, 0, sizeof ctx->myaddr);
@@ -458,7 +459,7 @@
            strerror (errno));
       _assuan_release_context (ctx);
       _assuan_close (fd);
-      return ASSUAN_Connect_Failed;
+      return _assuan_error (ASSUAN_Connect_Failed);
     }
 
   /* Rendezvous with our peer.  */
@@ -469,8 +470,9 @@
     fp = fdopen (rendezvousfd, "w+");
     if (! fp)
       {
-	_assuan_log_printf ("can't open rendezvous port: %s\n", strerror (errno));
-	return ASSUAN_Connect_Failed;
+	_assuan_log_printf ("can't open rendezvous port: %s\n",
+                            strerror (errno));
+	return _assuan_error (ASSUAN_Connect_Failed);
       }
 
     /* Send our address.  */
@@ -498,13 +500,17 @@
   return 0;
 }
 
+/* Connect to a Unix domain socket server.  RENDEZVOUSFD is
+   bidirectional file descriptor (normally returned via socketpair)
+   which the client can use to rendezvous with the server.  SERVER is
+   the server's pid.  */
 assuan_error_t
-assuan_domain_connect (assuan_context_t * r_ctx, int rendezvousfd, pid_t peer)
+assuan_domain_connect (assuan_context_t *r_ctx, int rendezvousfd, pid_t server)
 {
   assuan_error_t aerr;
   int okay, off;
 
-  aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+  aerr = _assuan_domain_init (r_ctx, rendezvousfd, server);
   if (aerr)
     return aerr;
 
@@ -518,7 +524,7 @@
       _assuan_log_printf ("can't connect to server: `");
       _assuan_log_sanitized_string ((*r_ctx)->inbound.line);
       fprintf (assuan_get_assuan_log_stream (), "'\n");
-      aerr = ASSUAN_Connect_Failed;
+      aerr = _assuan_error (ASSUAN_Connect_Failed);
     }
 
   if (aerr)

Modified: trunk/src/assuan-domain-server.c
===================================================================
--- trunk/src/assuan-domain-server.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-domain-server.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -27,15 +27,18 @@
 
 #include "assuan-defs.h"
 
-/* Initialize a server.  */
+/* Initialize a server.  RENDEZVOUSFD is a bidirectional file
+   descriptor (normally returned via socketpair) that the domain
+   server can use to rendezvous with the client.  CLIENT is the
+   client's pid.  */
 assuan_error_t
 assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
 			   int rendezvousfd,
-			   pid_t peer)
+			   pid_t client)
 {
   assuan_error_t err;
 
-  err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+  err = _assuan_domain_init (r_ctx, rendezvousfd, client);
   if (err)
     return err;
 

Modified: trunk/src/assuan-handler.c
===================================================================
--- trunk/src/assuan-handler.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-handler.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -246,7 +246,7 @@
     cmd_name = NULL;
 
   if (!cmd_name)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   if (!handler)
     { /* find a default handler. */
@@ -269,7 +269,7 @@
       ctx->cmdtbl_size = 50;
       ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl);
       if (!ctx->cmdtbl)
-        return ASSUAN_Out_Of_Core;
+        return _assuan_error (ASSUAN_Out_Of_Core);
       ctx->cmdtbl_used = 0;
     }
   else if (ctx->cmdtbl_used >= ctx->cmdtbl_size)
@@ -278,7 +278,7 @@
 
       x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x);
       if (!x)
-        return ASSUAN_Out_Of_Core;
+        return _assuan_error (ASSUAN_Out_Of_Core);
       ctx->cmdtbl = x;
       ctx->cmdtbl_size += 50;
     }
@@ -293,7 +293,7 @@
 assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->bye_notify_fnc = fnc;
   return 0;
 }
@@ -302,7 +302,7 @@
 assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->reset_notify_fnc = fnc;
   return 0;
 }
@@ -311,7 +311,7 @@
 assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->cancel_notify_fnc = fnc;
   return 0;
 }
@@ -322,7 +322,7 @@
                                           const char*, const char*))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->option_handler_fnc = fnc;
   return 0;
 }
@@ -332,7 +332,7 @@
                               void (*fnc)(ASSUAN_CONTEXT, const char *))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->input_notify_fnc = fnc;
   return 0;
 }
@@ -342,7 +342,7 @@
                               void (*fnc)(ASSUAN_CONTEXT, const char *))
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   ctx->output_notify_fnc = fnc;
   return 0;
 }
@@ -407,7 +407,7 @@
   for (p=line; *p && *p != ' ' && *p != '\t'; p++)
     ;
   if (p==line)
-    return set_error (ctx, Invalid_Command, "leading white-space"); 
+    return set_error (ctx, Syntax_Error, "leading white-space"); 
   if (*p) 
     { /* Skip over leading WS after the keyword */
       *p++ = 0;
@@ -447,7 +447,7 @@
   int rc;
 
   if (ctx->in_inquire)
-    return ASSUAN_Nested_Commands;
+    return _assuan_error (ASSUAN_Nested_Commands);
 
   rc = _assuan_read_line (ctx);
   if (rc)
@@ -478,7 +478,7 @@
     {
       rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK");
     }
-  else if (rc == -1)
+  else if (err_is_eof (rc))
     { /* No error checking because the peer may have already disconnect */ 
       assuan_write_line (ctx, "OK closing connection");
       ctx->finish_handler (ctx);
@@ -489,7 +489,7 @@
 
       if (rc < 100)
         sprintf (errline, "ERR %d server fault (%.50s)",
-                 ASSUAN_Server_Fault, assuan_strerror (rc));
+                 _assuan_error (ASSUAN_Server_Fault), assuan_strerror (rc));
       else
         {
           const char *text = ctx->err_no == rc? ctx->err_str:NULL;
@@ -499,7 +499,7 @@
              strings from libgpg-error without creating a dependency.
              They are used for debugging purposes only, so there is no
              problem if they are not available.  We need to make sure
-             that we are using elf because only this guarantees that
+             that we are using ELF because only this guarantees that
              weak symbol support is available in case GNU ld is not
              used. */
           unsigned int source, code;
@@ -561,7 +561,7 @@
     rc = process_request (ctx);
   } while (!rc);
 
-  if (rc == -1)
+  if (err_is_eof (rc))
     rc = 0;
 
   return rc;
@@ -662,7 +662,7 @@
 assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   if (!line)
     {
       xfree (ctx->okay_line);
@@ -674,7 +674,7 @@
          we should allocate the entire line in secure memory */
       char *buf = xtrymalloc (3+strlen(line)+1);
       if (!buf)
-        return ASSUAN_Out_Of_Core;
+        return _assuan_error (ASSUAN_Out_Of_Core);
       strcpy (buf, "OK ");
       strcpy (buf+3, line);
       xfree (ctx->okay_line);
@@ -694,7 +694,7 @@
   assuan_error_t ae;
 
   if ( !ctx || !keyword)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   if (!text)
     text = "";
 

Modified: trunk/src/assuan-inquire.c
===================================================================
--- trunk/src/assuan-inquire.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-inquire.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -147,14 +147,14 @@
   int nodataexpected;
 
   if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   nodataexpected = !r_buffer && !r_length && !maxlen;
   if (!nodataexpected && (!r_buffer || !r_length))
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   if (!ctx->is_server)
-    return ASSUAN_Not_A_Server;
+    return _assuan_error (ASSUAN_Not_A_Server);
   if (ctx->in_inquire)
-    return ASSUAN_Nested_Commands;
+    return _assuan_error (ASSUAN_Nested_Commands);
   
   ctx->in_inquire = 1;
   if (nodataexpected)
@@ -183,12 +183,12 @@
         break; /* END command received*/
       if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
         {
-          rc = ASSUAN_Canceled;
+          rc = _assuan_error (ASSUAN_Canceled);
           goto leave;
         }
       if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
         {
-          rc = ASSUAN_Unexpected_Command;
+          rc = _assuan_error (ASSUAN_Unexpected_Command);
           goto leave;
         }
       if (linelen < 3)
@@ -215,7 +215,7 @@
         }
       if (mb.too_large)
         {
-          rc = ASSUAN_Too_Much_Data;
+          rc = _assuan_error (ASSUAN_Too_Much_Data);
           goto leave;
         }
     }
@@ -224,7 +224,7 @@
     {
       *r_buffer = get_membuf (&mb, r_length);
       if (!*r_buffer)
-        rc = ASSUAN_Out_Of_Core;
+        rc = _assuan_error (ASSUAN_Out_Of_Core);
     }
 
  leave:

Modified: trunk/src/assuan-listen.c
===================================================================
--- trunk/src/assuan-listen.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-listen.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -31,7 +31,7 @@
 assuan_set_hello_line (assuan_context_t ctx, const char *line)
 {
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   if (!line)
     {
       xfree (ctx->hello_line);
@@ -41,7 +41,7 @@
     {
       char *buf = xtrymalloc (3+strlen(line)+1);
       if (!buf)
-        return ASSUAN_Out_Of_Core;
+        return _assuan_error (ASSUAN_Out_Of_Core);
       if (strchr (line, '\n'))
         strcpy (buf, line);
       else
@@ -74,7 +74,7 @@
   const char *p, *pend;
 
   if (!ctx)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   if (ctx->pipe_mode > 1)
     return -1; /* second invocation for pipemode -> terminate */
@@ -135,7 +135,7 @@
 assuan_close_input_fd (assuan_context_t ctx)
 {
   if (!ctx || ctx->input_fd == -1)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   _assuan_close (ctx->input_fd);
   ctx->input_fd = -1;
   return 0;
@@ -147,7 +147,7 @@
 assuan_close_output_fd (assuan_context_t ctx)
 {
   if (!ctx || ctx->output_fd == -1)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   _assuan_close (ctx->output_fd);
   ctx->output_fd = -1;

Modified: trunk/src/assuan-logging.c
===================================================================
--- trunk/src/assuan-logging.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-logging.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -28,6 +28,7 @@
 #ifdef HAVE_W32_SYSTEM
 #include <windows.h>
 #endif /*HAVE_W32_SYSTEM*/
+#include <errno.h>
 
 #include "assuan-defs.h"
 
@@ -81,18 +82,17 @@
   va_list arg_ptr;
   FILE *fp;
   const char *prf;
-
+  int save_errno = errno;
+  
   fp = assuan_get_assuan_log_stream ();
   prf = assuan_get_assuan_log_prefix ();
   if (*prf)
-    {
-      fputs (prf, fp);
-      fputs (": ", fp);
-    }
+    fprintf (fp, "%s[%u]: ", prf, (unsigned int)getpid ());
 
   va_start (arg_ptr, format);
   vfprintf (fp, format, arg_ptr );
   va_end (arg_ptr);
+  errno = save_errno;
 }
 
 

Modified: trunk/src/assuan-pipe-connect.c
===================================================================
--- trunk/src/assuan-pipe-connect.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-pipe-connect.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -270,7 +270,7 @@
   HANDLE nullfd = INVALID_HANDLE_VALUE;
 
   if (!ctx || !name || !argv || !argv[0])
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   fix_signals ();
 
@@ -278,13 +278,13 @@
 
   /* Build the command line.  */
   if (build_w32_commandline (argv, &cmdline))
-    return ASSUAN_Out_Of_Core;
+    return _assuan_error (ASSUAN_Out_Of_Core);
 
   /* Create thew two pipes. */
   if (create_inheritable_pipe (rp, 0))
     {
       xfree (cmdline);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
   
   if (create_inheritable_pipe (wp, 1))
@@ -292,7 +292,7 @@
       CloseHandle (fd_to_handle (rp[0]));
       CloseHandle (fd_to_handle (rp[1]));
       xfree (cmdline);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
 
   
@@ -304,7 +304,7 @@
       CloseHandle (fd_to_handle (wp[0]));
       CloseHandle (fd_to_handle (wp[1]));
       xfree (cmdline);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
 
   (*ctx)->pipe_mode = 1;
@@ -391,7 +391,7 @@
         CloseHandle (nullfd);
       xfree (cmdline);
       _assuan_release_context (*ctx); 
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
   xfree (cmdline);
   cmdline = NULL;
@@ -421,20 +421,20 @@
   char mypidstr[50];
 
   if (!ctx || !name || !argv || !argv[0])
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   fix_signals ();
 
   sprintf (mypidstr, "%lu", (unsigned long)getpid ());
 
   if (pipe (rp) < 0)
-    return ASSUAN_General_Error;
+    return _assuan_error (ASSUAN_General_Error);
 
   if (pipe (wp) < 0)
     {
       close (rp[0]);
       close (rp[1]);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
   
   err = _assuan_new_context (ctx);
@@ -462,7 +462,7 @@
       close (wp[0]);
       close (wp[1]);
       _assuan_release_context (*ctx); 
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
 
   if ((*ctx)->pid == 0)
@@ -559,7 +559,8 @@
           /* oops - use the pipe to tell the parent about it */
           snprintf (errbuf, sizeof(errbuf)-1,
                     "ERR %d can't exec `%s': %.50s\n",
-                    ASSUAN_Problem_Starting_Server, name, strerror (errno));
+                    _assuan_error (ASSUAN_Problem_Starting_Server),
+                    name, strerror (errno));
           errbuf[sizeof(errbuf)-1] = 0;
           writen (1, errbuf, strlen (errbuf));
           _exit (4);
@@ -594,7 +595,7 @@
       {
 	_assuan_log_printf ("can't connect server: `%s'\n",
                             (*ctx)->inbound.line);
-	err = ASSUAN_Connect_Failed;
+	err = _assuan_error (ASSUAN_Connect_Failed);
       }
   }
 

Modified: trunk/src/assuan-pipe-server.c
===================================================================
--- trunk/src/assuan-pipe-server.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-pipe-server.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -66,7 +66,7 @@
   *r_ctx = NULL;
   ctx = xtrycalloc (1, sizeof *ctx);
   if (!ctx)
-    return ASSUAN_Out_Of_Core;
+    return _assuan_error (ASSUAN_Out_Of_Core);
   ctx->input_fd = -1;
   ctx->output_fd = -1;
 

Modified: trunk/src/assuan-socket-connect.c
===================================================================
--- trunk/src/assuan-socket-connect.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-socket-connect.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -89,7 +89,7 @@
   const char *s;
 
   if (!r_ctx || !name)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
   *r_ctx = NULL;
 
   /* We require that the name starts with a slash, so that we can
@@ -99,10 +99,10 @@
   if (*s && s[1] == ':')
     s += 2;
   if (*s != DIRSEP_C && *s != '/')
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   if (strlen (name)+1 >= sizeof srvr_addr.sun_path)
-    return ASSUAN_Invalid_Value;
+    return _assuan_error (ASSUAN_Invalid_Value);
 
   err = _assuan_new_context (&ctx); 
   if (err)
@@ -116,7 +116,7 @@
     {
       _assuan_log_printf ("can't create socket: %s\n", strerror (errno));
       _assuan_release_context (ctx);
-      return ASSUAN_General_Error;
+      return _assuan_error (ASSUAN_General_Error);
     }
 
   memset (&srvr_addr, 0, sizeof srvr_addr);
@@ -132,7 +132,7 @@
                           name, strerror (errno));
       _assuan_release_context (ctx);
       _assuan_close (fd);
-      return ASSUAN_Connect_Failed;
+      return _assuan_error (ASSUAN_Connect_Failed);
     }
 
   ctx->inbound.fd = fd;
@@ -152,7 +152,7 @@
         /*LOG ("can't connect to server: `");*/
 	_assuan_log_sanitized_string (ctx->inbound.line);
 	fprintf (assuan_get_assuan_log_stream (), "'\n");
-	err = ASSUAN_Connect_Failed;
+	err = _assuan_error (ASSUAN_Connect_Failed);
       }
   }
 

Modified: trunk/src/assuan-socket-server.c
===================================================================
--- trunk/src/assuan-socket-server.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan-socket-server.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -79,7 +79,7 @@
   if (fd == -1)
     {
       ctx->os_errno = errno;
-      return ASSUAN_Accept_Failed;
+      return _assuan_error (ASSUAN_Accept_Failed);
     }
 
   ctx->connected_fd = fd;
@@ -119,7 +119,7 @@
   *r_ctx = NULL;
   ctx = xtrycalloc (1, sizeof *ctx);
   if (!ctx)
-    return ASSUAN_Out_Of_Core;
+    return _assuan_error (ASSUAN_Out_Of_Core);
   ctx->is_server = 1;
   ctx->input_fd = -1;
   ctx->output_fd = -1;
@@ -153,7 +153,7 @@
   *r_ctx = NULL;
   ctx = xtrycalloc (1, sizeof *ctx);
   if (!ctx)
-    return ASSUAN_Out_Of_Core;
+    return _assuan_error (ASSUAN_Out_Of_Core);
   ctx->is_server = 1;
   ctx->pipe_mode = 1; /* we want a second accept to indicate EOF */
   ctx->input_fd = -1;

Modified: trunk/src/assuan.h
===================================================================
--- trunk/src/assuan.h	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/assuan.h	2006-09-06 16:36:45 UTC (rev 196)
@@ -27,24 +27,32 @@
 #include <unistd.h>
 
 
-/* To use this file with libraries the following macros are often
-   useful:
+/* To use this file with libraries the following macros are useful:
 
-   #define _ASSUAN_EXT_SYM_PREFIX _foo_
+     #define _ASSUAN_EXT_SYM_PREFIX _foo_
    
      This prefixes all external symbols with "_foo_".
 
-   #define _ASSUAN_NO_PTH 
+     #define _ASSUAN_ONLY_GPG_ERRORS
 
-     This avoids inclusion of special GNU Pth hacks.
+     If this is defined all old-style Assuan error codes are made
+     inactive as well as other dereacted stuff.
 
-   #define _ASSUAN_NO_FIXED_SIGNALS 
+   The follwing macros are used internally in the implementation of
+   libassuan:
 
-     This disables changing of certain signal handler; i.e. SIGPIPE.
+     #define _ASSUAN_NO_PTH 
 
-   #define _ASSUAN_USE_DOUBLE_FORK
+       This avoids inclusion of special GNU Pth hacks.
 
-     Use a double fork approach when connecting to a server through a pipe.
+     #define _ASSUAN_NO_FIXED_SIGNALS 
+
+       This disables changing of certain signal handler; i.e. SIGPIPE.
+
+     #define _ASSUAN_USE_DOUBLE_FORK
+
+       Use a double fork approach when connecting to a server through
+       a pipe.
  */
 
 
@@ -105,6 +113,8 @@
 #define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential)
 #define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential)
 #define assuan_strerror _ASSUAN_PREFIX(assuan_strerror)
+#define assuan_set_assuan_err_source \
+  _ASSUAN_PREFIX(assuan_set_assuan_err_source)
 #define assuan_set_assuan_log_stream \
   _ASSUAN_PREFIX(assuan_set_assuan_log_stream)
 #define assuan_get_assuan_log_stream \
@@ -156,19 +166,27 @@
 #endif
 #endif
 
-
+#ifndef _ASSUAN_ONLY_GPG_ERRORS
+/* Assuan error codes.  These are only used by old applications or
+   those applications which won't make use of libgpg-error. */
 typedef enum
 {
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_No_Error = 0,
+#endif
   ASSUAN_General_Error = 1,
   ASSUAN_Out_Of_Core = 2,
   ASSUAN_Invalid_Value = 3,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Timeout = 4,
+#endif
   ASSUAN_Read_Error = 5,
   ASSUAN_Write_Error = 6,
   ASSUAN_Problem_Starting_Server = 7,
   ASSUAN_Not_A_Server = 8,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Not_A_Client = 9,
+#endif
   ASSUAN_Nested_Commands = 10,
   ASSUAN_Invalid_Response = 11,
   ASSUAN_No_Data_Callback = 12,
@@ -179,24 +197,33 @@
   /* Error codes above 99 are meant as status codes */
   ASSUAN_Not_Implemented = 100,
   ASSUAN_Server_Fault    = 101,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Invalid_Command = 102,
+#endif
   ASSUAN_Unknown_Command = 103,
   ASSUAN_Syntax_Error    = 104,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Parameter_Error = 105,
+#endif
   ASSUAN_Parameter_Conflict = 106,
   ASSUAN_Line_Too_Long = 107,
   ASSUAN_Line_Not_Terminated = 108,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_No_Input = 109,
   ASSUAN_No_Output = 110,
+#endif
   ASSUAN_Canceled = 111,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Unsupported_Algorithm = 112,
   ASSUAN_Server_Resource_Problem = 113,
   ASSUAN_Server_IO_Error = 114,
   ASSUAN_Server_Bug = 115,
   ASSUAN_No_Data_Available = 116,
   ASSUAN_Invalid_Data = 117,
+#endif
   ASSUAN_Unexpected_Command = 118,
   ASSUAN_Too_Much_Data = 119,
+#ifndef _ASSUAN_IN_LIBASSUAN
   ASSUAN_Inquire_Unknown = 120,
   ASSUAN_Inquire_Error = 121,
   ASSUAN_Invalid_Option = 122,
@@ -207,7 +234,7 @@
   ASSUAN_Locale_Problem = 127,
   ASSUAN_Not_Confirmed = 128,
 
-  /* Warning: Don't use the rror codes, below they are deprecated. */
+  /* Warning: Don't use the Error codes, below they are deprecated. */
   ASSUAN_Bad_Certificate = 201,
   ASSUAN_Bad_Certificate_Chain = 202,
   ASSUAN_Missing_Certificate = 203,
@@ -233,7 +260,7 @@
      at their own discretion. */
   ASSUAN_USER_ERROR_FIRST = 1000,
   ASSUAN_USER_ERROR_LAST = 9999
-
+#endif
 } assuan_error_t;
 
 typedef assuan_error_t AssuanError; /* Deprecated. */
@@ -258,6 +285,13 @@
 } AssuanCommand;
 
 
+#else  /*!_ASSUAN_ONLY_GPG_ERRORS*/
+
+typedef int assuan_error_t;
+
+#endif /*!_ASSUAN_ONLY_GPG_ERRORS*/
+
+
 /* Definitions of flags for assuan_set_flag(). */
 typedef enum
   {
@@ -274,7 +308,9 @@
 
 struct assuan_context_s;
 typedef struct assuan_context_s *assuan_context_t;
+#ifndef _ASSUAN_ONLY_GPG_ERRORS
 typedef struct assuan_context_s *ASSUAN_CONTEXT;
+#endif /*_ASSUAN_ONLY_GPG_ERRORS*/
 
 /*-- assuan-handler.c --*/
 int assuan_register_command (assuan_context_t ctx,
@@ -351,8 +387,8 @@
    which the client can use to rendezvous with the server.  SERVER s
    the server's pid.  */
 assuan_error_t assuan_domain_connect (assuan_context_t *r_ctx,
-				   int rendezvousfd,
-				   pid_t server);
+                                      int rendezvousfd,
+                                      pid_t server);
 
 /*-- assuan-domain-server.c --*/
 
@@ -360,8 +396,8 @@
    via socketpair) that the domain server can use to rendezvous with
    the client.  CLIENT is the client's pid.  */
 assuan_error_t assuan_init_domain_server (assuan_context_t *r_ctx,
-				       int rendezvousfd,
-				       pid_t client);
+                                          int rendezvousfd,
+                                          pid_t client);
 
 
 /*-- assuan-connect.c --*/
@@ -421,9 +457,21 @@
 int  assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag);
 
 
-/*-- assuan-errors.c (built) --*/
+/*-- assuan-errors.c --*/
+
+#ifndef _ASSUAN_ONLY_GPG_ERRORS
+/* Return a string describing the assuan error.  The use of this
+   function is deprecated; it is better to call
+   assuan_set_assuan_err_source once and then make use libgpg-error. */
 const char *assuan_strerror (assuan_error_t err);
+#endif /*_ASSUAN_ONLY_GPG_ERRORS*/
 
+/* Enable gpg-error style error codes.  ERRSOURCE is one of gpg-error
+   sources.  Note, that this function is not thread-safe and should be
+   used right at startup. Switching back to the old style mode is not
+   supported. */
+void assuan_set_assuan_err_source (int errsource);
+
 /*-- assuan-logging.c --*/
 
 /* Set the stream to which assuan should log message not associated

Modified: trunk/src/mkerrors
===================================================================
--- trunk/src/mkerrors	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/src/mkerrors	2006-09-06 16:36:45 UTC (rev 196)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # mkerrors - Extract error strings from assuan.h
 #            and create C source for assuan_strerror
-#	Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+#	Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
 #
 # This file is part of Assuan.
 #
@@ -21,15 +21,114 @@
 
 cat <<EOF
 /* Generated automatically by mkerrors */
-/* Do not edit! */
+/* Do not edit!  See mkerrors for copyright notice. */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
 #include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+#undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */
 #include "assuan.h"
 
+/* If true the modern gpg-error style error codes are used in the
+   API. */
+static unsigned int err_source;
+
+/* Enable gpg-error style error codes.  ERRSOURCE is one of gpg-error
+   sources.  Note, that this function is not thread-safe and should be
+   used right at startup. Switching back to the old style mode is not
+   supported. */
+void
+assuan_set_assuan_err_source (int errsource)
+{
+  errsource &= 0xff;
+  err_source = errsource? errsource : 31 /*GPG_ERR_SOURCE_ANY*/;
+}
+
+
+/* Helper to map old style Assuan error codes to gpg-error codes.
+   This is used internally to keep an compatible ABI. */
+int
+_assuan_error (int oldcode)
+{
+  unsigned int n;
+
+  if (!err_source)
+    return (oldcode & 0x00ffffff); /* Make sure that the gpg-error
+                                      source part is cleared. */
+
+  switch (oldcode)
+    {
+    case ASSUAN_General_Error:           n = 257; break;
+    case ASSUAN_Accept_Failed:           n = 258; break;
+    case ASSUAN_Connect_Failed:          n = 259; break;
+    case ASSUAN_Invalid_Response:        n = 260; break;
+    case ASSUAN_Invalid_Value:           n = 261; break;
+    case ASSUAN_Line_Not_Terminated:     n = 262; break;
+    case ASSUAN_Line_Too_Long:           n = 263; break;
+    case ASSUAN_Nested_Commands:         n = 264; break;
+    case ASSUAN_No_Data_Callback:        n = 265; break;
+    case ASSUAN_No_Inquire_Callback:     n = 266; break;
+    case ASSUAN_Not_A_Server:            n = 267; break;
+    case ASSUAN_Not_Implemented:         n =  69; break;
+    case ASSUAN_Parameter_Conflict:      n = 280; break;
+    case ASSUAN_Problem_Starting_Server: n = 269; break;
+    case ASSUAN_Server_Fault:            n =  80; break;
+    case ASSUAN_Syntax_Error:            n = 276; break;
+    case ASSUAN_Too_Much_Data:           n = 273; break;
+    case ASSUAN_Unexpected_Command:      n = 274; break;
+    case ASSUAN_Unknown_Command:         n = 275; break;
+    case ASSUAN_Canceled:                n = 277; break;
+
+    case ASSUAN_Read_Error:
+      switch (errno)
+        {
+        case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/  break;
+        default: n = 270;  /*GPG_ERR_ASS_READ_ERROR*/ break;
+        }
+      break;
+
+    case ASSUAN_Write_Error:
+      switch (errno)
+        {
+        case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/  break;
+        default: n = 271;  /*GPG_ERR_ASS_WRITE_ERROR*/ break;
+        }
+      break;
+      
+    case ASSUAN_Out_Of_Core:
+      switch (errno)
+        {
+        case 0:  /* Should not happen but a user might have provided
+                    an incomplete implemented malloc function.  Give
+                    him a chance to correct this fault but make sure
+                    an error is indeed returned. */
+          n = 16381; /*GPG_ERR_MISSING_ERRNO*/
+          break;
+        case ENOMEM: n = (1 << 15) | 86; break;
+        default:  
+          n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/
+          break;
+        }
+      break;
+
+    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.  */
+      break;
+    }
+
+  return ((err_source << 24) | (n & 0x00ffffff));
+
+}
+
+
 /**
  * assuan_strerror:
  * @err:  Error code 
@@ -54,6 +153,7 @@
 /ASSUAN_No_Error/    { okay=1 }
 !okay              {next}
 /}/                { exit 0 }
+/^#/               {next}
 /ASSUAN_[A-Za-z_]*/ { print_code($1) }
 
 
@@ -66,21 +166,62 @@
 '
 
 cat <<EOF
+  case -1: s = "EOF (-1)"; break;
     default: 
       {
-        unsigned int source, code;
+        unsigned int source, code, n;
 
         source = ((err >> 24) & 0xff);
         code = (err & 0x00ffffff);
-        if (source) /* Assume this is an libgpg-error. */
-          sprintf (buf, "ec=%u.%u", source, code ); 
+        if (source) 
+          {
+            /* Assume this is an libgpg-error and try to map the codes
+               back. */
+            switch (code)
+              {
+              case 257: n = ASSUAN_General_Error          ; break;
+              case 258: n = ASSUAN_Accept_Failed          ; break;
+              case 259: n = ASSUAN_Connect_Failed         ; break;
+              case 260: n = ASSUAN_Invalid_Response       ; break;
+              case 261: n = ASSUAN_Invalid_Value          ; break;
+              case 262: n = ASSUAN_Line_Not_Terminated    ; break;
+              case 263: n = ASSUAN_Line_Too_Long          ; break;
+              case 264: n = ASSUAN_Nested_Commands        ; break;
+              case 265: n = ASSUAN_No_Data_Callback       ; break;
+              case 266: n = ASSUAN_No_Inquire_Callback    ; break;
+              case 267: n = ASSUAN_Not_A_Server           ; break;
+              case  69: n = ASSUAN_Not_Implemented        ; break;
+              case 280: n = ASSUAN_Parameter_Conflict     ; break;
+              case 269: n = ASSUAN_Problem_Starting_Server; break;
+              case 270: n = ASSUAN_Read_Error             ; break;
+              case 271: n = ASSUAN_Write_Error            ; break;
+              case  80: n = ASSUAN_Server_Fault           ; break;
+              case 276: n = ASSUAN_Syntax_Error           ; break;
+              case 273: n = ASSUAN_Too_Much_Data          ; break;
+              case 274: n = ASSUAN_Unexpected_Command     ; break;
+              case 275: n = ASSUAN_Unknown_Command        ; break;
+              case 277: n = ASSUAN_Canceled               ; break;
+              case ((1<<15)|86): n = ASSUAN_Out_Of_Core   ; break;
+              default:  n = 0; break;
+              }
+            if (n)
+              s = assuan_strerror (n);
+            else
+              {
+                sprintf (buf, "ec=%u.%u", source, code ); 
+                s=buf;
+              }
+          }
         else
-          sprintf (buf, "ec=%d", err ); 
-        s=buf; break;
+          {
+            sprintf (buf, "ec=%d", err ); 
+            s=buf;
+          }
       }
+      break;
     }
 
   return s;
 }
 
-EOF
\ No newline at end of file
+EOF

Added: trunk/tests/Makefile.am
===================================================================
--- trunk/tests/Makefile.am	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/tests/Makefile.am	2006-09-06 16:36:45 UTC (rev 196)
@@ -0,0 +1,37 @@
+# Makefile for Assuan regression tests
+# Copyright (C) 2006 Free Software Foundation, Inc.
+#
+# This file is part of Assuan.
+#
+# Assuan is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Assuan is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+# MA 02110-1301, USA 
+
+## Process this file with automake to produce Makefile.in
+
+TESTS_ENVIRONMENT = 
+
+EXTRA_DIST = 
+
+BUILT_SOURCES = 
+CLEANFILES = 
+
+TESTS = fdpassing
+
+AM_CFLAGS = # $(GPG_ERROR_CFLAGS)
+
+noinst_HEADERS = common.h
+noinst_PROGRAMS = $(TESTS)
+LDADD =  ../src/libassuan.a  # $(GPG_ERROR_LIBS)
+

Added: trunk/tests/common.h
===================================================================
--- trunk/tests/common.h	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/tests/common.h	2006-09-06 16:36:45 UTC (rev 196)
@@ -0,0 +1,149 @@
+/* common.h - Common functions for the tests.
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Assuan.
+ *
+ * Assuan is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Assuan is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA. 
+ */
+
+#include <stdarg.h>
+
+
+static const char *log_prefix;
+static int errorcount;
+static int verbose;
+static int debug;
+
+
+void *
+xmalloc (size_t n)
+{
+  char *p = malloc (n);
+  if (!p)
+    {
+      fprintf (stderr, "out of core\n");
+      exit (1);
+    }
+  return p;
+}
+
+void *
+xcalloc (size_t n, size_t m)
+{
+  char *p = calloc (n, m);
+  if (!p)
+    {
+      fprintf (stderr, "out of core\n");
+      exit (1);
+    }
+  return p;
+}
+
+void
+xfree (void *a)
+{
+  if (a)
+    free (a);
+}
+
+
+void
+log_set_prefix (const char *s)
+{
+  log_prefix = strrchr (s, '/');
+  if (log_prefix)
+    log_prefix++;
+  else
+    log_prefix = s;
+}
+
+
+void
+log_info (const char *format, ...)
+{
+  va_list arg_ptr ;
+
+  if (!verbose)
+    return;
+
+  va_start (arg_ptr, format) ;
+  if (log_prefix)
+    fprintf (stderr, "%s[%u]: ", log_prefix, (unsigned int)getpid ());
+  vfprintf (stderr, format, arg_ptr );
+  va_end (arg_ptr);
+}
+
+
+void
+log_error (const char *format, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, format) ;
+  if (log_prefix)
+    fprintf (stderr, "%s[%u]: ", log_prefix, (unsigned int)getpid ());
+  vfprintf (stderr, format, arg_ptr );
+  va_end (arg_ptr);
+  errorcount++;
+}
+
+
+void
+log_fatal (const char *format, ...)
+{
+  va_list arg_ptr ;
+
+  va_start (arg_ptr, format) ;
+  if (log_prefix)
+    fprintf (stderr, "%s[%u]: ", log_prefix, (unsigned int)getpid ());
+  vfprintf (stderr, format, arg_ptr );
+  va_end (arg_ptr);
+  exit (2);
+}
+
+
+void
+log_printhex (const char *text, const void *buffer, size_t length)
+{
+  const unsigned char *s;
+
+  if (log_prefix)
+    fprintf (stderr, "%s[%u]: ", log_prefix, (unsigned int)getpid ());
+  fputs (text, stderr);
+  for (s=buffer; length; s++, length--)
+    fprintf (stderr, "%02X", *s);
+  putc ('\n', stderr);
+}
+
+
+/* Prepend FNAME with the srcdir environment variable's value and
+   return an allocated filename. */
+char *
+prepend_srcdir (const char *fname)
+{
+  static const char *srcdir;
+  char *result;
+
+  if (!srcdir && !(srcdir = getenv ("srcdir")))
+    srcdir = ".";
+  
+  result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+  strcpy (result, srcdir);
+  strcat (result, "/");
+  strcat (result, fname);
+  return result;
+}
+

Added: trunk/tests/fdpassing.c
===================================================================
--- trunk/tests/fdpassing.c	2006-06-27 10:37:31 UTC (rev 195)
+++ trunk/tests/fdpassing.c	2006-09-06 16:36:45 UTC (rev 196)
@@ -0,0 +1,213 @@
+/* fdpassing - Check the fiel descriptor passing.
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Assuan.
+ *
+ * Assuan is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Assuan is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA. 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/wait.h>  /* Used by main driver. */
+
+#include "../src/assuan.h"
+#include "common.h"
+
+
+/*
+
+       S E R V E R
+
+*/
+
+static int
+cmd_echo (assuan_context_t ctx, char *line)
+{
+  log_info ("got ECHO command (%s)\n", line);
+  return 0;
+}
+
+static assuan_error_t
+register_commands (assuan_context_t ctx)
+{
+  static struct {
+    const char *name;
+    int (*handler)(assuan_context_t, char *line);
+  } table[] = {
+    { "ECHO",       cmd_echo },
+    { "INPUT",      NULL },
+    { "OUTPUT",     NULL },
+    { NULL }
+  };
+  int i;
+  assuan_error_t rc;
+
+  for (i=0; table[i].name; i++)
+    {
+      rc = assuan_register_command (ctx, table[i].name, table[i].handler);
+      if (rc)
+        return rc;
+    }
+  return 0;
+}
+
+
+static void
+server (int fd)
+{
+  int rc;
+  assuan_context_t ctx;
+
+  log_info ("server started on fd %d\n", fd);
+
+  rc = assuan_init_domain_server (&ctx, fd, (pid_t)(-1));
+  if (rc)
+    log_fatal ("assuan_init_domain_server failed: %s\n", assuan_strerror (rc));
+
+  rc = register_commands (ctx);
+  if (rc)
+    log_fatal ("register_commands failed: %s\n", assuan_strerror(rc));
+
+  assuan_set_assuan_log_prefix (log_prefix);
+  assuan_set_log_stream (ctx, stderr);
+
+  for (;;) 
+    {
+      rc = assuan_accept (ctx);
+      if (rc)
+        {
+          log_error ("assuan_accept failed: %s\n", assuan_strerror (rc));
+          break;
+        }
+
+      rc = assuan_process (ctx);
+      if (rc)
+        log_error ("assuan_process failed: %s\n", assuan_strerror (rc));
+    }
+  
+  assuan_deinit_server (ctx);
+}
+
+
+
+
+/*
+
+       C L I E N T
+
+*/
+
+
+/* Client main.  If true is returned, a disconnect has not been done. */
+static int
+client (int fd)
+{
+  int rc;
+  assuan_context_t ctx;
+
+  log_info ("client started on fd %d\n", fd);
+
+  rc = assuan_domain_connect (&ctx, fd, (pid_t)(-1));
+  if (rc)
+    {
+      log_error ("assuan_domain_connect failed: %s\n", assuan_strerror (rc));
+      return -1;
+    }
+      
+
+  assuan_disconnect (ctx);
+  return 0;
+}
+
+
+
+
+/* 
+ 
+     M A I N
+
+*/
+int 
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  const char *srcdir = getenv ("srcdir");
+  int fds[2];
+  pid_t pid;
+  
+  if (!srcdir)
+    srcdir = ".";
+
+  if (argc)
+    {
+      log_set_prefix (*argv);
+      argc--; argv++;
+    }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--help"))
+        {
+          puts (
+"usage: ./fdpassing [options]\n"
+"\n"
+"       Options are --verbose and --debug");
+          exit (0);
+        }
+      if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+    }
+
+  /* Create a socketpair.  */
+  if ( socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) )
+    log_fatal ("socketpair failed: %s\n", strerror (errno));
+
+  /* Fork and run server and client.  */
+  pid = fork ();
+  if (pid == (pid_t)(-1))
+    log_fatal ("fork failed: %s\n", strerror (errno));
+  if (!pid)
+    {
+      server (fds[0]); /* The child is our server. */
+      log_info ("server finished\n");
+    }
+  else
+    {
+      if (client (fds[1])) /* The parent is the client.  */
+        {
+          log_info ("waiting for server to terminate...\n");
+          waitpid (pid, NULL, 0); 
+        }
+      log_info ("client finished\n");
+    }
+
+  return errorcount? 1:0;
+}
+




More information about the Gnupg-commits mailing list