common: Cope with AIX problem on number of open files.
[gnupg.git] / common / exechelp-posix.c
index 6ffc562..8a2b3b9 100644 (file)
@@ -4,12 +4,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.
 
 #include <stdio.h>
 #include <stdlib.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
 #ifdef HAVE_SIGNAL_H
 # include <signal.h>
 #endif
-#include <unistd.h> 
+#include <unistd.h>
 #include <fcntl.h>
 
-#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth.  */
-#undef HAVE_PTH
-#undef USE_GNU_PTH
+#ifdef WITHOUT_NPTH /* Give the Makefile a chance to build without Pth.  */
+#undef HAVE_NPTH
+#undef USE_NPTH
 #endif
 
-#ifdef USE_GNU_PTH      
-#include <pth.h>
+#ifdef HAVE_NPTH
+#include <npth.h>
 #endif
 #include <sys/wait.h>
 
 #include "exechelp.h"
 
 
-/* We have the usual problem here: Some modules are linked against pth
-   and some are not.  However we want to use pth_fork and pth_waitpid
-   here. Using a weak symbol works but is not portable - we should
-   provide a an explicit dummy pth module instead of using the
-   pragma.  */ 
-#pragma weak pth_fork
-#pragma weak pth_waitpid
-
-
 /* Return the maximum number of currently allowed open file
    descriptors.  Only useful on POSIX systems but returns a value on
    other systems too.  */
@@ -113,6 +117,13 @@ get_max_fds (void)
   if (max_fds == -1)
     max_fds = 256;  /* Arbitrary limit.  */
 
+  /* AIX returns INT32_MAX instead of a proper value.  We assume that
+     this is always an error and use an arbitrary limit.  */
+#ifdef INT32_MAX
+  if (max_fds == INT32_MAX)
+    max_fds = 256;
+#endif
+
   return max_fds;
 }
 
@@ -181,7 +192,7 @@ get_all_open_fds (void)
   array = calloc (narray, sizeof *array);
   if (!array)
     return NULL;
-  
+
   /* Note:  The list we return is ordered.  */
   for (idx=0, fd=0; fd < max_fd; fd++)
     if (!(fstat (fd, &statbuf) == -1 && errno == EBADF))
@@ -243,7 +254,7 @@ do_exec (const char *pgmname, const char *argv[],
         {
           fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
           if (fds[i] == -1)
-            log_fatal ("failed to open `%s': %s\n",
+            log_fatal ("failed to open '%s': %s\n",
                        "/dev/null", strerror (errno));
         }
     }
@@ -258,7 +269,7 @@ do_exec (const char *pgmname, const char *argv[],
 
   /* Close all other files. */
   close_all_fds (3, NULL);
-  
+
   if (preexec)
     preexec ();
   execv (pgmname, arg_list);
@@ -328,7 +339,7 @@ create_pipe_and_estream (int filedes[2], estream_t *r_fp,
     }
   return 0;
 }
-  
+
 
 
 /* Fork and exec the PGMNAME, see exechelp.h for details.  */
@@ -388,11 +399,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
     }
 
 
-#ifdef USE_GNU_PTH      
-  *pid = pth_fork? pth_fork () : fork ();
-#else
   *pid = fork ();
-#endif
   if (*pid == (pid_t)(-1))
     {
       err = gpg_err_make (errsource, gpg_err_code_from_syserror ());
@@ -415,7 +422,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
     }
 
   if (!*pid)
-    { 
+    {
       /* This is the child. */
       gcry_control (GCRYCTL_TERM_SECMEM);
       es_fclose (outfp);
@@ -454,11 +461,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
 {
   gpg_error_t err;
 
-#ifdef USE_GNU_PTH      
-  *pid = pth_fork? pth_fork () : fork ();
-#else
   *pid = fork ();
-#endif
   if (*pid == (pid_t)(-1))
     {
       err = gpg_error_from_syserror ();
@@ -467,7 +470,7 @@ gnupg_spawn_process_fd (const char *pgmname, const char *argv[],
     }
 
   if (!*pid)
-    { 
+    {
       gcry_control (GCRYCTL_TERM_SECMEM);
       /* Run child. */
       do_exec (pgmname, argv, infd, outfd, errfd, NULL);
@@ -491,17 +494,13 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
   if (pid == (pid_t)(-1))
     return gpg_error (GPG_ERR_INV_VALUE);
 
-#ifdef USE_GNU_PTH
-  if (pth_waitpid)
-    i = pth_waitpid (pid, &status, hang? 0:WNOHANG);
-  else
+#ifdef USE_NPTH
+  i = npth_waitpid (pid, &status, hang? 0:WNOHANG);
+#else
+  while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
+        && errno == EINTR);
 #endif
-    {
-      while ((i=waitpid (pid, &status, hang? 0:WNOHANG)) == (pid_t)(-1)
-             && errno == EINTR)
-        ;
-    }
-  
+
   if (i == (pid_t)(-1))
     {
       ec = gpg_err_code_from_errno (errno);
@@ -514,13 +513,13 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
     }
   else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
     {
-      log_error (_("error running `%s': probably not installed\n"), pgmname);
+      log_error (_("error running '%s': probably not installed\n"), pgmname);
       ec = GPG_ERR_CONFIGURATION;
     }
   else if (WIFEXITED (status) && WEXITSTATUS (status))
     {
       if (!r_exitcode)
-        log_error (_("error running `%s': exit status %d\n"), pgmname,
+        log_error (_("error running '%s': exit status %d\n"), pgmname,
                    WEXITSTATUS (status));
       else
         *r_exitcode = WEXITSTATUS (status);
@@ -528,10 +527,10 @@ gnupg_wait_process (const char *pgmname, pid_t pid, int hang, int *r_exitcode)
     }
   else if (!WIFEXITED (status))
     {
-      log_error (_("error running `%s': terminated\n"), pgmname);
+      log_error (_("error running '%s': terminated\n"), pgmname);
       ec = GPG_ERR_GENERAL;
     }
-  else 
+  else
     {
       if (r_exitcode)
         *r_exitcode = 0;
@@ -569,11 +568,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
   if (access (pgmname, X_OK))
     return gpg_error_from_syserror ();
 
-#ifdef USE_GNU_PTH      
-  pid = pth_fork? pth_fork () : fork ();
-#else
   pid = fork ();
-#endif
   if (pid == (pid_t)(-1))
     {
       log_error (_("error forking process: %s\n"), strerror (errno));
@@ -596,12 +591,12 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
       if (envp)
         for (i=0; envp[i]; i++)
           putenv (xstrdup (envp[i]));
-      
+
       do_exec (pgmname, argv, -1, -1, -1, NULL);
 
       /*NOTREACHED*/
     }
-  
+
   if (waitpid (pid, NULL, 0) == -1)
     log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
                strerror (errno));
@@ -618,6 +613,6 @@ gnupg_kill_process (pid_t pid)
 {
   if (pid != (pid_t)(-1))
     {
-      kill (pid, SIGTERM); 
+      kill (pid, SIGTERM);
     }
 }