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