LTP GCOV extension - code coverage report
Current view: directory - and-httpd/src - and-cntl.c
Test: And-httpd coverage
Date: 2006-09-11 Instrumented lines: 302
Code covered: 66.9 % Executed lines: 202

       1                 : 
       2                 : 
       3                 : #define EX_UTILS_NO_USE_INPUT 1
       4                 : #define EX_UTILS_NO_USE_IO_FD 1
       5                 : #define EX_UTILS_NO_USE_OPEN  1
       6                 : #define EX_UTILS_NO_USE_INIT  1
       7                 : #define EX_UTILS_NO_USE_EXIT  1
       8                 : #include "ex_utils.h"
       9                 : 
      10                 : #include <stdlib.h>
      11                 : #include <sys/socket.h>
      12                 : #include <getopt.h>
      13                 : #include <netinet/in.h>
      14                 : #include <netinet/tcp.h>
      15                 : #include <arpa/inet.h>
      16                 : #include <netdb.h>
      17                 : #include <sys/time.h>
      18                 : #include <time.h>
      19                 : #include <signal.h>
      20                 : 
      21                 : #include <socket_poll.h>
      22                 : #include <timer_q.h>
      23                 : 
      24                 : #define WAIT_SET_RECV_FLAG 1 /* work around ? */
      25                 : 
      26                 : #define CL_PACKET_MAX 0xFFFF
      27                 : #define CL_MAX_CONNECT 128
      28                 : 
      29                 : /* made up ... 8bits */
      30                 : #define CL_MSG_CLIENT_NONE INT_MAX
      31                 : #define CL_MSG_CLIENT_ZERO (INT_MAX - 1)
      32                 : #define CL_MAX_WAIT_SEND 16
      33                 : 
      34                 : 
      35                 : #include "evnt.h"
      36                 : 
      37                 : #define EX_UTILS_NO_FUNCS  1
      38                 : #include "ex_utils.h"
      39                 : 
      40                 : #include "mk.h"
      41                 : 
      42                 : MALLOC_CHECK_DECL();
      43                 : 
      44                 : #include "opt.h"
      45                 : 
      46                 : struct con
      47                 : {
      48                 :  struct Evnt ev[1];
      49                 : };
      50                 : 
      51                 : 
      52                 : 
      53                 : #define CLEN COMPILE_STRLEN
      54                 : 
      55                 : /* is the cstr a prefix of the vstr */
      56                 : #define VPREFIX(vstr, p, l, cstr)                                       \
      57                 :     (((l) >= CLEN(cstr)) &&                                             \
      58                 :      vstr_cmp_buf_eq(vstr, p, CLEN(cstr), cstr, CLEN(cstr)))
      59                 : 
      60                 : /* is the cstr a prefix of the vstr, no case */
      61                 : #define VIPREFIX(vstr, p, l, cstr)                                      \
      62                 :     (((l) >= CLEN(cstr)) &&                                             \
      63                 :      vstr_cmp_case_buf_eq(vstr, p, CLEN(cstr), cstr, CLEN(cstr)))
      64                 : 
      65                 : 
      66                 : static int io_r_fd = STDIN_FILENO;
      67                 : unsigned int io_ind_r = 0; /* socket poll */
      68                 : static Vstr_base *io_r = NULL;
      69                 : static int io_w_fd = STDOUT_FILENO;
      70                 : unsigned int io_ind_w = 0; /* socket poll */
      71                 : static Vstr_base *io_w = NULL;
      72                 : 
      73                 : static Timer_q_base *cl_timeout_base = NULL;
      74                 : static Timer_q_base *cl_timer_connect_base = NULL;
      75                 : 
      76                 : static int server_clients_count = 0; /* current number of clients */
      77                 : 
      78                 : static int server_clients = 1;
      79                 : static unsigned int server_timeout = (2 * 60); /* 2 minutes */
      80                 : 
      81                 : static const char *server_filename = NULL;
      82                 : 
      83                 : static Vlg *vlg = NULL;
      84                 : 
      85                 : 
      86                 : static void ui_out(void)
      87            2145 : {
      88            2145 :   if (!io_ind_w)
      89              40 :     return;
      90                 :   
      91            2105 :   SOCKET_POLL_INDICATOR(io_ind_w)->events |=  POLLOUT;
      92                 : }
      93                 : 
      94                 : static int cl_recv(struct Evnt *evnt)
      95             734 : {
      96             734 :   int ret = evnt_cb_func_recv(evnt);
      97                 :   
      98             734 :   if (!ret)
      99               0 :     goto malloc_bad;
     100                 : 
     101            3244 :   while (evnt->io_r->len)
     102                 :   {
     103            2645 :     size_t pos = 0;
     104            2645 :     size_t len = 0;
     105            2645 :     size_t ns1 = 0;
     106            2645 :     size_t vpos = 0;
     107            2645 :     size_t vlen = 0;
     108            2645 :     size_t nse2 = 0;
     109            2645 :     int done = FALSE;
     110                 :   
     111            2645 :     if (!(ns1 = vstr_parse_netstr(evnt->io_r, 1, evnt->io_r->len, &pos, &len)))
     112                 :     {
     113             500 :       if (!(SOCKET_POLL_INDICATOR(evnt->ind)->events & POLLIN))
     114               0 :         return (FALSE);
     115             500 :       return (TRUE);
     116                 :     }
     117                 : 
     118           13886 :     while ((nse2 = vstr_parse_netstr(evnt->io_r, pos, len, &vpos, &vlen)))
     119                 :     {
     120           10906 :       if (!done && !vlen && (nse2 == len))
     121                 :       {
     122             228 :         len = 0;
     123             228 :         evnt_got_pkt(evnt);
     124             228 :         break;
     125                 :       }
     126                 :       
     127           10678 :       if (done)
     128            8761 :         vstr_add_cstr_buf(io_w, io_w->len, " ");
     129                 :       
     130           10678 :       vstr_add_vstr(io_w, io_w->len, evnt->io_r, vpos, vlen, VSTR_TYPE_ADD_DEF);
     131                 :     
     132           10678 :       if (!done)
     133            1917 :         vstr_add_cstr_buf(io_w, io_w->len, ":");
     134                 :     
     135           10678 :       done = TRUE;
     136                 : 
     137           10678 :       len -= nse2; pos += nse2;
     138                 :     }
     139            2145 :     if (done)
     140            1917 :       vstr_add_cstr_buf(io_w, io_w->len, "\n");
     141                 : 
     142            2145 :     ui_out();
     143                 :   
     144            2145 :     if (len)
     145               0 :       VLG_WARN_RET(FALSE, (vlg, "invalid entry\n"));
     146                 : 
     147                 :   /*
     148                 :   if (io_w->conf->malloc_bad)
     149                 :     goto malloc_bad;
     150                 :   */
     151                 :   
     152            2145 :     vstr_del(evnt->io_r, 1, ns1);
     153                 :   }
     154                 :   
     155             234 :   return (TRUE);
     156                 :   
     157               0 :  malloc_bad:
     158               0 :   evnt->io_r->conf->malloc_bad = FALSE;
     159               0 :   evnt->io_w->conf->malloc_bad = FALSE;
     160               0 :   return (FALSE);
     161                 : }
     162                 : 
     163                 : #define UI_CMD(x)                                                       \
     164                 :     else if (vstr_cmp_case_cstr_eq(io_r, 1, len, x "\n"))               \
     165                 :     {                                                                   \
     166                 :       size_t ns1 = 0;                                                   \
     167                 :       Vstr_base *out = con->io_w;                                       \
     168                 :                                                                         \
     169                 :       if (!(ns1 = vstr_add_netstr_beg(out, out->len)) ||                \
     170                 :           !vstr_add_cstr_ptr(out, out->len, x) ||                       \
     171                 :           !vstr_add_netstr_end(out, ns1, out->len) ||                   \
     172                 :           !evnt_send_add(con, FALSE, 0))                                \
     173                 :       {                                                                 \
     174                 :         evnt_close(con);                                                \
     175                 :         return;                                                         \
     176                 :       }                                                                 \
     177                 :       evnt_put_pkt(con);                                                \
     178                 :     }                                                                   \
     179                 :     else if (VIPREFIX(io_r, 1, len, x " ")) do                          \
     180                 :     {                                                                   \
     181                 :       size_t ns1 = 0;                                                   \
     182                 :       size_t ns2 = 0;                                                   \
     183                 :       size_t cmd_pos = 1;                                               \
     184                 :       size_t cmd_len = len;                                             \
     185                 :       size_t tmp = 0;                                                   \
     186                 :       Vstr_base *out = con->io_w;                                       \
     187                 :                                                                         \
     188                 :       cmd_len -= CLEN(x); cmd_pos += CLEN(x);                           \
     189                 :       tmp = vstr_spn_cstr_chrs_fwd(io_r, cmd_pos, cmd_len, " ");        \
     190                 :       cmd_len -= tmp; cmd_pos += tmp;                                   \
     191                 :                                                                         \
     192                 :       if (!(ns1 = vstr_add_netstr_beg(out, out->len)) ||                \
     193                 :           !(ns2 = vstr_add_netstr_beg(out, out->len)) ||                \
     194                 :           !vstr_add_cstr_ptr(out, out->len, x) ||                       \
     195                 :           !vstr_add_netstr_end(out, ns2, out->len) ||                   \
     196                 :           !(ns2 = vstr_add_netstr_beg(out, out->len)) ||                \
     197                 :           !vstr_add_vstr(out, out->len, io_r, cmd_pos, cmd_len, 0) ||   \
     198                 :           !vstr_add_netstr_end(out, ns2, out->len) ||                   \
     199                 :           !vstr_add_netstr_end(out, ns1, out->len) ||                   \
     200                 :           !evnt_send_add(con, FALSE, 0))                                \
     201                 :       {                                                                 \
     202                 :         evnt_close(con);                                                \
     203                 :         return;                                                         \
     204                 :       }                                                                 \
     205                 :       evnt_put_pkt(con);                                                \
     206                 :     } while (FALSE)
     207                 : 
     208                 : static void cl_connect(void); /* fwd ref */
     209                 : static void ui_parse(void)
     210            1938 : {
     211            1938 :   size_t len = 0;
     212            1938 :   unsigned int count = 64;
     213            1938 :   struct Evnt *con = NULL;
     214                 : 
     215            1938 :   vlg_dbg3(vlg, "ui_parse %zu\n", io_r->len);
     216                 :   
     217            1938 :   if (!io_r->len)
     218            1706 :     return; /* don't start more connections for nothing */
     219                 : 
     220             232 :   if (!(con = evnt_find_least_used()))
     221                 :   {
     222               0 :     cl_connect();
     223               0 :     return;
     224                 :   }
     225                 :   
     226             580 :   while ((len = vstr_srch_chr_fwd(io_r, 1, io_r->len, '\n')) && --count)
     227                 :   {
     228             232 :     size_t line_len = len;
     229                 : 
     230                 :     if (0) { /* not reached */ }
     231             232 :     UI_CMD("CLOSE");
     232             192 :     UI_CMD("DBG");
     233             192 :     UI_CMD("UNDBG");
     234             192 :     UI_CMD("LIST");
     235             120 :     UI_CMD("STATUS");
     236                 : 
     237             232 :     vlg_dbg3(vlg, "bad input\n");
     238                 :     /* ignore everything else */
     239                 :     
     240             232 :     vstr_del(io_r, 1, line_len);
     241                 :   }
     242             232 :   vlg_dbg3(vlg, "io_r left = %zu\n", io_r->len);
     243                 : }
     244                 : #undef UI_CMD
     245                 : 
     246                 : static int cl_cb_func_connect(struct Evnt *evnt)
     247             232 : {
     248                 :   (void)evnt;
     249                 :   
     250             232 :   vlg_dbg3(vlg, "connect\n");
     251                 : 
     252             232 :   ui_parse();
     253                 :   
     254             232 :   return (TRUE);
     255                 : }
     256                 : 
     257                 : static int cl_cb_func_recv(struct Evnt *evnt)
     258             734 : {
     259             734 :   return (cl_recv(evnt));
     260                 : }
     261                 : 
     262                 : static void cl_cb_func_free(struct Evnt *evnt)
     263             232 : {
     264             232 :   struct con *con = (struct con *)evnt;
     265                 : 
     266             232 :   F(con);
     267                 : 
     268             232 :   --server_clients_count;
     269             232 : }
     270                 : 
     271                 : static struct con *cl_make(const char *server_fname)
     272             232 : {
     273             232 :   struct con *ret = MK(sizeof(struct con));
     274                 : 
     275             232 :   if (!ret)
     276               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     277             232 :   if (!evnt_make_con_local(ret->ev, server_fname))
     278               0 :     err(EXIT_FAILURE, "%s", __func__);
     279                 : 
     280             232 :   ret->ev->cbs->cb_func_connect = cl_cb_func_connect;
     281             232 :   ret->ev->cbs->cb_func_recv    = cl_cb_func_recv;
     282             232 :   ret->ev->cbs->cb_func_free    = cl_cb_func_free;
     283                 :   
     284             232 :   ++server_clients_count;
     285                 : 
     286             232 :   if (ret->ev->flag_q_none)
     287             232 :     cl_cb_func_connect(ret->ev);
     288                 :   
     289             232 :   return (ret);
     290                 : }
     291                 : 
     292                 : static void cl_connect(void)
     293             232 : {
     294             232 :   struct con *con = cl_make(server_filename);
     295                 :   struct timeval tv;
     296                 : 
     297             232 :   if (server_timeout)
     298                 :   {
     299             232 :     gettimeofday(&tv, NULL);
     300                 :     
     301             232 :     TIMER_Q_TIMEVAL_ADD_SECS(&tv, 0, rand() % server_timeout);
     302                 :   
     303             232 :     if (!(con->ev->tm_o = timer_q_add_node(cl_timeout_base, con, &tv,
     304                 :                                            TIMER_Q_FLAG_NODE_DEFAULT)))
     305               0 :       errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     306                 :   }
     307             232 : }
     308                 : 
     309                 : static unsigned int cl_scan_io_fds(unsigned int ready)
     310            1721 : {
     311            1721 :   const int bad_poll_flags = (POLLERR | /* POLLHUP | */ POLLNVAL);
     312                 : 
     313            1721 :   vlg_dbg2(vlg, "BEG ready = %u\n", ready);
     314            1721 :   if (io_ind_r &&
     315                 :       SOCKET_POLL_INDICATOR(io_ind_r)->revents & bad_poll_flags)
     316                 :   {
     317               0 :     --ready;
     318                 :     
     319               0 :     close(SOCKET_POLL_INDICATOR(io_ind_r)->fd);
     320               0 :     vlg_dbg2(vlg, "ERROR-POLL-IO_R(%d):\n",
     321                 :              SOCKET_POLL_INDICATOR(io_ind_r)->revents);
     322               0 :     socket_poll_del(io_ind_r);
     323               0 :     io_ind_r = 0;
     324                 :   }
     325            1721 :   if (SOCKET_POLL_INDICATOR(io_ind_w)->revents & bad_poll_flags)
     326                 :   {
     327              15 :     --ready;
     328                 :     
     329              15 :     close(SOCKET_POLL_INDICATOR(io_ind_w)->fd);
     330              15 :     vlg_dbg2(vlg, "ERROR-POLL-IO_W(%d):\n",
     331                 :              SOCKET_POLL_INDICATOR(io_ind_w)->revents);
     332              15 :     socket_poll_del(io_ind_w);
     333              15 :     io_ind_w = 0;
     334                 :   }
     335            1721 :   if (io_ind_r && (SOCKET_POLL_INDICATOR(io_ind_r)->revents & POLLIN))
     336                 :   {
     337                 :     unsigned int ern;
     338                 :     
     339               0 :     --ready;
     340               0 :     while (vstr_sc_read_iov_fd(io_r, io_r->len, io_r_fd, 4, 32, &ern))
     341                 :     { /* do nothing */ }
     342                 :     
     343               0 :     switch (ern)
     344                 :     {
     345                 :       case VSTR_TYPE_SC_READ_FD_ERR_EOF:
     346               0 :         close(SOCKET_POLL_INDICATOR(io_ind_r)->fd);        
     347               0 :         SOCKET_POLL_INDICATOR(io_ind_r)->fd = -1;        
     348               0 :         socket_poll_del(io_ind_r);
     349               0 :         io_ind_r = 0;
     350               0 :         errno = EAGAIN;
     351                 :       case VSTR_TYPE_SC_READ_FD_ERR_READ_ERRNO:
     352               0 :         if (errno != EAGAIN)
     353               0 :           break;
     354                 :       case VSTR_TYPE_SC_READ_FD_ERR_NONE:
     355               0 :         ui_parse();
     356                 :       default:
     357                 :         break;
     358                 :     }
     359               0 :     vlg_dbg2(vlg, "READ UI\n");
     360                 :   }
     361            1721 :   else if (io_ind_w)
     362            1706 :     ui_parse();
     363                 :   
     364            1721 :   if (io_ind_w && (SOCKET_POLL_INDICATOR(io_ind_w)->revents & POLLOUT))
     365                 :   {
     366                 :     unsigned int ern;
     367                 :     
     368             639 :     --ready;
     369                 :     
     370            1278 :     while (io_w->len && vstr_sc_write_fd(io_w, 1, io_w->len, io_w_fd, &ern))
     371                 :     { /* do nothing */ }
     372                 :     
     373             639 :     if (!io_w->len)
     374             639 :       SOCKET_POLL_INDICATOR(io_ind_w)->events &= ~POLLOUT;
     375             639 :     vlg_dbg2(vlg, "WRITE UI\n");
     376                 :   }
     377                 : 
     378            1721 :   return (ready);
     379                 : }
     380                 : 
     381                 : static void usage(const char *program_name, int ret, const char *prefix)
     382               0 : {
     383               0 :   Vstr_base *out = vstr_make_base(NULL);
     384                 : 
     385               0 :   if (!out)
     386               0 :     errno = ENOMEM, err(EXIT_FAILURE, "usage");
     387                 : 
     388               0 :   vstr_add_fmt(out, 0, "%s\n"
     389                 :           " Format: %s [-chmtwV] <server name>\n"
     390                 :           " --help -h         - Print this message.\n"
     391                 :           " --debug -d        - Enable debug info.\n"
     392                 :           " --clients -c      - Number of connections to make.\n"
     393                 :           " --nagle -n        - Enable/disable nagle TCP option.\n"
     394                 :           " --timeout -t      - Timeout (usecs) between each message.\n"
     395                 :           " --version -V      - Print the version string.\n",
     396                 :           prefix, program_name);
     397                 :   
     398               0 :   if (io_put_all(out, ret ? STDERR_FILENO : STDOUT_FILENO) == IO_FAIL)
     399               0 :     err(EXIT_FAILURE, "write");
     400                 :   
     401               0 :   exit (ret);
     402                 : }
     403                 : 
     404                 : 
     405                 : static void cl_cmd_line(int argc, char *argv[])
     406             232 : {
     407             232 :   char optchar = 0;
     408             232 :   const char *program_name = NULL;
     409                 :   struct option long_options[] =
     410                 :   {
     411                 :    {"help", no_argument, NULL, 'h'},
     412                 :    {"clients", required_argument, NULL, 'c'},
     413                 :    {"debug", required_argument, NULL, 'd'},
     414                 :    {"execute", required_argument, NULL, 'e'},
     415                 :    {"host", required_argument, NULL, 'H'},
     416                 :    {"port", required_argument, NULL, 'P'},
     417                 :    {"nagle", optional_argument, NULL, 'n'},
     418                 :    {"timeout", required_argument, NULL, 't'},
     419                 :    {"version", no_argument, NULL, 'V'},
     420                 :    {NULL, 0, NULL, 0}
     421             232 :   };
     422             232 :   Vstr_base *out = vstr_make_base(NULL);
     423                 : 
     424             232 :   if (!out)
     425               0 :     errno = ENOMEM, err(EXIT_FAILURE, "command line");
     426                 :   
     427             232 :   program_name = opt_program_name(argv[0], "cntl");
     428                 : 
     429             696 :   while ((optchar = getopt_long(argc, argv, "c:de:hH:nP:Rt:V",
     430                 :                                 long_options, NULL)) != -1)
     431                 :   {
     432             232 :     switch (optchar)
     433                 :     {
     434               0 :       case '?': usage(program_name, EXIT_FAILURE, "");
     435               0 :       case 'h': usage(program_name, EXIT_SUCCESS, "");
     436                 :         
     437                 :       case 'V':
     438               0 :           vstr_add_fmt(out, 0,"\
     439                 : %s version 1.0.0, compiled on %s.\n\
     440                 : Written by James Antill\n\
     441                 : \n\
     442                 : Uses Vstr string library.\n\
     443                 : ",
     444                 :                        program_name, __DATE__);
     445                 : 
     446               0 :         if (io_put_all(out, STDOUT_FILENO) == IO_FAIL)
     447               0 :           err(EXIT_FAILURE, "write");
     448                 :         
     449               0 :         exit (EXIT_SUCCESS);
     450                 : 
     451               0 :       case 'c': server_clients      = atoi(optarg); break;
     452               0 :       case 't': server_timeout      = atoi(optarg); break;
     453                 : 
     454               0 :       case 'd': vlg_debug(vlg);                     break;
     455                 :         
     456                 :       case 'e':
     457                 :         /* use cmd line instead of stdin */
     458             232 :         io_r_fd = -1;
     459             232 :         vstr_add_cstr_buf(io_r, io_r->len, optarg);
     460             232 :         vstr_add_cstr_buf(io_r, io_r->len, "\n");
     461             232 :         break;
     462                 :         
     463                 :       case 'n':
     464               0 :         if (!optarg)
     465               0 :         { evnt_opt_nagle = !evnt_opt_nagle; }
     466               0 :         else if (!strcasecmp("true", optarg))   evnt_opt_nagle = TRUE;
     467               0 :         else if (!strcasecmp("1", optarg))      evnt_opt_nagle = TRUE;
     468               0 :         else if (!strcasecmp("false", optarg))  evnt_opt_nagle = FALSE;
     469               0 :         else if (!strcasecmp("0", optarg))      evnt_opt_nagle = FALSE;
     470               0 :         break;
     471                 : 
     472                 :       default:
     473               0 :         abort();
     474                 :     }
     475                 :   }
     476             232 :   vstr_free_base(out); out = NULL;
     477                 : 
     478             232 :   argc -= optind;
     479             232 :   argv += optind;
     480                 : 
     481             232 :   if (argc != 1)
     482               0 :     usage(program_name, EXIT_FAILURE, "");
     483                 : 
     484             232 :   server_filename = argv[0];
     485             232 : }
     486                 : 
     487                 : static void cl_timer_cli(int type, void *data)
     488             464 : {
     489             464 :   struct con *con = data;
     490                 :   struct timeval tv;
     491             464 :   unsigned long diff = 0;
     492                 :   
     493             464 :   if (!con)
     494               0 :     return;
     495                 :   
     496             232 :   ASSERT(evnt_fd(con->ev) != -1);
     497                 :   
     498             464 :   if (type == TIMER_Q_TYPE_CALL_RUN_ALL)
     499               0 :     return;
     500                 : 
     501             464 :   con->ev->tm_o = NULL;
     502                 : 
     503             464 :   if (type == TIMER_Q_TYPE_CALL_DEL)
     504             232 :     return;
     505                 : 
     506             232 :   gettimeofday(&tv, NULL);
     507             232 :   diff = timer_q_timeval_udiff_secs(&tv, &con->ev->mtime);
     508             232 :   if (diff > server_timeout)
     509                 :   {
     510               0 :     vlg_dbg2(vlg, "timeout = %p (%lu, %lu)\n",
     511                 :              con, diff, (unsigned long)server_timeout);
     512               0 :     close(SOCKET_POLL_INDICATOR(con->ev->ind)->fd);
     513               0 :     return;
     514                 :   }
     515                 :   
     516             232 :   if (type == TIMER_Q_TYPE_CALL_RUN_ALL)
     517               0 :     return;
     518                 :   
     519             232 :   TIMER_Q_TIMEVAL_ADD_SECS(&tv, (server_timeout - diff) + 1, 0);
     520             232 :   if (!(con->ev->tm_o = timer_q_add_node(cl_timeout_base, con, &tv,
     521                 :                                          TIMER_Q_FLAG_NODE_DEFAULT)))
     522               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     523                 : }
     524                 : 
     525                 : static void cl_timer_con(int type, void *data)
     526               0 : {
     527               0 :   int count = 0;
     528                 : 
     529               0 :   ASSERT(!data);
     530                 :   
     531               0 :   if (type == TIMER_Q_TYPE_CALL_DEL)
     532               0 :     return;
     533                 :   
     534               0 :   while ((server_clients_count < server_clients) && (count < CL_MAX_CONNECT))
     535                 :   {
     536               0 :     cl_connect();
     537               0 :     ++count;
     538                 :   }
     539                 :   
     540               0 :   if (type == TIMER_Q_TYPE_CALL_RUN_ALL)
     541               0 :     return;
     542                 :   
     543               0 :   if (server_clients_count < server_clients)
     544                 :   {
     545                 :     struct timeval tv;
     546                 :     
     547               0 :     gettimeofday(&tv, NULL);
     548               0 :     TIMER_Q_TIMEVAL_ADD_SECS(&tv, 1, 0);
     549               0 :     if (!timer_q_add_node(cl_timer_connect_base, NULL, &tv,
     550                 :                           TIMER_Q_FLAG_NODE_DEFAULT))
     551               0 :       errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     552                 :   }
     553                 : }
     554                 : 
     555                 : static void cl_init(void)
     556             232 : {
     557             232 :   int flags = TIMER_Q_FLAG_BASE_DEFAULT;
     558                 :     
     559             232 :   cl_timeout_base       = timer_q_add_base(cl_timer_cli, flags);
     560             232 :   cl_timer_connect_base = timer_q_add_base(cl_timer_con, flags);
     561                 : 
     562             232 :   if (!cl_timeout_base)
     563               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     564             232 :   if (!cl_timer_connect_base)
     565               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     566                 :   
     567             232 :   vlg_init();
     568                 : 
     569             232 :   if (!(vlg = vlg_make()))
     570               0 :     errno = ENOMEM, err(EXIT_FAILURE, "init");
     571                 : 
     572             232 :   evnt_logger(vlg);
     573             232 : }
     574                 : 
     575                 : static void cl_beg(void)
     576             232 : {
     577             232 :   int count = 0;
     578                 : 
     579             232 :   vlg_dbg3(vlg, "cl_beg\n");
     580                 :   
     581             232 :   if (io_r_fd != -1)
     582                 :   {
     583               0 :     vlg_dbg3(vlg, "cl_beg io_r beg\n");
     584               0 :     evnt_fd__set_nonblock(io_r_fd,  TRUE);
     585               0 :     if (!(io_ind_r = socket_poll_add(io_r_fd)))
     586               0 :       errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     587               0 :     SOCKET_POLL_INDICATOR(io_ind_r)->events |= POLLIN;
     588                 :   }
     589                 :   
     590             232 :   evnt_fd__set_nonblock(io_w_fd, TRUE);
     591             232 :   if (!(io_ind_w = socket_poll_add(io_w_fd)))
     592               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     593                 : 
     594             580 :   while ((server_clients_count < server_clients) && (count < CL_MAX_CONNECT))
     595                 :   {
     596             232 :     cl_connect();
     597             232 :     ++count;
     598                 :   }
     599                 :   
     600             232 :   if (server_clients_count < server_clients)
     601                 :   {
     602                 :     struct timeval tv;
     603                 :     
     604               0 :     gettimeofday(&tv, NULL);
     605               0 :     TIMER_Q_TIMEVAL_ADD_SECS(&tv, 1, 0);
     606               0 :     if (!timer_q_add_node(cl_timer_connect_base, NULL, &tv,
     607                 :                           TIMER_Q_FLAG_NODE_DEFAULT))
     608               0 :       errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     609                 :   }
     610             232 : }
     611                 : 
     612                 : static void cl_signals(void)
     613             232 : {
     614                 :   struct sigaction sa;
     615                 :   
     616             232 :   if (sigemptyset(&sa.sa_mask) == -1)
     617               0 :     err(EXIT_FAILURE, "%s", __func__);
     618                 :   
     619                 :   /* don't use SA_RESTART ... */
     620             232 :   sa.sa_flags = 0;
     621                 :   /* ignore it... we don't have a use for it */
     622             232 :   sa.sa_handler = SIG_IGN;
     623                 :   
     624             232 :   if (sigaction(SIGPIPE, &sa, NULL) == -1)
     625               0 :     err(EXIT_FAILURE, "%s", __func__);
     626             232 : }
     627                 : 
     628                 : int main(int argc, char *argv[])
     629             232 : {
     630             232 :   if (!vstr_init())
     631               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     632                 : 
     633             232 :   if (!vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$') ||
     634                 :       !vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_SEP, "_") ||
     635                 :       !vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_GRP, "\3") ||
     636                 :       !vstr_sc_fmt_add_all(NULL))
     637               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     638                 :   
     639             232 :   if (!(io_r = vstr_make_base(NULL))) /* used in cmd line */
     640               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     641             232 :   if (!(io_w = vstr_make_base(NULL)))
     642               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     643                 :   
     644             232 :   if (!socket_poll_init(0, SOCKET_POLL_TYPE_MAP_DIRECT))
     645               0 :     errno = ENOMEM, err(EXIT_FAILURE, "%s", __func__);
     646                 : 
     647             232 :   srand(getpid() ^ time(NULL)); /* doesn't need to be secure... just different
     648                 :                                  * for different runs */
     649                 :   
     650             232 :   cl_signals();
     651                 :   
     652             232 :   cl_init();
     653                 :   
     654             232 :   cl_cmd_line(argc, argv);
     655                 : 
     656             232 :   cl_beg();
     657                 :   
     658            2185 :   while (io_ind_w && (io_w->len || evnt_waiting() || io_ind_r || io_r->len))
     659                 :   {
     660            1721 :     int ready = evnt_poll();
     661                 :     struct timeval tv;
     662                 :     
     663            1721 :     if ((ready == -1) && (errno != EINTR))
     664               0 :       err(EXIT_FAILURE, "%s", __func__);
     665            1721 :     if (ready == -1)
     666               0 :       continue;
     667                 : 
     668            1721 :     evnt_out_dbg3("1");
     669            1721 :     ready = cl_scan_io_fds(ready);
     670            1721 :     evnt_out_dbg3("2");
     671            1721 :     evnt_scan_fds(ready, CL_MAX_WAIT_SEND);
     672            1721 :     evnt_out_dbg3("3");
     673            1721 :     evnt_scan_send_fds();
     674            1721 :     evnt_out_dbg3("4");
     675                 :     
     676            1721 :     gettimeofday(&tv, NULL);
     677            1721 :     timer_q_run_norm(&tv);
     678                 : 
     679            1721 :     evnt_out_dbg3("5");
     680            1721 :     evnt_scan_send_fds();
     681            1721 :     evnt_out_dbg3("6");
     682                 :   }
     683             232 :   evnt_out_dbg3("E");
     684                 : 
     685             232 :   vstr_free_base(io_r);
     686             232 :   vstr_free_base(io_w);
     687                 : 
     688             232 :   timer_q_del_base(cl_timeout_base);
     689             232 :   timer_q_del_base(cl_timer_connect_base);
     690                 :   
     691             232 :   evnt_close_all();
     692                 :   
     693             232 :   vlg_free(vlg);
     694                 :   
     695             232 :   vlg_exit();
     696                 :   
     697             232 :   vstr_exit();
     698                 :   
     699             116 :   MALLOC_CHECK_EMPTY();
     700                 :   
     701             232 :   exit (EXIT_SUCCESS);
     702                 : }
     703                 :          

Generated by: LTP GCOV extension version 1.4