LCOV - code coverage report
Current view: top level - src - assuan-support.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 50 71 70.4 %
Date: 2016-09-12 13:07:23 Functions: 10 13 76.9 %

          Line data    Source code
       1             : #if HAVE_CONFIG_H
       2             : #include <config.h>
       3             : #endif
       4             : 
       5             : #include <assert.h>
       6             : #include <stdlib.h>
       7             : #include <errno.h>
       8             : 
       9             : #include "assuan.h"
      10             : 
      11             : #include "gpgme.h"
      12             : #include "ath.h"
      13             : #include "priv-io.h"
      14             : #include "debug.h"
      15             : 
      16             : 
      17             : struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks =
      18             :   {
      19             :     malloc,
      20             :     realloc,
      21             :     free
      22             :   };
      23             : 
      24             : 
      25             : int
      26         834 : _gpgme_assuan_log_cb (assuan_context_t ctx, void *hook,
      27             :                       unsigned int cat, const char *msg)
      28             : {
      29         834 :   if (msg == NULL)
      30         417 :     return 1;
      31             : 
      32         417 :   _gpgme_debug (DEBUG_ASSUAN, "%s", msg);
      33         417 :   return 0;
      34             : }
      35             : 
      36             : 
      37             : static void
      38           0 : my_usleep (assuan_context_t ctx, unsigned int usec)
      39             : {
      40             :   /* FIXME: Add to ath.  */
      41           0 :   __assuan_usleep (ctx, usec);
      42           0 : }
      43             : 
      44             : 
      45             : /* Create a pipe with an inheritable end.  */
      46             : static int
      47           0 : my_pipe (assuan_context_t ctx, assuan_fd_t fds[2], int inherit_idx)
      48             : {
      49             :   int res;
      50             :   int gfds[2];
      51             : 
      52           0 :   res = _gpgme_io_pipe (gfds, inherit_idx);
      53             : 
      54             :   /* For now... */
      55           0 :   fds[0] = (assuan_fd_t) gfds[0];
      56           0 :   fds[1] = (assuan_fd_t) gfds[1];
      57             : 
      58           0 :   return res;
      59             : }
      60             : 
      61             : 
      62             : /* Close the given file descriptor, created with _assuan_pipe or one
      63             :    of the socket functions.  */
      64             : static int
      65          17 : my_close (assuan_context_t ctx, assuan_fd_t fd)
      66             : {
      67          17 :   return _gpgme_io_close ((int) fd);
      68             : }
      69             : 
      70             : 
      71             : static gpgme_ssize_t
      72          12 : my_read (assuan_context_t ctx, assuan_fd_t fd, void *buffer, size_t size)
      73             : {
      74          12 :   return _gpgme_io_read ((int) fd, buffer, size);
      75             : }
      76             : 
      77             : 
      78             : static gpgme_ssize_t
      79          24 : my_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, size_t size)
      80             : {
      81          24 :   return _gpgme_io_write ((int) fd, buffer, size);
      82             : }
      83             : 
      84             : 
      85             : static int
      86         125 : my_recvmsg (assuan_context_t ctx, assuan_fd_t fd, assuan_msghdr_t msg,
      87             :             int flags)
      88             : {
      89             : #ifdef HAVE_W32_SYSTEM
      90             :   gpg_err_set_errno (ENOSYS);
      91             :   return -1;
      92             : #else
      93         125 :   return _gpgme_io_recvmsg ((int) fd, msg, flags);
      94             : #endif
      95             : }
      96             : 
      97             : 
      98             : 
      99             : static int
     100         240 : my_sendmsg (assuan_context_t ctx, assuan_fd_t fd, const assuan_msghdr_t msg,
     101             :             int flags)
     102             : {
     103             : #ifdef HAVE_W32_SYSTEM
     104             :   gpg_err_set_errno (ENOSYS);
     105             :   return -1;
     106             : #else
     107         240 :   return _gpgme_io_sendmsg ((int) fd, msg, flags);
     108             : #endif
     109             : }
     110             : 
     111             : 
     112             : /* If NAME is NULL, don't exec, just fork.  FD_CHILD_LIST is modified
     113             :    to reflect the value of the FD in the peer process (on
     114             :    Windows).  */
     115             : static int
     116           8 : my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
     117             :           const char **argv,
     118             :           assuan_fd_t fd_in, assuan_fd_t fd_out,
     119             :           assuan_fd_t *fd_child_list,
     120             :           void (*atfork) (void *opaque, int reserved),
     121             :           void *atforkvalue, unsigned int flags)
     122             : {
     123             :   int err;
     124             :   struct spawn_fd_item_s *fd_items;
     125             :   int i;
     126             : 
     127           8 :   assert (name);
     128             : 
     129           8 :   if (! name)
     130             :     {
     131           0 :       gpg_err_set_errno (ENOSYS);
     132           0 :       return -1;
     133             :     }
     134             : 
     135           8 :   i = 0;
     136           8 :   if (fd_child_list)
     137             :     {
     138          24 :       while (fd_child_list[i] != ASSUAN_INVALID_FD)
     139           8 :         i++;
     140             :     }
     141             :   /* fd_in, fd_out, terminator */
     142           8 :   i += 3;
     143           8 :   fd_items = calloc (i, sizeof (struct spawn_fd_item_s));
     144           8 :   if (! fd_items)
     145           0 :     return -1;
     146           8 :   i = 0;
     147           8 :   if (fd_child_list)
     148             :     {
     149          24 :       while (fd_child_list[i] != ASSUAN_INVALID_FD)
     150             :         {
     151           8 :           fd_items[i].fd = (int) fd_child_list[i];
     152           8 :           fd_items[i].dup_to = -1;
     153           8 :           i++;
     154             :         }
     155             :     }
     156           8 :   if (fd_in != ASSUAN_INVALID_FD)
     157             :     {
     158           0 :       fd_items[i].fd = (int) fd_in;
     159           0 :       fd_items[i].dup_to = 0;
     160           0 :       i++;
     161             :     }
     162           8 :   if (fd_out != ASSUAN_INVALID_FD)
     163             :     {
     164           0 :       fd_items[i].fd = (int) fd_out;
     165           0 :       fd_items[i].dup_to = 1;
     166           0 :       i++;
     167             :     }
     168           8 :   fd_items[i].fd = -1;
     169           8 :   fd_items[i].dup_to = -1;
     170             : 
     171           8 :   err = _gpgme_io_spawn (name, (char*const*)argv,
     172             :                          (IOSPAWN_FLAG_NOCLOSE | IOSPAWN_FLAG_DETACHED),
     173             :                          fd_items, atfork, atforkvalue, r_pid);
     174           8 :   if (! err)
     175             :     {
     176           8 :       i = 0;
     177             : 
     178           8 :       if (fd_child_list)
     179             :         {
     180          24 :           while (fd_child_list[i] != ASSUAN_INVALID_FD)
     181             :             {
     182           8 :               fd_child_list[i] = (assuan_fd_t) fd_items[i].peer_name;
     183           8 :               i++;
     184             :             }
     185             :         }
     186             :     }
     187           8 :   free (fd_items);
     188           8 :   return err;
     189             : }
     190             : 
     191             : 
     192             : /* If action is 0, like waitpid.  If action is 1, just release the PID?  */
     193             : static pid_t
     194           0 : my_waitpid (assuan_context_t ctx, pid_t pid,
     195             :             int nowait, int *status, int options)
     196             : {
     197             : #ifdef HAVE_W32_SYSTEM
     198             :   CloseHandle ((HANDLE) pid);
     199             : #else
     200             :   /* We can't just release the PID, a waitpid is mandatory.  But
     201             :      NOWAIT in POSIX systems just means the caller already did the
     202             :      waitpid for this child.  */
     203           0 :   if (! nowait)
     204           0 :     return _gpgme_ath_waitpid (pid, status, options);
     205             : #endif
     206           0 :   return 0;
     207             : }
     208             : 
     209             : 
     210             : 
     211             : 
     212             : static int
     213           8 : my_socketpair (assuan_context_t ctx, int namespace, int style,
     214             :                int protocol, assuan_fd_t filedes[2])
     215             : {
     216             : #ifdef HAVE_W32_SYSTEM
     217             :   gpg_err_set_errno (ENOSYS);
     218             :   return -1;
     219             : #else
     220             :   /* FIXME: Debug output missing.  */
     221           8 :   return __assuan_socketpair (ctx, namespace, style, protocol, filedes);
     222             : #endif
     223             : }
     224             : 
     225             : 
     226             : static int
     227           1 : my_socket (assuan_context_t ctx, int namespace, int style, int protocol)
     228             : {
     229           1 :   return _gpgme_io_socket (namespace, style, protocol);
     230             : }
     231             : 
     232             : 
     233             : static int
     234           1 : my_connect (assuan_context_t ctx, int sock, struct sockaddr *addr,
     235             :             socklen_t length)
     236             : {
     237           1 :   return _gpgme_io_connect (sock, addr, length);
     238             : }
     239             : 
     240             : 
     241             : /* Note for Windows: Ignore the incompatible pointer type warning for
     242             :    my_read and my_write.  Mingw has been changed to use int for
     243             :    ssize_t on 32 bit systems while we use long.  For 64 bit we use
     244             :    int64_t while mingw uses __int64_t.  It doe not matter at all
     245             :    because under Windows long and int are both 32 bit even on 64
     246             :    bit.  */
     247             : struct assuan_system_hooks _gpgme_assuan_system_hooks =
     248             :   {
     249             :     ASSUAN_SYSTEM_HOOKS_VERSION,
     250             :     my_usleep,
     251             :     my_pipe,
     252             :     my_close,
     253             :     my_read,
     254             :     my_write,
     255             :     my_recvmsg,
     256             :     my_sendmsg,
     257             :     my_spawn,
     258             :     my_waitpid,
     259             :     my_socketpair,
     260             :     my_socket,
     261             :     my_connect
     262             :   };
     263             : 

Generated by: LCOV version 1.11