LCOV - code coverage report
Current view: top level - gltests - test-poll.c (source / functions) Hit Total Coverage
Test: GNU SASL Lines: 107 143 74.8 %
Date: 2010-09-27 Functions: 11 13 84.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 29 56 51.8 %

           Branch data     Line data    Source code
       1                 :            : /* Test of poll() function.
       2                 :            :    Copyright (C) 2008-2010 Free Software Foundation, Inc.
       3                 :            : 
       4                 :            :    This program is free software; you can redistribute it and/or modify
       5                 :            :    it under the terms of the GNU General Public License as published by
       6                 :            :    the Free Software Foundation; either version 3, or (at your option)
       7                 :            :    any later version.
       8                 :            : 
       9                 :            :    This program is distributed in the hope that it will be useful,
      10                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            :    GNU General Public License for more details.
      13                 :            : 
      14                 :            :    You should have received a copy of the GNU General Public License
      15                 :            :    along with this program; if not, write to the Free Software Foundation,
      16                 :            :    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
      17                 :            : 
      18                 :            : /* Written by Paolo Bonzini.  */
      19                 :            : 
      20                 :            : #include <config.h>
      21                 :            : 
      22                 :            : #include <poll.h>
      23                 :            : 
      24                 :            : #include "signature.h"
      25                 :            : SIGNATURE_CHECK (poll, int, (struct pollfd[], nfds_t, int));
      26                 :            : 
      27                 :            : #include <stdio.h>
      28                 :            : #include <string.h>
      29                 :            : #include <sys/socket.h>
      30                 :            : #include <netinet/in.h>
      31                 :            : #include <arpa/inet.h>
      32                 :            : #include <fcntl.h>
      33                 :            : #include <stdlib.h>
      34                 :            : #include <stdbool.h>
      35                 :            : #include <sys/ioctl.h>
      36                 :            : #include <errno.h>
      37                 :            : 
      38                 :            : #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
      39                 :            : # define WIN32_NATIVE
      40                 :            : #endif
      41                 :            : 
      42                 :            : #ifdef WIN32_NATIVE
      43                 :            : #include <io.h>
      44                 :            : #define pipe(x) _pipe(x, 256, O_BINARY)
      45                 :            : #endif
      46                 :            : #ifdef HAVE_UNISTD_H
      47                 :            : #include <unistd.h>
      48                 :            : #endif
      49                 :            : #ifdef HAVE_SYS_WAIT_H
      50                 :            : #include <sys/wait.h>
      51                 :            : #endif
      52                 :            : 
      53                 :            : #ifndef SO_REUSEPORT
      54                 :            : #define SO_REUSEPORT    SO_REUSEADDR
      55                 :            : #endif
      56                 :            : 
      57                 :            : #define TEST_PORT       12345
      58                 :            : 
      59                 :            : 
      60                 :            : /* Minimal testing infrastructure.  */
      61                 :            : 
      62                 :            : static int failures;
      63                 :            : 
      64                 :            : static void
      65                 :          0 : failed (const char *reason)
      66                 :            : {
      67         [ #  # ]:          0 :   if (++failures > 1)
      68                 :          0 :     printf ("  ");
      69                 :          0 :   printf ("failed (%s)\n", reason);
      70                 :          0 : }
      71                 :            : 
      72                 :            : static int
      73                 :          3 : test (void (*fn) (void), const char *msg)
      74                 :            : {
      75                 :          3 :   failures = 0;
      76                 :          3 :   printf ("%s... ", msg);
      77                 :          3 :   fflush (stdout);
      78                 :          3 :   fn ();
      79                 :            : 
      80         [ +  - ]:          3 :   if (!failures)
      81                 :          3 :     printf ("passed\n");
      82                 :            : 
      83                 :          3 :   return failures;
      84                 :            : }
      85                 :            : 
      86                 :            : 
      87                 :            : /* Funny socket code.  */
      88                 :            : 
      89                 :            : static int
      90                 :          3 : open_server_socket ()
      91                 :            : {
      92                 :            :   int s, x;
      93                 :            :   struct sockaddr_in ia;
      94                 :            : 
      95                 :          3 :   s = socket (AF_INET, SOCK_STREAM, 0);
      96                 :            : 
      97                 :          3 :   memset (&ia, 0, sizeof (ia));
      98                 :          3 :   ia.sin_family = AF_INET;
      99                 :          3 :   inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
     100                 :          3 :   ia.sin_port = htons (TEST_PORT);
     101         [ -  + ]:          3 :   if (bind (s, (struct sockaddr *) &ia, sizeof (ia)) < 0)
     102                 :            :     {
     103                 :          0 :       perror ("bind");
     104                 :          0 :       exit (77);
     105                 :            :     }
     106                 :            : 
     107                 :          3 :   x = 1;
     108                 :          3 :   setsockopt (s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x));
     109                 :            : 
     110         [ -  + ]:          3 :   if (listen (s, 1) < 0)
     111                 :            :     {
     112                 :          0 :       perror ("listen");
     113                 :          0 :       exit (77);
     114                 :            :     }
     115                 :            : 
     116                 :          3 :   return s;
     117                 :            : }
     118                 :            : 
     119                 :            : static int
     120                 :          3 : connect_to_socket (int blocking)
     121                 :            : {
     122                 :            :   int s;
     123                 :            :   struct sockaddr_in ia;
     124                 :            : 
     125                 :          3 :   s = socket (AF_INET, SOCK_STREAM, 0);
     126                 :            : 
     127                 :          3 :   memset (&ia, 0, sizeof (ia));
     128                 :          3 :   ia.sin_family = AF_INET;
     129                 :          3 :   inet_pton (AF_INET, "127.0.0.1", &ia.sin_addr);
     130                 :          3 :   ia.sin_port = htons (TEST_PORT);
     131                 :            : 
     132         [ +  + ]:          3 :   if (!blocking)
     133                 :            :     {
     134                 :            : #ifdef WIN32_NATIVE
     135                 :            :       unsigned long iMode = 1;
     136                 :            :       ioctl (s, FIONBIO, (char *) &iMode);
     137                 :            : 
     138                 :            : #elif defined F_GETFL
     139                 :          2 :       int oldflags = fcntl (s, F_GETFL, NULL);
     140                 :            : 
     141         [ +  - ]:          2 :       if (!(oldflags & O_NONBLOCK))
     142                 :          2 :         fcntl (s, F_SETFL, oldflags | O_NONBLOCK);
     143                 :            : #endif
     144                 :            :     }
     145                 :            : 
     146 [ +  +  +  -  - :          5 :   if (connect (s, (struct sockaddr *) &ia, sizeof (ia)) < 0
                      + ]
     147                 :          5 :       && (blocking || errno != EINPROGRESS))
     148                 :            :     {
     149                 :          0 :       perror ("connect");
     150                 :          0 :       exit (77);
     151                 :            :     }
     152                 :            : 
     153                 :          3 :   return s;
     154                 :            : }
     155                 :            : 
     156                 :            : 
     157                 :            : /* A slightly more convenient interface to poll(2).  */
     158                 :            : 
     159                 :            : static int
     160                 :         14 : poll1 (int fd, int ev, int time)
     161                 :            : {
     162                 :            :   struct pollfd pfd;
     163                 :            :   int r;
     164                 :            : 
     165                 :         14 :   pfd.fd = fd;
     166                 :         14 :   pfd.events = ev;
     167                 :         14 :   pfd.revents = 0;
     168                 :         14 :   r = poll (&pfd, 1, time);
     169         [ -  + ]:         14 :   if (r < 0)
     170                 :          0 :     return r;
     171                 :            : 
     172         [ -  + ]:         14 :   if (pfd.revents & ~(POLLHUP | POLLERR | POLLNVAL | ev))
     173                 :          0 :     failed ("invalid flag combination (unrequested events)");
     174                 :            : 
     175                 :         14 :   return pfd.revents;
     176                 :            : }
     177                 :            : 
     178                 :            : static int
     179                 :          9 : poll1_nowait (int fd, int ev)
     180                 :            : {
     181                 :          9 :   return poll1 (fd, ev, 0);
     182                 :            : }
     183                 :            : 
     184                 :            : static int
     185                 :          5 : poll1_wait (int fd, int ev)
     186                 :            : {
     187                 :          5 :   return poll1 (fd, ev, -1);
     188                 :            : }
     189                 :            : 
     190                 :            : 
     191                 :            : /* Test poll(2) for TTYs.  */
     192                 :            : 
     193                 :            : #ifdef INTERACTIVE
     194                 :            : static void
     195                 :            : test_tty (void)
     196                 :            : {
     197                 :            :   if (poll1_nowait (0, POLLIN | POLLRDNORM) != 0)
     198                 :            :     failed ("can read");
     199                 :            :   if (poll1_nowait (0, POLLOUT) == 0)
     200                 :            :     failed ("cannot write");
     201                 :            : 
     202                 :            :   if (poll1_wait (0, POLLIN | POLLRDNORM) == 0)
     203                 :            :     failed ("return with infinite timeout");
     204                 :            : 
     205                 :            :   getchar ();
     206                 :            :   if (poll1_nowait (0, POLLIN | POLLRDNORM) != 0)
     207                 :            :     failed ("can read after getc");
     208                 :            : }
     209                 :            : #endif
     210                 :            : 
     211                 :            : 
     212                 :            : /* Test poll(2) for unconnected nonblocking sockets.  */
     213                 :            : 
     214                 :            : static void
     215                 :          1 : test_connect_first (void)
     216                 :            : {
     217                 :          1 :   int s = open_server_socket ();
     218                 :            :   struct sockaddr_in ia;
     219                 :            :   socklen_t addrlen;
     220                 :            : 
     221                 :            :   int c1, c2;
     222                 :            : 
     223         [ -  + ]:          1 :   if (poll1_nowait (s, POLLIN | POLLRDNORM | POLLRDBAND) != 0)
     224                 :          0 :     failed ("can read, socket not connected");
     225                 :            : 
     226                 :          1 :   c1 = connect_to_socket (false);
     227                 :            : 
     228         [ -  + ]:          1 :   if (poll1_wait (s, POLLIN | POLLRDNORM | POLLRDBAND) != (POLLIN | POLLRDNORM))
     229                 :          0 :     failed ("expecting POLLIN | POLLRDNORM on passive socket");
     230         [ -  + ]:          1 :   if (poll1_nowait (s, POLLIN | POLLRDBAND) != POLLIN)
     231                 :          0 :     failed ("expecting POLLIN on passive socket");
     232         [ -  + ]:          1 :   if (poll1_nowait (s, POLLRDNORM | POLLRDBAND) != POLLRDNORM)
     233                 :          0 :     failed ("expecting POLLRDNORM on passive socket");
     234                 :            : 
     235                 :          1 :   addrlen = sizeof (ia);
     236                 :          1 :   c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
     237                 :          1 :   close (s);
     238                 :          1 :   close (c1);
     239                 :          1 :   close (c2);
     240                 :          1 : }
     241                 :            : 
     242                 :            : 
     243                 :            : /* Test poll(2) for unconnected blocking sockets.  */
     244                 :            : 
     245                 :            : static void
     246                 :          1 : test_accept_first (void)
     247                 :            : {
     248                 :            : #ifndef WIN32_NATIVE
     249                 :          1 :   int s = open_server_socket ();
     250                 :            :   struct sockaddr_in ia;
     251                 :            :   socklen_t addrlen;
     252                 :            :   char buf[3];
     253                 :            :   int c, pid;
     254                 :            : 
     255                 :          1 :   pid = fork ();
     256         [ -  + ]:          2 :   if (pid < 0)
     257                 :          0 :     return;
     258                 :            : 
     259         [ +  + ]:          2 :   if (pid == 0)
     260                 :            :     {
     261                 :          1 :       addrlen = sizeof (ia);
     262                 :          1 :       c = accept (s, (struct sockaddr *) &ia, &addrlen);
     263                 :          1 :       close (s);
     264                 :          1 :       write (c, "foo", 3);
     265                 :          1 :       read (c, buf, 3);
     266                 :          1 :       shutdown (c, SHUT_RD);
     267                 :          1 :       close (c);
     268                 :          1 :       exit (0);
     269                 :            :     }
     270                 :            :   else
     271                 :            :     {
     272                 :          1 :       close (s);
     273                 :          1 :       c = connect_to_socket (true);
     274         [ -  + ]:          1 :       if (poll1_nowait (c, POLLOUT | POLLWRNORM | POLLRDBAND)
     275                 :            :           != (POLLOUT | POLLWRNORM))
     276                 :          0 :         failed ("cannot write after blocking connect");
     277                 :          1 :       write (c, "foo", 3);
     278                 :          1 :       wait (&pid);
     279         [ -  + ]:          1 :       if (poll1_wait (c, POLLIN) != POLLIN)
     280                 :          0 :         failed ("cannot read data left in the socket by closed process");
     281                 :          1 :       read (c, buf, 3);
     282                 :          1 :       write (c, "foo", 3);
     283         [ -  + ]:          1 :       if ((poll1_wait (c, POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
     284                 :          0 :         failed ("expecting POLLHUP after shutdown");
     285                 :          1 :       close (c);
     286                 :            :     }
     287                 :            : #endif
     288                 :            : }
     289                 :            : 
     290                 :            : 
     291                 :            : /* Common code for pipes and connected sockets.  */
     292                 :            : 
     293                 :            : static void
     294                 :          1 : test_pair (int rd, int wd)
     295                 :            : {
     296                 :            :   char buf[3];
     297         [ -  + ]:          1 :   if (poll1_wait (wd, POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND)
     298                 :            :       != (POLLOUT | POLLWRNORM))
     299                 :          0 :     failed ("expecting POLLOUT | POLLWRNORM before writing");
     300         [ -  + ]:          1 :   if (poll1_nowait (wd, POLLIN | POLLRDNORM | POLLOUT | POLLRDBAND) != POLLOUT)
     301                 :          0 :     failed ("expecting POLLOUT before writing");
     302         [ -  + ]:          1 :   if (poll1_nowait (wd, POLLIN | POLLRDNORM | POLLWRNORM | POLLRDBAND)
     303                 :            :       != POLLWRNORM)
     304                 :          0 :     failed ("expecting POLLWRNORM before writing");
     305                 :            : 
     306                 :          1 :   write (wd, "foo", 3);
     307         [ -  + ]:          1 :   if (poll1_wait (rd, POLLIN | POLLRDNORM) != (POLLIN | POLLRDNORM))
     308                 :          0 :     failed ("expecting POLLIN | POLLRDNORM after writing");
     309         [ -  + ]:          1 :   if (poll1_nowait (rd, POLLIN) != POLLIN)
     310                 :          0 :     failed ("expecting POLLIN after writing");
     311         [ -  + ]:          1 :   if (poll1_nowait (rd, POLLRDNORM) != POLLRDNORM)
     312                 :          0 :     failed ("expecting POLLRDNORM after writing");
     313                 :            : 
     314                 :          1 :   read (rd, buf, 3);
     315                 :          1 : }
     316                 :            : 
     317                 :            : 
     318                 :            : /* Test poll(2) on connected sockets.  */
     319                 :            : 
     320                 :            : static void
     321                 :          1 : test_socket_pair (void)
     322                 :            : {
     323                 :            :   struct sockaddr_in ia;
     324                 :            : 
     325                 :          1 :   socklen_t addrlen = sizeof (ia);
     326                 :          1 :   int s = open_server_socket ();
     327                 :          1 :   int c1 = connect_to_socket (false);
     328                 :          1 :   int c2 = accept (s, (struct sockaddr *) &ia, &addrlen);
     329                 :            : 
     330                 :          1 :   close (s);
     331                 :            : 
     332                 :          1 :   test_pair (c1, c2);
     333                 :          1 :   close (c1);
     334                 :          1 :   write (c2, "foo", 3);
     335         [ -  + ]:          1 :   if ((poll1_nowait (c2, POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
     336                 :          0 :     failed ("expecting POLLHUP after shutdown");
     337                 :            : 
     338                 :          1 :   close (c2);
     339                 :          1 : }
     340                 :            : 
     341                 :            : 
     342                 :            : /* Test poll(2) on pipes.  */
     343                 :            : 
     344                 :            : static void
     345                 :          0 : test_pipe (void)
     346                 :            : {
     347                 :            :   int fd[2];
     348                 :            : 
     349                 :          0 :   pipe (fd);
     350                 :          0 :   test_pair (fd[0], fd[1]);
     351                 :          0 :   close (fd[0]);
     352         [ #  # ]:          0 :   if ((poll1_wait (fd[1], POLLIN | POLLOUT) & (POLLHUP | POLLERR)) == 0)
     353                 :          0 :     failed ("expecting POLLHUP after shutdown");
     354                 :            : 
     355                 :          0 :   close (fd[1]);
     356                 :          0 : }
     357                 :            : 
     358                 :            : 
     359                 :            : /* Do them all.  */
     360                 :            : 
     361                 :            : int
     362                 :          1 : main ()
     363                 :            : {
     364                 :            :   int result;
     365                 :            : 
     366                 :            : #ifdef INTERACTIVE
     367                 :            :   printf ("Please press Enter\n");
     368                 :            :   test (test_tty, "TTY");
     369                 :            : #endif
     370                 :            : 
     371                 :          1 :   result = test (test_connect_first, "Unconnected socket test");
     372                 :          1 :   result += test (test_socket_pair, "Connected sockets test");
     373                 :          1 :   result += test (test_accept_first, "General socket test with fork");
     374                 :            :   /* GNU SASL doesn't use poll on pipes.  The pipe test breaks Wine,
     375                 :            :      see <http://bugs.winehq.org/show_bug.cgi?id=15272>.
     376                 :            : 
     377                 :            :   result += test (test_pipe, "Pipe test");
     378                 :            :   */
     379                 :            : 
     380                 :          1 :   exit (result);
     381                 :            : }

Generated by: LCOV version 1.8