Update the docs for the new network APIs
[platform/upstream/glib.git] / gio / gunixconnection.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2009 Codethink Limited
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation; either version 2 of the licence or (at
8  * your option) any later version.
9  *
10  * See the included COPYING file for more information.
11  *
12  * Authors: Ryan Lortie <desrt@desrt.ca>
13  */
14
15 #include "config.h"
16 #include "gunixconnection.h"
17 #include "glibintl.h"
18
19 /**
20  * SECTION: gunixconnection
21  * @title: GUnixConnection
22  * @short_description: a Unix domain #GSocketConnection
23  * @see_also: #GSocketConnection.
24  *
25  * This is the subclass of #GSocketConnection that is created
26  * for UNIX domain sockets.
27  *
28  * It contains functions to do some of the unix socket specific
29  * functionallity like passing file descriptors.
30  *
31  * Since: 2.22
32  **/
33
34 #include <gio/gsocketcontrolmessage.h>
35 #include <gio/gunixfdmessage.h>
36 #include <gio/gsocket.h>
37 #include <unistd.h>
38
39 #include "gioalias.h"
40
41 G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection,
42                          G_TYPE_SOCKET_CONNECTION,
43   g_socket_connection_factory_register_type (g_define_type_id,
44                                              G_SOCKET_FAMILY_UNIX,
45                                              G_SOCKET_TYPE_STREAM,
46                                              0);
47                          );
48
49 /**
50  * g_unix_connection_send_fd:
51  * @connection: a #GUnixConnection.
52  * @fd: a file descriptor
53  * @cancellable: optional #GCancellable object, %NULL to ignore.
54  * @error: #GError for error reporting, or %NULL to ignore.
55  *
56  * Passes a file descriptor to the recieving side of the
57  * connection. The recieving end has to call g_unix_connection_receive_fd()
58  * to accept the file descriptor.
59  *
60  * As well as sending the fd this also writes a single byte to the
61  * stream, as this is required for fd passing to work on some
62  * implementations.
63  *
64  * Returns: a %TRUE on success, %NULL on error.
65  *
66  * Since: 2.22
67  **/
68 gboolean
69 g_unix_connection_send_fd (GUnixConnection  *connection,
70                            gint              fd,
71                            GCancellable     *cancellable,
72                            GError          **error)
73 {
74   GSocketControlMessage *scm;
75   GSocket *socket;
76
77   g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
78   g_return_val_if_fail (fd >= 0, FALSE);
79
80   scm = g_unix_fd_message_new ();
81
82   if (!g_unix_fd_message_append_fd (G_UNIX_FD_MESSAGE (scm), fd, error))
83     {
84       g_object_unref (scm);
85       return FALSE;
86     }
87
88   g_object_get (connection, "socket", &socket, NULL);
89   if (!g_socket_condition_wait (socket, G_IO_OUT, cancellable, error) ||
90       g_socket_send_message (socket, NULL, NULL, 0, &scm, 1, 0, error) != 1)
91     /* XXX could it 'fail' with zero? */
92     {
93       g_object_unref (socket);
94       g_object_unref (scm);
95
96       return FALSE;
97     }
98
99   g_object_unref (socket);
100   g_object_unref (scm);
101
102   return TRUE;
103 }
104
105 /**
106  * g_unix_connection_receive_fd:
107  * @connection: a #GUnixConnection.
108  * @cancellable: optional #GCancellable object, %NULL to ignore.
109  * @error: #GError for error reporting, or %NULL to ignore.
110  *
111  * Recieves a file descriptor from the sending end of the
112  * connection. The sending end has to call g_unix_connection_send_fd()
113  * for this to work.
114  *
115  * As well as reading the fd this also reads a single byte from the
116  * stream, as this is required for fd passing to work on some
117  * implementations.
118  *
119  * Returns: a file descriptor on success, -1 on error.
120  *
121  * Since: 2.22
122  **/
123 gint
124 g_unix_connection_receive_fd (GUnixConnection  *connection,
125                               GCancellable     *cancellable,
126                               GError          **error)
127 {
128   GSocketControlMessage **scms;
129   gint *fds, nfd, fd, nscm;
130   GUnixFDMessage *fdmsg;
131   GSocket *socket;
132
133   g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), -1);
134
135   g_object_get (connection, "socket", &socket, NULL);
136   if (!g_socket_condition_wait (socket, G_IO_IN, cancellable, error) ||
137       g_socket_receive_message (socket, NULL, NULL, 0,
138                                 &scms, &nscm, NULL, error) != 1)
139     /* XXX it _could_ 'fail' with zero. */
140     {
141       g_object_unref (socket);
142
143       return -1;
144     }
145
146   g_object_unref (socket);
147
148   if (nscm != 1)
149     {
150       gint i;
151
152       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
153                    _("Expecting 1 control message, got %d"), nscm);
154
155       for (i = 0; i < nscm; i++)
156         g_object_unref (scms[i]);
157
158       g_free (scms);
159
160       return -1;
161     }
162
163   if (!G_IS_UNIX_FD_MESSAGE (scms[0]))
164     {
165       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
166                            _("Unexpected type of ancillary data"));
167       g_object_unref (scms[0]);
168       g_free (scms);
169
170       return -1;
171     }
172
173   fdmsg = G_UNIX_FD_MESSAGE (scms[0]);
174   g_free (scms);
175
176   fds = g_unix_fd_message_steal_fds (fdmsg, &nfd);
177   g_object_unref (fdmsg);
178
179   if (nfd != 1)
180     {
181       gint i;
182
183       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
184                    _("Expecting one fd, but got %d\n"), nfd);
185
186       for (i = 0; i < nfd; i++)
187         close (fds[i]);
188
189       g_free (fds);
190
191       return -1;
192     }
193
194   fd = *fds;
195   g_free (fds);
196
197   if (fd < 0)
198     {
199       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
200                    _("Received invalid fd"));
201       fd = -1;
202     }
203
204   return fd;
205 }
206
207 static void
208 g_unix_connection_init (GUnixConnection *connection)
209 {
210 }
211
212 static void
213 g_unix_connection_class_init (GUnixConnectionClass *class)
214 {
215 }
216
217 /* TODO: Other stuff we might want to add are:
218 void                    g_unix_connection_send_fd_async                 (GUnixConnection      *connection,
219                                                                          gint                  fd,
220                                                                          gboolean              close,
221                                                                          gint                  io_priority,
222                                                                          GAsyncReadyCallback   callback,
223                                                                          gpointer              user_data);
224 gboolean                g_unix_connection_send_fd_finish                (GUnixConnection      *connection,
225                                                                          GError              **error);
226
227 gboolean                g_unix_connection_send_fds                      (GUnixConnection      *connection,
228                                                                          gint                 *fds,
229                                                                          gint                  nfds,
230                                                                          GError              **error);
231 void                    g_unix_connection_send_fds_async                (GUnixConnection      *connection,
232                                                                          gint                 *fds,
233                                                                          gint                  nfds,
234                                                                          gint                  io_priority,
235                                                                          GAsyncReadyCallback   callback,
236                                                                          gpointer              user_data);
237 gboolean                g_unix_connection_send_fds_finish               (GUnixConnection      *connection,
238                                                                          GError              **error);
239
240 void                    g_unix_connection_receive_fd_async              (GUnixConnection      *connection,
241                                                                          gint                  io_priority,
242                                                                          GAsyncReadyCallback   callback,
243                                                                          gpointer              user_data);
244 gint                    g_unix_connection_receive_fd_finish             (GUnixConnection      *connection,
245                                                                          GError              **error);
246
247
248 gboolean                g_unix_connection_send_credentials              (GUnixConnection      *connection,
249                                                                          GError              **error);
250 void                    g_unix_connection_send_credentials_async        (GUnixConnection      *connection,
251                                                                          gint                  io_priority,
252                                                                          GAsyncReadyCallback   callback,
253                                                                          gpointer              user_data);
254 gboolean                g_unix_connection_send_credentials_finish       (GUnixConnection      *connection,
255                                                                          GError              **error);
256
257 gboolean                g_unix_connection_send_fake_credentials         (GUnixConnection      *connection,
258                                                                          guint64               pid,
259                                                                          guint64               uid,
260                                                                          guint64               gid,
261                                                                          GError              **error);
262 void                    g_unix_connection_send_fake_credentials_async   (GUnixConnection      *connection,
263                                                                          guint64               pid,
264                                                                          guint64               uid,
265                                                                          guint64               gid,
266                                                                          gint                  io_priority,
267                                                                          GAsyncReadyCallback   callback,
268                                                                          gpointer              user_data);
269 gboolean                g_unix_connection_send_fake_credentials_finish  (GUnixConnection      *connection,
270                                                                          GError              **error);
271
272 gboolean                g_unix_connection_receive_credentials           (GUnixConnection      *connection,
273                                                                          guint64              *pid,
274                                                                          guint64              *uid,
275                                                                          guint64              *gid,
276                                                                          GError              **error);
277 void                    g_unix_connection_receive_credentials_async     (GUnixConnection      *connection,
278                                                                          gint                  io_priority,
279                                                                          GAsyncReadyCallback   callback,
280                                                                          gpointer              user_data);
281 gboolean                g_unix_connection_receive_credentials_finish    (GUnixConnection      *connection,
282                                                                          guint64              *pid,
283                                                                          guint64              *uid,
284                                                                          guint64              *gid,
285                                                                          GError              **error);
286
287 gboolean                g_unix_connection_create_pair                   (GUnixConnection     **one,
288                                                                          GUnixConnection     **two,
289                                                                          GError              **error);
290 */
291
292 #define __G_UNIX_CONNECTION_C__
293 #include "gioaliasdef.c"