g-icon: Fix memory leak in test
[platform/upstream/glib.git] / gio / tests / socket.c
1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2008-2011 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <gio/gio.h>
22
23 #ifdef G_OS_UNIX
24 #include <errno.h>
25 #include <sys/wait.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <gio/gnetworking.h>
29 #include <gio/gunixconnection.h>
30 #endif
31
32 #include "gnetworkingprivate.h"
33
34 typedef struct {
35   GSocket *server;
36   GSocket *client;
37   GSocketFamily family;
38   GThread *thread;
39   GMainLoop *loop;
40 } IPTestData;
41
42 static gpointer
43 echo_server_thread (gpointer user_data)
44 {
45   IPTestData *data = user_data;
46   GSocket *sock;
47   GError *error = NULL;
48   gssize nread, nwrote;
49   gchar buf[128];
50
51   sock = g_socket_accept (data->server, NULL, &error);
52   g_assert_no_error (error);
53
54   while (TRUE)
55     {
56       nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
57       g_assert_no_error (error);
58       g_assert_cmpint (nread, >=, 0);
59
60       if (nread == 0)
61         break;
62
63       nwrote = g_socket_send (sock, buf, nread, NULL, &error);
64       g_assert_no_error (error);
65       g_assert_cmpint (nwrote, ==, nread);
66     }
67
68   g_socket_close (sock, &error);
69   g_assert_no_error (error);
70   g_object_unref (sock);
71   return NULL;
72 }
73
74 static IPTestData *
75 create_server (GSocketFamily family,
76                GThreadFunc   server_thread,
77                gboolean      v4mapped)
78 {
79   IPTestData *data;
80   GSocket *server;
81   GError *error = NULL;
82   GSocketAddress *addr;
83   GInetAddress *iaddr;
84
85   data = g_slice_new (IPTestData);
86   data->family = family;
87
88   data->server = server = g_socket_new (family,
89                                         G_SOCKET_TYPE_STREAM,
90                                         G_SOCKET_PROTOCOL_DEFAULT,
91                                         &error);
92   g_assert_no_error (error);
93
94   g_assert_cmpint (g_socket_get_family (server), ==, family);
95   g_assert_cmpint (g_socket_get_socket_type (server), ==, G_SOCKET_TYPE_STREAM);
96   g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
97
98   g_socket_set_blocking (server, TRUE);
99
100 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
101   if (v4mapped)
102     {
103       g_socket_set_option (data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL);
104       if (! g_socket_speaks_ipv4 (data->server))
105         {
106           g_object_unref (data->server);
107           g_slice_free (IPTestData, data);
108           return NULL;
109         }
110     }
111 #endif
112
113   if (v4mapped)
114     iaddr = g_inet_address_new_any (family);
115   else
116     iaddr = g_inet_address_new_loopback (family);
117   addr = g_inet_socket_address_new (iaddr, 0);
118   g_object_unref (iaddr);
119
120   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0);
121   g_socket_bind (server, addr, TRUE, &error);
122   g_assert_no_error (error);
123   g_object_unref (addr);
124
125   addr = g_socket_get_local_address (server, &error);
126   g_assert_no_error (error);
127   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0);
128   g_object_unref (addr);
129
130   g_socket_listen (server, &error);
131   g_assert_no_error (error);
132
133   data->thread = g_thread_new ("server", server_thread, data);
134
135   return data;
136 }
137
138 static const gchar *testbuf = "0123456789abcdef";
139
140 static gboolean
141 test_ip_async_read_ready (GSocket      *client,
142                           GIOCondition  cond,
143                           gpointer      user_data)
144 {
145   IPTestData *data = user_data;
146   GError *error = NULL;
147   gssize len;
148   gchar buf[128];
149
150   g_assert_cmpint (cond, ==, G_IO_IN);
151
152   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
153   g_assert_no_error (error);
154   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
155
156   g_assert_cmpstr (testbuf, ==, buf);
157
158   g_main_loop_quit (data->loop);
159
160   return FALSE;
161 }
162
163 static gboolean
164 test_ip_async_write_ready (GSocket      *client,
165                            GIOCondition  cond,
166                            gpointer      user_data)
167 {
168   IPTestData *data = user_data;
169   GError *error = NULL;
170   GSource *source;
171   gssize len;
172
173   g_assert_cmpint (cond, ==, G_IO_OUT);
174
175   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
176   g_assert_no_error (error);
177   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
178
179   source = g_socket_create_source (client, G_IO_IN, NULL);
180   g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready,
181                          data, NULL);
182   g_source_attach (source, NULL);
183   g_source_unref (source);
184
185   return FALSE;
186 }
187
188 static gboolean
189 test_ip_async_timed_out (GSocket      *client,
190                          GIOCondition  cond,
191                          gpointer      user_data)
192 {
193   IPTestData *data = user_data;
194   GError *error = NULL;
195   GSource *source;
196   gssize len;
197   gchar buf[128];
198
199   if (data->family == G_SOCKET_FAMILY_IPV4)
200     {
201       g_assert_cmpint (cond, ==, G_IO_IN);
202       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
203       g_assert_cmpint (len, ==, -1);
204       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
205       g_clear_error (&error);
206     }
207
208   source = g_socket_create_source (client, G_IO_OUT, NULL);
209   g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready,
210                          data, NULL);
211   g_source_attach (source, NULL);
212   g_source_unref (source);
213
214   return FALSE;
215 }
216
217 static gboolean
218 test_ip_async_connected (GSocket      *client,
219                          GIOCondition  cond,
220                          gpointer      user_data)
221 {
222   IPTestData *data = user_data;
223   GError *error = NULL;
224   GSource *source;
225   gssize len;
226   gchar buf[128];
227
228   g_socket_check_connect_result (client, &error);
229   g_assert_no_error (error);
230   /* We do this after the check_connect_result, since that will give a
231    * more useful assertion in case of error.
232    */
233   g_assert_cmpint (cond, ==, G_IO_OUT);
234
235   g_assert (g_socket_is_connected (client));
236
237   /* This adds 1 second to "make check", so let's just only do it once. */
238   if (data->family == G_SOCKET_FAMILY_IPV4)
239     {
240       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
241       g_assert_cmpint (len, ==, -1);
242       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
243       g_clear_error (&error);
244
245       source = g_socket_create_source (client, G_IO_IN, NULL);
246       g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out,
247                              data, NULL);
248       g_source_attach (source, NULL);
249       g_source_unref (source);
250     }
251   else
252     test_ip_async_timed_out (client, 0, data);
253
254   return FALSE;
255 }
256
257 static gboolean
258 idle_test_ip_async_connected (gpointer user_data)
259 {
260   IPTestData *data = user_data;
261
262   return test_ip_async_connected (data->client, G_IO_OUT, data);
263 }
264
265 static void
266 test_ip_async (GSocketFamily family)
267 {
268   IPTestData *data;
269   GError *error = NULL;
270   GSocket *client;
271   GSocketAddress *addr;
272   GSource *source;
273   gssize len;
274   gchar buf[128];
275
276   data = create_server (family, echo_server_thread, FALSE);
277   addr = g_socket_get_local_address (data->server, &error);
278
279   client = g_socket_new (family,
280                          G_SOCKET_TYPE_STREAM,
281                          G_SOCKET_PROTOCOL_DEFAULT,
282                          &error);
283   g_assert_no_error (error);
284   data->client = client;
285
286   g_assert_cmpint (g_socket_get_family (client), ==, family);
287   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
288   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
289
290   g_socket_set_blocking (client, FALSE);
291   g_socket_set_timeout (client, 1);
292
293   if (g_socket_connect (client, addr, NULL, &error))
294     {
295       g_assert_no_error (error);
296       g_idle_add (idle_test_ip_async_connected, data);
297     }
298   else
299     {
300       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
301       g_clear_error (&error);
302       source = g_socket_create_source (client, G_IO_OUT, NULL);
303       g_source_set_callback (source, (GSourceFunc)test_ip_async_connected,
304                              data, NULL);
305       g_source_attach (source, NULL);
306       g_source_unref (source);
307     }
308   g_object_unref (addr);
309
310   data->loop = g_main_loop_new (NULL, TRUE);
311   g_main_loop_run (data->loop);
312   g_main_loop_unref (data->loop);
313
314   g_socket_shutdown (client, FALSE, TRUE, &error);
315   g_assert_no_error (error);
316
317   g_thread_join (data->thread);
318
319   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
320   g_assert_no_error (error);
321   g_assert_cmpint (len, ==, 0);
322
323   g_socket_close (client, &error);
324   g_assert_no_error (error);
325   g_socket_close (data->server, &error);
326   g_assert_no_error (error);
327
328   g_object_unref (data->server);
329   g_object_unref (client);
330
331   g_slice_free (IPTestData, data);
332 }
333
334 static void
335 test_ipv4_async (void)
336 {
337   test_ip_async (G_SOCKET_FAMILY_IPV4);
338 }
339
340 static void
341 test_ipv6_async (void)
342 {
343   test_ip_async (G_SOCKET_FAMILY_IPV6);
344 }
345
346 static void
347 test_ip_sync (GSocketFamily family)
348 {
349   IPTestData *data;
350   GError *error = NULL;
351   GSocket *client;
352   GSocketAddress *addr;
353   gssize len;
354   gchar buf[128];
355
356   data = create_server (family, echo_server_thread, FALSE);
357   addr = g_socket_get_local_address (data->server, &error);
358
359   client = g_socket_new (family,
360                          G_SOCKET_TYPE_STREAM,
361                          G_SOCKET_PROTOCOL_DEFAULT,
362                          &error);
363   g_assert_no_error (error);
364
365   g_assert_cmpint (g_socket_get_family (client), ==, family);
366   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
367   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
368
369   g_socket_set_blocking (client, TRUE);
370   g_socket_set_timeout (client, 1);
371
372   g_socket_connect (client, addr, NULL, &error);
373   g_assert_no_error (error);
374   g_assert (g_socket_is_connected (client));
375   g_object_unref (addr);
376
377   /* This adds 1 second to "make check", so let's just only do it once. */
378   if (family == G_SOCKET_FAMILY_IPV4)
379     {
380       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
381       g_assert_cmpint (len, ==, -1);
382       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
383       g_clear_error (&error);
384     }
385
386   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
387   g_assert_no_error (error);
388   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
389   
390   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
391   g_assert_no_error (error);
392   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
393
394   g_assert_cmpstr (testbuf, ==, buf);
395
396   g_socket_shutdown (client, FALSE, TRUE, &error);
397   g_assert_no_error (error);
398
399   g_thread_join (data->thread);
400
401   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
402   g_assert_no_error (error);
403   g_assert_cmpint (len, ==, 0);
404
405   g_socket_close (client, &error);
406   g_assert_no_error (error);
407   g_socket_close (data->server, &error);
408   g_assert_no_error (error);
409
410   g_object_unref (data->server);
411   g_object_unref (client);
412
413   g_slice_free (IPTestData, data);
414 }
415
416 static void
417 test_ipv4_sync (void)
418 {
419   test_ip_sync (G_SOCKET_FAMILY_IPV4);
420 }
421
422 static void
423 test_ipv6_sync (void)
424 {
425   test_ip_sync (G_SOCKET_FAMILY_IPV6);
426 }
427
428 static gpointer
429 graceful_server_thread (gpointer user_data)
430 {
431   IPTestData *data = user_data;
432   GSocket *sock;
433   GError *error = NULL;
434   gssize len;
435
436   sock = g_socket_accept (data->server, NULL, &error);
437   g_assert_no_error (error);
438
439   len = g_socket_send (sock, testbuf, strlen (testbuf) + 1, NULL, &error);
440   g_assert_no_error (error);
441   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
442
443   return sock;
444 }
445
446 static void
447 test_close_graceful (void)
448 {
449   GSocketFamily family = G_SOCKET_FAMILY_IPV4;
450   IPTestData *data;
451   GError *error = NULL;
452   GSocket *client, *server;
453   GSocketAddress *addr;
454   gssize len;
455   gchar buf[128];
456
457   data = create_server (family, graceful_server_thread, FALSE);
458   addr = g_socket_get_local_address (data->server, &error);
459
460   client = g_socket_new (family,
461                          G_SOCKET_TYPE_STREAM,
462                          G_SOCKET_PROTOCOL_DEFAULT,
463                          &error);
464   g_assert_no_error (error);
465
466   g_assert_cmpint (g_socket_get_family (client), ==, family);
467   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
468   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
469
470   g_socket_set_blocking (client, TRUE);
471   g_socket_set_timeout (client, 1);
472
473   g_socket_connect (client, addr, NULL, &error);
474   g_assert_no_error (error);
475   g_assert (g_socket_is_connected (client));
476   g_object_unref (addr);
477
478   server = g_thread_join (data->thread);
479
480   /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */
481   g_socket_shutdown (server, FALSE, TRUE, &error);
482   g_assert_no_error (error);
483
484   /* we must timeout */
485   g_socket_condition_wait (client, G_IO_HUP, NULL, &error);
486   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
487   g_clear_error (&error);
488
489   /* check that the remaining data is received */
490   len = g_socket_receive (client, buf, strlen (testbuf) + 1, NULL, &error);
491   g_assert_no_error (error);
492   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
493
494   /* and only then the connection is closed */
495   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
496   g_assert_no_error (error);
497   g_assert_cmpint (len, ==, 0);
498
499   g_socket_close (server, &error);
500   g_assert_no_error (error);
501
502   g_socket_close (client, &error);
503   g_assert_no_error (error);
504
505   g_object_unref (server);
506   g_object_unref (data->server);
507   g_object_unref (client);
508
509   g_slice_free (IPTestData, data);
510 }
511
512 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
513 static gpointer
514 v4mapped_server_thread (gpointer user_data)
515 {
516   IPTestData *data = user_data;
517   GSocket *sock;
518   GError *error = NULL;
519   GSocketAddress *addr;
520
521   sock = g_socket_accept (data->server, NULL, &error);
522   g_assert_no_error (error);
523
524   g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6);
525
526   addr = g_socket_get_local_address (sock, &error);
527   g_assert_no_error (error);
528   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
529   g_object_unref (addr);
530
531   addr = g_socket_get_remote_address (sock, &error);
532   g_assert_no_error (error);
533   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
534   g_object_unref (addr);
535
536   g_socket_close (sock, &error);
537   g_assert_no_error (error);
538   g_object_unref (sock);
539   return NULL;
540 }
541
542 static void
543 test_ipv6_v4mapped (void)
544 {
545   IPTestData *data;
546   GError *error = NULL;
547   GSocket *client;
548   GSocketAddress *addr, *v4addr;
549   GInetAddress *iaddr;
550
551   data = create_server (G_SOCKET_FAMILY_IPV6, v4mapped_server_thread, TRUE);
552
553   if (data == NULL)
554     {
555       g_test_message ("Test not run: not supported by the OS");
556       return;
557     }
558
559   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
560                          G_SOCKET_TYPE_STREAM,
561                          G_SOCKET_PROTOCOL_DEFAULT,
562                          &error);
563   g_assert_no_error (error);
564
565   g_socket_set_blocking (client, TRUE);
566   g_socket_set_timeout (client, 1);
567
568   addr = g_socket_get_local_address (data->server, &error);
569   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
570   v4addr = g_inet_socket_address_new (iaddr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)));
571   g_object_unref (iaddr);
572   g_object_unref (addr);
573
574   g_socket_connect (client, v4addr, NULL, &error);
575   g_assert_no_error (error);
576   g_assert (g_socket_is_connected (client));
577
578   g_thread_join (data->thread);
579
580   g_socket_close (client, &error);
581   g_assert_no_error (error);
582   g_socket_close (data->server, &error);
583   g_assert_no_error (error);
584
585   g_object_unref (data->server);
586   g_object_unref (client);
587   g_object_unref (v4addr);
588
589   g_slice_free (IPTestData, data);
590 }
591 #endif
592
593 static void
594 test_timed_wait (void)
595 {
596   IPTestData *data;
597   GError *error = NULL;
598   GSocket *client;
599   GSocketAddress *addr;
600   gint64 start_time;
601   gint poll_duration;
602
603   data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE);
604   addr = g_socket_get_local_address (data->server, &error);
605
606   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
607                          G_SOCKET_TYPE_STREAM,
608                          G_SOCKET_PROTOCOL_DEFAULT,
609                          &error);
610   g_assert_no_error (error);
611
612   g_socket_set_blocking (client, TRUE);
613   g_socket_set_timeout (client, 1);
614
615   g_socket_connect (client, addr, NULL, &error);
616   g_assert_no_error (error);
617   g_object_unref (addr);
618
619   start_time = g_get_monotonic_time ();
620   g_socket_condition_timed_wait (client, G_IO_IN, 100000 /* 100 ms */,
621                                  NULL, &error);
622   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
623   g_clear_error (&error);
624   poll_duration = g_get_monotonic_time () - start_time;
625
626   g_assert_cmpint (poll_duration, >=, 98000);
627   g_assert_cmpint (poll_duration, <, 112000);
628
629   g_socket_close (client, &error);
630   g_assert_no_error (error);
631
632   g_thread_join (data->thread);
633
634   g_socket_close (data->server, &error);
635   g_assert_no_error (error);
636
637   g_object_unref (data->server);
638   g_object_unref (client);
639
640   g_slice_free (IPTestData, data);
641 }
642
643 static void
644 test_sockaddr (void)
645 {
646   struct sockaddr_in6 sin6, gsin6;
647   GSocketAddress *saddr;
648   GInetSocketAddress *isaddr;
649   GInetAddress *iaddr;
650   GError *error = NULL;
651
652   memset (&sin6, 0, sizeof (sin6));
653   sin6.sin6_family = AF_INET6;
654   sin6.sin6_addr = in6addr_loopback;
655   sin6.sin6_port = g_htons (42);
656   sin6.sin6_scope_id = 17;
657   sin6.sin6_flowinfo = 1729;
658
659   saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6));
660   g_assert (G_IS_INET_SOCKET_ADDRESS (saddr));
661
662   isaddr = G_INET_SOCKET_ADDRESS (saddr);
663   iaddr = g_inet_socket_address_get_address (isaddr);
664   g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6);
665   g_assert (g_inet_address_get_is_loopback (iaddr));
666
667   g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42);
668   g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17);
669   g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729);
670
671   g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error);
672   g_assert_no_error (error);
673
674   g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0);
675   g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port);
676   g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id);
677   g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
678
679   g_object_unref (saddr);
680 }
681
682 #ifdef G_OS_UNIX
683 static void
684 test_unix_from_fd (void)
685 {
686   gint fd;
687   GError *error;
688   GSocket *s;
689
690   fd = socket (AF_UNIX, SOCK_STREAM, 0);
691   g_assert_cmpint (fd, !=, -1);
692
693   error = NULL;
694   s = g_socket_new_from_fd (fd, &error);
695   g_assert_no_error (error);
696   g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX);
697   g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
698   g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
699   g_object_unref (s);
700 }
701
702 static void
703 test_unix_connection (void)
704 {
705   gint fd;
706   GError *error;
707   GSocket *s;
708   GSocketConnection *c;
709
710   fd = socket (AF_UNIX, SOCK_STREAM, 0);
711   g_assert_cmpint (fd, !=, -1);
712
713   error = NULL;
714   s = g_socket_new_from_fd (fd, &error);
715   g_assert_no_error (error);
716   c = g_socket_connection_factory_create_connection (s);
717   g_assert (G_IS_UNIX_CONNECTION (c));
718   g_object_unref (c);
719   g_object_unref (s);
720 }
721
722 static GSocketConnection *
723 create_connection_for_fd (int fd)
724 {
725   GError *err = NULL;
726   GSocket *socket;
727   GSocketConnection *connection;
728
729   socket = g_socket_new_from_fd (fd, &err);
730   g_assert_no_error (err);
731   g_assert (G_IS_SOCKET (socket));
732   connection = g_socket_connection_factory_create_connection (socket);
733   g_assert (G_IS_UNIX_CONNECTION (connection));
734   g_object_unref (socket);
735   return connection;
736 }
737
738 #define TEST_DATA "failure to say failure to say 'i love gnome-panel!'."
739
740 static void
741 test_unix_connection_ancillary_data (void)
742 {
743   GError *err = NULL;
744   gint pv[2], sv[3];
745   gint status, fd, len;
746   char buffer[1024];
747   pid_t pid;
748
749   status = pipe (pv);
750   g_assert_cmpint (status, ==, 0);
751
752   status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
753   g_assert_cmpint (status, ==, 0);
754
755   pid = fork ();
756   g_assert_cmpint (pid, >=, 0);
757
758   /* Child: close its copy of the write end of the pipe, receive it
759    * again from the parent over the socket, and write some text to it.
760    *
761    * Parent: send the write end of the pipe (still open for the
762    * parent) over the socket, close it, and read some text from the
763    * read end of the pipe.
764    */
765   if (pid == 0)
766     {
767       GSocketConnection *connection;
768
769       close (sv[1]);
770       connection = create_connection_for_fd (sv[0]);
771
772       status = close (pv[1]);
773       g_assert_cmpint (status, ==, 0);
774
775       err = NULL;
776       fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL,
777                                          &err);
778       g_assert_no_error (err);
779       g_assert_cmpint (fd, >, -1);
780       g_object_unref (connection);
781
782       do
783         len = write (fd, TEST_DATA, sizeof (TEST_DATA));
784       while (len == -1 && errno == EINTR);
785       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
786       exit (0);
787     }
788   else
789     {
790       GSocketConnection *connection;
791
792       close (sv[0]);
793       connection = create_connection_for_fd (sv[1]);
794
795       err = NULL;
796       g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL,
797                                  &err);
798       g_assert_no_error (err);
799       g_object_unref (connection);
800
801       status = close (pv[1]);
802       g_assert_cmpint (status, ==, 0);
803
804       memset (buffer, 0xff, sizeof buffer);
805       do
806         len = read (pv[0], buffer, sizeof buffer);
807       while (len == -1 && errno == EINTR);
808
809       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
810       g_assert_cmpstr (buffer, ==, TEST_DATA);
811
812       waitpid (pid, &status, 0);
813       g_assert (WIFEXITED (status));
814       g_assert_cmpint (WEXITSTATUS (status), ==, 0);
815     }
816
817   /* TODO: add test for g_unix_connection_send_credentials() and
818    * g_unix_connection_receive_credentials().
819    */
820 }
821 #endif /* G_OS_UNIX */
822
823 static void
824 test_reuse_tcp (void)
825 {
826   GSocket *sock1, *sock2;
827   GError *error = NULL;
828   GInetAddress *iaddr;
829   GSocketAddress *addr;
830
831   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
832                         G_SOCKET_TYPE_STREAM,
833                         G_SOCKET_PROTOCOL_DEFAULT,
834                         &error);
835   g_assert_no_error (error);
836
837   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
838   addr = g_inet_socket_address_new (iaddr, 0);
839   g_object_unref (iaddr);
840   g_socket_bind (sock1, addr, TRUE, &error);
841   g_object_unref (addr);
842   g_assert_no_error (error);
843
844   g_socket_listen (sock1, &error);
845   g_assert_no_error (error);
846
847   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
848                         G_SOCKET_TYPE_STREAM,
849                         G_SOCKET_PROTOCOL_DEFAULT,
850                         &error);
851   g_assert_no_error (error);
852
853   addr = g_socket_get_local_address (sock1, &error);
854   g_assert_no_error (error);
855   g_socket_bind (sock2, addr, TRUE, &error);
856   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
857   g_object_unref (addr);
858
859   g_object_unref (sock1);
860   g_object_unref (sock2);
861 }
862
863 static void
864 test_reuse_udp (void)
865 {
866   GSocket *sock1, *sock2;
867   GError *error = NULL;
868   GInetAddress *iaddr;
869   GSocketAddress *addr;
870
871   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
872                         G_SOCKET_TYPE_DATAGRAM,
873                         G_SOCKET_PROTOCOL_DEFAULT,
874                         &error);
875   g_assert_no_error (error);
876
877   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
878   addr = g_inet_socket_address_new (iaddr, 0);
879   g_object_unref (iaddr);
880   g_socket_bind (sock1, addr, TRUE, &error);
881   g_object_unref (addr);
882   g_assert_no_error (error);
883
884   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
885                         G_SOCKET_TYPE_DATAGRAM,
886                         G_SOCKET_PROTOCOL_DEFAULT,
887                         &error);
888   g_assert_no_error (error);
889
890   addr = g_socket_get_local_address (sock1, &error);
891   g_assert_no_error (error);
892   g_socket_bind (sock2, addr, TRUE, &error);
893   g_object_unref (addr);
894   g_assert_no_error (error);
895
896   g_object_unref (sock1);
897   g_object_unref (sock2);
898 }
899
900 static void
901 test_datagram_get_available (void)
902 {
903   GError *err = NULL;
904   GSocket *server, *client;
905   GInetAddress *addr;
906   GSocketAddress *saddr;
907   gchar data[] = "0123456789abcdef";
908   gchar buf[34];
909   gssize nread;
910
911   server = g_socket_new (G_SOCKET_FAMILY_IPV4,
912                                 G_SOCKET_TYPE_DATAGRAM,
913                                 G_SOCKET_PROTOCOL_DEFAULT,
914                                 &err);
915   g_assert_no_error (err);
916   g_assert (G_IS_SOCKET (server));
917
918   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
919                          G_SOCKET_TYPE_DATAGRAM,
920                          G_SOCKET_PROTOCOL_DEFAULT,
921                          &err);
922   g_assert_no_error (err);
923   g_assert (G_IS_SOCKET (client));
924
925   addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
926   saddr = g_inet_socket_address_new (addr, 0);
927
928   g_socket_bind (server, saddr, TRUE, &err);
929   g_assert_no_error (err);
930   g_object_unref (saddr);
931   g_object_unref (addr);
932
933   saddr = g_socket_get_local_address (server, &err);
934   g_assert_no_error (err);
935
936   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
937   g_assert_no_error (err);
938
939   while (!g_socket_condition_wait (server, G_IO_IN, NULL, NULL))
940     ;
941   g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
942
943   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
944   g_assert_no_error (err);
945
946   /* g_socket_condition_wait() won't help here since the socket is
947    * definitely already readable. So there's a race condition here, but
948    * at least the failure mode is passes-when-it-shouldn't, not
949    * fails-when-it-shouldn't.
950    */
951   g_usleep (100000);
952   g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
953
954   g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data));
955   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
956   g_assert_cmpint (nread, ==, sizeof (data));
957   g_assert_no_error (err);
958
959   g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
960
961   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
962   g_assert_cmpint (nread, ==, sizeof (data));
963   g_assert_no_error (err);
964
965   g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
966
967   g_socket_close (server, &err);
968   g_assert_no_error (err);
969
970   g_object_unref (saddr);
971   g_object_unref (server);
972   g_object_unref (client);
973 }
974
975 int
976 main (int   argc,
977       char *argv[])
978 {
979   g_test_init (&argc, &argv, NULL);
980
981   g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync);
982   g_test_add_func ("/socket/ipv4_async", test_ipv4_async);
983   g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync);
984   g_test_add_func ("/socket/ipv6_async", test_ipv6_async);
985 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
986   g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped);
987 #endif
988   g_test_add_func ("/socket/close_graceful", test_close_graceful);
989   g_test_add_func ("/socket/timed_wait", test_timed_wait);
990   g_test_add_func ("/socket/address", test_sockaddr);
991 #ifdef G_OS_UNIX
992   g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
993   g_test_add_func ("/socket/unix-connection", test_unix_connection);
994   g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
995 #endif
996   g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
997   g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
998   g_test_add_func ("/socket/datagram_get_available", test_datagram_get_available);
999
1000   return g_test_run();
1001 }
1002