(root)/
glib-2.79.0/
glib/
glib-unix.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 2011 Red Hat, Inc.
       3   * Copyright 2023 Collabora Ltd.
       4   *
       5   * glib-unix.c: UNIX specific API wrappers and convenience functions
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   *
       9   * This library is free software; you can redistribute it and/or
      10   * modify it under the terms of the GNU Lesser General Public
      11   * License as published by the Free Software Foundation; either
      12   * version 2.1 of the License, or (at your option) any later version.
      13   *
      14   * This library is distributed in the hope that it will be useful,
      15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * Lesser General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU Lesser General Public
      20   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      21   *
      22   * Authors: Colin Walters <walters@verbum.org>
      23   */
      24  
      25  #include "config.h"
      26  
      27  #include "glib-unix.h"
      28  #include "glib-unixprivate.h"
      29  #include "gmain-internal.h"
      30  
      31  #include <string.h>
      32  #include <sys/types.h>
      33  #include <pwd.h>
      34  
      35  G_STATIC_ASSERT (sizeof (ssize_t) == GLIB_SIZEOF_SSIZE_T);
      36  G_STATIC_ASSERT (G_ALIGNOF (gssize) == G_ALIGNOF (ssize_t));
      37  
      38  G_STATIC_ASSERT (sizeof (GPid) == sizeof (pid_t));
      39  G_STATIC_ASSERT (G_ALIGNOF (GPid) == G_ALIGNOF (pid_t));
      40  
      41  /* If this assertion fails, then the ABI of g_unix_open_pipe() would be
      42   * ambiguous on this platform.
      43   * On Linux, usually O_NONBLOCK == 04000 and FD_CLOEXEC == 1, but the same
      44   * might not be true everywhere. */
      45  G_STATIC_ASSERT (O_NONBLOCK != FD_CLOEXEC);
      46  
      47  G_DEFINE_QUARK (g-unix-error-quark, g_unix_error)
      48  
      49  static gboolean
      50  g_unix_set_error_from_errno (GError **error,
      51                               gint     saved_errno)
      52  {
      53    g_set_error_literal (error,
      54                         G_UNIX_ERROR,
      55                         0,
      56                         g_strerror (saved_errno));
      57    errno = saved_errno;
      58    return FALSE;
      59  }
      60  
      61  /**
      62   * g_unix_open_pipe:
      63   * @fds: (array fixed-size=2): Array of two integers
      64   * @flags: Bitfield of file descriptor flags, as for fcntl()
      65   * @error: a #GError
      66   *
      67   * Similar to the UNIX pipe() call, but on modern systems like Linux
      68   * uses the pipe2() system call, which atomically creates a pipe with
      69   * the configured flags.
      70   *
      71   * As of GLib 2.78, the supported flags are `O_CLOEXEC`/`FD_CLOEXEC` (see below)
      72   * and `O_NONBLOCK`. Prior to GLib 2.78, only `FD_CLOEXEC` was supported — if
      73   * you wanted to configure `O_NONBLOCK` then that had to be done separately with
      74   * `fcntl()`.
      75   *
      76   * Since GLib 2.80, the constants %G_UNIX_PIPE_END_READ and
      77   * %G_UNIX_PIPE_END_WRITE can be used as mnemonic indexes in @fds.
      78   *
      79   * It is a programmer error to call this function with unsupported flags, and a
      80   * critical warning will be raised.
      81   *
      82   * As of GLib 2.78, it is preferred to pass `O_CLOEXEC` in, rather than
      83   * `FD_CLOEXEC`, as that matches the underlying `pipe()` API more closely. Prior
      84   * to 2.78, only `FD_CLOEXEC` was supported. Support for `FD_CLOEXEC` may be
      85   * deprecated and removed in future.
      86   *
      87   * Returns: %TRUE on success, %FALSE if not (and errno will be set).
      88   *
      89   * Since: 2.30
      90   */
      91  gboolean
      92  g_unix_open_pipe (int     *fds,
      93                    int      flags,
      94                    GError **error)
      95  {
      96    /* We only support O_CLOEXEC/FD_CLOEXEC and O_NONBLOCK */
      97    g_return_val_if_fail ((flags & (O_CLOEXEC | FD_CLOEXEC | O_NONBLOCK)) == flags, FALSE);
      98  
      99  #if O_CLOEXEC != FD_CLOEXEC && !defined(G_DISABLE_CHECKS)
     100    if (flags & FD_CLOEXEC)
     101      g_debug ("g_unix_open_pipe() called with FD_CLOEXEC; please migrate to using O_CLOEXEC instead");
     102  #endif
     103  
     104    if (!g_unix_open_pipe_internal (fds,
     105                                    (flags & (O_CLOEXEC | FD_CLOEXEC)) != 0,
     106                                    (flags & O_NONBLOCK) != 0))
     107      return g_unix_set_error_from_errno (error, errno);
     108  
     109    return TRUE;
     110  }
     111  
     112  /**
     113   * g_unix_set_fd_nonblocking:
     114   * @fd: A file descriptor
     115   * @nonblock: If %TRUE, set the descriptor to be non-blocking
     116   * @error: a #GError
     117   *
     118   * Control the non-blocking state of the given file descriptor,
     119   * according to @nonblock. On most systems this uses %O_NONBLOCK, but
     120   * on some older ones may use %O_NDELAY.
     121   *
     122   * Returns: %TRUE if successful
     123   *
     124   * Since: 2.30
     125   */
     126  gboolean
     127  g_unix_set_fd_nonblocking (gint       fd,
     128                             gboolean   nonblock,
     129                             GError   **error)
     130  {
     131  #ifdef F_GETFL
     132    glong fcntl_flags;
     133    fcntl_flags = fcntl (fd, F_GETFL);
     134  
     135    if (fcntl_flags == -1)
     136      return g_unix_set_error_from_errno (error, errno);
     137  
     138    if (nonblock)
     139      fcntl_flags |= O_NONBLOCK;
     140    else
     141      fcntl_flags &= ~O_NONBLOCK;
     142  
     143    if (fcntl (fd, F_SETFL, fcntl_flags) == -1)
     144      return g_unix_set_error_from_errno (error, errno);
     145    return TRUE;
     146  #else
     147    return g_unix_set_error_from_errno (error, EINVAL);
     148  #endif
     149  }
     150  
     151  /**
     152   * g_unix_signal_source_new:
     153   * @signum: A signal number
     154   *
     155   * Create a #GSource that will be dispatched upon delivery of the UNIX
     156   * signal @signum.  In GLib versions before 2.36, only `SIGHUP`, `SIGINT`,
     157   * `SIGTERM` can be monitored.  In GLib 2.36, `SIGUSR1` and `SIGUSR2`
     158   * were added. In GLib 2.54, `SIGWINCH` was added.
     159   *
     160   * Note that unlike the UNIX default, all sources which have created a
     161   * watch will be dispatched, regardless of which underlying thread
     162   * invoked g_unix_signal_source_new().
     163   *
     164   * For example, an effective use of this function is to handle `SIGTERM`
     165   * cleanly; flushing any outstanding files, and then calling
     166   * g_main_loop_quit().  It is not safe to do any of this from a regular
     167   * UNIX signal handler; such a handler may be invoked while malloc() or
     168   * another library function is running, causing reentrancy issues if the
     169   * handler attempts to use those functions.  None of the GLib/GObject
     170   * API is safe against this kind of reentrancy.
     171   *
     172   * The interaction of this source when combined with native UNIX
     173   * functions like sigprocmask() is not defined.
     174   *
     175   * The source will not initially be associated with any #GMainContext
     176   * and must be added to one with g_source_attach() before it will be
     177   * executed.
     178   *
     179   * Returns: A newly created #GSource
     180   *
     181   * Since: 2.30
     182   */
     183  GSource *
     184  g_unix_signal_source_new (int signum)
     185  {
     186    g_return_val_if_fail (signum == SIGHUP || signum == SIGINT || signum == SIGTERM ||
     187                          signum == SIGUSR1 || signum == SIGUSR2 || signum == SIGWINCH,
     188                          NULL);
     189  
     190    return _g_main_create_unix_signal_watch (signum);
     191  }
     192  
     193  /**
     194   * g_unix_signal_add_full: (rename-to g_unix_signal_add)
     195   * @priority: the priority of the signal source. Typically this will be in
     196   *            the range between %G_PRIORITY_DEFAULT and %G_PRIORITY_HIGH.
     197   * @signum: Signal number
     198   * @handler: Callback
     199   * @user_data: Data for @handler
     200   * @notify: #GDestroyNotify for @handler
     201   *
     202   * A convenience function for g_unix_signal_source_new(), which
     203   * attaches to the default #GMainContext.  You can remove the watch
     204   * using g_source_remove().
     205   *
     206   * Returns: An ID (greater than 0) for the event source
     207   *
     208   * Since: 2.30
     209   */
     210  guint
     211  g_unix_signal_add_full (int            priority,
     212                          int            signum,
     213                          GSourceFunc    handler,
     214                          gpointer       user_data,
     215                          GDestroyNotify notify)
     216  {
     217    guint id;
     218    GSource *source;
     219  
     220    source = g_unix_signal_source_new (signum);
     221  
     222    if (priority != G_PRIORITY_DEFAULT)
     223      g_source_set_priority (source, priority);
     224  
     225    g_source_set_callback (source, handler, user_data, notify);
     226    id = g_source_attach (source, NULL);
     227    g_source_unref (source);
     228  
     229    return id;
     230  }
     231  
     232  /**
     233   * g_unix_signal_add:
     234   * @signum: Signal number
     235   * @handler: Callback
     236   * @user_data: Data for @handler
     237   *
     238   * A convenience function for g_unix_signal_source_new(), which
     239   * attaches to the default #GMainContext.  You can remove the watch
     240   * using g_source_remove().
     241   *
     242   * Returns: An ID (greater than 0) for the event source
     243   *
     244   * Since: 2.30
     245   */
     246  guint
     247  g_unix_signal_add (int         signum,
     248                     GSourceFunc handler,
     249                     gpointer    user_data)
     250  {
     251    return g_unix_signal_add_full (G_PRIORITY_DEFAULT, signum, handler, user_data, NULL);
     252  }
     253  
     254  typedef struct
     255  {
     256    GSource source;
     257  
     258    gint     fd;
     259    gpointer tag;
     260  } GUnixFDSource;
     261  
     262  static gboolean
     263  g_unix_fd_source_dispatch (GSource     *source,
     264                             GSourceFunc  callback,
     265                             gpointer     user_data)
     266  {
     267    GUnixFDSource *fd_source = (GUnixFDSource *) source;
     268    GUnixFDSourceFunc func = (GUnixFDSourceFunc) callback;
     269  
     270    if (!callback)
     271      {
     272        g_warning ("GUnixFDSource dispatched without callback. "
     273                   "You must call g_source_set_callback().");
     274        return FALSE;
     275      }
     276  
     277    return (* func) (fd_source->fd, g_source_query_unix_fd (source, fd_source->tag), user_data);
     278  }
     279  
     280  GSourceFuncs g_unix_fd_source_funcs = {
     281    NULL, NULL, g_unix_fd_source_dispatch, NULL, NULL, NULL
     282  };
     283  
     284  /**
     285   * g_unix_fd_source_new:
     286   * @fd: a file descriptor
     287   * @condition: I/O conditions to watch for on @fd
     288   *
     289   * Creates a #GSource to watch for a particular I/O condition on a file
     290   * descriptor.
     291   *
     292   * The source will never close the @fd — you must do it yourself.
     293   *
     294   * Any callback attached to the returned #GSource must have type
     295   * #GUnixFDSourceFunc.
     296   *
     297   * Returns: the newly created #GSource
     298   *
     299   * Since: 2.36
     300   **/
     301  GSource *
     302  g_unix_fd_source_new (gint         fd,
     303                        GIOCondition condition)
     304  {
     305    GUnixFDSource *fd_source;
     306    GSource *source;
     307  
     308    source = g_source_new (&g_unix_fd_source_funcs, sizeof (GUnixFDSource));
     309    fd_source = (GUnixFDSource *) source;
     310  
     311    fd_source->fd = fd;
     312    fd_source->tag = g_source_add_unix_fd (source, fd, condition);
     313  
     314    return source;
     315  }
     316  
     317  /**
     318   * g_unix_fd_add_full:
     319   * @priority: the priority of the source
     320   * @fd: a file descriptor
     321   * @condition: IO conditions to watch for on @fd
     322   * @function: a #GUnixFDSourceFunc
     323   * @user_data: data to pass to @function
     324   * @notify: function to call when the idle is removed, or %NULL
     325   *
     326   * Sets a function to be called when the IO condition, as specified by
     327   * @condition becomes true for @fd.
     328   *
     329   * This is the same as g_unix_fd_add(), except that it allows you to
     330   * specify a non-default priority and a provide a #GDestroyNotify for
     331   * @user_data.
     332   *
     333   * Returns: the ID (greater than 0) of the event source
     334   *
     335   * Since: 2.36
     336   **/
     337  guint
     338  g_unix_fd_add_full (gint              priority,
     339                      gint              fd,
     340                      GIOCondition      condition,
     341                      GUnixFDSourceFunc function,
     342                      gpointer          user_data,
     343                      GDestroyNotify    notify)
     344  {
     345    GSource *source;
     346    guint id;
     347  
     348    g_return_val_if_fail (function != NULL, 0);
     349  
     350    source = g_unix_fd_source_new (fd, condition);
     351  
     352    if (priority != G_PRIORITY_DEFAULT)
     353      g_source_set_priority (source, priority);
     354  
     355    g_source_set_callback (source, (GSourceFunc) function, user_data, notify);
     356    id = g_source_attach (source, NULL);
     357    g_source_unref (source);
     358  
     359    return id;
     360  }
     361  
     362  /**
     363   * g_unix_fd_add:
     364   * @fd: a file descriptor
     365   * @condition: IO conditions to watch for on @fd
     366   * @function: a #GUnixFDSourceFunc
     367   * @user_data: data to pass to @function
     368   *
     369   * Sets a function to be called when the IO condition, as specified by
     370   * @condition becomes true for @fd.
     371   *
     372   * @function will be called when the specified IO condition becomes
     373   * %TRUE.  The function is expected to clear whatever event caused the
     374   * IO condition to become true and return %TRUE in order to be notified
     375   * when it happens again.  If @function returns %FALSE then the watch
     376   * will be cancelled.
     377   *
     378   * The return value of this function can be passed to g_source_remove()
     379   * to cancel the watch at any time that it exists.
     380   *
     381   * The source will never close the fd -- you must do it yourself.
     382   *
     383   * Returns: the ID (greater than 0) of the event source
     384   *
     385   * Since: 2.36
     386   **/
     387  guint
     388  g_unix_fd_add (gint              fd,
     389                 GIOCondition      condition,
     390                 GUnixFDSourceFunc function,
     391                 gpointer          user_data)
     392  {
     393    return g_unix_fd_add_full (G_PRIORITY_DEFAULT, fd, condition, function, user_data, NULL);
     394  }
     395  
     396  /**
     397   * g_unix_get_passwd_entry:
     398   * @user_name: the username to get the passwd file entry for
     399   * @error: return location for a #GError, or %NULL
     400   *
     401   * Get the `passwd` file entry for the given @user_name using `getpwnam_r()`.
     402   * This can fail if the given @user_name doesn’t exist.
     403   *
     404   * The returned `struct passwd` has been allocated using g_malloc() and should
     405   * be freed using g_free(). The strings referenced by the returned struct are
     406   * included in the same allocation, so are valid until the `struct passwd` is
     407   * freed.
     408   *
     409   * This function is safe to call from multiple threads concurrently.
     410   *
     411   * You will need to include `pwd.h` to get the definition of `struct passwd`.
     412   *
     413   * Returns: (transfer full): passwd entry, or %NULL on error; free the returned
     414   *    value with g_free()
     415   * Since: 2.64
     416   */
     417  struct passwd *
     418  g_unix_get_passwd_entry (const gchar  *user_name,
     419                           GError      **error)
     420  {
     421    struct passwd *passwd_file_entry;
     422    struct
     423      {
     424        struct passwd pwd;
     425        char string_buffer[];
     426      } *buffer = NULL;
     427    gsize string_buffer_size = 0;
     428    GError *local_error = NULL;
     429  
     430    g_return_val_if_fail (user_name != NULL, NULL);
     431    g_return_val_if_fail (error == NULL || *error == NULL, NULL);
     432  
     433  #ifdef _SC_GETPW_R_SIZE_MAX
     434      {
     435        /* Get the recommended buffer size */
     436        glong string_buffer_size_long = sysconf (_SC_GETPW_R_SIZE_MAX);
     437        if (string_buffer_size_long > 0)
     438          string_buffer_size = string_buffer_size_long;
     439      }
     440  #endif /* _SC_GETPW_R_SIZE_MAX */
     441  
     442    /* Default starting size. */
     443    if (string_buffer_size == 0)
     444      string_buffer_size = 64;
     445  
     446    do
     447      {
     448        int retval;
     449  
     450        g_free (buffer);
     451        /* Allocate space for the `struct passwd`, and then a buffer for all its
     452         * strings (whose size is @string_buffer_size, which increases in this
     453         * loop until it’s big enough). Add 6 extra bytes to work around a bug in
     454         * macOS < 10.3. See #156446.
     455         */
     456        buffer = g_malloc0 (sizeof (*buffer) + string_buffer_size + 6);
     457  
     458        retval = getpwnam_r (user_name, &buffer->pwd, buffer->string_buffer,
     459                             string_buffer_size, &passwd_file_entry);
     460  
     461        /* Bail out if: the lookup was successful, or if the user id can't be
     462         * found (should be pretty rare case actually), or if the buffer should be
     463         * big enough and yet lookups are still not successful.
     464         */
     465        if (passwd_file_entry != NULL)
     466          {
     467            /* Success. */
     468            break;
     469          }
     470        else if (retval == 0 ||
     471            retval == ENOENT || retval == ESRCH ||
     472            retval == EBADF || retval == EPERM)
     473          {
     474            /* Username not found. */
     475            g_unix_set_error_from_errno (&local_error, retval);
     476            break;
     477          }
     478        else if (retval == ERANGE)
     479          {
     480            /* Can’t allocate enough string buffer space. */
     481            if (string_buffer_size > 32 * 1024)
     482              {
     483                g_unix_set_error_from_errno (&local_error, retval);
     484                break;
     485              }
     486  
     487            string_buffer_size *= 2;
     488            continue;
     489          }
     490        else
     491          {
     492            g_unix_set_error_from_errno (&local_error, retval);
     493            break;
     494          }
     495      }
     496    while (passwd_file_entry == NULL);
     497  
     498    g_assert (passwd_file_entry == NULL ||
     499              (gpointer) passwd_file_entry == (gpointer) buffer);
     500  
     501    /* Success or error. */
     502    if (local_error != NULL)
     503      {
     504        g_clear_pointer (&buffer, g_free);
     505        g_propagate_error (error, g_steal_pointer (&local_error));
     506      }
     507  
     508    return (struct passwd *) g_steal_pointer (&buffer);
     509  }