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

Generated by: LCOV version 1.13