Register DCO for Stefan Tomanek.
[gnupg.git] / common / init.c
index f551416..91ee912 100644 (file)
@@ -3,12 +3,22 @@
  *
  * This file is part of GnuPG.
  *
- * GnuPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
  *
- * GnuPG is distributed in the hope that it will be useful,
+ *   - the GNU Lesser General Public License as published by the Free
+ *     Software Foundation; either version 3 of the License, or (at
+ *     your option) any later version.
+ *
+ * or
+ *
+ *   - the GNU General Public License as published by the Free
+ *     Software Foundation; either version 2 of the License, or (at
+ *     your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file 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 General Public License for more details.
 #endif
 
 #ifdef HAVE_W32_SYSTEM
-#include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
 #endif
 #ifdef HAVE_NPTH
-#include <npth.h>
+# include <npth.h>
 #endif
 #ifdef HAVE_W32CE_SYSTEM
 # include <assuan.h> /* For _assuan_w32ce_finish_pipe. */
 
 #include "util.h"
 
+/* This object is used to register memory cleanup functions.
+   Technically they are not needed but they can avoid frequent
+   questions about un-released memory.  Note that we use the system
+   malloc and not any wrappers.  */
+struct mem_cleanup_item_s;
+typedef struct mem_cleanup_item_s *mem_cleanup_item_t;
+
+struct mem_cleanup_item_s
+{
+  mem_cleanup_item_t next;
+  void (*func) (void);
+};
+
+static mem_cleanup_item_t mem_cleanup_list;
+
+
+/* The default error source of the application.  This is different
+   from GPG_ERR_SOURCE_DEFAULT in that it does not depend on the
+   source file and thus is usable in code shared by applications.  */
+gpg_err_source_t default_errsource;
+
 
 #ifdef HAVE_W32CE_SYSTEM
 static void parse_std_file_handles (int *argcp, char ***argvp);
@@ -49,6 +83,36 @@ sleep_on_exit (void)
 #endif /*HAVE_W32CE_SYSTEM*/
 
 
+static void
+run_mem_cleanup (void)
+{
+  mem_cleanup_item_t next;
+
+  while (mem_cleanup_list)
+    {
+      next = mem_cleanup_list->next;
+      mem_cleanup_list->func ();
+      free (mem_cleanup_list);
+      mem_cleanup_list = next;
+    }
+}
+
+
+void
+register_mem_cleanup_func (void (*func)(void))
+{
+  mem_cleanup_item_t item;
+
+  item = malloc (sizeof *item);
+  if (item)
+    {
+      item->func = func;
+      item->next = mem_cleanup_list;
+      mem_cleanup_list = item;
+    }
+}
+
+
 /* If STRING is not NULL write string to es_stdout or es_stderr.  MODE
    must be 1 or 2.  If STRING is NULL flush the respective stream.  */
 static int
@@ -74,28 +138,30 @@ writestring_via_estream (int mode, const char *string)
    required for logging is ready.  ARGCP and ARGVP are the addresses
    of the parameters given to main.  This function may modify them.
 
+   This function should be called only via the macro
+   init_common_subsystems.
+
    CAUTION: This might be called while running suid(root).  */
 void
-init_common_subsystems (int *argcp, char ***argvp)
+_init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
 {
+  /* Store the error source in a gloabl variable. */
+  default_errsource = errsource;
+
+  atexit (run_mem_cleanup);
+
   /* Try to auto set the character set.  */
   set_native_charset (NULL);
 
 #ifdef HAVE_W32_SYSTEM
   /* For W32 we need to initialize the socket layer.  This is because
      we use recv and send in libassuan as well as at some other
-     places.  If we are building with PTH we let pth_init do it.  We
-     can't do much on error so we ignore them.  An error would anyway
-     later pop up if one of the socket functions is used. */
-# ifdef HAVE_NPTH
-  pth_init ();
-# else
+     places.  */
   {
     WSADATA wsadat;
 
     WSAStartup (0x202, &wsadat);
   }
-# endif /*!HAVE_NPTH*/
 #endif
 
 #ifdef HAVE_W32CE_SYSTEM