Merge remote-tracking branch 'gvdb/master'
[platform/upstream/glib.git] / gio / tests / unix-fd.c
1 #include <gio/gio.h>
2 #include <gio/gunixfdmessage.h>
3 #include <gio/gunixsocketaddress.h>
4 #include <sys/socket.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 /* ensures that no FDs are left open at the end */
9 static void
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
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
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
61   create_fd_list (fd_list);
62
63   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
64   g_assert_cmpint (s, ==, 0);
65   sv[2] = -1;
66
67   list = g_unix_fd_list_new_from_array (sv, -1);
68   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new_with_fd_list (list));
69   g_object_unref (list);
70
71   g_assert (g_unix_fd_message_get_fd_list (message) == list);
72   g_object_get (message, "fd-list", &l2, NULL);
73   g_assert (l2 == list);
74   g_assert_cmpint (g_unix_fd_list_get_length (list), ==, 2);
75
76   peek = g_unix_fd_list_peek_fds (list, &s);
77   g_assert_cmpint (s, ==, 2);
78   stolen = g_unix_fd_message_steal_fds (message, &s);
79   g_assert_cmpint (s, ==, 2);
80   g_assert (stolen == peek);
81
82   g_assert_cmpint (stolen[0], ==, sv[0]);
83   g_assert_cmpint (stolen[1], ==, sv[1]);
84   g_assert_cmpint (stolen[2], ==, sv[2]);
85   g_free (stolen);
86
87   g_unix_fd_message_append_fd (message, sv[0], &err);
88   g_assert_no_error (err);
89   s = close (sv[0]);
90   g_assert_cmpint (s, ==, 0);
91   g_unix_fd_message_append_fd (message, sv[1], &err);
92   g_assert_no_error (err);
93   s = close (sv[1]);
94   g_assert_cmpint (s, ==, 0);
95
96   s = close (g_unix_fd_list_get (list, 0, &err));
97   g_assert_no_error (err);
98   g_assert_cmpint (s, ==, 0);
99   s = close (g_unix_fd_list_get (list, 1, &err));
100   g_assert_no_error (err);
101   g_assert_cmpint (s, ==, 0);
102   s = close (g_unix_fd_list_get (list, 0, &err));
103   g_assert_no_error (err);
104   g_assert_cmpint (s, ==, 0);
105   s = close (g_unix_fd_list_get (list, 1, &err));
106   g_assert_no_error (err);
107   g_assert_cmpint (s, ==, 0);
108   s = close (g_unix_fd_list_get (list, 0, &err));
109   g_assert_no_error (err);
110   g_assert_cmpint (s, ==, 0);
111   s = close (g_unix_fd_list_get (list, 1, &err));
112   g_assert_no_error (err);
113   g_assert_cmpint (s, ==, 0);
114
115   g_object_unref (message);
116   g_object_unref (list);
117
118
119
120   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new ());
121   list = g_unix_fd_message_get_fd_list (message);
122   s = pipe (sv);
123   g_assert_cmpint (s, ==, 0);
124
125   s = g_unix_fd_list_append (list, sv[0], &err);
126   g_assert_no_error (err);
127   g_assert_cmpint (s, >=, 0);
128   s = g_unix_fd_list_append (list, sv[1], &err);
129   g_assert_no_error (err);
130   g_assert_cmpint (s, >=, 0);
131
132   s = close (sv[0]);
133   g_assert_cmpint (s, ==, 0);
134   s = close (sv[1]);
135   g_assert_cmpint (s, ==, 0);
136   s = close (g_unix_fd_list_get (list, 0, &err));
137   g_assert_no_error (err);
138   g_assert_cmpint (s, ==, 0);
139   s = close (g_unix_fd_list_get (list, 1, &err));
140   g_assert_no_error (err);
141   g_assert_cmpint (s, ==, 0);
142
143   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
144   g_assert_cmpint (s, ==, 0);
145
146   sockets[0] = g_socket_new_from_fd (sv[0], &err);
147   g_assert_no_error (err);
148   g_assert (G_IS_SOCKET (sockets[0]));
149   sockets[1] = g_socket_new_from_fd (sv[1], &err);
150   g_assert_no_error (err);
151   g_assert (G_IS_SOCKET (sockets[1]));
152
153   addr = g_socket_get_local_address (sockets[0], &err);
154   g_assert_no_error (err);
155   g_assert (G_IS_UNIX_SOCKET_ADDRESS (addr));
156   g_assert_cmpint (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (addr)), ==, G_UNIX_SOCKET_ADDRESS_ANONYMOUS);
157   g_assert_cmpint (g_unix_socket_address_get_path_len (G_UNIX_SOCKET_ADDRESS (addr)), ==, 0);
158   g_object_unref (addr);
159
160   buffer[0] = 0xff;
161   ov.buffer = buffer;
162   ov.size = 1;
163   s = g_socket_send_message (sockets[0], NULL, &ov, 1,
164                              (GSocketControlMessage **) &message,
165                              1, 0, NULL, &err);
166   g_assert_no_error (err);
167   g_assert_cmpint (s, ==, 1);
168   g_object_unref (message);
169
170   message = NULL;
171
172   flags = 0;
173   iv.buffer = buffer;
174   iv.size = 1;
175   s = g_socket_receive_message (sockets[1], NULL, &iv, 1,
176                                 (GSocketControlMessage ***) &mv,
177                                 &nm, &flags, NULL, &err);
178   g_assert_no_error (err);
179   g_assert_cmpint (s, ==, 1);
180   g_object_unref (sockets[0]);
181   g_object_unref (sockets[1]);
182
183   g_assert_cmpint (nm, ==, 1);
184   message = mv[0];
185   g_free (mv);
186
187   g_assert (G_IS_UNIX_FD_MESSAGE (message));
188   list = g_object_ref (g_unix_fd_message_get_fd_list (message));
189   g_object_unref (message);
190
191   peek = g_unix_fd_list_peek_fds (list, &s);
192   g_assert_cmpint (s, ==, 2);
193   sv[0] = g_unix_fd_list_get (list, 1, &err);
194   g_assert_no_error (err);
195
196   strcpy (buffer, "failure to say failure to say 'i love gnome-panel!'.");
197   s = write (sv[0], buffer, strlen (buffer) + 1);
198   g_assert_cmpint (s, ==, strlen (buffer) + 1);
199
200   close (sv[0]);
201   memset (buffer, 0xff, sizeof buffer);
202
203   s = read (peek[0], buffer, sizeof buffer);
204   g_assert_cmpint (s, ==, 53);
205   g_assert_cmpstr (buffer, ==,
206                    "failure to say failure to say 'i love gnome-panel!'.");
207
208   g_object_unref (list);
209
210   check_fd_list (fd_list);
211 }
212
213 int
214 main (int argc, char **argv)
215 {
216   g_test_init (&argc, &argv, NULL);
217
218   g_type_init ();
219
220   g_test_add_func ("/unix-streams/file-descriptors", test_fds);
221
222   return g_test_run();
223
224 }