• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gio/gio.h>
2 #include <gio/gnetworking.h>
3 #include <gio/gunixfdmessage.h>
4 #include <gio/gunixsocketaddress.h>
5 #include <string.h>
6 #include <unistd.h>
7 
8 /* ensures that no FDs are left open at the end */
9 static void
check_fd_list(const gint * fd_list)10 check_fd_list (const gint *fd_list)
11 {
12   gint i;
13 
14   for (i = 0; i < 40; i++)
15     {
16       int my_fd;
17 
18       my_fd = dup (0);
19       g_assert_cmpint (fd_list[i], ==, my_fd);
20     }
21 
22   for (i = 0; i < 40; i++)
23     close (fd_list[i]);
24 }
25 
26 static void
create_fd_list(gint * fd_list)27 create_fd_list (gint *fd_list)
28 {
29   gint i;
30 
31   for (i = 0; i < 40; i++)
32     {
33       fd_list[i] = dup (0);
34       g_assert_cmpint (fd_list[i], >, 0);
35     }
36 
37   for (i = 0; i < 40; i++)
38     close (fd_list[i]);
39 }
40 
41 static void
test_fds(void)42 test_fds (void)
43 {
44   GError *err = NULL;
45   GUnixFDMessage *message;
46   GUnixFDMessage **mv;
47   GUnixFDList *list, *l2;
48   GSocket *sockets[2];
49   GSocketAddress *addr;
50   const gint *peek;
51   char buffer[1024];
52   gint fd_list[40];
53   GOutputVector ov;
54   GInputVector iv;
55   gint *stolen;
56   gint sv[3];
57   gint flags;
58   gint nm;
59   gint s;
60   gchar *path;
61   GByteArray *array;
62   gboolean abstract;
63   GUnixSocketAddressType type;
64 
65   create_fd_list (fd_list);
66 
67   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
68   g_assert_cmpint (s, ==, 0);
69   sv[2] = -1;
70 
71   list = g_unix_fd_list_new_from_array (sv, -1);
72   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new_with_fd_list (list));
73   g_object_unref (list);
74 
75   g_assert (g_unix_fd_message_get_fd_list (message) == list);
76   g_object_get (message, "fd-list", &l2, NULL);
77   g_assert (l2 == list);
78   g_assert_cmpint (g_unix_fd_list_get_length (list), ==, 2);
79 
80   peek = g_unix_fd_list_peek_fds (list, &s);
81   g_assert_cmpint (s, ==, 2);
82   stolen = g_unix_fd_message_steal_fds (message, &s);
83   g_assert_cmpint (s, ==, 2);
84   g_assert (stolen == peek);
85 
86   g_assert_cmpint (stolen[0], ==, sv[0]);
87   g_assert_cmpint (stolen[1], ==, sv[1]);
88   g_assert_cmpint (stolen[2], ==, sv[2]);
89   g_free (stolen);
90 
91   g_unix_fd_message_append_fd (message, sv[0], &err);
92   g_assert_no_error (err);
93   s = close (sv[0]);
94   g_assert_cmpint (s, ==, 0);
95   g_unix_fd_message_append_fd (message, sv[1], &err);
96   g_assert_no_error (err);
97   s = close (sv[1]);
98   g_assert_cmpint (s, ==, 0);
99 
100   s = close (g_unix_fd_list_get (list, 0, &err));
101   g_assert_no_error (err);
102   g_assert_cmpint (s, ==, 0);
103   s = close (g_unix_fd_list_get (list, 1, &err));
104   g_assert_no_error (err);
105   g_assert_cmpint (s, ==, 0);
106   s = close (g_unix_fd_list_get (list, 0, &err));
107   g_assert_no_error (err);
108   g_assert_cmpint (s, ==, 0);
109   s = close (g_unix_fd_list_get (list, 1, &err));
110   g_assert_no_error (err);
111   g_assert_cmpint (s, ==, 0);
112   s = close (g_unix_fd_list_get (list, 0, &err));
113   g_assert_no_error (err);
114   g_assert_cmpint (s, ==, 0);
115   s = close (g_unix_fd_list_get (list, 1, &err));
116   g_assert_no_error (err);
117   g_assert_cmpint (s, ==, 0);
118 
119   g_object_unref (message);
120   g_object_unref (list);
121 
122   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new ());
123   list = g_unix_fd_message_get_fd_list (message);
124   s = pipe (sv);
125   g_assert_cmpint (s, ==, 0);
126 
127   s = g_unix_fd_list_append (list, sv[0], &err);
128   g_assert_no_error (err);
129   g_assert_cmpint (s, >=, 0);
130   s = g_unix_fd_list_append (list, sv[1], &err);
131   g_assert_no_error (err);
132   g_assert_cmpint (s, >=, 0);
133 
134   s = close (sv[0]);
135   g_assert_cmpint (s, ==, 0);
136   s = close (sv[1]);
137   g_assert_cmpint (s, ==, 0);
138   s = close (g_unix_fd_list_get (list, 0, &err));
139   g_assert_no_error (err);
140   g_assert_cmpint (s, ==, 0);
141   s = close (g_unix_fd_list_get (list, 1, &err));
142   g_assert_no_error (err);
143   g_assert_cmpint (s, ==, 0);
144 
145   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
146   g_assert_cmpint (s, ==, 0);
147 
148   sockets[0] = g_socket_new_from_fd (sv[0], &err);
149   g_assert_no_error (err);
150   g_assert (G_IS_SOCKET (sockets[0]));
151   sockets[1] = g_socket_new_from_fd (sv[1], &err);
152   g_assert_no_error (err);
153   g_assert (G_IS_SOCKET (sockets[1]));
154 
155   addr = g_socket_get_local_address (sockets[0], &err);
156   g_assert_no_error (err);
157   g_assert (G_IS_UNIX_SOCKET_ADDRESS (addr));
158   g_assert_cmpint (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (addr)), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
159   g_assert_cmpint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (addr)), ==, 0);
160 
161 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
162   g_assert (!g_unix_socket_address_get_is_abstract (G_UNIX_SOCKET_ADDRESS (addr)));
163 G_GNUC_END_IGNORE_DEPRECATIONS
164 
165   g_object_get (addr,
166                 "path", &path,
167                 "path-as-array", &array,
168                 "abstract", &abstract,
169                 "address-type", &type,
170                 NULL);
171   g_assert_cmpstr (path, ==, "");
172   g_assert_cmpint (array->len, ==, 0);
173   g_assert (!abstract);
174   g_assert (type == G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
175   g_free (path);
176   g_byte_array_free (array, TRUE);
177 
178   g_object_unref (addr);
179 
180   buffer[0] = 0xff;
181   ov.buffer = buffer;
182   ov.size = 1;
183   s = g_socket_send_message (sockets[0], NULL, &ov, 1,
184                              (GSocketControlMessage **) &message,
185                              1, 0, NULL, &err);
186   g_assert_no_error (err);
187   g_assert_cmpint (s, ==, 1);
188   g_object_unref (message);
189 
190   message = NULL;
191 
192   flags = 0;
193   iv.buffer = buffer;
194   iv.size = 1;
195   s = g_socket_receive_message (sockets[1], NULL, &iv, 1,
196                                 (GSocketControlMessage ***) &mv,
197                                 &nm, &flags, NULL, &err);
198   g_assert_no_error (err);
199   g_assert_cmpint (s, ==, 1);
200   g_object_unref (sockets[0]);
201   g_object_unref (sockets[1]);
202 
203   g_assert_cmpint (nm, ==, 1);
204   message = mv[0];
205   g_free (mv);
206 
207   g_assert (G_IS_UNIX_FD_MESSAGE (message));
208   list = g_object_ref (g_unix_fd_message_get_fd_list (message));
209   g_object_unref (message);
210 
211   peek = g_unix_fd_list_peek_fds (list, &s);
212   g_assert_cmpint (s, ==, 2);
213   sv[0] = g_unix_fd_list_get (list, 1, &err);
214   g_assert_no_error (err);
215 
216   strcpy (buffer, "failure to say failure to say 'i love gnome-panel!'.");
217   s = write (sv[0], buffer, strlen (buffer) + 1);
218   g_assert_cmpint (s, ==, strlen (buffer) + 1);
219 
220   close (sv[0]);
221   memset (buffer, 0xff, sizeof buffer);
222 
223   s = read (peek[0], buffer, sizeof buffer);
224   g_assert_cmpint (s, ==, 53);
225   g_assert_cmpstr (buffer, ==,
226                    "failure to say failure to say 'i love gnome-panel!'.");
227 
228   g_object_unref (list);
229 
230   check_fd_list (fd_list);
231 }
232 
233 int
main(int argc,char ** argv)234 main (int argc, char **argv)
235 {
236   g_test_init (&argc, &argv, NULL);
237 
238   g_test_add_func ("/unix-streams/file-descriptors", test_fds);
239 
240   return g_test_run();
241 
242 }
243