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__ */
|