File: glib-unix.h

package info (click to toggle)
glib2.0 2.86.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 73,060 kB
  • sloc: ansic: 544,382; python: 9,702; sh: 1,612; xml: 1,482; perl: 1,222; cpp: 535; makefile: 321; javascript: 11
file content (360 lines) | stat: -rw-r--r-- 11,503 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/* glib-unix.h - Unix specific integration
 * Copyright (C) 2011 Red Hat, Inc.
 * Copyright 2023 Collabora Ltd.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __G_UNIX_H__
#define __G_UNIX_H__

/* We need to include the UNIX headers needed to use the APIs below,
 * but we also take this opportunity to include a wide selection of
 * other UNIX headers.  If one of the headers below is broken on some
 * system, work around it here (or better, fix the system or tell
 * people to use a better one).
 */
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>

#include <glib.h>
#include <glib/gstdio.h>

#ifndef G_OS_UNIX
#error "This header may only be used on UNIX"
#endif

G_BEGIN_DECLS

/**
 * G_UNIX_ERROR:
 *
 * Error domain for API in the g_unix_ namespace. Note that there is no
 * exported enumeration mapping %errno. Instead, all functions ensure that
 * %errno is relevant. The code for all %G_UNIX_ERROR is always 0, and the
 * error message is always generated via g_strerror().
 *
 * It is expected that most code will not look at %errno from these APIs.
 * Important cases where one would want to differentiate between errors are
 * already covered by existing cross-platform GLib API, such as e.g. #GFile
 * wrapping `ENOENT`. However, it is provided for completeness, at least.
 */
#define G_UNIX_ERROR (g_unix_error_quark())

GLIB_AVAILABLE_IN_2_30
GQuark g_unix_error_quark (void);

GLIB_AVAILABLE_IN_2_30
gboolean g_unix_open_pipe (gint    *fds,
                           gint     flags,
                           GError **error);

GLIB_AVAILABLE_IN_2_30
gboolean g_unix_set_fd_nonblocking (gint       fd,
                                    gboolean   nonblock,
                                    GError   **error);

GLIB_AVAILABLE_IN_2_30
GSource *g_unix_signal_source_new  (gint signum);

GLIB_AVAILABLE_IN_2_30
guint    g_unix_signal_add_full    (gint           priority,
                                    gint           signum,
                                    GSourceFunc    handler,
                                    gpointer       user_data,
                                    GDestroyNotify notify);

GLIB_AVAILABLE_IN_2_30
guint    g_unix_signal_add         (gint        signum,
                                    GSourceFunc handler,
                                    gpointer    user_data);

/**
 * GUnixFDSourceFunc:
 * @fd: the fd that triggered the event
 * @condition: the IO conditions reported on @fd
 * @user_data: user data passed to g_unix_fd_add()
 *
 * The type of functions to be called when a UNIX fd watch source
 * triggers.
 *
 * Returns: %FALSE if the source should be removed
 **/
typedef gboolean (*GUnixFDSourceFunc) (gint         fd,
                                       GIOCondition condition,
                                       gpointer     user_data);

GLIB_AVAILABLE_IN_2_36
GSource *g_unix_fd_source_new      (gint         fd,
                                    GIOCondition condition);

GLIB_AVAILABLE_IN_2_36
guint    g_unix_fd_add_full        (gint              priority,
                                    gint              fd,
                                    GIOCondition      condition,
                                    GUnixFDSourceFunc function,
                                    gpointer          user_data,
                                    GDestroyNotify    notify);

GLIB_AVAILABLE_IN_2_36
guint    g_unix_fd_add             (gint              fd,
                                    GIOCondition      condition,
                                    GUnixFDSourceFunc function,
                                    gpointer          user_data);

GLIB_AVAILABLE_IN_2_64
struct passwd *g_unix_get_passwd_entry (const gchar  *user_name,
                                        GError      **error);

/**
 * GUnixPipe:
 * @fds: A pair of file descriptors, each negative if closed or not yet opened.
 *  The file descriptor with index %G_UNIX_PIPE_END_READ is readable.
 *  The file descriptor with index %G_UNIX_PIPE_END_WRITE is writable.
 *
 * A Unix pipe. The advantage of this type over `int[2]` is that it can
 * be closed automatically when it goes out of scope, using `g_auto(GUnixPipe)`,
 * on compilers that support that feature.
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_TYPE_IN_2_80
typedef struct {
  int fds[2];
} GUnixPipe;

/**
 * GUnixPipeEnd:
 * @G_UNIX_PIPE_END_READ: The readable file descriptor 0
 * @G_UNIX_PIPE_END_WRITE: The writable file descriptor 1
 *
 * Mnemonic constants for the ends of a Unix pipe.
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_TYPE_IN_2_80
typedef enum
{
  G_UNIX_PIPE_END_READ = 0,
  G_UNIX_PIPE_END_WRITE = 1
} GUnixPipeEnd;

/**
 * G_UNIX_PIPE_INIT:
 *
 * Initializer for a #GUnixPipe that has not yet been opened.
 * Both of its file descriptors are initialized to `-1` (invalid),
 * the same as if they had been closed.
 *
 * Since: 2.80
 */
#define G_UNIX_PIPE_INIT { { -1, -1 } } GLIB_AVAILABLE_MACRO_IN_2_80

/* Suppress "Not available before" warnings when declaring the
 * implementations */
G_GNUC_BEGIN_IGNORE_DEPRECATIONS

/**
 * g_unix_pipe_open:
 * @self: A pair of file descriptors
 * @flags: Flags to pass to g_unix_open_pipe(), typically `O_CLOEXEC`
 * @error: Used to report an error on failure
 *
 * Open a pipe. This is the same as g_unix_open_pipe(), but uses the
 * #GUnixPipe data structure.
 *
 * Returns: %TRUE on success
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline gboolean g_unix_pipe_open (GUnixPipe  *self,
                                         int         flags,
                                         GError    **error);

GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline gboolean
g_unix_pipe_open (GUnixPipe *self,
                  int flags,
                  GError **error)
{
  return g_unix_open_pipe (self->fds, flags, error);
}

/**
 * g_unix_pipe_get:
 * @self: A pair of file descriptors
 * @end: One of the ends of the pipe
 *
 * Return one of the ends of the pipe. It remains owned by @self.
 *
 * This function is async-signal safe (see [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
 * signal handler or a #GSpawnChildSetupFunc.
 *
 * This function preserves the value of `errno`.
 *
 * Returns: a non-negative file descriptor owned by @self, which must not
 *  be closed by the caller, or a negative number if the corresponding
 *  end of the pipe was already closed or stolen
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline int g_unix_pipe_get (GUnixPipe    *self,
                                   GUnixPipeEnd  end);

GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline int
g_unix_pipe_get (GUnixPipe *self,
                 GUnixPipeEnd end)
{
  return self->fds[end];
}

/**
 * g_unix_pipe_steal:
 * @self: A pair of file descriptors
 * @end: One of the ends of the pipe
 *
 * Return one of the ends of the pipe. It becomes owned by the caller,
 * and the file descriptor in the data structure is set to `-1`,
 * similar to g_steal_fd().
 *
 * This function is async-signal safe (see [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7))), making it safe to call from a
 * signal handler or a #GSpawnChildSetupFunc.
 *
 * This function preserves the value of `errno`.
 *
 * Returns: a non-negative file descriptor, which becomes owned by the
 *  caller and must be closed by the caller if required, or a negative
 *  number if the corresponding end of the pipe was already closed or stolen
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline int g_unix_pipe_steal (GUnixPipe    *self,
                                     GUnixPipeEnd  end);

GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline int
g_unix_pipe_steal (GUnixPipe *self,
                   GUnixPipeEnd end)
{
  return g_steal_fd (&self->fds[end]);
}

/**
 * g_unix_pipe_close:
 * @self: A pair of file descriptors
 * @end: One of the ends of the pipe
 * @error: Optionally used to report an error on failure
 *
 * Close one of the ends of the pipe and set the relevant member of @fds
 * to `-1` before returning, equivalent to g_clear_fd().
 *
 * Like g_close(), if closing the file descriptor fails, the error is
 * stored in both %errno and @error. If this function succeeds,
 * %errno is undefined.
 *
 * This function is async-signal safe if @error is %NULL and the relevant
 * member of @fds is either negative or a valid open file descriptor.
 * This makes it safe to call from a signal handler or a #GSpawnChildSetupFunc
 * under those conditions.
 * See [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7)) for more details.
 *
 * To close both file descriptors and ignore any errors, use
 * g_unix_pipe_clear() instead.
 *
 * Returns: %TRUE on success
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline gboolean g_unix_pipe_close (GUnixPipe     *self,
                                          GUnixPipeEnd   end,
                                          GError       **error);

GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline gboolean
g_unix_pipe_close (GUnixPipe *self,
                   GUnixPipeEnd end,
                   GError **error)
{
  return g_clear_fd (&self->fds[end], error);
}

/**
 * g_unix_pipe_clear:
 * @self: a #GUnixPipe
 *
 * Close both ends of the pipe, unless they have already been closed or
 * stolen. Any errors are ignored: use g_unix_pipe_close() or g_clear_fd()
 * if error-handling is required.
 *
 * This function is async-signal safe if @error is %NULL and each member
 * of @fds are either negative or a valid open file descriptor.
 * As a result, it is safe to call this function or use `g_auto(GUnixPipe)`
 * (on compilers that support it) in a signal handler or a
 * #GSpawnChildSetupFunc, as long as those conditions are ensured to be true.
 * See [`signal(7)`](man:signal(7)) and
 * [`signal-safety(7)`](man:signal-safety(7)) for more details.
 *
 * This function preserves the value of `errno`.
 *
 * Since: 2.80
 */
GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline void g_unix_pipe_clear (GUnixPipe *self);

GLIB_AVAILABLE_STATIC_INLINE_IN_2_80
static inline void
g_unix_pipe_clear (GUnixPipe *self)
{
  /* Don't overwrite thread-local errno if closing the fd fails */
  int errsv = errno;

  if (!g_unix_pipe_close (self, G_UNIX_PIPE_END_READ, NULL))
    {
      /* ignore */
    }

  if (!g_unix_pipe_close (self, G_UNIX_PIPE_END_WRITE, NULL))
    {
      /* ignore */
    }

  errno = errsv;
}

G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (GUnixPipe, g_unix_pipe_clear)

GLIB_AVAILABLE_IN_2_80
int g_closefrom (int lowfd);

GLIB_AVAILABLE_IN_2_80
int g_fdwalk_set_cloexec (int lowfd);

G_GNUC_END_IGNORE_DEPRECATIONS

G_END_DECLS

#endif  /* __G_UNIX_H__ */