BugĀ 601637 - add GUnixFDList
[dana/cg-glib.git] / gio / tests / unix-fd.c
1 #include <gio/gio.h>
2 #include <gio/gunixfdmessage.h>
3 #include <sys/socket.h>
4 #include <string.h>
5 #include <unistd.h>
6
7 /* ensures that no FDs are left open at the end */
8 static void
9 check_fd_list (const gint *fd_list)
10 {
11   gint i;
12
13   for (i = 0; i < 40; i++)
14     {
15       int my_fd;
16
17       my_fd = dup (0);
18       g_assert_cmpint (fd_list[i], ==, my_fd);
19     }
20
21   for (i = 0; i < 40; i++)
22     close (fd_list[i]);
23 }
24
25 static void
26 create_fd_list (gint *fd_list)
27 {
28   gint i;
29
30   for (i = 0; i < 40; i++)
31     {
32       fd_list[i] = dup (0);
33       g_assert_cmpint (fd_list[i], >, 0);
34     }
35
36   for (i = 0; i < 40; i++)
37     close (fd_list[i]);
38 }
39
40 static void
41 test_fds (void)
42 {
43   GUnixFDMessage *message;
44   GUnixFDMessage **mv;
45   GUnixFDList *list, *l2;
46   GSocket *sockets[2];
47   const gint *peek;
48   char buffer[1024];
49   gint fd_list[40];
50   GOutputVector ov;
51   GInputVector iv;
52   gint *stolen;
53   gint sv[3];
54   gint flags;
55   gint nm;
56   gint s;
57
58   create_fd_list (fd_list);
59
60   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
61   g_assert_cmpint (s, ==, 0);
62   sv[2] = -1;
63
64   list = g_unix_fd_list_new_from_array (sv, -1);
65   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new_with_fd_list (list));
66   g_object_unref (list);
67
68   g_assert (g_unix_fd_message_get_fd_list (message) == list);
69   g_object_get (message, "fd-list", &l2, NULL);
70   g_assert (l2 == list);
71   g_assert_cmpint (g_unix_fd_list_get_length (list), ==, 2);
72
73   peek = g_unix_fd_list_peek_fds (list, &s);
74   g_assert_cmpint (s, ==, 2);
75   stolen = g_unix_fd_message_steal_fds (message, &s);
76   g_assert_cmpint (s, ==, 2);
77   g_assert (stolen == peek);
78
79   g_assert_cmpint (stolen[0], ==, sv[0]);
80   g_assert_cmpint (stolen[1], ==, sv[1]);
81   g_assert_cmpint (stolen[2], ==, sv[2]);
82   g_free (stolen);
83
84   g_unix_fd_message_append_fd (message, sv[0], NULL);
85   s = close (sv[0]);
86   g_assert_cmpint (s, ==, 0);
87   g_unix_fd_message_append_fd (message, sv[1], NULL);
88   s = close (sv[1]);
89   g_assert_cmpint (s, ==, 0);
90
91   s = close (g_unix_fd_list_get (list, 0, NULL));
92   g_assert_cmpint (s, ==, 0);
93   s = close (g_unix_fd_list_get (list, 1, NULL));
94   g_assert_cmpint (s, ==, 0);
95   s = close (g_unix_fd_list_get (list, 0, NULL));
96   g_assert_cmpint (s, ==, 0);
97   s = close (g_unix_fd_list_get (list, 1, NULL));
98   g_assert_cmpint (s, ==, 0);
99   s = close (g_unix_fd_list_get (list, 0, NULL));
100   g_assert_cmpint (s, ==, 0);
101   s = close (g_unix_fd_list_get (list, 1, NULL));
102   g_assert_cmpint (s, ==, 0);
103
104   g_object_unref (message);
105   g_object_unref (list);
106
107
108
109   message = G_UNIX_FD_MESSAGE (g_unix_fd_message_new ());
110   list = g_unix_fd_message_get_fd_list (message);
111   s = pipe (sv);
112   g_assert_cmpint (s, ==, 0);
113
114   s = g_unix_fd_list_append (list, sv[0], NULL);
115   g_assert_cmpint (s, >=, 0);
116   s = g_unix_fd_list_append (list, sv[1], NULL);
117   g_assert_cmpint (s, >=, 0);
118
119   s = close (sv[0]);
120   g_assert_cmpint (s, ==, 0);
121   s = close (sv[1]);
122   g_assert_cmpint (s, ==, 0);
123   s = close (g_unix_fd_list_get (list, 0, NULL));
124   g_assert_cmpint (s, ==, 0);
125   s = close (g_unix_fd_list_get (list, 1, NULL));
126   g_assert_cmpint (s, ==, 0);
127
128   s = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
129   g_assert_cmpint (s, ==, 0);
130
131   sockets[0] = g_socket_new_from_fd (sv[0], NULL);
132   g_assert (G_IS_SOCKET (sockets[0]));
133   sockets[1] = g_socket_new_from_fd (sv[1], NULL);
134   g_assert (G_IS_SOCKET (sockets[1]));
135
136   buffer[0] = 0xff;
137   ov.buffer = buffer;
138   ov.size = 1;
139   s = g_socket_send_message (sockets[0], NULL, &ov, 1,
140                              (GSocketControlMessage **) &message,
141                              1, 0, NULL, NULL);
142   g_assert_cmpint (s, ==, 1);
143   g_object_unref (message);
144
145   message = NULL;
146
147   flags = 0;
148   iv.buffer = buffer;
149   iv.size = 1;
150   s = g_socket_receive_message (sockets[1], NULL, &iv, 1,
151                                 (GSocketControlMessage ***) &mv,
152                                 &nm, &flags, NULL, NULL);
153   g_assert_cmpint (s, ==, 1);
154   g_object_unref (sockets[0]);
155   g_object_unref (sockets[1]);
156
157   g_assert_cmpint (nm, ==, 1);
158   message = mv[0];
159   g_free (mv);
160
161   g_assert (G_IS_UNIX_FD_MESSAGE (message));
162   list = g_object_ref (g_unix_fd_message_get_fd_list (message));
163   g_object_unref (message);
164
165   peek = g_unix_fd_list_peek_fds (list, &s);
166   g_assert_cmpint (s, ==, 2);
167   sv[0] = g_unix_fd_list_get (list, 1, NULL);
168
169   strcpy (buffer, "failure to say failure to say 'i love gnome-panel!'.");
170   s = write (sv[0], buffer, strlen (buffer) + 1);
171   g_assert_cmpint (s, ==, strlen (buffer) + 1);
172
173   close (sv[0]);
174   memset (buffer, 0xff, sizeof buffer);
175
176   s = read (peek[0], buffer, sizeof buffer);
177   g_assert_cmpint (s, ==, 53);
178   g_assert_cmpstr (buffer, ==,
179                    "failure to say failure to say 'i love gnome-panel!'.");
180
181   g_object_unref (list);
182
183   check_fd_list (fd_list);
184 }
185
186 int
187 main (int argc, char **argv)
188 {
189   g_test_init (&argc, &argv, NULL);
190
191   g_type_init ();
192
193   g_test_add_func ("/unix-streams/file-descriptors", test_fds);
194
195   return g_test_run();
196
197 }