LCOV - code coverage report
Current view: top level - tests - fdpassing.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 80 126 63.5 %
Date: 2016-11-29 14:54:18 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* fdpassing - Check the file descriptor passing.
       2             :    Copyright (C) 2006, 2009 Free Software Foundation, Inc.
       3             : 
       4             :    This file is part of Assuan.
       5             : 
       6             :    Assuan is free software; you can redistribute it and/or modify it
       7             :    under the terms of the GNU Lesser General Public License as
       8             :    published by the Free Software Foundation; either version 3 of
       9             :    the License, or (at your option) any later version.
      10             : 
      11             :    Assuan is distributed in the hope that it will be useful, but
      12             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :    Lesser General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU Lesser General Public
      17             :    License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <stdio.h>
      21             : #include <stdlib.h>
      22             : #include <string.h>
      23             : #include <assert.h>
      24             : #include <sys/stat.h>
      25             : #include <sys/socket.h>
      26             : #include <unistd.h>
      27             : #include <errno.h>
      28             : #include <sys/wait.h>  /* Used by main driver. */
      29             : 
      30             : #include "../src/assuan.h"
      31             : #include "common.h"
      32             : 
      33             : 
      34             : /*
      35             : 
      36             :        S E R V E R
      37             : 
      38             : */
      39             : 
      40             : static gpg_error_t
      41           6 : cmd_echo (assuan_context_t ctx, char *line)
      42             : {
      43             :   int fd;
      44             :   int c;
      45             :   FILE *fp;
      46             :   int nbytes;
      47             : 
      48           6 :   log_info ("got ECHO command (%s)\n", line);
      49             : 
      50           6 :   fd = assuan_get_input_fd (ctx);
      51           6 :   if (fd == -1)
      52           0 :     return gpg_error (GPG_ERR_ASS_NO_INPUT);
      53           6 :   fp = fdopen (fd, "r");
      54           6 :   if (!fp)
      55             :     {
      56           0 :       log_error ("fdopen failed on input fd: %s\n", strerror (errno));
      57           0 :       return gpg_error (GPG_ERR_ASS_GENERAL);
      58             :     }
      59           6 :   nbytes = 0;
      60        2700 :   while ( (c=getc (fp)) != -1)
      61             :     {
      62        2688 :       putc (c, stdout);
      63        2688 :       nbytes++;
      64             :     }
      65           6 :   fflush (stdout);
      66           6 :   log_info ("done printing %d bytes to stdout\n", nbytes);
      67             : 
      68           6 :   fclose (fp);
      69           6 :   return 0;
      70             : }
      71             : 
      72             : static gpg_error_t
      73           1 : register_commands (assuan_context_t ctx)
      74             : {
      75             :   static struct
      76             :   {
      77             :     const char *name;
      78             :     gpg_error_t (*handler) (assuan_context_t, char *line);
      79             :   } table[] =
      80             :       {
      81             :         { "ECHO", cmd_echo },
      82             :         { "INPUT", NULL },
      83             :         { "OUTPUT", NULL },
      84             :         { NULL, NULL }
      85             :       };
      86             :   int i;
      87             :   gpg_error_t rc;
      88             : 
      89           4 :   for (i=0; table[i].name; i++)
      90             :     {
      91           3 :       rc = assuan_register_command (ctx, table[i].name, table[i].handler, NULL);
      92           3 :       if (rc)
      93           0 :         return rc;
      94             :     }
      95           1 :   return 0;
      96             : }
      97             : 
      98             : 
      99             : static void
     100           1 : server (void)
     101             : {
     102             :   int rc;
     103             :   assuan_context_t ctx;
     104             : 
     105           1 :   log_info ("server started\n");
     106             : 
     107           1 :   rc = assuan_new (&ctx);
     108           1 :   if (rc)
     109           0 :     log_fatal ("assuan_new failed: %s\n", gpg_strerror (rc));
     110             : 
     111           1 :   rc = assuan_init_pipe_server (ctx, NULL);
     112           1 :   if (rc)
     113           0 :     log_fatal ("assuan_init_pipe_server failed: %s\n", gpg_strerror (rc));
     114             : 
     115           1 :   rc = register_commands (ctx);
     116           1 :   if (rc)
     117           0 :     log_fatal ("register_commands failed: %s\n", gpg_strerror(rc));
     118             : 
     119           1 :   assuan_set_log_stream (ctx, stderr);
     120             : 
     121             :   for (;;)
     122             :     {
     123           2 :       rc = assuan_accept (ctx);
     124           2 :       if (rc)
     125             :         {
     126           1 :           if (rc != -1)
     127           0 :             log_error ("assuan_accept failed: %s\n", gpg_strerror (rc));
     128           1 :           break;
     129             :         }
     130             : 
     131           1 :       log_info ("client connected.  Client's pid is %ld\n",
     132           1 :                 (long)assuan_get_pid (ctx));
     133             : 
     134           1 :       rc = assuan_process (ctx);
     135           1 :       if (rc)
     136           0 :         log_error ("assuan_process failed: %s\n", gpg_strerror (rc));
     137           1 :     }
     138             : 
     139           1 :   assuan_release (ctx);
     140           1 : }
     141             : 
     142             : 
     143             : 
     144             : 
     145             : /*
     146             : 
     147             :        C L I E N T
     148             : 
     149             : */
     150             : 
     151             : 
     152             : /* Client main.  If true is returned, a disconnect has not been done. */
     153             : static int
     154           1 : client (assuan_context_t ctx, const char *fname)
     155             : {
     156             :   int rc;
     157             :   FILE *fp;
     158             :   int i;
     159             : 
     160           1 :   log_info ("client started. Servers's pid is %ld\n",
     161           1 :             (long)assuan_get_pid (ctx));
     162             : 
     163           7 :   for (i=0; i < 6; i++)
     164             :     {
     165           6 :       fp = fopen (fname, "r");
     166           6 :       if (!fp)
     167             :         {
     168           0 :           log_error ("failed to open `%s': %s\n", fname,
     169           0 :                      strerror (errno));
     170           0 :           return -1;
     171             :         }
     172             : 
     173           6 :       rc = assuan_sendfd (ctx, fileno (fp));
     174           6 :       if (rc)
     175             :         {
     176           0 :           log_error ("assuan_sendfd failed: %s\n", gpg_strerror (rc));
     177           0 :           return -1;
     178             :         }
     179           6 :       fclose (fp);
     180             : 
     181           6 :       rc = assuan_transact (ctx, "INPUT FD", NULL, NULL, NULL, NULL,
     182             :                             NULL, NULL);
     183           6 :       if (rc)
     184             :         {
     185           0 :           log_error ("sending INPUT FD failed: %s\n", gpg_strerror (rc));
     186           0 :           return -1;
     187             :         }
     188             : 
     189           6 :       rc = assuan_transact (ctx, "ECHO", NULL, NULL, NULL, NULL, NULL, NULL);
     190           6 :       if (rc)
     191             :         {
     192           0 :           log_error ("sending ECHO failed: %s\n", gpg_strerror (rc));
     193           0 :           return -1;
     194             :         }
     195             :     }
     196             : 
     197             :   /* Give us some time to check with lsof that all descriptors are closed. */
     198             : /*   sleep (10); */
     199             : 
     200           1 :   assuan_release (ctx);
     201           1 :   return 0;
     202             : }
     203             : 
     204             : 
     205             : 
     206             : 
     207             : /*
     208             : 
     209             :      M A I N
     210             : 
     211             : */
     212             : int
     213           2 : main (int argc, char **argv)
     214             : {
     215           2 :   int last_argc = -1;
     216             :   assuan_context_t ctx;
     217             :   gpg_error_t err;
     218             :   int no_close_fds[2];
     219             :   const char *arglist[10];
     220           2 :   int is_server = 0;
     221           2 :   int with_exec = 0;
     222           2 :   char *fname = prepend_srcdir ("motd");
     223             : 
     224           2 :   if (argc)
     225             :     {
     226           2 :       log_set_prefix (*argv);
     227           2 :       argc--; argv++;
     228             :     }
     229           4 :   while (argc && last_argc != argc )
     230             :     {
     231           0 :       last_argc = argc;
     232           0 :       if (!strcmp (*argv, "--help"))
     233             :         {
     234           0 :           puts (
     235             : "usage: ./fdpassing [options]\n"
     236             : "\n"
     237             : "Options:\n"
     238             : "  --verbose      Show what is going on\n"
     239             : "  --with-exec    Exec the child.  Default is just a fork\n"
     240             : );
     241           0 :           exit (0);
     242             :         }
     243           0 :       if (!strcmp (*argv, "--verbose"))
     244             :         {
     245           0 :           verbose = 1;
     246           0 :           argc--; argv++;
     247             :         }
     248           0 :       else if (!strcmp (*argv, "--debug"))
     249             :         {
     250           0 :           verbose = debug = 1;
     251           0 :           argc--; argv++;
     252             :         }
     253           0 :       else if (!strcmp (*argv, "--server"))
     254             :         {
     255           0 :           is_server = 1;
     256           0 :           argc--; argv++;
     257             :         }
     258           0 :       else if (!strcmp (*argv, "--with-exec"))
     259             :         {
     260           0 :           with_exec = 1;
     261           0 :           argc--; argv++;
     262             :         }
     263             :     }
     264             : 
     265             : 
     266           2 :   assuan_set_assuan_log_prefix (log_prefix);
     267             : 
     268           2 :   if (is_server)
     269             :     {
     270           0 :       server ();
     271           0 :       log_info ("server finished\n");
     272             :     }
     273             :   else
     274             :     {
     275             :       const char *loc;
     276             : 
     277           2 :       no_close_fds[0] = 2;
     278           2 :       no_close_fds[1] = -1;
     279           2 :       if (with_exec)
     280             :         {
     281           0 :           arglist[0] = "fdpassing";
     282           0 :           arglist[1] = "--server";
     283           0 :           arglist[2] = verbose? "--verbose":NULL;
     284           0 :           arglist[3] = NULL;
     285             :         }
     286             : 
     287           2 :       err = assuan_new (&ctx);
     288           2 :       if (err)
     289           0 :         log_fatal ("assuan_new failed: %s\n", gpg_strerror (err));
     290             : 
     291           2 :       err = assuan_pipe_connect (ctx, with_exec? "./fdpassing":NULL,
     292             :                                  with_exec ? arglist : &loc,
     293             :                                  no_close_fds, NULL, NULL, 1);
     294           2 :       if (err)
     295             :         {
     296           0 :           log_error ("assuan_pipe_connect failed: %s\n", gpg_strerror (err));
     297           0 :           assuan_release (ctx);
     298           0 :           errorcount++;
     299             :         }
     300           2 :       else if (!with_exec && loc[0] == 's')
     301             :         {
     302           1 :           server ();
     303           1 :           assuan_release (ctx);
     304           1 :           log_info ("server finished\n");
     305             :         }
     306             :       else
     307             :         {
     308           1 :           if (client (ctx, fname))
     309             :             {
     310           0 :               log_info ("waiting for server to terminate...\n");
     311           0 :               assuan_release (ctx);
     312             :             }
     313           1 :           log_info ("client finished\n");
     314             :         }
     315             :     }
     316             : 
     317           2 :   xfree (fname);
     318           2 :   return errorcount ? 1 : 0;
     319             : }
     320             : 

Generated by: LCOV version 1.11