mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 08:22:16 +01:00 
			
		
		
		
	Install a public "gnetworking.h" header that can be used to include the relevant OS-dependent networking headers. This does not really abstract away unix-vs-windows however; error codes, in particular, are incompatible. gnetworkingprivate.h now contains just a few internal URI-related functions Also add a g_networking_init() function to gnetworking.h, which can be used to explicitly initialize OS-level networking, rather than having that happen as a side-effect of registering GInetAddress. https://bugzilla.gnome.org/show_bug.cgi?id=623187
		
			
				
	
	
		
			243 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <gio/gio.h>
 | |
| #include <gio/gnetworking.h>
 | |
| #include <gio/gunixfdmessage.h>
 | |
| #include <gio/gunixsocketaddress.h>
 | |
| #include <string.h>
 | |
| #include <unistd.h>
 | |
| 
 | |
| /* ensures that no FDs are left open at the end */
 | |
| static void
 | |
| check_fd_list (const gint *fd_list)
 | |
| {
 | |
|   gint i;
 | |
| 
 | |
|   for (i = 0; i < 40; i++)
 | |
|     {
 | |
|       int my_fd;
 | |
| 
 | |
|       my_fd = dup (0);
 | |
|       g_assert_cmpint (fd_list[i], ==, my_fd);
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < 40; i++)
 | |
|     close (fd_list[i]);
 | |
| }
 | |
| 
 | |
| static void
 | |
| create_fd_list (gint *fd_list)
 | |
| {
 | |
|   gint i;
 | |
| 
 | |
|   for (i = 0; i < 40; i++)
 | |
|     {
 | |
|       fd_list[i] = dup (0);
 | |
|       g_assert_cmpint (fd_list[i], >, 0);
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < 40; i++)
 | |
|     close (fd_list[i]);
 | |
| }
 | |
| 
 | |
| static void
 | |
| test_fds (void)
 | |
| {
 | |
|   GError *err = NULL;
 | |
|   GUnixFDMessage *message;
 | |
|   GUnixFDMessage **mv;
 | |
|   GUnixFDList *list, *l2;
 | |
|   GSocket *sockets[2];
 | |
|   GSocketAddress *addr;
 | |
|   const gint *peek;
 | |
|   char buffer[1024];
 | |
|   gint fd_list[40];
 | |
|   GOutputVector ov;
 | |
|   GInputVector iv;
 | |
|   gint *stolen;
 | |
|   gint sv[3];
 | |
|   gint flags;
 | |
|   gint nm;
 | |
|   gint s;
 | |
|   gchar *path;
 | |
|   GByteArray *array;
 | |
|   gboolean abstract;
 | |
|   GUnixSocketAddressType type;
 | |
| 
 | |
|   create_fd_list (fd_list);
 | |
| 
 | |
|   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   sv[2] = -1;
 | |
| 
 | |
|   list = g_unix_fd_list_new_from_array (sv, -1);
 | |
|   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new_with_fd_list (list));
 | |
|   g_object_unref (list);
 | |
| 
 | |
|   g_assert (g_unix_fd_message_get_fd_list (message) == list);
 | |
|   g_object_get (message, "fd-list", &l2, NULL);
 | |
|   g_assert (l2 == list);
 | |
|   g_assert_cmpint (g_unix_fd_list_get_length (list), ==, 2);
 | |
| 
 | |
|   peek = g_unix_fd_list_peek_fds (list, &s);
 | |
|   g_assert_cmpint (s, ==, 2);
 | |
|   stolen = g_unix_fd_message_steal_fds (message, &s);
 | |
|   g_assert_cmpint (s, ==, 2);
 | |
|   g_assert (stolen == peek);
 | |
| 
 | |
|   g_assert_cmpint (stolen[0], ==, sv[0]);
 | |
|   g_assert_cmpint (stolen[1], ==, sv[1]);
 | |
|   g_assert_cmpint (stolen[2], ==, sv[2]);
 | |
|   g_free (stolen);
 | |
| 
 | |
|   g_unix_fd_message_append_fd (message, sv[0], &err);
 | |
|   g_assert_no_error (err);
 | |
|   s = close (sv[0]);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   g_unix_fd_message_append_fd (message, sv[1], &err);
 | |
|   g_assert_no_error (err);
 | |
|   s = close (sv[1]);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
| 
 | |
|   s = close (g_unix_fd_list_get (list, 0, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 1, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 0, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 1, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 0, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 1, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
| 
 | |
|   g_object_unref (message);
 | |
|   g_object_unref (list);
 | |
| 
 | |
|   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new ());
 | |
|   list = g_unix_fd_message_get_fd_list (message);
 | |
|   s = pipe (sv);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
| 
 | |
|   s = g_unix_fd_list_append (list, sv[0], &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, >=, 0);
 | |
|   s = g_unix_fd_list_append (list, sv[1], &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, >=, 0);
 | |
| 
 | |
|   s = close (sv[0]);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (sv[1]);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 0, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
|   s = close (g_unix_fd_list_get (list, 1, &err));
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
| 
 | |
|   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
 | |
|   g_assert_cmpint (s, ==, 0);
 | |
| 
 | |
|   sockets[0] = g_socket_new_from_fd (sv[0], &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert (G_IS_SOCKET (sockets[0]));
 | |
|   sockets[1] = g_socket_new_from_fd (sv[1], &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert (G_IS_SOCKET (sockets[1]));
 | |
| 
 | |
|   addr = g_socket_get_local_address (sockets[0], &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert (G_IS_UNIX_SOCKET_ADDRESS (addr));
 | |
|   g_assert_cmpint (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (addr)), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
 | |
|   g_assert_cmpint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (addr)), ==, 0);
 | |
| 
 | |
| G_GNUC_BEGIN_IGNORE_DEPRECATIONS
 | |
|   g_assert (!g_unix_socket_address_get_is_abstract (G_UNIX_SOCKET_ADDRESS (addr)));
 | |
| G_GNUC_END_IGNORE_DEPRECATIONS
 | |
| 
 | |
|   g_object_get (addr,
 | |
|                 "path", &path,
 | |
|                 "path-as-array", &array,
 | |
|                 "abstract", &abstract,
 | |
|                 "address-type", &type,
 | |
|                 NULL);
 | |
|   g_assert_cmpstr (path, ==, "");
 | |
|   g_assert_cmpint (array->len, ==, 0);
 | |
|   g_assert (!abstract);
 | |
|   g_assert (type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
 | |
|   g_free (path);
 | |
|   g_byte_array_free (array, TRUE);
 | |
| 
 | |
|   g_object_unref (addr);
 | |
| 
 | |
|   buffer[0] = 0xff;
 | |
|   ov.buffer = buffer;
 | |
|   ov.size = 1;
 | |
|   s = g_socket_send_message (sockets[0], NULL, &ov, 1,
 | |
|                              (GSocketControlMessage **) &message,
 | |
|                              1, 0, NULL, &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 1);
 | |
|   g_object_unref (message);
 | |
| 
 | |
|   message = NULL;
 | |
| 
 | |
|   flags = 0;
 | |
|   iv.buffer = buffer;
 | |
|   iv.size = 1;
 | |
|   s = g_socket_receive_message (sockets[1], NULL, &iv, 1,
 | |
|                                 (GSocketControlMessage ***) &mv,
 | |
|                                 &nm, &flags, NULL, &err);
 | |
|   g_assert_no_error (err);
 | |
|   g_assert_cmpint (s, ==, 1);
 | |
|   g_object_unref (sockets[0]);
 | |
|   g_object_unref (sockets[1]);
 | |
| 
 | |
|   g_assert_cmpint (nm, ==, 1);
 | |
|   message = mv[0];
 | |
|   g_free (mv);
 | |
| 
 | |
|   g_assert (G_IS_UNIX_FD_MESSAGE (message));
 | |
|   list = g_object_ref (g_unix_fd_message_get_fd_list (message));
 | |
|   g_object_unref (message);
 | |
| 
 | |
|   peek = g_unix_fd_list_peek_fds (list, &s);
 | |
|   g_assert_cmpint (s, ==, 2);
 | |
|   sv[0] = g_unix_fd_list_get (list, 1, &err);
 | |
|   g_assert_no_error (err);
 | |
| 
 | |
|   strcpy (buffer, "failure to say failure to say 'i love gnome-panel!'.");
 | |
|   s = write (sv[0], buffer, strlen (buffer) + 1);
 | |
|   g_assert_cmpint (s, ==, strlen (buffer) + 1);
 | |
| 
 | |
|   close (sv[0]);
 | |
|   memset (buffer, 0xff, sizeof buffer);
 | |
| 
 | |
|   s = read (peek[0], buffer, sizeof buffer);
 | |
|   g_assert_cmpint (s, ==, 53);
 | |
|   g_assert_cmpstr (buffer, ==,
 | |
|                    "failure to say failure to say 'i love gnome-panel!'.");
 | |
| 
 | |
|   g_object_unref (list);
 | |
| 
 | |
|   check_fd_list (fd_list);
 | |
| }
 | |
| 
 | |
| int
 | |
| main (int argc, char **argv)
 | |
| {
 | |
|   g_test_init (&argc, &argv, NULL);
 | |
| 
 | |
|   g_test_add_func ("/unix-streams/file-descriptors", test_fds);
 | |
| 
 | |
|   return g_test_run();
 | |
| 
 | |
| }
 |