LCOV - code coverage report
Current view: top level - gio/tests - socket.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 92.1 % 1258 1159
Test Date: 2024-11-26 05:23:01 Functions: 98.1 % 52 51
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GLib testing framework examples and tests
       2                 :             :  *
       3                 :             :  * Copyright (C) 2008-2011 Red Hat, Inc.
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :             :  *
       7                 :             :  * This library is free software; you can redistribute it and/or
       8                 :             :  * modify it under the terms of the GNU Lesser General Public
       9                 :             :  * License as published by the Free Software Foundation; either
      10                 :             :  * version 2.1 of the License, or (at your option) any later version.
      11                 :             :  *
      12                 :             :  * This library is distributed in the hope that it will be useful,
      13                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :             :  * Lesser General Public License for more details.
      16                 :             :  *
      17                 :             :  * You should have received a copy of the GNU Lesser General
      18                 :             :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :             :  */
      20                 :             : 
      21                 :             : #include <gio/gio.h>
      22                 :             : #include <glib/gstdio.h>
      23                 :             : #include "glib-private.h"
      24                 :             : 
      25                 :             : #include <gio/gcredentialsprivate.h>
      26                 :             : #include <gio/gunixconnection.h>
      27                 :             : 
      28                 :             : #ifdef G_OS_UNIX
      29                 :             : #include <errno.h>
      30                 :             : #include <sys/wait.h>
      31                 :             : #include <string.h>
      32                 :             : #include <stdlib.h>
      33                 :             : #include <gio/gnetworking.h>
      34                 :             : #endif
      35                 :             : 
      36                 :             : #ifdef G_OS_WIN32
      37                 :             : #include "giowin32-afunix.h"
      38                 :             : #include <io.h>
      39                 :             : #endif
      40                 :             : 
      41                 :             : #include "gnetworkingprivate.h"
      42                 :             : 
      43                 :             : static gboolean ipv6_supported;
      44                 :             : 
      45                 :             : typedef struct {
      46                 :             :   GSocket *server;  /* (owned) (not nullable) */
      47                 :             :   GSocket *client;  /* (owned) (nullable) */
      48                 :             :   GSocketFamily family;
      49                 :             :   GThread *thread;  /* (owned) (not nullable) */
      50                 :             :   GMainLoop *loop;  /* (owned) (nullable) */
      51                 :             :   GCancellable *cancellable; /* to shut down dgram echo server thread; (owned) (nullable) */
      52                 :             : } IPTestData;
      53                 :             : 
      54                 :             : static void
      55                 :          13 : ip_test_data_free (IPTestData *data)
      56                 :             : {
      57                 :          13 :   g_clear_object (&data->server);
      58                 :          13 :   g_clear_object (&data->client);
      59                 :          13 :   g_clear_pointer (&data->loop, g_main_loop_unref);
      60                 :          13 :   g_clear_object (&data->cancellable);
      61                 :             : 
      62                 :          13 :   g_slice_free (IPTestData, data);
      63                 :          13 : }
      64                 :             : 
      65                 :             : static gpointer
      66                 :           3 : echo_server_dgram_thread (gpointer user_data)
      67                 :             : {
      68                 :           3 :   IPTestData *data = user_data;
      69                 :             :   GSocketAddress *sa;
      70                 :           3 :   GCancellable *cancellable = data->cancellable;
      71                 :             :   GSocket *sock;
      72                 :           3 :   GError *error = NULL;
      73                 :             :   gssize nread, nwrote;
      74                 :             :   gchar buf[128];
      75                 :             : 
      76                 :           3 :   sock = data->server;
      77                 :             : 
      78                 :             :   while (TRUE)
      79                 :             :     {
      80                 :          23 :       nread = g_socket_receive_from (sock, &sa, buf, sizeof (buf), cancellable, &error);
      81                 :          23 :       if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
      82                 :           3 :         break;
      83                 :          20 :       g_assert_no_error (error);
      84                 :          20 :       g_assert_cmpint (nread, >=, 0);
      85                 :             : 
      86                 :          20 :       nwrote = g_socket_send_to (sock, sa, buf, nread, cancellable, &error);
      87                 :          20 :       if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
      88                 :           0 :         break;
      89                 :          20 :       g_assert_no_error (error);
      90                 :          20 :       g_assert_cmpint (nwrote, ==, nread);
      91                 :             : 
      92                 :          20 :       g_object_unref (sa);
      93                 :             :     }
      94                 :             : 
      95                 :           3 :   g_clear_error (&error);
      96                 :             : 
      97                 :           3 :   return NULL;
      98                 :             : }
      99                 :             : 
     100                 :             : static gpointer
     101                 :           7 : echo_server_thread (gpointer user_data)
     102                 :             : {
     103                 :           7 :   IPTestData *data = user_data;
     104                 :             :   GSocket *sock;
     105                 :           7 :   GError *error = NULL;
     106                 :             :   gssize nread, nwrote;
     107                 :             :   gchar buf[128];
     108                 :             : 
     109                 :           7 :   sock = g_socket_accept (data->server, NULL, &error);
     110                 :           7 :   g_assert_no_error (error);
     111                 :             : 
     112                 :             :   while (TRUE)
     113                 :             :     {
     114                 :          16 :       nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
     115                 :          16 :       g_assert_no_error (error);
     116                 :          16 :       g_assert_cmpint (nread, >=, 0);
     117                 :             : 
     118                 :          16 :       if (nread == 0)
     119                 :           7 :         break;
     120                 :             : 
     121                 :           9 :       nwrote = g_socket_send (sock, buf, nread, NULL, &error);
     122                 :           9 :       g_assert_no_error (error);
     123                 :           9 :       g_assert_cmpint (nwrote, ==, nread);
     124                 :             :     }
     125                 :             : 
     126                 :           7 :   g_socket_close (sock, &error);
     127                 :           7 :   g_assert_no_error (error);
     128                 :           7 :   g_object_unref (sock);
     129                 :           7 :   return NULL;
     130                 :             : }
     131                 :             : 
     132                 :             : static IPTestData *
     133                 :          12 : create_server_full (GSocketFamily   family,
     134                 :             :                     GSocketType     socket_type,
     135                 :             :                     GThreadFunc     server_thread,
     136                 :             :                     gboolean        v4mapped,
     137                 :             :                     GError        **error)
     138                 :             : {
     139                 :             :   IPTestData *data;
     140                 :             :   GSocket *server;
     141                 :             :   GSocketAddress *addr;
     142                 :             :   GInetAddress *iaddr;
     143                 :             : 
     144                 :          12 :   data = g_slice_new0 (IPTestData);
     145                 :          12 :   data->family = family;
     146                 :             : 
     147                 :          12 :   data->server = server = g_socket_new (family,
     148                 :             :                                         socket_type,
     149                 :             :                                         G_SOCKET_PROTOCOL_DEFAULT,
     150                 :             :                                         error);
     151                 :          12 :   if (server == NULL)
     152                 :           0 :     goto error;
     153                 :             : 
     154                 :          12 :   g_assert_cmpint (g_socket_get_family (server), ==, family);
     155                 :          12 :   g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type);
     156                 :          12 :   g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
     157                 :             : #ifdef G_OS_WIN32
     158                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (server)));
     159                 :             : #endif
     160                 :             : 
     161                 :          12 :   g_socket_set_blocking (server, TRUE);
     162                 :             : 
     163                 :             : #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
     164                 :          12 :   if (v4mapped)
     165                 :             :     {
     166                 :           1 :       g_socket_set_option (data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL);
     167                 :           1 :       if (!g_socket_speaks_ipv4 (data->server))
     168                 :             :         {
     169                 :           0 :           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
     170                 :             :                                "IPv6-only server cannot speak IPv4");
     171                 :           0 :           goto error;
     172                 :             :         }
     173                 :             :     }
     174                 :             : #endif
     175                 :             : 
     176                 :          12 :   if (v4mapped)
     177                 :           1 :     iaddr = g_inet_address_new_any (family);
     178                 :             :   else
     179                 :          11 :     iaddr = g_inet_address_new_loopback (family);
     180                 :          12 :   addr = g_inet_socket_address_new (iaddr, 0);
     181                 :          12 :   g_object_unref (iaddr);
     182                 :             : 
     183                 :          12 :   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0);
     184                 :          12 :   if (!g_socket_bind (server, addr, TRUE, error))
     185                 :             :     {
     186                 :           0 :       g_object_unref (addr);
     187                 :           0 :       goto error;
     188                 :             :     }
     189                 :          12 :   g_object_unref (addr);
     190                 :             : 
     191                 :          12 :   addr = g_socket_get_local_address (server, error);
     192                 :          12 :   if (addr == NULL)
     193                 :           0 :     goto error;
     194                 :          12 :   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0);
     195                 :          12 :   g_object_unref (addr);
     196                 :             : 
     197                 :          12 :   if (socket_type == G_SOCKET_TYPE_STREAM)
     198                 :             :     {
     199                 :           9 :       if (!g_socket_listen (server, error))
     200                 :           0 :         goto error;
     201                 :             :     }
     202                 :             :   else
     203                 :             :     {
     204                 :           3 :       data->cancellable = g_cancellable_new ();
     205                 :             :     }
     206                 :             : 
     207                 :          12 :   data->thread = g_thread_new ("server", server_thread, data);
     208                 :             : 
     209                 :          12 :   return data;
     210                 :             : 
     211                 :           0 : error:
     212                 :           0 :   ip_test_data_free (data);
     213                 :             : 
     214                 :           0 :   return NULL;
     215                 :             : }
     216                 :             : 
     217                 :             : static IPTestData *
     218                 :           9 : create_server (GSocketFamily   family,
     219                 :             :                GThreadFunc     server_thread,
     220                 :             :                gboolean        v4mapped,
     221                 :             :                GError        **error)
     222                 :             : {
     223                 :           9 :   return create_server_full (family, G_SOCKET_TYPE_STREAM, server_thread, v4mapped, error);
     224                 :             : }
     225                 :             : 
     226                 :             : static const gchar *testbuf = "0123456789abcdef";
     227                 :             : 
     228                 :             : static gboolean
     229                 :           2 : test_ip_async_read_ready (GSocket      *client,
     230                 :             :                           GIOCondition  cond,
     231                 :             :                           gpointer      user_data)
     232                 :             : {
     233                 :           2 :   IPTestData *data = user_data;
     234                 :           2 :   GError *error = NULL;
     235                 :             :   gssize len;
     236                 :             :   gchar buf[128];
     237                 :             : 
     238                 :           2 :   g_assert_cmpint (cond, ==, G_IO_IN);
     239                 :             : 
     240                 :           2 :   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     241                 :           2 :   g_assert_no_error (error);
     242                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     243                 :             : 
     244                 :           2 :   g_assert_cmpstr (testbuf, ==, buf);
     245                 :             : 
     246                 :           2 :   g_main_loop_quit (data->loop);
     247                 :             : 
     248                 :           2 :   return FALSE;
     249                 :             : }
     250                 :             : 
     251                 :             : static gboolean
     252                 :           2 : test_ip_async_write_ready (GSocket      *client,
     253                 :             :                            GIOCondition  cond,
     254                 :             :                            gpointer      user_data)
     255                 :             : {
     256                 :           2 :   IPTestData *data = user_data;
     257                 :           2 :   GError *error = NULL;
     258                 :             :   GSource *source;
     259                 :             :   gssize len;
     260                 :             : 
     261                 :           2 :   g_assert_cmpint (cond, ==, G_IO_OUT);
     262                 :             : 
     263                 :           2 :   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
     264                 :           2 :   g_assert_no_error (error);
     265                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     266                 :             : 
     267                 :           2 :   source = g_socket_create_source (client, G_IO_IN, NULL);
     268                 :           2 :   g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready,
     269                 :             :                          data, NULL);
     270                 :           2 :   g_source_attach (source, NULL);
     271                 :           2 :   g_source_unref (source);
     272                 :             : 
     273                 :           2 :   return FALSE;
     274                 :             : }
     275                 :             : 
     276                 :             : static gboolean
     277                 :           2 : test_ip_async_timed_out (GSocket      *client,
     278                 :             :                          GIOCondition  cond,
     279                 :             :                          gpointer      user_data)
     280                 :             : {
     281                 :           2 :   IPTestData *data = user_data;
     282                 :           2 :   GError *error = NULL;
     283                 :             :   GSource *source;
     284                 :             :   gssize len;
     285                 :             :   gchar buf[128];
     286                 :             : 
     287                 :           2 :   if (data->family == G_SOCKET_FAMILY_IPV4)
     288                 :             :     {
     289                 :           1 :       g_assert_cmpint (cond, ==, G_IO_IN);
     290                 :           1 :       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     291                 :           1 :       g_assert_cmpint (len, ==, -1);
     292                 :           1 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
     293                 :           1 :       g_clear_error (&error);
     294                 :             :     }
     295                 :             : 
     296                 :           2 :   source = g_socket_create_source (client, G_IO_OUT, NULL);
     297                 :           2 :   g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready,
     298                 :             :                          data, NULL);
     299                 :           2 :   g_source_attach (source, NULL);
     300                 :           2 :   g_source_unref (source);
     301                 :             : 
     302                 :           2 :   return FALSE;
     303                 :             : }
     304                 :             : 
     305                 :             : static gboolean
     306                 :           2 : test_ip_async_connected (GSocket      *client,
     307                 :             :                          GIOCondition  cond,
     308                 :             :                          gpointer      user_data)
     309                 :             : {
     310                 :           2 :   IPTestData *data = user_data;
     311                 :           2 :   GError *error = NULL;
     312                 :             :   GSource *source;
     313                 :             :   gssize len;
     314                 :             :   gchar buf[128];
     315                 :             : 
     316                 :           2 :   g_socket_check_connect_result (client, &error);
     317                 :           2 :   g_assert_no_error (error);
     318                 :             :   /* We do this after the check_connect_result, since that will give a
     319                 :             :    * more useful assertion in case of error.
     320                 :             :    */
     321                 :           2 :   g_assert_cmpint (cond, ==, G_IO_OUT);
     322                 :             : 
     323                 :           2 :   g_assert_true (g_socket_is_connected (client));
     324                 :             : 
     325                 :             :   /* This adds 1 second to "make check", so let's just only do it once. */
     326                 :           2 :   if (data->family == G_SOCKET_FAMILY_IPV4)
     327                 :             :     {
     328                 :           1 :       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     329                 :           1 :       g_assert_cmpint (len, ==, -1);
     330                 :           1 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
     331                 :           1 :       g_clear_error (&error);
     332                 :             : 
     333                 :           1 :       source = g_socket_create_source (client, G_IO_IN, NULL);
     334                 :           1 :       g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out,
     335                 :             :                              data, NULL);
     336                 :           1 :       g_source_attach (source, NULL);
     337                 :           1 :       g_source_unref (source);
     338                 :             :     }
     339                 :             :   else
     340                 :           1 :     test_ip_async_timed_out (client, 0, data);
     341                 :             : 
     342                 :           2 :   return FALSE;
     343                 :             : }
     344                 :             : 
     345                 :             : static gboolean
     346                 :           0 : idle_test_ip_async_connected (gpointer user_data)
     347                 :             : {
     348                 :           0 :   IPTestData *data = user_data;
     349                 :             : 
     350                 :           0 :   return test_ip_async_connected (data->client, G_IO_OUT, data);
     351                 :             : }
     352                 :             : 
     353                 :             : static void
     354                 :           2 : test_ip_async (GSocketFamily family)
     355                 :             : {
     356                 :             :   IPTestData *data;
     357                 :           2 :   GError *error = NULL;
     358                 :             :   GSocket *client;
     359                 :             :   GSocketAddress *addr;
     360                 :             :   GSource *source;
     361                 :             :   gssize len;
     362                 :             :   gchar buf[128];
     363                 :             : 
     364                 :           2 :   data = create_server (family, echo_server_thread, FALSE, &error);
     365                 :           2 :   if (error != NULL)
     366                 :             :     {
     367                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
     368                 :           0 :       g_clear_error (&error);
     369                 :           0 :       return;
     370                 :             :     }
     371                 :           2 :   g_assert_nonnull (data);
     372                 :             : 
     373                 :           2 :   addr = g_socket_get_local_address (data->server, &error);
     374                 :           2 :   g_assert_no_error (error);
     375                 :             : 
     376                 :           2 :   client = g_socket_new (family,
     377                 :             :                          G_SOCKET_TYPE_STREAM,
     378                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
     379                 :             :                          &error);
     380                 :           2 :   g_assert_no_error (error);
     381                 :           2 :   data->client = client;
     382                 :             : 
     383                 :           2 :   g_assert_cmpint (g_socket_get_family (client), ==, family);
     384                 :           2 :   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
     385                 :           2 :   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
     386                 :             : 
     387                 :           2 :   g_socket_set_blocking (client, FALSE);
     388                 :           2 :   g_socket_set_timeout (client, 1);
     389                 :             : 
     390                 :           2 :   if (g_socket_connect (client, addr, NULL, &error))
     391                 :             :     {
     392                 :           0 :       g_assert_no_error (error);
     393                 :           0 :       g_idle_add (idle_test_ip_async_connected, data);
     394                 :             :     }
     395                 :             :   else
     396                 :             :     {
     397                 :           2 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
     398                 :           2 :       g_clear_error (&error);
     399                 :           2 :       source = g_socket_create_source (client, G_IO_OUT, NULL);
     400                 :           2 :       g_source_set_callback (source, (GSourceFunc)test_ip_async_connected,
     401                 :             :                              data, NULL);
     402                 :           2 :       g_source_attach (source, NULL);
     403                 :           2 :       g_source_unref (source);
     404                 :             :     }
     405                 :           2 :   g_object_unref (addr);
     406                 :             : 
     407                 :           2 :   data->loop = g_main_loop_new (NULL, TRUE);
     408                 :           2 :   g_main_loop_run (data->loop);
     409                 :           2 :   g_clear_pointer (&data->loop, g_main_loop_unref);
     410                 :             : 
     411                 :           2 :   g_socket_shutdown (client, FALSE, TRUE, &error);
     412                 :           2 :   g_assert_no_error (error);
     413                 :             : 
     414                 :           2 :   g_thread_join (data->thread);
     415                 :             : 
     416                 :           2 :   if (family == G_SOCKET_FAMILY_IPV4)
     417                 :             :     {
     418                 :             :       /* Test that reading on a remote-closed socket gets back 0 bytes. */
     419                 :           1 :       len = g_socket_receive_with_blocking (client, buf, sizeof (buf),
     420                 :             :                                             TRUE, NULL, &error);
     421                 :           1 :       g_assert_no_error (error);
     422                 :           1 :       g_assert_cmpint (len, ==, 0);
     423                 :             :     }
     424                 :             :   else
     425                 :             :     {
     426                 :             :       /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */
     427                 :           1 :       len = g_socket_send_with_blocking (client, testbuf, strlen (testbuf) + 1,
     428                 :             :                                          TRUE, NULL, &error);
     429                 :           1 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
     430                 :           1 :       g_assert_cmpint (len, ==, -1);
     431                 :           1 :       g_clear_error (&error);
     432                 :             :     }
     433                 :             : 
     434                 :           2 :   g_socket_close (client, &error);
     435                 :           2 :   g_assert_no_error (error);
     436                 :           2 :   g_socket_close (data->server, &error);
     437                 :           2 :   g_assert_no_error (error);
     438                 :             : 
     439                 :           2 :   ip_test_data_free (data);
     440                 :             : }
     441                 :             : 
     442                 :             : static void
     443                 :           1 : test_ipv4_async (void)
     444                 :             : {
     445                 :           1 :   test_ip_async (G_SOCKET_FAMILY_IPV4);
     446                 :           1 : }
     447                 :             : 
     448                 :             : static void
     449                 :           1 : test_ipv6_async (void)
     450                 :             : {
     451                 :           1 :   if (!ipv6_supported)
     452                 :             :     {
     453                 :           0 :       g_test_skip ("No support for IPv6");
     454                 :           0 :       return;
     455                 :             :     }
     456                 :             : 
     457                 :           1 :   test_ip_async (G_SOCKET_FAMILY_IPV6);
     458                 :             : }
     459                 :             : 
     460                 :             : static const gchar testbuf2[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     461                 :             : 
     462                 :             : static void
     463                 :           2 : test_ip_sync (GSocketFamily family)
     464                 :             : {
     465                 :             :   IPTestData *data;
     466                 :           2 :   GError *error = NULL;
     467                 :             :   GSocket *client;
     468                 :             :   GSocketAddress *addr;
     469                 :             :   gssize len;
     470                 :             :   gchar buf[128];
     471                 :             : 
     472                 :           2 :   data = create_server (family, echo_server_thread, FALSE, &error);
     473                 :           2 :   if (error != NULL)
     474                 :             :     {
     475                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
     476                 :           0 :       g_clear_error (&error);
     477                 :           0 :       return;
     478                 :             :     }
     479                 :             : 
     480                 :           2 :   addr = g_socket_get_local_address (data->server, &error);
     481                 :           2 :   g_assert_no_error (error);
     482                 :             : 
     483                 :           2 :   client = g_socket_new (family,
     484                 :             :                          G_SOCKET_TYPE_STREAM,
     485                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
     486                 :             :                          &error);
     487                 :           2 :   g_assert_no_error (error);
     488                 :             : 
     489                 :           2 :   g_assert_cmpint (g_socket_get_family (client), ==, family);
     490                 :           2 :   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
     491                 :           2 :   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
     492                 :             : #ifdef G_OS_WIN32
     493                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
     494                 :             : #endif
     495                 :           2 :   g_socket_set_blocking (client, TRUE);
     496                 :           2 :   g_socket_set_timeout (client, 1);
     497                 :             : 
     498                 :           2 :   g_socket_connect (client, addr, NULL, &error);
     499                 :           2 :   g_assert_no_error (error);
     500                 :           2 :   g_assert_true (g_socket_is_connected (client));
     501                 :           2 :   g_object_unref (addr);
     502                 :             : 
     503                 :             :   /* This adds 1 second to "make check", so let's just only do it once. */
     504                 :           2 :   if (family == G_SOCKET_FAMILY_IPV4)
     505                 :             :     {
     506                 :           1 :       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     507                 :           1 :       g_assert_cmpint (len, ==, -1);
     508                 :           1 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
     509                 :           1 :       g_clear_error (&error);
     510                 :             :     }
     511                 :             : 
     512                 :           2 :   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
     513                 :           2 :   g_assert_no_error (error);
     514                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     515                 :             :   
     516                 :           2 :   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     517                 :           2 :   g_assert_no_error (error);
     518                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     519                 :             : 
     520                 :           2 :   g_assert_cmpstr (testbuf, ==, buf);
     521                 :             : 
     522                 :             :   {
     523                 :           2 :     GOutputVector v[7] = { { NULL, 0 }, };
     524                 :             : 
     525                 :           2 :     v[0].buffer = testbuf2 + 0;
     526                 :           2 :     v[0].size = 3;
     527                 :           2 :     v[1].buffer = testbuf2 + 3;
     528                 :           2 :     v[1].size = 5;
     529                 :           2 :     v[2].buffer = testbuf2 + 3 + 5;
     530                 :           2 :     v[2].size = 0;
     531                 :           2 :     v[3].buffer = testbuf2 + 3 + 5;
     532                 :           2 :     v[3].size = 6;
     533                 :           2 :     v[4].buffer = testbuf2 + 3 + 5 + 6;
     534                 :           2 :     v[4].size = 2;
     535                 :           2 :     v[5].buffer = testbuf2 + 3 + 5 + 6 + 2;
     536                 :           2 :     v[5].size = 1;
     537                 :           2 :     v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1;
     538                 :           2 :     v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1);
     539                 :             : 
     540                 :           2 :     len = g_socket_send_message (client, NULL, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error);
     541                 :           2 :     g_assert_no_error (error);
     542                 :           2 :     g_assert_cmpint (len, ==, strlen (testbuf2));
     543                 :             : 
     544                 :           2 :     memset (buf, 0, sizeof (buf));
     545                 :           2 :     len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     546                 :           2 :     g_assert_no_error (error);
     547                 :           2 :     g_assert_cmpint (len, ==, strlen (testbuf2));
     548                 :           2 :     g_assert_cmpstr (testbuf2, ==, buf);
     549                 :             :   }
     550                 :             : 
     551                 :           2 :   g_socket_shutdown (client, FALSE, TRUE, &error);
     552                 :           2 :   g_assert_no_error (error);
     553                 :             : 
     554                 :           2 :   g_thread_join (data->thread);
     555                 :             : 
     556                 :           2 :   if (family == G_SOCKET_FAMILY_IPV4)
     557                 :             :     {
     558                 :             :       /* Test that reading on a remote-closed socket gets back 0 bytes. */
     559                 :           1 :       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
     560                 :           1 :       g_assert_no_error (error);
     561                 :           1 :       g_assert_cmpint (len, ==, 0);
     562                 :             :     }
     563                 :             :   else
     564                 :             :     {
     565                 :             :       /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */
     566                 :           1 :       len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
     567                 :           1 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
     568                 :           1 :       g_assert_cmpint (len, ==, -1);
     569                 :           1 :       g_clear_error (&error);
     570                 :             :     }
     571                 :             : 
     572                 :           2 :   g_socket_close (client, &error);
     573                 :           2 :   g_assert_no_error (error);
     574                 :           2 :   g_socket_close (data->server, &error);
     575                 :           2 :   g_assert_no_error (error);
     576                 :             : 
     577                 :           2 :   g_object_unref (client);
     578                 :             : 
     579                 :           2 :   ip_test_data_free (data);
     580                 :             : }
     581                 :             : 
     582                 :             : static void
     583                 :           1 : test_ipv4_sync (void)
     584                 :             : {
     585                 :           1 :   test_ip_sync (G_SOCKET_FAMILY_IPV4);
     586                 :           1 : }
     587                 :             : 
     588                 :             : static void
     589                 :           1 : test_ipv6_sync (void)
     590                 :             : {
     591                 :           1 :   if (!ipv6_supported)
     592                 :             :     {
     593                 :           0 :       g_test_skip ("No support for IPv6");
     594                 :           0 :       return;
     595                 :             :     }
     596                 :             : 
     597                 :           1 :   test_ip_sync (G_SOCKET_FAMILY_IPV6);
     598                 :             : }
     599                 :             : 
     600                 :             : static void
     601                 :           2 : test_ip_sync_dgram (GSocketFamily family)
     602                 :             : {
     603                 :             :   IPTestData *data;
     604                 :           2 :   GError *error = NULL;
     605                 :             :   GSocket *client;
     606                 :             :   GSocketAddress *dest_addr;
     607                 :             :   gssize len;
     608                 :             :   gchar buf[128];
     609                 :             : 
     610                 :           2 :   data = create_server_full (family, G_SOCKET_TYPE_DATAGRAM,
     611                 :             :                              echo_server_dgram_thread, FALSE, &error);
     612                 :           2 :   if (error != NULL)
     613                 :             :     {
     614                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
     615                 :           0 :       g_clear_error (&error);
     616                 :           0 :       return;
     617                 :             :     }
     618                 :             : 
     619                 :           2 :   dest_addr = g_socket_get_local_address (data->server, &error);
     620                 :           2 :   g_assert_no_error (error);
     621                 :             : 
     622                 :           2 :   client = g_socket_new (family,
     623                 :             :                          G_SOCKET_TYPE_DATAGRAM,
     624                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
     625                 :             :                          &error);
     626                 :           2 :   g_assert_no_error (error);
     627                 :             : 
     628                 :           2 :   g_assert_cmpint (g_socket_get_family (client), ==, family);
     629                 :           2 :   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
     630                 :           2 :   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
     631                 :             : #ifdef G_OS_WIN32
     632                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
     633                 :             : #endif
     634                 :             : 
     635                 :           2 :   g_socket_set_blocking (client, TRUE);
     636                 :           2 :   g_socket_set_timeout (client, 1);
     637                 :             : 
     638                 :           2 :   len = g_socket_send_to (client, dest_addr, testbuf, strlen (testbuf) + 1, NULL, &error);
     639                 :           2 :   g_assert_no_error (error);
     640                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     641                 :             : 
     642                 :           2 :   len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     643                 :           2 :   g_assert_no_error (error);
     644                 :           2 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     645                 :             : 
     646                 :           2 :   g_assert_cmpstr (testbuf, ==, buf);
     647                 :             : 
     648                 :             :   {
     649                 :           2 :     GOutputMessage m[3] = { { NULL, NULL, 0, 0, NULL, 0 }, };
     650                 :           2 :     GInputMessage im[3] = { { NULL, NULL, 0, 0, 0, NULL, 0 }, };
     651                 :           2 :     GOutputVector v[7] = { { NULL, 0 }, };
     652                 :           2 :     GInputVector iv[7] = { { NULL, 0 }, };
     653                 :             : 
     654                 :           2 :     v[0].buffer = testbuf2 + 0;
     655                 :           2 :     v[0].size = 3;
     656                 :           2 :     v[1].buffer = testbuf2 + 3;
     657                 :           2 :     v[1].size = 5;
     658                 :           2 :     v[2].buffer = testbuf2 + 3 + 5;
     659                 :           2 :     v[2].size = 0;
     660                 :           2 :     v[3].buffer = testbuf2 + 3 + 5;
     661                 :           2 :     v[3].size = 6;
     662                 :           2 :     v[4].buffer = testbuf2 + 3 + 5 + 6;
     663                 :           2 :     v[4].size = 2;
     664                 :           2 :     v[5].buffer = testbuf2 + 3 + 5 + 6 + 2;
     665                 :           2 :     v[5].size = 1;
     666                 :           2 :     v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1;
     667                 :           2 :     v[6].size = strlen (testbuf2) - (3 + 5 + 6 + 2 + 1);
     668                 :             : 
     669                 :           2 :     iv[0].buffer = buf + 0;
     670                 :           2 :     iv[0].size = 3;
     671                 :           2 :     iv[1].buffer = buf + 3;
     672                 :           2 :     iv[1].size = 5;
     673                 :           2 :     iv[2].buffer = buf + 3 + 5;
     674                 :           2 :     iv[2].size = 0;
     675                 :           2 :     iv[3].buffer = buf + 3 + 5;
     676                 :           2 :     iv[3].size = 6;
     677                 :           2 :     iv[4].buffer = buf + 3 + 5 + 6;
     678                 :           2 :     iv[4].size = 2;
     679                 :           2 :     iv[5].buffer = buf + 3 + 5 + 6 + 2;
     680                 :           2 :     iv[5].size = 1;
     681                 :           2 :     iv[6].buffer = buf + 3 + 5 + 6 + 2 + 1;
     682                 :           2 :     iv[6].size = sizeof (buf) - (3 + 5 + 6 + 2 + 1);
     683                 :             : 
     684                 :           2 :     len = g_socket_send_message (client, dest_addr, v, G_N_ELEMENTS (v), NULL, 0, 0, NULL, &error);
     685                 :           2 :     g_assert_no_error (error);
     686                 :           2 :     g_assert_cmpint (len, ==, strlen (testbuf2));
     687                 :             : 
     688                 :           2 :     memset (buf, 0, sizeof (buf));
     689                 :           2 :     len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     690                 :           2 :     g_assert_no_error (error);
     691                 :           2 :     g_assert_cmpint (len, ==, strlen (testbuf2));
     692                 :           2 :     g_assert_cmpstr (testbuf2, ==, buf);
     693                 :             : 
     694                 :           2 :     m[0].vectors = &v[0];
     695                 :           2 :     m[0].num_vectors = 1;
     696                 :           2 :     m[0].address = dest_addr;
     697                 :           2 :     m[1].vectors = &v[0];
     698                 :           2 :     m[1].num_vectors = 6;
     699                 :           2 :     m[1].address = dest_addr;
     700                 :           2 :     m[2].vectors = &v[6];
     701                 :           2 :     m[2].num_vectors = 1;
     702                 :           2 :     m[2].address = dest_addr;
     703                 :             : 
     704                 :           2 :     len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
     705                 :           2 :     g_assert_no_error (error);
     706                 :           2 :     g_assert_cmpint (len, ==, G_N_ELEMENTS (m));
     707                 :           2 :     g_assert_cmpint (m[0].bytes_sent, ==, 3);
     708                 :           2 :     g_assert_cmpint (m[1].bytes_sent, ==, 17);
     709                 :           2 :     g_assert_cmpint (m[2].bytes_sent, ==, v[6].size);
     710                 :             : 
     711                 :           2 :     memset (buf, 0, sizeof (buf));
     712                 :           2 :     len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     713                 :           2 :     g_assert_no_error (error);
     714                 :           2 :     g_assert_cmpint (len, ==, 3);
     715                 :             : 
     716                 :           2 :     memset (buf, 0, sizeof (buf));
     717                 :           2 :     len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     718                 :           2 :     g_assert_no_error (error);
     719                 :             :     /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */
     720                 :           2 :     g_assert_cmpint (len, ==, 17);
     721                 :           2 :     g_assert_cmpmem (testbuf2, 17, buf, 17);
     722                 :             : 
     723                 :           2 :     memset (buf, 0, sizeof (buf));
     724                 :           2 :     len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     725                 :           2 :     g_assert_no_error (error);
     726                 :           2 :     g_assert_cmpint (len, ==, v[6].size);
     727                 :           2 :     g_assert_cmpstr (buf, ==, v[6].buffer);
     728                 :             : 
     729                 :             :     /* reset since we're re-using the message structs */
     730                 :           2 :     m[0].bytes_sent = 0;
     731                 :           2 :     m[1].bytes_sent = 0;
     732                 :           2 :     m[2].bytes_sent = 0;
     733                 :             : 
     734                 :             :     /* now try receiving multiple messages */
     735                 :           2 :     len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
     736                 :           2 :     g_assert_no_error (error);
     737                 :           2 :     g_assert_cmpint (len, ==, G_N_ELEMENTS (m));
     738                 :           2 :     g_assert_cmpint (m[0].bytes_sent, ==, 3);
     739                 :           2 :     g_assert_cmpint (m[1].bytes_sent, ==, 17);
     740                 :           2 :     g_assert_cmpint (m[2].bytes_sent, ==, v[6].size);
     741                 :             : 
     742                 :           2 :     im[0].vectors = &iv[0];
     743                 :           2 :     im[0].num_vectors = 1;
     744                 :           2 :     im[1].vectors = &iv[0];
     745                 :           2 :     im[1].num_vectors = 6;
     746                 :           2 :     im[2].vectors = &iv[6];
     747                 :           2 :     im[2].num_vectors = 1;
     748                 :             : 
     749                 :           2 :     memset (buf, 0, sizeof (buf));
     750                 :           2 :     len = g_socket_receive_messages (client, im, G_N_ELEMENTS (im), 0,
     751                 :             :                                      NULL, &error);
     752                 :           2 :     g_assert_no_error (error);
     753                 :           2 :     g_assert_cmpint (len, ==, G_N_ELEMENTS (im));
     754                 :             : 
     755                 :           2 :     g_assert_cmpuint (im[0].bytes_received, ==, 3);
     756                 :             :     /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */
     757                 :           2 :     g_assert_cmpuint (im[1].bytes_received, ==, 17);
     758                 :           2 :     g_assert_cmpuint (im[2].bytes_received, ==, v[6].size);
     759                 :             : 
     760                 :             :     /* reset since we're re-using the message structs */
     761                 :           2 :     m[0].bytes_sent = 0;
     762                 :           2 :     m[1].bytes_sent = 0;
     763                 :           2 :     m[2].bytes_sent = 0;
     764                 :             : 
     765                 :             :     /* now try to generate an early return by omitting the destination address on [1] */
     766                 :           2 :     m[1].address = NULL;
     767                 :           2 :     len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
     768                 :           2 :     g_assert_no_error (error);
     769                 :           2 :     g_assert_cmpint (len, ==, 1);
     770                 :             : 
     771                 :           2 :     g_assert_cmpint (m[0].bytes_sent, ==, 3);
     772                 :           2 :     g_assert_cmpint (m[1].bytes_sent, ==, 0);
     773                 :           2 :     g_assert_cmpint (m[2].bytes_sent, ==, 0);
     774                 :             : 
     775                 :             :     /* reset since we're re-using the message structs */
     776                 :           2 :     m[0].bytes_sent = 0;
     777                 :           2 :     m[1].bytes_sent = 0;
     778                 :           2 :     m[2].bytes_sent = 0;
     779                 :             : 
     780                 :             :     /* now try to generate an error by omitting all destination addresses */
     781                 :           2 :     m[0].address = NULL;
     782                 :           2 :     m[1].address = NULL;
     783                 :           2 :     m[2].address = NULL;
     784                 :           2 :     len = g_socket_send_messages (client, m, G_N_ELEMENTS (m), 0, NULL, &error);
     785                 :             :     /* This error code may vary between platforms and over time; it is not guaranteed API: */
     786                 :             : #ifndef G_OS_WIN32
     787                 :           2 :     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DESTINATION_UNSET);
     788                 :             : #else
     789                 :             :     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED);
     790                 :             : #endif
     791                 :           2 :     g_clear_error (&error);
     792                 :           2 :     g_assert_cmpint (len, ==, -1);
     793                 :             : 
     794                 :           2 :     g_assert_cmpint (m[0].bytes_sent, ==, 0);
     795                 :           2 :     g_assert_cmpint (m[1].bytes_sent, ==, 0);
     796                 :           2 :     g_assert_cmpint (m[2].bytes_sent, ==, 0);
     797                 :             : 
     798                 :           2 :     len = g_socket_receive_from (client, NULL, buf, sizeof (buf), NULL, &error);
     799                 :           2 :     g_assert_cmpint (len, ==, 3);
     800                 :             :   }
     801                 :             : 
     802                 :           2 :   g_cancellable_cancel (data->cancellable);
     803                 :             : 
     804                 :           2 :   g_thread_join (data->thread);
     805                 :             : 
     806                 :           2 :   g_socket_close (client, &error);
     807                 :           2 :   g_assert_no_error (error);
     808                 :           2 :   g_socket_close (data->server, &error);
     809                 :           2 :   g_assert_no_error (error);
     810                 :             : 
     811                 :           2 :   g_object_unref (client);
     812                 :           2 :   g_object_unref (dest_addr);
     813                 :             : 
     814                 :           2 :   ip_test_data_free (data);
     815                 :             : }
     816                 :             : 
     817                 :             : static void
     818                 :           1 : test_ipv4_sync_dgram (void)
     819                 :             : {
     820                 :           1 :   test_ip_sync_dgram (G_SOCKET_FAMILY_IPV4);
     821                 :           1 : }
     822                 :             : 
     823                 :             : static void
     824                 :           1 : test_ipv6_sync_dgram (void)
     825                 :             : {
     826                 :           1 :   if (!ipv6_supported)
     827                 :             :     {
     828                 :           0 :       g_test_skip ("No support for IPv6");
     829                 :           0 :       return;
     830                 :             :     }
     831                 :             : 
     832                 :           1 :   test_ip_sync_dgram (G_SOCKET_FAMILY_IPV6);
     833                 :             : }
     834                 :             : 
     835                 :             : static gpointer
     836                 :           2 : cancellable_thread_cb (gpointer data)
     837                 :             : {
     838                 :           2 :   GCancellable *cancellable = data;
     839                 :             : 
     840                 :           2 :   g_usleep ((guint64) (0.1 * G_USEC_PER_SEC));
     841                 :           2 :   g_cancellable_cancel (cancellable);
     842                 :           2 :   g_object_unref (cancellable);
     843                 :             : 
     844                 :           2 :   return NULL;
     845                 :             : }
     846                 :             : 
     847                 :             : static void
     848                 :           2 : test_ip_sync_dgram_timeouts (GSocketFamily family)
     849                 :             : {
     850                 :           2 :   GError *error = NULL;
     851                 :           2 :   GSocket *client = NULL;
     852                 :           2 :   GCancellable *cancellable = NULL;
     853                 :           2 :   GThread *cancellable_thread = NULL;
     854                 :             :   gssize len;
     855                 :             : #ifdef G_OS_WIN32
     856                 :             :   GInetAddress *iaddr;
     857                 :             :   GSocketAddress *addr;
     858                 :             : #endif
     859                 :             : 
     860                 :           2 :   client = g_socket_new (family,
     861                 :             :                          G_SOCKET_TYPE_DATAGRAM,
     862                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
     863                 :             :                          &error);
     864                 :           2 :   g_assert_no_error (error);
     865                 :             : 
     866                 :           2 :   g_assert_cmpint (g_socket_get_family (client), ==, family);
     867                 :           2 :   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
     868                 :           2 :   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
     869                 :             : #ifdef G_OS_WIN32
     870                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
     871                 :             : #endif
     872                 :             : 
     873                 :             : #ifdef G_OS_WIN32
     874                 :             :   /* Winsock can't recv() on unbound udp socket */
     875                 :             :   iaddr = g_inet_address_new_loopback (family);
     876                 :             :   addr = g_inet_socket_address_new (iaddr, 0);
     877                 :             :   g_object_unref (iaddr);
     878                 :             :   g_socket_bind (client, addr, TRUE, &error);
     879                 :             :   g_object_unref (addr);
     880                 :             :   g_assert_no_error (error);
     881                 :             : #endif
     882                 :             : 
     883                 :             :   /* No overall timeout: test the per-operation timeouts instead. */
     884                 :           2 :   g_socket_set_timeout (client, 0);
     885                 :             : 
     886                 :           2 :   cancellable = g_cancellable_new ();
     887                 :             : 
     888                 :             :   /* Check for timeouts when no server is running. */
     889                 :             :   {
     890                 :             :     gint64 start_time;
     891                 :           2 :     GInputMessage im = { NULL, NULL, 0, 0, 0, NULL, 0 };
     892                 :           2 :     GInputVector iv = { NULL, 0 };
     893                 :             :     guint8 buf[128];
     894                 :             : 
     895                 :           2 :     iv.buffer = buf;
     896                 :           2 :     iv.size = sizeof (buf);
     897                 :             : 
     898                 :           2 :     im.vectors = &iv;
     899                 :           2 :     im.num_vectors = 1;
     900                 :             : 
     901                 :           2 :     memset (buf, 0, sizeof (buf));
     902                 :             : 
     903                 :             :     /* Try a non-blocking read. */
     904                 :           2 :     g_socket_set_blocking (client, FALSE);
     905                 :           2 :     len = g_socket_receive_messages (client, &im, 1, 0  /* flags */,
     906                 :             :                                      NULL, &error);
     907                 :           2 :     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
     908                 :           2 :     g_assert_cmpint (len, ==, -1);
     909                 :           2 :     g_clear_error (&error);
     910                 :             : 
     911                 :             :     /* Try a timeout read. Can’t really validate the time taken more than
     912                 :             :      * checking it’s positive. */
     913                 :           2 :     g_socket_set_timeout (client, 1);
     914                 :           2 :     g_socket_set_blocking (client, TRUE);
     915                 :           2 :     start_time = g_get_monotonic_time ();
     916                 :           2 :     len = g_socket_receive_messages (client, &im, 1, 0  /* flags */,
     917                 :             :                                      NULL, &error);
     918                 :           2 :     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
     919                 :           2 :     g_assert_cmpint (len, ==, -1);
     920                 :           2 :     g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0);
     921                 :           2 :     g_clear_error (&error);
     922                 :             : 
     923                 :             :     /* Try a blocking read, cancelled from another thread. */
     924                 :           2 :     g_socket_set_timeout (client, 0);
     925                 :           2 :     cancellable_thread = g_thread_new ("cancellable",
     926                 :             :                                        cancellable_thread_cb,
     927                 :             :                                        g_object_ref (cancellable));
     928                 :             : 
     929                 :           2 :     start_time = g_get_monotonic_time ();
     930                 :           2 :     len = g_socket_receive_messages (client, &im, 1, 0  /* flags */,
     931                 :             :                                      cancellable, &error);
     932                 :           2 :     g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
     933                 :           2 :     g_assert_cmpint (len, ==, -1);
     934                 :           2 :     g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0);
     935                 :           2 :     g_clear_error (&error);
     936                 :             : 
     937                 :           2 :     g_thread_join (cancellable_thread);
     938                 :             :   }
     939                 :             : 
     940                 :           2 :   g_socket_close (client, &error);
     941                 :           2 :   g_assert_no_error (error);
     942                 :             : 
     943                 :           2 :   g_object_unref (client);
     944                 :           2 :   g_object_unref (cancellable);
     945                 :           2 : }
     946                 :             : 
     947                 :             : static void
     948                 :           1 : test_ipv4_sync_dgram_timeouts (void)
     949                 :             : {
     950                 :           1 :   test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV4);
     951                 :           1 : }
     952                 :             : 
     953                 :             : static void
     954                 :           1 : test_ipv6_sync_dgram_timeouts (void)
     955                 :             : {
     956                 :           1 :   if (!ipv6_supported)
     957                 :             :     {
     958                 :           0 :       g_test_skip ("No support for IPv6");
     959                 :           0 :       return;
     960                 :             :     }
     961                 :             : 
     962                 :           1 :   test_ip_sync_dgram_timeouts (G_SOCKET_FAMILY_IPV6);
     963                 :             : }
     964                 :             : 
     965                 :             : static gpointer
     966                 :           1 : graceful_server_thread (gpointer user_data)
     967                 :             : {
     968                 :           1 :   IPTestData *data = user_data;
     969                 :             :   GSocket *sock;
     970                 :           1 :   GError *error = NULL;
     971                 :             :   gssize len;
     972                 :             : 
     973                 :           1 :   sock = g_socket_accept (data->server, NULL, &error);
     974                 :           1 :   g_assert_no_error (error);
     975                 :             : 
     976                 :           1 :   len = g_socket_send (sock, testbuf, strlen (testbuf) + 1, NULL, &error);
     977                 :           1 :   g_assert_no_error (error);
     978                 :           1 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
     979                 :             : 
     980                 :           1 :   return sock;
     981                 :             : }
     982                 :             : 
     983                 :             : static void
     984                 :           1 : test_close_graceful (void)
     985                 :             : {
     986                 :           1 :   GSocketFamily family = G_SOCKET_FAMILY_IPV4;
     987                 :             :   IPTestData *data;
     988                 :           1 :   GError *error = NULL;
     989                 :             :   GSocket *client, *server;
     990                 :             :   GSocketAddress *addr;
     991                 :             :   gssize len;
     992                 :             :   gchar buf[128];
     993                 :             : 
     994                 :           1 :   data = create_server (family, graceful_server_thread, FALSE, &error);
     995                 :           1 :   if (error != NULL)
     996                 :             :     {
     997                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
     998                 :           0 :       g_clear_error (&error);
     999                 :           0 :       return;
    1000                 :             :     }
    1001                 :             : 
    1002                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    1003                 :           1 :   g_assert_no_error (error);
    1004                 :             : 
    1005                 :           1 :   client = g_socket_new (family,
    1006                 :             :                          G_SOCKET_TYPE_STREAM,
    1007                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1008                 :             :                          &error);
    1009                 :           1 :   g_assert_no_error (error);
    1010                 :             : 
    1011                 :           1 :   g_assert_cmpint (g_socket_get_family (client), ==, family);
    1012                 :           1 :   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
    1013                 :           1 :   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
    1014                 :             : #ifdef G_OS_WIN32
    1015                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
    1016                 :             : #endif
    1017                 :             : 
    1018                 :           1 :   g_socket_set_blocking (client, TRUE);
    1019                 :           1 :   g_socket_set_timeout (client, 1);
    1020                 :             : 
    1021                 :           1 :   g_socket_connect (client, addr, NULL, &error);
    1022                 :           1 :   g_assert_no_error (error);
    1023                 :           1 :   g_assert_true (g_socket_is_connected (client));
    1024                 :           1 :   g_object_unref (addr);
    1025                 :             : 
    1026                 :           1 :   server = g_thread_join (data->thread);
    1027                 :             : 
    1028                 :             :   /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */
    1029                 :           1 :   g_socket_shutdown (server, FALSE, TRUE, &error);
    1030                 :           1 :   g_assert_no_error (error);
    1031                 :             : 
    1032                 :             :   /* we must timeout */
    1033                 :           1 :   g_socket_condition_wait (client, G_IO_HUP, NULL, &error);
    1034                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
    1035                 :           1 :   g_clear_error (&error);
    1036                 :             : 
    1037                 :             :   /* check that the remaining data is received */
    1038                 :           1 :   len = g_socket_receive (client, buf, strlen (testbuf) + 1, NULL, &error);
    1039                 :           1 :   g_assert_no_error (error);
    1040                 :           1 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
    1041                 :             : 
    1042                 :             :   /* and only then the connection is closed */
    1043                 :           1 :   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
    1044                 :           1 :   g_assert_no_error (error);
    1045                 :           1 :   g_assert_cmpint (len, ==, 0);
    1046                 :             : 
    1047                 :           1 :   g_socket_close (server, &error);
    1048                 :           1 :   g_assert_no_error (error);
    1049                 :             : 
    1050                 :           1 :   g_socket_close (client, &error);
    1051                 :           1 :   g_assert_no_error (error);
    1052                 :             : 
    1053                 :           1 :   g_object_unref (server);
    1054                 :           1 :   g_object_unref (client);
    1055                 :             : 
    1056                 :           1 :   ip_test_data_free (data);
    1057                 :             : }
    1058                 :             : 
    1059                 :             : #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
    1060                 :             : static gpointer
    1061                 :           1 : v4mapped_server_thread (gpointer user_data)
    1062                 :             : {
    1063                 :           1 :   IPTestData *data = user_data;
    1064                 :             :   GSocket *sock;
    1065                 :           1 :   GError *error = NULL;
    1066                 :             :   GSocketAddress *addr;
    1067                 :             : 
    1068                 :           1 :   sock = g_socket_accept (data->server, NULL, &error);
    1069                 :           1 :   g_assert_no_error (error);
    1070                 :             : 
    1071                 :           1 :   g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6);
    1072                 :             : 
    1073                 :           1 :   addr = g_socket_get_local_address (sock, &error);
    1074                 :           1 :   g_assert_no_error (error);
    1075                 :           1 :   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
    1076                 :           1 :   g_object_unref (addr);
    1077                 :             : 
    1078                 :           1 :   addr = g_socket_get_remote_address (sock, &error);
    1079                 :           1 :   g_assert_no_error (error);
    1080                 :           1 :   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
    1081                 :           1 :   g_object_unref (addr);
    1082                 :             : 
    1083                 :           1 :   g_socket_close (sock, &error);
    1084                 :           1 :   g_assert_no_error (error);
    1085                 :           1 :   g_object_unref (sock);
    1086                 :           1 :   return NULL;
    1087                 :             : }
    1088                 :             : 
    1089                 :             : static void
    1090                 :           1 : test_ipv6_v4mapped (void)
    1091                 :             : {
    1092                 :             :   IPTestData *data;
    1093                 :           1 :   GError *error = NULL;
    1094                 :             :   GSocket *client;
    1095                 :             :   GSocketAddress *addr, *v4addr;
    1096                 :             :   GInetAddress *iaddr;
    1097                 :             : 
    1098                 :           1 :   if (!ipv6_supported)
    1099                 :             :     {
    1100                 :           0 :       g_test_skip ("No support for IPv6");
    1101                 :           0 :       return;
    1102                 :             :     }
    1103                 :             : 
    1104                 :           1 :   data = create_server (G_SOCKET_FAMILY_IPV6, v4mapped_server_thread, TRUE, &error);
    1105                 :           1 :   if (error != NULL)
    1106                 :             :     {
    1107                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    1108                 :           0 :       g_clear_error (&error);
    1109                 :           0 :       return;
    1110                 :             :     }
    1111                 :             : 
    1112                 :           1 :   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1113                 :             :                          G_SOCKET_TYPE_STREAM,
    1114                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1115                 :             :                          &error);
    1116                 :           1 :   g_assert_no_error (error);
    1117                 :             : 
    1118                 :           1 :   g_socket_set_blocking (client, TRUE);
    1119                 :           1 :   g_socket_set_timeout (client, 1);
    1120                 :             : 
    1121                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    1122                 :           1 :   g_assert_no_error (error);
    1123                 :           1 :   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    1124                 :           1 :   v4addr = g_inet_socket_address_new (iaddr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)));
    1125                 :           1 :   g_object_unref (iaddr);
    1126                 :           1 :   g_object_unref (addr);
    1127                 :             : 
    1128                 :           1 :   g_socket_connect (client, v4addr, NULL, &error);
    1129                 :           1 :   g_assert_no_error (error);
    1130                 :           1 :   g_assert_true (g_socket_is_connected (client));
    1131                 :             : 
    1132                 :           1 :   g_thread_join (data->thread);
    1133                 :             : 
    1134                 :           1 :   g_socket_close (client, &error);
    1135                 :           1 :   g_assert_no_error (error);
    1136                 :           1 :   g_socket_close (data->server, &error);
    1137                 :           1 :   g_assert_no_error (error);
    1138                 :             : 
    1139                 :           1 :   g_object_unref (client);
    1140                 :           1 :   g_object_unref (v4addr);
    1141                 :             : 
    1142                 :           1 :   ip_test_data_free (data);
    1143                 :             : }
    1144                 :             : #endif
    1145                 :             : 
    1146                 :             : static void
    1147                 :           1 : test_timed_wait (void)
    1148                 :             : {
    1149                 :             :   IPTestData *data;
    1150                 :           1 :   GError *error = NULL;
    1151                 :             :   GSocket *client;
    1152                 :             :   GSocketAddress *addr;
    1153                 :             :   gint64 start_time;
    1154                 :             :   gint poll_duration;
    1155                 :             : 
    1156                 :           1 :   if (!g_test_thorough ())
    1157                 :             :     {
    1158                 :           1 :       g_test_skip ("Not running timing heavy test");
    1159                 :           1 :       return;
    1160                 :             :     }
    1161                 :             : 
    1162                 :           0 :   data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error);
    1163                 :           0 :   if (error != NULL)
    1164                 :             :     {
    1165                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    1166                 :           0 :       g_clear_error (&error);
    1167                 :           0 :       return;
    1168                 :             :     }
    1169                 :             : 
    1170                 :           0 :   addr = g_socket_get_local_address (data->server, &error);
    1171                 :           0 :   g_assert_no_error (error);
    1172                 :             : 
    1173                 :           0 :   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1174                 :             :                          G_SOCKET_TYPE_STREAM,
    1175                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1176                 :             :                          &error);
    1177                 :           0 :   g_assert_no_error (error);
    1178                 :             : 
    1179                 :           0 :   g_socket_set_blocking (client, TRUE);
    1180                 :           0 :   g_socket_set_timeout (client, 1);
    1181                 :             : 
    1182                 :           0 :   g_socket_connect (client, addr, NULL, &error);
    1183                 :           0 :   g_assert_no_error (error);
    1184                 :           0 :   g_object_unref (addr);
    1185                 :             : 
    1186                 :           0 :   start_time = g_get_monotonic_time ();
    1187                 :           0 :   g_socket_condition_timed_wait (client, G_IO_IN, 100000 /* 100 ms */,
    1188                 :             :                                  NULL, &error);
    1189                 :           0 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
    1190                 :           0 :   g_clear_error (&error);
    1191                 :           0 :   poll_duration = g_get_monotonic_time () - start_time;
    1192                 :             : 
    1193                 :           0 :   g_assert_cmpint (poll_duration, >=, 98000);
    1194                 :           0 :   g_assert_cmpint (poll_duration, <, 112000);
    1195                 :             : 
    1196                 :           0 :   g_socket_close (client, &error);
    1197                 :           0 :   g_assert_no_error (error);
    1198                 :             : 
    1199                 :           0 :   g_thread_join (data->thread);
    1200                 :             : 
    1201                 :           0 :   g_socket_close (data->server, &error);
    1202                 :           0 :   g_assert_no_error (error);
    1203                 :             : 
    1204                 :           0 :   g_object_unref (client);
    1205                 :             : 
    1206                 :           0 :   ip_test_data_free (data);
    1207                 :             : }
    1208                 :             : 
    1209                 :             : static int
    1210                 :           1 : duplicate_socket_fd (int fd)
    1211                 :             : {
    1212                 :             : #ifdef G_OS_WIN32
    1213                 :             :   WSAPROTOCOL_INFO info;
    1214                 :             : 
    1215                 :             :   if (WSADuplicateSocket ((SOCKET)fd,
    1216                 :             :                           GetCurrentProcessId (),
    1217                 :             :                           &info))
    1218                 :             :     {
    1219                 :             :       gchar *emsg = g_win32_error_message (WSAGetLastError ());
    1220                 :             :       g_test_message ("Error duplicating socket: %s", emsg);
    1221                 :             :       g_free (emsg);
    1222                 :             :       return -1;
    1223                 :             :     }
    1224                 :             : 
    1225                 :             :   return (int)WSASocket (FROM_PROTOCOL_INFO,
    1226                 :             :                          FROM_PROTOCOL_INFO,
    1227                 :             :                          FROM_PROTOCOL_INFO,
    1228                 :             :                          &info, 0, 0);
    1229                 :             : #else
    1230                 :           1 :   return dup (fd);
    1231                 :             : #endif
    1232                 :             : }
    1233                 :             : 
    1234                 :             : static void
    1235                 :           1 : test_fd_reuse (void)
    1236                 :             : {
    1237                 :             :   IPTestData *data;
    1238                 :           1 :   GError *error = NULL;
    1239                 :             :   GSocket *client;
    1240                 :             :   GSocket *client2;
    1241                 :             :   GSocketAddress *addr;
    1242                 :             :   int fd;
    1243                 :             :   gssize len;
    1244                 :             :   gchar buf[128];
    1245                 :             : 
    1246                 :           1 :   g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=741707");
    1247                 :             : 
    1248                 :           1 :   data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE, &error);
    1249                 :           1 :   if (error != NULL)
    1250                 :             :     {
    1251                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    1252                 :           0 :       g_clear_error (&error);
    1253                 :           0 :       return;
    1254                 :             :     }
    1255                 :             : 
    1256                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    1257                 :           1 :   g_assert_no_error (error);
    1258                 :             : 
    1259                 :           1 :   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1260                 :             :                          G_SOCKET_TYPE_STREAM,
    1261                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1262                 :             :                          &error);
    1263                 :           1 :   g_assert_no_error (error);
    1264                 :             : 
    1265                 :           1 :   g_socket_set_blocking (client, TRUE);
    1266                 :           1 :   g_socket_set_timeout (client, 1);
    1267                 :             : 
    1268                 :           1 :   g_socket_connect (client, addr, NULL, &error);
    1269                 :           1 :   g_assert_no_error (error);
    1270                 :           1 :   g_assert_true (g_socket_is_connected (client));
    1271                 :           1 :   g_object_unref (addr);
    1272                 :             : 
    1273                 :             :   /* we have to dup otherwise the fd gets closed twice on unref */
    1274                 :           1 :   fd = duplicate_socket_fd (g_socket_get_fd (client));
    1275                 :           1 :   client2 = g_socket_new_from_fd (fd, &error);
    1276                 :           1 :   g_assert_no_error (error);
    1277                 :             : 
    1278                 :           1 :   g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client));
    1279                 :           1 :   g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client));
    1280                 :           1 :   g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP);
    1281                 :             : #ifdef G_OS_WIN32
    1282                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (client)));
    1283                 :             : #endif
    1284                 :             : 
    1285                 :           1 :   len = g_socket_send (client2, testbuf, strlen (testbuf) + 1, NULL, &error);
    1286                 :           1 :   g_assert_no_error (error);
    1287                 :           1 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
    1288                 :             : 
    1289                 :           1 :   len = g_socket_receive (client2, buf, sizeof (buf), NULL, &error);
    1290                 :           1 :   g_assert_no_error (error);
    1291                 :           1 :   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
    1292                 :             : 
    1293                 :           1 :   g_assert_cmpstr (testbuf, ==, buf);
    1294                 :             : 
    1295                 :           1 :   g_socket_shutdown (client, FALSE, TRUE, &error);
    1296                 :           1 :   g_assert_no_error (error);
    1297                 :             :   /* The semantics of dup()+shutdown() are ambiguous; this call will succeed
    1298                 :             :    * on Linux, but return ENOTCONN on OS X.
    1299                 :             :    */
    1300                 :           1 :   g_socket_shutdown (client2, FALSE, TRUE, NULL);
    1301                 :             : 
    1302                 :           1 :   g_thread_join (data->thread);
    1303                 :             : 
    1304                 :           1 :   g_socket_close (client, &error);
    1305                 :           1 :   g_assert_no_error (error);
    1306                 :           1 :   g_socket_close (client2, &error);
    1307                 :           1 :   g_assert_no_error (error);
    1308                 :           1 :   g_socket_close (data->server, &error);
    1309                 :           1 :   g_assert_no_error (error);
    1310                 :             : 
    1311                 :           1 :   g_assert_cmpint (g_socket_get_fd (client), ==, -1);
    1312                 :           1 :   g_assert_cmpint (g_socket_get_fd (client2), ==, -1);
    1313                 :           1 :   g_assert_cmpint (g_socket_get_fd (data->server), ==, -1);
    1314                 :             : 
    1315                 :           1 :   g_object_unref (client);
    1316                 :           1 :   g_object_unref (client2);
    1317                 :             : 
    1318                 :           1 :   ip_test_data_free (data);
    1319                 :             : }
    1320                 :             : 
    1321                 :             : static void
    1322                 :           1 : test_sockaddr (void)
    1323                 :             : {
    1324                 :             :   struct sockaddr_in6 sin6, gsin6;
    1325                 :             :   GSocketAddress *saddr;
    1326                 :             :   GInetSocketAddress *isaddr;
    1327                 :             :   GInetAddress *iaddr;
    1328                 :           1 :   GError *error = NULL;
    1329                 :             : 
    1330                 :           1 :   memset (&sin6, 0, sizeof (sin6));
    1331                 :           1 :   sin6.sin6_family = AF_INET6;
    1332                 :           1 :   sin6.sin6_addr = in6addr_loopback;
    1333                 :           1 :   sin6.sin6_port = g_htons (42);
    1334                 :           1 :   sin6.sin6_scope_id = 17;
    1335                 :           1 :   sin6.sin6_flowinfo = 1729;
    1336                 :             : 
    1337                 :           1 :   saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6));
    1338                 :           1 :   g_assert_true (G_IS_INET_SOCKET_ADDRESS (saddr));
    1339                 :             : 
    1340                 :           1 :   isaddr = G_INET_SOCKET_ADDRESS (saddr);
    1341                 :           1 :   iaddr = g_inet_socket_address_get_address (isaddr);
    1342                 :           1 :   g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6);
    1343                 :           1 :   g_assert_true (g_inet_address_get_is_loopback (iaddr));
    1344                 :             : 
    1345                 :           1 :   g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42);
    1346                 :           1 :   g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17);
    1347                 :           1 :   g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729);
    1348                 :             : 
    1349                 :           1 :   g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error);
    1350                 :           1 :   g_assert_no_error (error);
    1351                 :             : 
    1352                 :           1 :   g_assert_cmpmem (&sin6.sin6_addr, sizeof (struct in6_addr), &gsin6.sin6_addr, sizeof (struct in6_addr));
    1353                 :           1 :   g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port);
    1354                 :           1 :   g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id);
    1355                 :           1 :   g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
    1356                 :             : 
    1357                 :           1 :   g_object_unref (saddr);
    1358                 :           1 : }
    1359                 :             : 
    1360                 :             : static void
    1361                 :           2 : bind_win32_unixfd (int fd)
    1362                 :             : {
    1363                 :             : #ifdef G_OS_WIN32
    1364                 :             :   gint len, ret;
    1365                 :             :   struct sockaddr_un addr;
    1366                 :             : 
    1367                 :             :   memset (&addr, 0, sizeof addr);
    1368                 :             :   addr.sun_family = AF_UNIX;
    1369                 :             :   len = g_snprintf (addr.sun_path, sizeof addr.sun_path, "%s" G_DIR_SEPARATOR_S "%d.sock", g_get_tmp_dir (), fd);
    1370                 :             :   g_assert_cmpint (len, <=, sizeof addr.sun_path);
    1371                 :             :   ret = bind (fd, (struct sockaddr *)&addr, sizeof addr);
    1372                 :             :   g_assert_cmpint (ret, ==, 0);
    1373                 :             :   g_remove (addr.sun_path);
    1374                 :             : #endif
    1375                 :           2 : }
    1376                 :             : 
    1377                 :             : static void
    1378                 :           1 : test_unix_from_fd (void)
    1379                 :             : {
    1380                 :             :   gint fd;
    1381                 :             :   GError *error;
    1382                 :             :   GSocket *s;
    1383                 :             : 
    1384                 :           1 :   fd = socket (AF_UNIX, SOCK_STREAM, 0);
    1385                 :             : #ifdef G_OS_WIN32
    1386                 :             :   if (fd == -1)
    1387                 :             :     {
    1388                 :             :       g_test_skip ("AF_UNIX not supported on this Windows system.");
    1389                 :             :       return;
    1390                 :             :     }
    1391                 :             : #endif
    1392                 :           1 :   g_assert_cmpint (fd, !=, -1);
    1393                 :             : 
    1394                 :           1 :   bind_win32_unixfd (fd);
    1395                 :             : 
    1396                 :           1 :   error = NULL;
    1397                 :           1 :   s = g_socket_new_from_fd (fd, &error);
    1398                 :           1 :   g_assert_no_error (error);
    1399                 :           1 :   g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX);
    1400                 :           1 :   g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
    1401                 :           1 :   g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
    1402                 :             : #ifdef G_OS_WIN32
    1403                 :             :   g_assert_true (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) ((HANDLE)(gintptr) g_socket_get_fd (s)));
    1404                 :             : #endif
    1405                 :           1 :   g_object_unref (s);
    1406                 :           1 : }
    1407                 :             : 
    1408                 :             : static void
    1409                 :           1 : test_unix_connection (void)
    1410                 :             : {
    1411                 :             :   gint fd;
    1412                 :             :   GError *error;
    1413                 :             :   GSocket *s;
    1414                 :             :   GSocketConnection *c;
    1415                 :             : 
    1416                 :           1 :   fd = socket (AF_UNIX, SOCK_STREAM, 0);
    1417                 :             : #ifdef G_OS_WIN32
    1418                 :             :   if (fd == -1)
    1419                 :             :     {
    1420                 :             :       g_test_skip ("AF_UNIX not supported on this Windows system.");
    1421                 :             :       return;
    1422                 :             :     }
    1423                 :             : #endif
    1424                 :           1 :   g_assert_cmpint (fd, !=, -1);
    1425                 :             : 
    1426                 :           1 :   bind_win32_unixfd (fd);
    1427                 :             : 
    1428                 :           1 :   error = NULL;
    1429                 :           1 :   s = g_socket_new_from_fd (fd, &error);
    1430                 :           1 :   g_assert_no_error (error);
    1431                 :           1 :   c = g_socket_connection_factory_create_connection (s);
    1432                 :           1 :   g_assert_true (G_IS_UNIX_CONNECTION (c));
    1433                 :           1 :   g_object_unref (c);
    1434                 :           1 :   g_object_unref (s);
    1435                 :           1 : }
    1436                 :             : 
    1437                 :             : #ifdef G_OS_UNIX
    1438                 :             : static GSocketConnection *
    1439                 :           2 : create_connection_for_fd (int fd)
    1440                 :             : {
    1441                 :           2 :   GError *err = NULL;
    1442                 :             :   GSocket *socket;
    1443                 :             :   GSocketConnection *connection;
    1444                 :             : 
    1445                 :           2 :   socket = g_socket_new_from_fd (fd, &err);
    1446                 :           2 :   g_assert_no_error (err);
    1447                 :           2 :   g_assert_true (G_IS_SOCKET (socket));
    1448                 :           2 :   connection = g_socket_connection_factory_create_connection (socket);
    1449                 :           2 :   g_assert_true (G_IS_UNIX_CONNECTION (connection));
    1450                 :           2 :   g_object_unref (socket);
    1451                 :           2 :   return connection;
    1452                 :             : }
    1453                 :             : 
    1454                 :             : #define TEST_DATA "failure to say failure to say 'i love gnome-panel!'."
    1455                 :             : 
    1456                 :             : static void
    1457                 :           1 : test_unix_connection_ancillary_data (void)
    1458                 :             : {
    1459                 :           1 :   GError *err = NULL;
    1460                 :             :   gint pv[2], sv[3];
    1461                 :             :   gint status, fd, len;
    1462                 :             :   char buffer[1024];
    1463                 :             :   pid_t pid;
    1464                 :             : 
    1465                 :           1 :   status = pipe (pv);
    1466                 :           1 :   g_assert_cmpint (status, ==, 0);
    1467                 :             : 
    1468                 :           1 :   status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
    1469                 :           1 :   g_assert_cmpint (status, ==, 0);
    1470                 :             : 
    1471                 :           1 :   pid = fork ();
    1472                 :           2 :   g_assert_cmpint (pid, >=, 0);
    1473                 :             : 
    1474                 :             :   /* Child: close its copy of the write end of the pipe, receive it
    1475                 :             :    * again from the parent over the socket, and write some text to it.
    1476                 :             :    *
    1477                 :             :    * Parent: send the write end of the pipe (still open for the
    1478                 :             :    * parent) over the socket, close it, and read some text from the
    1479                 :             :    * read end of the pipe.
    1480                 :             :    */
    1481                 :           2 :   if (pid == 0)
    1482                 :             :     {
    1483                 :             :       GSocketConnection *connection;
    1484                 :             : 
    1485                 :           1 :       close (sv[1]);
    1486                 :           1 :       connection = create_connection_for_fd (sv[0]);
    1487                 :             : 
    1488                 :           1 :       status = close (pv[1]);
    1489                 :           1 :       g_assert_cmpint (status, ==, 0);
    1490                 :             : 
    1491                 :           1 :       err = NULL;
    1492                 :           1 :       fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL,
    1493                 :             :                                          &err);
    1494                 :           1 :       g_assert_no_error (err);
    1495                 :           1 :       g_assert_cmpint (fd, >, -1);
    1496                 :           1 :       g_object_unref (connection);
    1497                 :             : 
    1498                 :             :       do
    1499                 :           1 :         len = write (fd, TEST_DATA, sizeof (TEST_DATA));
    1500                 :           1 :       while (len == -1 && errno == EINTR);
    1501                 :           1 :       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
    1502                 :           1 :       exit (0);
    1503                 :             :     }
    1504                 :             :   else
    1505                 :             :     {
    1506                 :             :       GSocketConnection *connection;
    1507                 :             : 
    1508                 :           1 :       close (sv[0]);
    1509                 :           1 :       connection = create_connection_for_fd (sv[1]);
    1510                 :             : 
    1511                 :           1 :       err = NULL;
    1512                 :           1 :       g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL,
    1513                 :             :                                  &err);
    1514                 :           1 :       g_assert_no_error (err);
    1515                 :           1 :       g_object_unref (connection);
    1516                 :             : 
    1517                 :           1 :       status = close (pv[1]);
    1518                 :           1 :       g_assert_cmpint (status, ==, 0);
    1519                 :             : 
    1520                 :           1 :       memset (buffer, 0xff, sizeof buffer);
    1521                 :             :       do
    1522                 :           1 :         len = read (pv[0], buffer, sizeof buffer);
    1523                 :           1 :       while (len == -1 && errno == EINTR);
    1524                 :             : 
    1525                 :           1 :       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
    1526                 :           1 :       g_assert_cmpstr (buffer, ==, TEST_DATA);
    1527                 :             : 
    1528                 :           1 :       waitpid (pid, &status, 0);
    1529                 :           1 :       g_assert_true (WIFEXITED (status));
    1530                 :           1 :       g_assert_cmpint (WEXITSTATUS (status), ==, 0);
    1531                 :             :     }
    1532                 :             : 
    1533                 :             :   /* TODO: add test for g_unix_connection_send_credentials() and
    1534                 :             :    * g_unix_connection_receive_credentials().
    1535                 :             :    */
    1536                 :           1 : }
    1537                 :             : #endif
    1538                 :             : 
    1539                 :             : #ifdef G_OS_WIN32
    1540                 :             : static void
    1541                 :             : test_handle_not_socket (void)
    1542                 :             : {
    1543                 :             :   GError *err = NULL;
    1544                 :             :   gchar *name = NULL;
    1545                 :             :   HANDLE hReadPipe, hWritePipe, h;
    1546                 :             :   int fd;
    1547                 :             : 
    1548                 :             :   g_assert_true (CreatePipe (&hReadPipe, &hWritePipe, NULL, 2048));
    1549                 :             :   g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (hReadPipe));
    1550                 :             :   g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (hWritePipe));
    1551                 :             :   CloseHandle (hReadPipe);
    1552                 :             :   CloseHandle (hWritePipe);
    1553                 :             : 
    1554                 :             :   h = (HANDLE) _get_osfhandle (1);
    1555                 :             :   g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (h));
    1556                 :             : 
    1557                 :             :   fd = g_file_open_tmp (NULL, &name, &err);
    1558                 :             :   g_assert_no_error (err);
    1559                 :             :   h = (HANDLE) _get_osfhandle (fd);
    1560                 :             :   g_assert_false (GLIB_PRIVATE_CALL (g_win32_handle_is_socket) (h));
    1561                 :             :   g_close (fd, &err);
    1562                 :             :   g_assert_no_error (err);
    1563                 :             :   g_unlink (name);
    1564                 :             :   g_free (name);
    1565                 :             : }
    1566                 :             : #endif
    1567                 :             : 
    1568                 :             : static gboolean
    1569                 :           1 : postmortem_source_cb (GSocket      *socket,
    1570                 :             :                       GIOCondition  condition,
    1571                 :             :                       gpointer      user_data)
    1572                 :             : {
    1573                 :           1 :   gboolean *been_here = user_data;
    1574                 :             : 
    1575                 :           1 :   g_assert_cmpint (condition, ==, G_IO_NVAL);
    1576                 :             : 
    1577                 :           1 :   *been_here = TRUE;
    1578                 :           1 :   return FALSE;
    1579                 :             : }
    1580                 :             : 
    1581                 :             : static void
    1582                 :           1 : test_source_postmortem (void)
    1583                 :             : {
    1584                 :             :   GMainContext *context;
    1585                 :             :   GSocket *socket;
    1586                 :             :   GSource *source;
    1587                 :           1 :   GError *error = NULL;
    1588                 :           1 :   gboolean callback_visited = FALSE;
    1589                 :             : 
    1590                 :           1 :   socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
    1591                 :             : #ifdef G_OS_WIN32
    1592                 :             :   if (error)
    1593                 :             :     {
    1594                 :             :       g_test_skip_printf ("AF_UNIX not supported on this Windows system: %s", error->message);
    1595                 :             :       g_clear_error (&error);
    1596                 :             :       return;
    1597                 :             :     }
    1598                 :             : #endif
    1599                 :           1 :   g_assert_no_error (error);
    1600                 :             : 
    1601                 :           1 :   context = g_main_context_new ();
    1602                 :             : 
    1603                 :           1 :   source = g_socket_create_source (socket, G_IO_IN, NULL);
    1604                 :           1 :   g_source_set_callback (source, (GSourceFunc) postmortem_source_cb,
    1605                 :             :                          &callback_visited, NULL);
    1606                 :           1 :   g_source_attach (source, context);
    1607                 :           1 :   g_source_unref (source);
    1608                 :             : 
    1609                 :           1 :   g_socket_close (socket, &error);
    1610                 :           1 :   g_assert_no_error (error);
    1611                 :           1 :   g_object_unref (socket);
    1612                 :             : 
    1613                 :             :   /* Test that, after a socket is closed, its source callback should be called
    1614                 :             :    * exactly once. */
    1615                 :           1 :   g_main_context_iteration (context, FALSE);
    1616                 :           1 :   g_assert_true (callback_visited);
    1617                 :           1 :   g_assert_false (g_main_context_pending (context));
    1618                 :             : 
    1619                 :           1 :   g_main_context_unref (context);
    1620                 :           1 : }
    1621                 :             : 
    1622                 :             : static void
    1623                 :           1 : test_reuse_tcp (void)
    1624                 :             : {
    1625                 :             :   GSocket *sock1, *sock2;
    1626                 :           1 :   GError *error = NULL;
    1627                 :             :   GInetAddress *iaddr;
    1628                 :             :   GSocketAddress *addr;
    1629                 :             : 
    1630                 :           1 :   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1631                 :             :                         G_SOCKET_TYPE_STREAM,
    1632                 :             :                         G_SOCKET_PROTOCOL_DEFAULT,
    1633                 :             :                         &error);
    1634                 :           1 :   g_assert_no_error (error);
    1635                 :             : 
    1636                 :           1 :   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    1637                 :           1 :   addr = g_inet_socket_address_new (iaddr, 0);
    1638                 :           1 :   g_object_unref (iaddr);
    1639                 :           1 :   g_socket_bind (sock1, addr, TRUE, &error);
    1640                 :           1 :   g_object_unref (addr);
    1641                 :           1 :   g_assert_no_error (error);
    1642                 :             : 
    1643                 :           1 :   g_socket_listen (sock1, &error);
    1644                 :           1 :   g_assert_no_error (error);
    1645                 :             : 
    1646                 :           1 :   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1647                 :             :                         G_SOCKET_TYPE_STREAM,
    1648                 :             :                         G_SOCKET_PROTOCOL_DEFAULT,
    1649                 :             :                         &error);
    1650                 :           1 :   g_assert_no_error (error);
    1651                 :             : 
    1652                 :           1 :   addr = g_socket_get_local_address (sock1, &error);
    1653                 :           1 :   g_assert_no_error (error);
    1654                 :           1 :   g_socket_bind (sock2, addr, TRUE, &error);
    1655                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
    1656                 :           1 :   g_clear_error (&error);
    1657                 :           1 :   g_object_unref (addr);
    1658                 :             : 
    1659                 :           1 :   g_object_unref (sock1);
    1660                 :           1 :   g_object_unref (sock2);
    1661                 :           1 : }
    1662                 :             : 
    1663                 :             : static void
    1664                 :           1 : test_reuse_udp (void)
    1665                 :             : {
    1666                 :             :   GSocket *sock1, *sock2;
    1667                 :           1 :   GError *error = NULL;
    1668                 :             :   GInetAddress *iaddr;
    1669                 :             :   GSocketAddress *addr;
    1670                 :             : 
    1671                 :           1 :   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1672                 :             :                         G_SOCKET_TYPE_DATAGRAM,
    1673                 :             :                         G_SOCKET_PROTOCOL_DEFAULT,
    1674                 :             :                         &error);
    1675                 :           1 :   g_assert_no_error (error);
    1676                 :             : 
    1677                 :           1 :   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    1678                 :           1 :   addr = g_inet_socket_address_new (iaddr, 0);
    1679                 :           1 :   g_object_unref (iaddr);
    1680                 :           1 :   g_socket_bind (sock1, addr, TRUE, &error);
    1681                 :           1 :   g_object_unref (addr);
    1682                 :           1 :   g_assert_no_error (error);
    1683                 :             : 
    1684                 :           1 :   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1685                 :             :                         G_SOCKET_TYPE_DATAGRAM,
    1686                 :             :                         G_SOCKET_PROTOCOL_DEFAULT,
    1687                 :             :                         &error);
    1688                 :           1 :   g_assert_no_error (error);
    1689                 :             : 
    1690                 :           1 :   addr = g_socket_get_local_address (sock1, &error);
    1691                 :           1 :   g_assert_no_error (error);
    1692                 :           1 :   g_socket_bind (sock2, addr, TRUE, &error);
    1693                 :           1 :   g_object_unref (addr);
    1694                 :           1 :   g_assert_no_error (error);
    1695                 :             : 
    1696                 :           1 :   g_object_unref (sock1);
    1697                 :           1 :   g_object_unref (sock2);
    1698                 :           1 : }
    1699                 :             : 
    1700                 :             : static void
    1701                 :           2 : test_get_available (gconstpointer user_data)
    1702                 :             : {
    1703                 :           2 :   GSocketType socket_type = GPOINTER_TO_UINT (user_data);
    1704                 :           2 :   GError *err = NULL;
    1705                 :             :   GSocket *listener, *server, *client;
    1706                 :             :   GInetAddress *addr;
    1707                 :             :   GSocketAddress *saddr, *boundaddr;
    1708                 :           2 :   gchar data[] = "0123456789abcdef";
    1709                 :             :   gchar buf[34];
    1710                 :             :   gssize nread;
    1711                 :             : 
    1712                 :           2 :   listener = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1713                 :             :                            socket_type,
    1714                 :             :                            G_SOCKET_PROTOCOL_DEFAULT,
    1715                 :             :                            &err);
    1716                 :           2 :   g_assert_no_error (err);
    1717                 :           2 :   g_assert_true (G_IS_SOCKET (listener));
    1718                 :             : 
    1719                 :           2 :   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1720                 :             :                          socket_type,
    1721                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1722                 :             :                          &err);
    1723                 :           2 :   g_assert_no_error (err);
    1724                 :           2 :   g_assert_true (G_IS_SOCKET (client));
    1725                 :             : 
    1726                 :           2 :   if (socket_type == G_SOCKET_TYPE_STREAM)
    1727                 :             :     {
    1728                 :           1 :       g_socket_set_option (client, IPPROTO_TCP, TCP_NODELAY, TRUE, &err);
    1729                 :           1 :       g_assert_no_error (err);
    1730                 :             :     }
    1731                 :             : 
    1732                 :           2 :   addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
    1733                 :           2 :   saddr = g_inet_socket_address_new (addr, 0);
    1734                 :             : 
    1735                 :           2 :   g_socket_bind (listener, saddr, TRUE, &err);
    1736                 :           2 :   g_assert_no_error (err);
    1737                 :           2 :   g_object_unref (saddr);
    1738                 :           2 :   g_object_unref (addr);
    1739                 :             : 
    1740                 :           2 :   boundaddr = g_socket_get_local_address (listener, &err);
    1741                 :           2 :   g_assert_no_error (err);
    1742                 :             : 
    1743                 :           2 :   addr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    1744                 :           2 :   saddr = g_inet_socket_address_new (addr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr)));
    1745                 :           2 :   g_object_unref (addr);
    1746                 :           2 :   g_object_unref (boundaddr);
    1747                 :             : 
    1748                 :           2 :   if (socket_type == G_SOCKET_TYPE_STREAM)
    1749                 :             :     {
    1750                 :           1 :       g_socket_listen (listener, &err);
    1751                 :           1 :       g_assert_no_error (err);
    1752                 :           1 :       g_socket_connect (client, saddr, NULL, &err);
    1753                 :           1 :       g_assert_no_error (err);
    1754                 :             : 
    1755                 :           1 :       server = g_socket_accept (listener, NULL, &err);
    1756                 :           1 :       g_assert_no_error (err);
    1757                 :           1 :       g_socket_set_blocking (server, FALSE);
    1758                 :           1 :       g_object_unref (listener);
    1759                 :             :     }
    1760                 :             :   else
    1761                 :           1 :     server = listener;
    1762                 :             : 
    1763                 :           2 :   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
    1764                 :           2 :   g_assert_no_error (err);
    1765                 :             : 
    1766                 :           2 :   while (!g_socket_condition_wait (server, G_IO_IN, NULL, NULL))
    1767                 :             :     ;
    1768                 :           2 :   g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
    1769                 :             : 
    1770                 :           2 :   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
    1771                 :           2 :   g_assert_no_error (err);
    1772                 :             : 
    1773                 :             :   /* We need to wait until the data has actually been copied into the
    1774                 :             :    * server socket's buffers, but g_socket_condition_wait() won't help
    1775                 :             :    * here since the socket is definitely already readable. So there's
    1776                 :             :    * a race condition in checking its available bytes. In the TCP
    1777                 :             :    * case, we poll for a bit until the new data shows up. In the UDP
    1778                 :             :    * case, there's not much we can do, but at least the failure mode
    1779                 :             :    * is passes-when-it-shouldn't, not fails-when-it-shouldn't.
    1780                 :             :    */
    1781                 :           2 :   if (socket_type == G_SOCKET_TYPE_STREAM)
    1782                 :             :     {
    1783                 :             :       int tries;
    1784                 :             : 
    1785                 :           1 :       for (tries = 0; tries < 100; tries++)
    1786                 :             :         {
    1787                 :           1 :           gssize res = g_socket_get_available_bytes (server);
    1788                 :           1 :           if ((res == -1) || ((gsize) res > sizeof (data)))
    1789                 :             :             break;
    1790                 :           0 :           g_usleep (100000);
    1791                 :             :         }
    1792                 :             : 
    1793                 :           1 :       g_assert_cmpint (g_socket_get_available_bytes (server), ==, 2 * sizeof (data));
    1794                 :             :     }
    1795                 :             :   else
    1796                 :             :     {
    1797                 :           1 :       g_usleep (100000);
    1798                 :           1 :       g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
    1799                 :             :     }
    1800                 :             : 
    1801                 :           2 :   g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data));
    1802                 :           2 :   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
    1803                 :           2 :   g_assert_no_error (err);
    1804                 :             : 
    1805                 :           2 :   if (socket_type == G_SOCKET_TYPE_STREAM)
    1806                 :             :     {
    1807                 :           1 :       g_assert_cmpint (nread, ==, 2 * sizeof (data));
    1808                 :           1 :       g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
    1809                 :             :     }
    1810                 :             :   else
    1811                 :             :     {
    1812                 :           1 :       g_assert_cmpint (nread, ==, sizeof (data));
    1813                 :           1 :       g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
    1814                 :             :     }
    1815                 :             : 
    1816                 :           2 :   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
    1817                 :           2 :   if (socket_type == G_SOCKET_TYPE_STREAM)
    1818                 :             :     {
    1819                 :           1 :       g_assert_cmpint (nread, ==, -1);
    1820                 :           1 :       g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
    1821                 :           1 :       g_clear_error (&err);
    1822                 :             :     }
    1823                 :             :   else
    1824                 :             :     {
    1825                 :           1 :       g_assert_cmpint (nread, ==, sizeof (data));
    1826                 :           1 :       g_assert_no_error (err);
    1827                 :             :     }
    1828                 :             : 
    1829                 :           2 :   g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
    1830                 :             : 
    1831                 :           2 :   g_socket_close (server, &err);
    1832                 :           2 :   g_assert_no_error (err);
    1833                 :             : 
    1834                 :           2 :   g_object_unref (saddr);
    1835                 :           2 :   g_object_unref (server);
    1836                 :           2 :   g_object_unref (client);
    1837                 :           2 : }
    1838                 :             : 
    1839                 :             : typedef struct {
    1840                 :             :   GInputStream *is;
    1841                 :             :   GOutputStream *os;
    1842                 :             :   const guint8 *write_data;
    1843                 :             :   guint8 *read_data;
    1844                 :             : } TestReadWriteData;
    1845                 :             : 
    1846                 :             : static gpointer
    1847                 :           1 : test_read_write_write_thread (gpointer user_data)
    1848                 :             : {
    1849                 :           1 :   TestReadWriteData *data = user_data;
    1850                 :             :   gsize bytes_written;
    1851                 :           1 :   GError *error = NULL;
    1852                 :             :   gboolean res;
    1853                 :             : 
    1854                 :           1 :   res = g_output_stream_write_all (data->os, data->write_data, 1024, &bytes_written, NULL, &error);
    1855                 :           1 :   g_assert_true (res);
    1856                 :           1 :   g_assert_no_error (error);
    1857                 :           1 :   g_assert_cmpint (bytes_written, ==, 1024);
    1858                 :             : 
    1859                 :           1 :   return NULL;
    1860                 :             : }
    1861                 :             : 
    1862                 :             : static gpointer
    1863                 :           2 : test_read_write_read_thread (gpointer user_data)
    1864                 :             : {
    1865                 :           2 :   TestReadWriteData *data = user_data;
    1866                 :             :   gsize bytes_read;
    1867                 :           2 :   GError *error = NULL;
    1868                 :             :   gboolean res;
    1869                 :             : 
    1870                 :           2 :   res = g_input_stream_read_all (data->is, data->read_data, 1024, &bytes_read, NULL, &error);
    1871                 :           2 :   g_assert_true (res);
    1872                 :           2 :   g_assert_no_error (error);
    1873                 :           2 :   g_assert_cmpint (bytes_read, ==, 1024);
    1874                 :             : 
    1875                 :           2 :   return NULL;
    1876                 :             : }
    1877                 :             : 
    1878                 :             : static gpointer
    1879                 :           1 : test_read_write_writev_thread (gpointer user_data)
    1880                 :             : {
    1881                 :           1 :   TestReadWriteData *data = user_data;
    1882                 :             :   gsize bytes_written;
    1883                 :           1 :   GError *error = NULL;
    1884                 :             :   gboolean res;
    1885                 :             :   GOutputVector vectors[3];
    1886                 :             : 
    1887                 :           1 :   vectors[0].buffer = data->write_data;
    1888                 :           1 :   vectors[0].size = 256;
    1889                 :           1 :   vectors[1].buffer = data->write_data + 256;
    1890                 :           1 :   vectors[1].size = 256;
    1891                 :           1 :   vectors[2].buffer = data->write_data + 512;
    1892                 :           1 :   vectors[2].size = 512;
    1893                 :             : 
    1894                 :           1 :   res = g_output_stream_writev_all (data->os, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error);
    1895                 :           1 :   g_assert_true (res);
    1896                 :           1 :   g_assert_no_error (error);
    1897                 :           1 :   g_assert_cmpint (bytes_written, ==, 1024);
    1898                 :             : 
    1899                 :           1 :   return NULL;
    1900                 :             : }
    1901                 :             : 
    1902                 :             : /* test if normal read/write/writev via the GSocket*Streams works on TCP sockets */
    1903                 :             : static void
    1904                 :           2 : test_read_write (gconstpointer user_data)
    1905                 :             : {
    1906                 :           2 :   gboolean writev = GPOINTER_TO_INT (user_data);
    1907                 :           2 :   GError *err = NULL;
    1908                 :             :   GSocket *listener, *server, *client;
    1909                 :             :   GInetAddress *addr;
    1910                 :             :   GSocketAddress *saddr, *boundaddr;
    1911                 :             :   TestReadWriteData data;
    1912                 :             :   guint8 data_write[1024], data_read[1024];
    1913                 :             :   GSocketConnection *server_stream, *client_stream;
    1914                 :             :   GThread *write_thread, *read_thread;
    1915                 :             :   guint i;
    1916                 :             : 
    1917                 :           2 :   listener = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1918                 :             :                            G_SOCKET_TYPE_STREAM,
    1919                 :             :                            G_SOCKET_PROTOCOL_DEFAULT,
    1920                 :             :                            &err);
    1921                 :           2 :   g_assert_no_error (err);
    1922                 :           2 :   g_assert_true (G_IS_SOCKET (listener));
    1923                 :             : 
    1924                 :           2 :   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
    1925                 :             :                          G_SOCKET_TYPE_STREAM,
    1926                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    1927                 :             :                          &err);
    1928                 :           2 :   g_assert_no_error (err);
    1929                 :           2 :   g_assert_true (G_IS_SOCKET (client));
    1930                 :             : 
    1931                 :           2 :   addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
    1932                 :           2 :   saddr = g_inet_socket_address_new (addr, 0);
    1933                 :             : 
    1934                 :           2 :   g_socket_bind (listener, saddr, TRUE, &err);
    1935                 :           2 :   g_assert_no_error (err);
    1936                 :           2 :   g_object_unref (saddr);
    1937                 :           2 :   g_object_unref (addr);
    1938                 :             : 
    1939                 :           2 :   boundaddr = g_socket_get_local_address (listener, &err);
    1940                 :           2 :   g_assert_no_error (err);
    1941                 :             : 
    1942                 :           2 :   g_socket_listen (listener, &err);
    1943                 :           2 :   g_assert_no_error (err);
    1944                 :             : 
    1945                 :           2 :   addr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
    1946                 :           2 :   saddr = g_inet_socket_address_new (addr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr)));
    1947                 :           2 :   g_object_unref (addr);
    1948                 :           2 :   g_object_unref (boundaddr);
    1949                 :             : 
    1950                 :           2 :   g_socket_connect (client, saddr, NULL, &err);
    1951                 :           2 :   g_assert_no_error (err);
    1952                 :             : 
    1953                 :           2 :   server = g_socket_accept (listener, NULL, &err);
    1954                 :           2 :   g_assert_no_error (err);
    1955                 :           2 :   g_socket_set_blocking (server, FALSE);
    1956                 :           2 :   g_object_unref (listener);
    1957                 :             : 
    1958                 :           2 :   server_stream = g_socket_connection_factory_create_connection (server);
    1959                 :           2 :   g_assert_nonnull (server_stream);
    1960                 :           2 :   client_stream = g_socket_connection_factory_create_connection (client);
    1961                 :           2 :   g_assert_nonnull (client_stream);
    1962                 :             : 
    1963                 :        2050 :   for (i = 0; i < sizeof (data_write); i++)
    1964                 :        2048 :     data_write[i] = i;
    1965                 :             : 
    1966                 :           2 :   data.is = g_io_stream_get_input_stream (G_IO_STREAM (server_stream));
    1967                 :           2 :   data.os = g_io_stream_get_output_stream (G_IO_STREAM (client_stream));
    1968                 :           2 :   data.read_data = data_read;
    1969                 :           2 :   data.write_data = data_write;
    1970                 :             : 
    1971                 :           2 :   if (writev)
    1972                 :           1 :     write_thread = g_thread_new ("writer", test_read_write_writev_thread, &data);
    1973                 :             :   else
    1974                 :           1 :     write_thread = g_thread_new ("writer", test_read_write_write_thread, &data);
    1975                 :           2 :   read_thread = g_thread_new ("reader", test_read_write_read_thread, &data);
    1976                 :             : 
    1977                 :           2 :   g_thread_join (write_thread);
    1978                 :           2 :   g_thread_join (read_thread);
    1979                 :             : 
    1980                 :           2 :   g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read);
    1981                 :             : 
    1982                 :           2 :   g_socket_close (server, &err);
    1983                 :           2 :   g_assert_no_error (err);
    1984                 :             : 
    1985                 :           2 :   g_object_unref (server_stream);
    1986                 :           2 :   g_object_unref (client_stream);
    1987                 :             : 
    1988                 :           2 :   g_object_unref (saddr);
    1989                 :           2 :   g_object_unref (server);
    1990                 :           2 :   g_object_unref (client);
    1991                 :           2 : }
    1992                 :             : 
    1993                 :             : #ifdef SO_NOSIGPIPE
    1994                 :             : static void
    1995                 :             : test_nosigpipe (void)
    1996                 :             : {
    1997                 :             :   GSocket *sock;
    1998                 :             :   GError *error = NULL;
    1999                 :             :   gint value;
    2000                 :             : 
    2001                 :             :   sock = g_socket_new (AF_INET,
    2002                 :             :                        G_SOCKET_TYPE_STREAM,
    2003                 :             :                        G_SOCKET_PROTOCOL_DEFAULT,
    2004                 :             :                        &error);
    2005                 :             :   g_assert_no_error (error);
    2006                 :             : 
    2007                 :             :   g_socket_get_option (sock, SOL_SOCKET, SO_NOSIGPIPE, &value, &error);
    2008                 :             :   g_assert_no_error (error);
    2009                 :             :   g_assert_true (value);
    2010                 :             : 
    2011                 :             :   g_object_unref (sock);
    2012                 :             : }
    2013                 :             : #endif
    2014                 :             : 
    2015                 :             : #if G_CREDENTIALS_SUPPORTED
    2016                 :             : static gpointer client_setup_thread (gpointer user_data);
    2017                 :             : 
    2018                 :             : static void
    2019                 :           1 : test_credentials_tcp_client (void)
    2020                 :             : {
    2021                 :           1 :   const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
    2022                 :             :   IPTestData *data;
    2023                 :           1 :   GError *error = NULL;
    2024                 :             :   GSocket *client;
    2025                 :             :   GSocketAddress *addr;
    2026                 :             :   GCredentials *creds;
    2027                 :             : 
    2028                 :           1 :   data = create_server (family, echo_server_thread, FALSE, &error);
    2029                 :           1 :   if (error != NULL)
    2030                 :             :     {
    2031                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    2032                 :           0 :       g_clear_error (&error);
    2033                 :           0 :       return;
    2034                 :             :     }
    2035                 :             : 
    2036                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    2037                 :           1 :   g_assert_no_error (error);
    2038                 :             : 
    2039                 :           1 :   client = g_socket_new (family,
    2040                 :             :                          G_SOCKET_TYPE_STREAM,
    2041                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    2042                 :             :                          &error);
    2043                 :           1 :   g_assert_no_error (error);
    2044                 :             : 
    2045                 :           1 :   g_socket_set_blocking (client, TRUE);
    2046                 :           1 :   g_socket_set_timeout (client, 1);
    2047                 :             : 
    2048                 :           1 :   g_socket_connect (client, addr, NULL, &error);
    2049                 :           1 :   g_assert_no_error (error);
    2050                 :           1 :   g_object_unref (addr);
    2051                 :             : 
    2052                 :           1 :   creds = g_socket_get_credentials (client, &error);
    2053                 :           1 :   if (creds != NULL)
    2054                 :             :     {
    2055                 :           1 :       gchar *str = g_credentials_to_string (creds);
    2056                 :           1 :       g_test_message ("Supported on this OS: %s", str);
    2057                 :           1 :       g_free (str);
    2058                 :           1 :       g_clear_object (&creds);
    2059                 :             :     }
    2060                 :             :   else
    2061                 :             :     {
    2062                 :           0 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
    2063                 :           0 :       g_test_message ("Unsupported on this OS: %s", error->message);
    2064                 :           0 :       g_clear_error (&error);
    2065                 :             :     }
    2066                 :             : 
    2067                 :           1 :   g_socket_close (client, &error);
    2068                 :           1 :   g_assert_no_error (error);
    2069                 :             : 
    2070                 :           1 :   g_thread_join (data->thread);
    2071                 :             : 
    2072                 :           1 :   g_socket_close (data->server, &error);
    2073                 :           1 :   g_assert_no_error (error);
    2074                 :             : 
    2075                 :           1 :   g_object_unref (client);
    2076                 :             : 
    2077                 :           1 :   ip_test_data_free (data);
    2078                 :             : }
    2079                 :             : 
    2080                 :             : static void
    2081                 :           1 : test_credentials_tcp_server (void)
    2082                 :             : {
    2083                 :           1 :   const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
    2084                 :             :   IPTestData *data;
    2085                 :             :   GSocket *server;
    2086                 :           1 :   GError *error = NULL;
    2087                 :           1 :   GSocketAddress *addr = NULL;
    2088                 :           1 :   GInetAddress *iaddr = NULL;
    2089                 :           1 :   GSocket *sock = NULL;
    2090                 :             :   GCredentials *creds;
    2091                 :             : 
    2092                 :           1 :   data = g_slice_new0 (IPTestData);
    2093                 :           1 :   data->family = family;
    2094                 :           1 :   data->server = server = g_socket_new (family,
    2095                 :             :                                         G_SOCKET_TYPE_STREAM,
    2096                 :             :                                         G_SOCKET_PROTOCOL_DEFAULT,
    2097                 :             :                                         &error);
    2098                 :           1 :   if (error != NULL)
    2099                 :           0 :     goto skip;
    2100                 :             : 
    2101                 :           1 :   g_socket_set_blocking (server, TRUE);
    2102                 :             : 
    2103                 :           1 :   iaddr = g_inet_address_new_loopback (family);
    2104                 :           1 :   addr = g_inet_socket_address_new (iaddr, 0);
    2105                 :             : 
    2106                 :           1 :   if (!g_socket_bind (server, addr, TRUE, &error))
    2107                 :           0 :     goto skip;
    2108                 :             : 
    2109                 :           1 :   if (!g_socket_listen (server, &error))
    2110                 :           0 :     goto skip;
    2111                 :             : 
    2112                 :           1 :   data->thread = g_thread_new ("client", client_setup_thread, data);
    2113                 :             : 
    2114                 :           1 :   sock = g_socket_accept (server, NULL, &error);
    2115                 :           1 :   g_assert_no_error (error);
    2116                 :             : 
    2117                 :           1 :   creds = g_socket_get_credentials (sock, &error);
    2118                 :           1 :   if (creds != NULL)
    2119                 :             :     {
    2120                 :           1 :       gchar *str = g_credentials_to_string (creds);
    2121                 :           1 :       g_test_message ("Supported on this OS: %s", str);
    2122                 :           1 :       g_free (str);
    2123                 :           1 :       g_clear_object (&creds);
    2124                 :             :     }
    2125                 :             :   else
    2126                 :             :     {
    2127                 :           0 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
    2128                 :           0 :       g_test_message ("Unsupported on this OS: %s", error->message);
    2129                 :           0 :       g_clear_error (&error);
    2130                 :             :     }
    2131                 :             : 
    2132                 :           1 :   goto beach;
    2133                 :             : 
    2134                 :           0 : skip:
    2135                 :           0 :   g_test_skip_printf ("Failed to create server: %s", error->message);
    2136                 :           0 :   goto beach;
    2137                 :             : 
    2138                 :           1 : beach:
    2139                 :             :   {
    2140                 :           1 :     g_clear_error (&error);
    2141                 :             : 
    2142                 :           1 :     g_clear_object (&sock);
    2143                 :           1 :     g_clear_object (&addr);
    2144                 :           1 :     g_clear_object (&iaddr);
    2145                 :             : 
    2146                 :           1 :     g_clear_pointer (&data->thread, g_thread_join);
    2147                 :             : 
    2148                 :           1 :     ip_test_data_free (data);
    2149                 :             :   }
    2150                 :           1 : }
    2151                 :             : 
    2152                 :             : static gpointer
    2153                 :           1 : client_setup_thread (gpointer user_data)
    2154                 :             : {
    2155                 :           1 :   IPTestData *data = user_data;
    2156                 :             :   GSocketAddress *addr;
    2157                 :             :   GSocket *client;
    2158                 :           1 :   GError *error = NULL;
    2159                 :             : 
    2160                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    2161                 :           1 :   g_assert_no_error (error);
    2162                 :             : 
    2163                 :           1 :   data->client = client = g_socket_new (data->family,
    2164                 :             :                                         G_SOCKET_TYPE_STREAM,
    2165                 :             :                                         G_SOCKET_PROTOCOL_DEFAULT,
    2166                 :             :                                         &error);
    2167                 :           1 :   g_assert_no_error (error);
    2168                 :             : 
    2169                 :           1 :   g_socket_set_blocking (client, TRUE);
    2170                 :           1 :   g_socket_set_timeout (client, 1);
    2171                 :             : 
    2172                 :           1 :   g_socket_connect (client, addr, NULL, &error);
    2173                 :           1 :   g_assert_no_error (error);
    2174                 :             : 
    2175                 :           1 :   g_object_unref (addr);
    2176                 :             : 
    2177                 :           1 :   return NULL;
    2178                 :             : }
    2179                 :             : 
    2180                 :             : #ifdef G_OS_WIN32
    2181                 :             : /*
    2182                 :             :  * _g_win32_socketpair:
    2183                 :             :  *
    2184                 :             :  * Create a pair of connected sockets, similar to POSIX/BSD socketpair().
    2185                 :             :  *
    2186                 :             :  * Windows does not (yet) provide a socketpair() function. However, since the
    2187                 :             :  * introduction of AF_UNIX sockets, it is possible to implement a fairly close
    2188                 :             :  * function.
    2189                 :             :  */
    2190                 :             : static gint
    2191                 :             : _g_win32_socketpair (gint            domain,
    2192                 :             :                      gint            type,
    2193                 :             :                      gint            protocol,
    2194                 :             :                      gint            sv[2])
    2195                 :             : {
    2196                 :             :   struct sockaddr_un addr = { 0, };
    2197                 :             :   socklen_t socklen;
    2198                 :             :   SOCKET listener = INVALID_SOCKET;
    2199                 :             :   SOCKET client = INVALID_SOCKET;
    2200                 :             :   SOCKET server = INVALID_SOCKET;
    2201                 :             :   gchar *path = NULL;
    2202                 :             :   wchar_t *path_utf16 = NULL;
    2203                 :             :   int tmpfd, rv = -1;
    2204                 :             :   u_long arg, br;
    2205                 :             : 
    2206                 :             :   g_return_val_if_fail (sv != NULL, -1);
    2207                 :             : 
    2208                 :             :   addr.sun_family = AF_UNIX;
    2209                 :             :   socklen = sizeof (addr);
    2210                 :             : 
    2211                 :             :   tmpfd = g_file_open_tmp (NULL, &path, NULL);
    2212                 :             :   if (tmpfd == -1)
    2213                 :             :     {
    2214                 :             :       WSASetLastError (WSAEACCES);
    2215                 :             :       goto out;
    2216                 :             :     }
    2217                 :             : 
    2218                 :             :   g_close (tmpfd, NULL);
    2219                 :             : 
    2220                 :             :   if (strlen (path) >= sizeof (addr.sun_path))
    2221                 :             :     {
    2222                 :             :       WSASetLastError (WSAEACCES);
    2223                 :             :       goto out;
    2224                 :             :     }
    2225                 :             : 
    2226                 :             :   strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
    2227                 :             : 
    2228                 :             :   listener = socket (domain, type, protocol);
    2229                 :             :   if (listener == INVALID_SOCKET)
    2230                 :             :     goto out;
    2231                 :             : 
    2232                 :             :   path_utf16 = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);
    2233                 :             :   if (!path_utf16)
    2234                 :             :     goto out;
    2235                 :             : 
    2236                 :             :   if (DeleteFile (path_utf16) == 0)
    2237                 :             :     {
    2238                 :             :       if (GetLastError () != ERROR_FILE_NOT_FOUND)
    2239                 :             :         goto out;
    2240                 :             :     }
    2241                 :             : 
    2242                 :             :   if (bind (listener, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR)
    2243                 :             :     goto out;
    2244                 :             : 
    2245                 :             :   if (listen (listener, 1) == SOCKET_ERROR)
    2246                 :             :     goto out;
    2247                 :             : 
    2248                 :             :   client = socket (domain, type, protocol);
    2249                 :             :   if (client == INVALID_SOCKET)
    2250                 :             :     goto out;
    2251                 :             : 
    2252                 :             :   arg = 1;
    2253                 :             :   if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
    2254                 :             :     goto out;
    2255                 :             : 
    2256                 :             :   if (connect (client, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR &&
    2257                 :             :       WSAGetLastError () != WSAEWOULDBLOCK)
    2258                 :             :     goto out;
    2259                 :             : 
    2260                 :             :   server = accept (listener, NULL, NULL);
    2261                 :             :   if (server == INVALID_SOCKET)
    2262                 :             :     goto out;
    2263                 :             : 
    2264                 :             :   arg = 0;
    2265                 :             :   if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
    2266                 :             :     goto out;
    2267                 :             : 
    2268                 :             :   if (WSAIoctl (server, SIO_AF_UNIX_GETPEERPID,
    2269                 :             :                 NULL, 0U,
    2270                 :             :                 &arg, sizeof (arg), &br,
    2271                 :             :                 NULL, NULL) == SOCKET_ERROR || arg != GetCurrentProcessId ())
    2272                 :             :     {
    2273                 :             :       WSASetLastError (WSAEACCES);
    2274                 :             :       goto out;
    2275                 :             :     }
    2276                 :             : 
    2277                 :             :   sv[0] = server;
    2278                 :             :   server = INVALID_SOCKET;
    2279                 :             :   sv[1] = client;
    2280                 :             :   client = INVALID_SOCKET;
    2281                 :             :   rv = 0;
    2282                 :             : 
    2283                 :             :  out:
    2284                 :             :   if (listener != INVALID_SOCKET)
    2285                 :             :     closesocket (listener);
    2286                 :             :   if (client != INVALID_SOCKET)
    2287                 :             :     closesocket (client);
    2288                 :             :   if (server != INVALID_SOCKET)
    2289                 :             :     closesocket (server);
    2290                 :             : 
    2291                 :             :   if (path_utf16)
    2292                 :             :     DeleteFile (path_utf16);
    2293                 :             : 
    2294                 :             :   g_free (path_utf16);
    2295                 :             :   g_free (path);
    2296                 :             :   return rv;
    2297                 :             : }
    2298                 :             : #endif /* G_OS_WIN32 */
    2299                 :             : 
    2300                 :             : static void
    2301                 :           1 : test_credentials_unix_socketpair (void)
    2302                 :             : {
    2303                 :             :   gint fds[2];
    2304                 :             :   gint status;
    2305                 :             :   GSocket *sock[2];
    2306                 :           1 :   GError *error = NULL;
    2307                 :             :   GCredentials *creds;
    2308                 :             : 
    2309                 :             : #ifdef G_OS_WIN32
    2310                 :             :   status = _g_win32_socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
    2311                 :             :   if (status != 0)
    2312                 :             :     {
    2313                 :             :       g_test_skip ("AF_UNIX not supported on this Windows system.");
    2314                 :             :       return;
    2315                 :             :     }
    2316                 :             : #else
    2317                 :           1 :   status = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
    2318                 :             : #endif
    2319                 :           1 :   g_assert_cmpint (status, ==, 0);
    2320                 :             : 
    2321                 :           1 :   sock[0] = g_socket_new_from_fd (fds[0], &error);
    2322                 :           1 :   g_assert_no_error (error);
    2323                 :           1 :   sock[1] = g_socket_new_from_fd (fds[1], &error);
    2324                 :           1 :   g_assert_no_error (error);
    2325                 :             : 
    2326                 :           1 :   creds = g_socket_get_credentials (sock[0], &error);
    2327                 :           1 :   if (creds != NULL)
    2328                 :             :     {
    2329                 :           1 :       gchar *str = g_credentials_to_string (creds);
    2330                 :           1 :       g_test_message ("Supported on this OS: %s", str);
    2331                 :           1 :       g_free (str);
    2332                 :           1 :       g_clear_object (&creds);
    2333                 :             :     }
    2334                 :             :   else
    2335                 :             :     {
    2336                 :           0 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
    2337                 :           0 :       g_test_message ("Unsupported on this OS: %s", error->message);
    2338                 :           0 :       g_clear_error (&error);
    2339                 :             :     }
    2340                 :             : 
    2341                 :           1 :   g_object_unref (sock[0]);
    2342                 :           1 :   g_object_unref (sock[1]);
    2343                 :           1 : }
    2344                 :             : #endif
    2345                 :             : 
    2346                 :             : static void
    2347                 :           1 : test_receive_bytes (void)
    2348                 :             : {
    2349                 :           1 :   const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
    2350                 :             :   IPTestData *data;
    2351                 :           1 :   GError *error = NULL;
    2352                 :             :   GSocket *client;
    2353                 :             :   GSocketAddress *addr;
    2354                 :             :   gssize len;
    2355                 :           1 :   GBytes *bytes = NULL;
    2356                 :             :   gint64 time_start;
    2357                 :           1 :   GCancellable *cancellable = NULL;
    2358                 :             : 
    2359                 :           1 :   g_test_summary ("Test basic functionality of g_socket_receive_bytes()");
    2360                 :             : 
    2361                 :           1 :   data = create_server (family, echo_server_thread, FALSE, &error);
    2362                 :           1 :   if (error != NULL)
    2363                 :             :     {
    2364                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    2365                 :           0 :       g_clear_error (&error);
    2366                 :           0 :       return;
    2367                 :             :     }
    2368                 :             : 
    2369                 :           1 :   addr = g_socket_get_local_address (data->server, &error);
    2370                 :           1 :   g_assert_no_error (error);
    2371                 :             : 
    2372                 :           1 :   client = g_socket_new (family,
    2373                 :             :                          G_SOCKET_TYPE_STREAM,
    2374                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    2375                 :             :                          &error);
    2376                 :           1 :   g_assert_no_error (error);
    2377                 :             : 
    2378                 :           1 :   g_socket_set_blocking (client, TRUE);
    2379                 :           1 :   g_socket_set_timeout (client, 10);
    2380                 :             : 
    2381                 :           1 :   g_socket_connect (client, addr, NULL, &error);
    2382                 :           1 :   g_assert_no_error (error);
    2383                 :           1 :   g_object_unref (addr);
    2384                 :             : 
    2385                 :             :   /* Send something. */
    2386                 :           1 :   len = g_socket_send (client, "hello", strlen ("hello"), NULL, &error);
    2387                 :           1 :   g_assert_no_error (error);
    2388                 :           1 :   g_assert_cmpint (len, ==, strlen ("hello"));
    2389                 :             : 
    2390                 :             :   /* And receive it back again. */
    2391                 :           1 :   bytes = g_socket_receive_bytes (client, 5, -1, NULL, &error);
    2392                 :           1 :   g_assert_no_error (error);
    2393                 :           1 :   g_assert_nonnull (bytes);
    2394                 :           1 :   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 5);
    2395                 :           1 :   g_assert_cmpmem (g_bytes_get_data (bytes, NULL), 5, "hello", 5);
    2396                 :           1 :   g_bytes_unref (bytes);
    2397                 :             : 
    2398                 :             :   /* Try again with a receive buffer which is bigger than the sent bytes, to
    2399                 :             :    * test sub-buffer handling. */
    2400                 :           1 :   len = g_socket_send (client, "hello", strlen ("hello"), NULL, &error);
    2401                 :           1 :   g_assert_no_error (error);
    2402                 :           1 :   g_assert_cmpint (len, ==, strlen ("hello"));
    2403                 :             : 
    2404                 :             :   /* And receive it back again. */
    2405                 :           1 :   bytes = g_socket_receive_bytes (client, 500, -1, NULL, &error);
    2406                 :           1 :   g_assert_no_error (error);
    2407                 :           1 :   g_assert_nonnull (bytes);
    2408                 :           1 :   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 5);
    2409                 :           1 :   g_assert_cmpmem (g_bytes_get_data (bytes, NULL), 5, "hello", 5);
    2410                 :           1 :   g_bytes_unref (bytes);
    2411                 :             : 
    2412                 :             :   /* Try receiving when there’s nothing to receive, with a timeout. This should
    2413                 :             :    * be the per-operation timeout, not the socket’s overall timeout */
    2414                 :           1 :   time_start = g_get_real_time ();
    2415                 :           1 :   bytes = g_socket_receive_bytes (client, 500, 10, NULL, &error);
    2416                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
    2417                 :           1 :   g_assert_null (bytes);
    2418                 :           1 :   g_assert_cmpint (g_get_real_time () - time_start, <, g_socket_get_timeout (client) * G_USEC_PER_SEC);
    2419                 :           1 :   g_clear_error (&error);
    2420                 :             : 
    2421                 :             :   /* And try receiving when already cancelled. */
    2422                 :           1 :   cancellable = g_cancellable_new ();
    2423                 :           1 :   g_cancellable_cancel (cancellable);
    2424                 :           1 :   bytes = g_socket_receive_bytes (client, 500, -1, cancellable, &error);
    2425                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
    2426                 :           1 :   g_assert_null (bytes);
    2427                 :           1 :   g_clear_error (&error);
    2428                 :           1 :   g_clear_object (&cancellable);
    2429                 :             : 
    2430                 :             :   /* Tidy up. */
    2431                 :           1 :   g_socket_close (client, &error);
    2432                 :           1 :   g_assert_no_error (error);
    2433                 :             : 
    2434                 :           1 :   g_cancellable_cancel (data->cancellable);
    2435                 :           1 :   g_thread_join (data->thread);
    2436                 :             : 
    2437                 :           1 :   g_socket_close (data->server, &error);
    2438                 :           1 :   g_assert_no_error (error);
    2439                 :             : 
    2440                 :           1 :   g_object_unref (client);
    2441                 :             : 
    2442                 :           1 :   ip_test_data_free (data);
    2443                 :             : }
    2444                 :             : 
    2445                 :             : static void
    2446                 :           1 : test_receive_bytes_from (void)
    2447                 :             : {
    2448                 :           1 :   const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
    2449                 :             :   IPTestData *data;
    2450                 :           1 :   GError *error = NULL;
    2451                 :             :   GSocket *client;
    2452                 :           1 :   GSocketAddress *dest_addr = NULL, *sender_addr = NULL;
    2453                 :             :   gssize len;
    2454                 :           1 :   GBytes *bytes = NULL;
    2455                 :             :   gint64 time_start;
    2456                 :           1 :   GCancellable *cancellable = NULL;
    2457                 :             : 
    2458                 :           1 :   g_test_summary ("Test basic functionality of g_socket_receive_bytes_from()");
    2459                 :             : 
    2460                 :           1 :   data = create_server_full (family, G_SOCKET_TYPE_DATAGRAM,
    2461                 :             :                              echo_server_dgram_thread, FALSE, &error);
    2462                 :           1 :   if (error != NULL)
    2463                 :             :     {
    2464                 :           0 :       g_test_skip_printf ("Failed to create server: %s", error->message);
    2465                 :           0 :       g_clear_error (&error);
    2466                 :           0 :       return;
    2467                 :             :     }
    2468                 :             : 
    2469                 :           1 :   dest_addr = g_socket_get_local_address (data->server, &error);
    2470                 :           1 :   g_assert_no_error (error);
    2471                 :             : 
    2472                 :           1 :   client = g_socket_new (family,
    2473                 :             :                          G_SOCKET_TYPE_DATAGRAM,
    2474                 :             :                          G_SOCKET_PROTOCOL_DEFAULT,
    2475                 :             :                          &error);
    2476                 :           1 :   g_assert_no_error (error);
    2477                 :             : 
    2478                 :           1 :   g_socket_set_blocking (client, TRUE);
    2479                 :           1 :   g_socket_set_timeout (client, 10);
    2480                 :             : 
    2481                 :             :   /* Send something. */
    2482                 :           1 :   len = g_socket_send_to (client, dest_addr, "hello", strlen ("hello"), NULL, &error);
    2483                 :           1 :   g_assert_no_error (error);
    2484                 :           1 :   g_assert_cmpint (len, ==, strlen ("hello"));
    2485                 :             : 
    2486                 :             :   /* And receive it back again. */
    2487                 :           1 :   bytes = g_socket_receive_bytes_from (client, &sender_addr, 5, -1, NULL, &error);
    2488                 :           1 :   g_assert_no_error (error);
    2489                 :           1 :   g_assert_nonnull (bytes);
    2490                 :           1 :   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 5);
    2491                 :           1 :   g_assert_cmpmem (g_bytes_get_data (bytes, NULL), 5, "hello", 5);
    2492                 :           1 :   g_assert_nonnull (sender_addr);
    2493                 :           1 :   g_clear_object (&sender_addr);
    2494                 :           1 :   g_bytes_unref (bytes);
    2495                 :             : 
    2496                 :             :   /* Try again with a receive buffer which is bigger than the sent bytes, to
    2497                 :             :    * test sub-buffer handling. */
    2498                 :           1 :   len = g_socket_send_to (client, dest_addr, "hello", strlen ("hello"), NULL, &error);
    2499                 :           1 :   g_assert_no_error (error);
    2500                 :           1 :   g_assert_cmpint (len, ==, strlen ("hello"));
    2501                 :             : 
    2502                 :             :   /* And receive it back again. */
    2503                 :           1 :   bytes = g_socket_receive_bytes_from (client, NULL, 500, -1, NULL, &error);
    2504                 :           1 :   g_assert_no_error (error);
    2505                 :           1 :   g_assert_nonnull (bytes);
    2506                 :           1 :   g_assert_cmpuint (g_bytes_get_size (bytes), ==, 5);
    2507                 :           1 :   g_assert_cmpmem (g_bytes_get_data (bytes, NULL), 5, "hello", 5);
    2508                 :           1 :   g_bytes_unref (bytes);
    2509                 :             : 
    2510                 :             :   /* Try receiving when there’s nothing to receive, with a timeout. This should
    2511                 :             :    * be the per-operation timeout, not the socket’s overall timeout */
    2512                 :           1 :   time_start = g_get_real_time ();
    2513                 :           1 :   bytes = g_socket_receive_bytes_from (client, &sender_addr, 500, 10, NULL, &error);
    2514                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
    2515                 :           1 :   g_assert_null (bytes);
    2516                 :           1 :   g_assert_null (sender_addr);
    2517                 :           1 :   g_assert_cmpint (g_get_real_time () - time_start, <, g_socket_get_timeout (client) * G_USEC_PER_SEC);
    2518                 :           1 :   g_clear_error (&error);
    2519                 :             : 
    2520                 :             :   /* And try receiving when already cancelled. */
    2521                 :           1 :   cancellable = g_cancellable_new ();
    2522                 :           1 :   g_cancellable_cancel (cancellable);
    2523                 :           1 :   bytes = g_socket_receive_bytes_from (client, &sender_addr, 500, -1, cancellable, &error);
    2524                 :           1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
    2525                 :           1 :   g_assert_null (bytes);
    2526                 :           1 :   g_assert_null (sender_addr);
    2527                 :           1 :   g_clear_error (&error);
    2528                 :           1 :   g_clear_object (&cancellable);
    2529                 :             : 
    2530                 :             :   /* Tidy up. */
    2531                 :           1 :   g_socket_close (client, &error);
    2532                 :           1 :   g_assert_no_error (error);
    2533                 :             : 
    2534                 :           1 :   g_cancellable_cancel (data->cancellable);
    2535                 :           1 :   g_thread_join (data->thread);
    2536                 :             : 
    2537                 :           1 :   g_socket_close (data->server, &error);
    2538                 :           1 :   g_assert_no_error (error);
    2539                 :             : 
    2540                 :           1 :   g_object_unref (dest_addr);
    2541                 :           1 :   g_object_unref (client);
    2542                 :             : 
    2543                 :           1 :   ip_test_data_free (data);
    2544                 :             : }
    2545                 :             : 
    2546                 :             : int
    2547                 :           1 : main (int   argc,
    2548                 :             :       char *argv[])
    2549                 :             : {
    2550                 :             :   GSocket *sock;
    2551                 :           1 :   GError *error = NULL;
    2552                 :             : 
    2553                 :           1 :   g_test_init (&argc, &argv, NULL);
    2554                 :             : 
    2555                 :           1 :   sock = g_socket_new (G_SOCKET_FAMILY_IPV6,
    2556                 :             :                        G_SOCKET_TYPE_STREAM,
    2557                 :             :                        G_SOCKET_PROTOCOL_DEFAULT,
    2558                 :             :                        &error);
    2559                 :           1 :   if (sock != NULL)
    2560                 :             :     {
    2561                 :           1 :       ipv6_supported = TRUE;
    2562                 :           1 :       g_object_unref (sock);
    2563                 :             :     }
    2564                 :             :   else
    2565                 :             :     {
    2566                 :           0 :       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
    2567                 :           0 :       g_clear_error (&error);
    2568                 :             :     }
    2569                 :             : 
    2570                 :           1 :   g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync);
    2571                 :           1 :   g_test_add_func ("/socket/ipv4_async", test_ipv4_async);
    2572                 :           1 :   g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync);
    2573                 :           1 :   g_test_add_func ("/socket/ipv6_async", test_ipv6_async);
    2574                 :           1 :   g_test_add_func ("/socket/ipv4_sync/datagram", test_ipv4_sync_dgram);
    2575                 :           1 :   g_test_add_func ("/socket/ipv4_sync/datagram/timeouts", test_ipv4_sync_dgram_timeouts);
    2576                 :           1 :   g_test_add_func ("/socket/ipv6_sync/datagram", test_ipv6_sync_dgram);
    2577                 :           1 :   g_test_add_func ("/socket/ipv6_sync/datagram/timeouts", test_ipv6_sync_dgram_timeouts);
    2578                 :             : #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
    2579                 :           1 :   g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped);
    2580                 :             : #endif
    2581                 :           1 :   g_test_add_func ("/socket/close_graceful", test_close_graceful);
    2582                 :           1 :   g_test_add_func ("/socket/timed_wait", test_timed_wait);
    2583                 :           1 :   g_test_add_func ("/socket/fd_reuse", test_fd_reuse);
    2584                 :           1 :   g_test_add_func ("/socket/address", test_sockaddr);
    2585                 :           1 :   g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
    2586                 :           1 :   g_test_add_func ("/socket/unix-connection", test_unix_connection);
    2587                 :             : #ifdef G_OS_UNIX
    2588                 :           1 :   g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
    2589                 :             : #endif
    2590                 :             : #ifdef G_OS_WIN32
    2591                 :             :   g_test_add_func ("/socket/win32-handle-not-socket", test_handle_not_socket);
    2592                 :             : #endif
    2593                 :           1 :   g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
    2594                 :           1 :   g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
    2595                 :           1 :   g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
    2596                 :           1 :   g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM),
    2597                 :             :                         test_get_available);
    2598                 :           1 :   g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM),
    2599                 :             :                         test_get_available);
    2600                 :           1 :   g_test_add_data_func ("/socket/read_write", GUINT_TO_POINTER (FALSE),
    2601                 :             :                         test_read_write);
    2602                 :           1 :   g_test_add_data_func ("/socket/read_writev", GUINT_TO_POINTER (TRUE),
    2603                 :             :                         test_read_write);
    2604                 :             : #ifdef SO_NOSIGPIPE
    2605                 :             :   g_test_add_func ("/socket/nosigpipe", test_nosigpipe);
    2606                 :             : #endif
    2607                 :             : #if G_CREDENTIALS_SUPPORTED
    2608                 :           1 :   g_test_add_func ("/socket/credentials/tcp_client", test_credentials_tcp_client);
    2609                 :           1 :   g_test_add_func ("/socket/credentials/tcp_server", test_credentials_tcp_server);
    2610                 :           1 :   g_test_add_func ("/socket/credentials/unix_socketpair", test_credentials_unix_socketpair);
    2611                 :             : #endif
    2612                 :           1 :   g_test_add_func ("/socket/receive_bytes", test_receive_bytes);
    2613                 :           1 :   g_test_add_func ("/socket/receive_bytes_from", test_receive_bytes_from);
    2614                 :             : 
    2615                 :           1 :   return g_test_run();
    2616                 :             : }
        

Generated by: LCOV version 2.0-1