/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright © 2009 Codethink Limited
 *
 * 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.
 *
 * See the included COPYING file for more information.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 */

/**
 * SECTION:gunixfdlist
 * @title: GUnixFDList
 * @short_description: An object containing a set of UNIX file descriptors
 * @include: gio/gunixfdlist.h
 * @see_also: #GUnixFDMessage
 *
 * A #GUnixFDList contains a list of file descriptors.  It owns the file
 * descriptors that it contains, closing them when finalized.
 *
 * It may be wrapped in a #GUnixFDMessage and sent over a #GSocket in
 * the %G_SOCKET_FAMILY_UNIX family by using g_socket_send_message()
 * and received using g_socket_receive_message().
 *
 * Before 2.74, `<gio/gunixfdlist.h>` belonged to the UNIX-specific GIO
 * interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file when
 * using it.
 *
 * Since 2.74, the API is available for Windows.
 */

/**
 * GUnixFDList:
 *
 * #GUnixFDList is an opaque data structure and can only be accessed
 * using the following functions.
 **/

#include "config.h"

#include <fcntl.h>
#include <string.h>
#include <errno.h>

#include "gunixfdlist.h"
#include "gnetworking.h"
#include "gioerror.h"
#include "glib/glib-private.h"
#include "glib/gstdio.h"

#ifdef G_OS_WIN32
#include <io.h>
#endif

struct _GUnixFDListPrivate
{
  gint *fds;
  gint nfd;
};

G_DEFINE_TYPE_WITH_PRIVATE (GUnixFDList, g_unix_fd_list, G_TYPE_OBJECT)

static void
g_unix_fd_list_init (GUnixFDList *list)
{
  list->priv = g_unix_fd_list_get_instance_private (list);
}

static void
g_unix_fd_list_finalize (GObject *object)
{
  GUnixFDList *list = G_UNIX_FD_LIST (object);
  gint i;

  for (i = 0; i < list->priv->nfd; i++)
    g_close (list->priv->fds[i], NULL);
  g_free (list->priv->fds);

  G_OBJECT_CLASS (g_unix_fd_list_parent_class)
    ->finalize (object);
}

static void
g_unix_fd_list_class_init (GUnixFDListClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->finalize = g_unix_fd_list_finalize;
}

static int
dup_close_on_exec_fd (gint     fd,
                      GError **error)
{
  gint new_fd;
#ifndef G_OS_WIN32
  gint s;
#endif

#ifdef F_DUPFD_CLOEXEC
  do
    new_fd = fcntl (fd, F_DUPFD_CLOEXEC, 0l);
  while (new_fd < 0 && (errno == EINTR));

  if (new_fd >= 0)
    return new_fd;

  /* if that didn't work (new libc/old kernel?), try it the other way. */
#endif

  do
    new_fd = dup (fd);
  while (new_fd < 0 && (errno == EINTR));

  if (new_fd < 0)
    {
      int saved_errno = errno;

      g_set_error (error, G_IO_ERROR,
                   g_io_error_from_errno (saved_errno),
                   "dup: %s", g_strerror (saved_errno));

      return -1;
    }

#ifdef G_OS_WIN32
  new_fd = GLIB_PRIVATE_CALL (g_win32_reopen_noninherited) (new_fd, 0, error);
#else
  do
    {
      s = fcntl (new_fd, F_GETFD);

      if (s >= 0)
        s = fcntl (new_fd, F_SETFD, (long) (s | FD_CLOEXEC));
    }
  while (s < 0 && (errno == EINTR));

  if (s < 0)
    {
      int saved_errno = errno;

      g_set_error (error, G_IO_ERROR,
                   g_io_error_from_errno (saved_errno),
                   "fcntl: %s", g_strerror (saved_errno));
      g_close (new_fd, NULL);

      return -1;
    }
#endif

  return new_fd;
}

/**
 * g_unix_fd_list_new:
 *
 * Creates a new #GUnixFDList containing no file descriptors.
 *
 * Returns: a new #GUnixFDList
 *
 * Since: 2.24
 **/
GUnixFDList *
g_unix_fd_list_new (void)
{
  return g_object_new (G_TYPE_UNIX_FD_LIST, NULL);
}

/**
 * g_unix_fd_list_new_from_array:
 * @fds: (array length=n_fds): the initial list of file descriptors
 * @n_fds: the length of #fds, or -1
 *
 * Creates a new #GUnixFDList containing the file descriptors given in
 * @fds.  The file descriptors become the property of the new list and
 * may no longer be used by the caller.  The array itself is owned by
 * the caller.
 *
 * Each file descriptor in the array should be set to close-on-exec.
 *
 * If @n_fds is -1 then @fds must be terminated with -1.
 *
 * Returns: a new #GUnixFDList
 *
 * Since: 2.24
 **/
GUnixFDList *
g_unix_fd_list_new_from_array (const gint *fds,
                               gint        n_fds)
{
  GUnixFDList *list;

  g_return_val_if_fail (fds != NULL || n_fds == 0, NULL);

  if (n_fds == -1)
    for (n_fds = 0; fds[n_fds] != -1; n_fds++);

  list = g_object_new (G_TYPE_UNIX_FD_LIST, NULL);
  list->priv->fds = g_new (gint, n_fds + 1);
  list->priv->nfd = n_fds;

  if (n_fds > 0)
    memcpy (list->priv->fds, fds, sizeof (gint) * n_fds);
  list->priv->fds[n_fds] = -1;

  return list;
}

/**
 * g_unix_fd_list_steal_fds:
 * @list: a #GUnixFDList
 * @length: (out) (optional): pointer to the length of the returned
 *     array, or %NULL
 *
 * Returns the array of file descriptors that is contained in this
 * object.
 *
 * After this call, the descriptors are no longer contained in
 * @list. Further calls will return an empty list (unless more
 * descriptors have been added).
 *
 * The return result of this function must be freed with g_free().
 * The caller is also responsible for closing all of the file
 * descriptors.  The file descriptors in the array are set to
 * close-on-exec.
 *
 * If @length is non-%NULL then it is set to the number of file
 * descriptors in the returned array. The returned array is also
 * terminated with -1.
 *
 * This function never returns %NULL. In case there are no file
 * descriptors contained in @list, an empty array is returned.
 *
 * Returns: (array length=length) (transfer full): an array of file
 *     descriptors
 *
 * Since: 2.24
 */
gint *
g_unix_fd_list_steal_fds (GUnixFDList *list,
                          gint        *length)
{
  gint *result;

  g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), NULL);

  /* will be true for fresh object or if we were just called */
  if (list->priv->fds == NULL)
    {
      list->priv->fds = g_new (gint, 1);
      list->priv->fds[0] = -1;
      list->priv->nfd = 0;
    }

  if (length)
    *length = list->priv->nfd;
  result = list->priv->fds;

  list->priv->fds = NULL;
  list->priv->nfd = 0;

  return result;
}

/**
 * g_unix_fd_list_peek_fds:
 * @list: a #GUnixFDList
 * @length: (out) (optional): pointer to the length of the returned
 *     array, or %NULL
 *
 * Returns the array of file descriptors that is contained in this
 * object.
 *
 * After this call, the descriptors remain the property of @list.  The
 * caller must not close them and must not free the array.  The array is
 * valid only until @list is changed in any way.
 *
 * If @length is non-%NULL then it is set to the number of file
 * descriptors in the returned array. The returned array is also
 * terminated with -1.
 *
 * This function never returns %NULL. In case there are no file
 * descriptors contained in @list, an empty array is returned.
 *
 * Returns: (array length=length) (transfer none): an array of file
 *     descriptors
 *
 * Since: 2.24
 */
const gint *
g_unix_fd_list_peek_fds (GUnixFDList *list,
                         gint        *length)
{
  g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), NULL);

  /* will be true for fresh object or if steal() was just called */
  if (list->priv->fds == NULL)
    {
      list->priv->fds = g_new (gint, 1);
      list->priv->fds[0] = -1;
      list->priv->nfd = 0;
    }

  if (length)
    *length = list->priv->nfd;

  return list->priv->fds;
}

/**
 * g_unix_fd_list_append:
 * @list: a #GUnixFDList
 * @fd: a valid open file descriptor
 * @error: a #GError pointer
 *
 * Adds a file descriptor to @list.
 *
 * The file descriptor is duplicated using dup(). You keep your copy
 * of the descriptor and the copy contained in @list will be closed
 * when @list is finalized.
 *
 * A possible cause of failure is exceeding the per-process or
 * system-wide file descriptor limit.
 *
 * The index of the file descriptor in the list is returned.  If you use
 * this index with g_unix_fd_list_get() then you will receive back a
 * duplicated copy of the same file descriptor.
 *
 * Returns: the index of the appended fd in case of success, else -1
 *          (and @error is set)
 *
 * Since: 2.24
 */
gint
g_unix_fd_list_append (GUnixFDList  *list,
                       gint          fd,
                       GError      **error)
{
  gint new_fd;

  g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), -1);
  g_return_val_if_fail (fd >= 0, -1);
  g_return_val_if_fail (error == NULL || *error == NULL, -1);

  if ((new_fd = dup_close_on_exec_fd (fd, error)) < 0)
    return -1;

  list->priv->fds = g_realloc (list->priv->fds,
                                  sizeof (gint) *
                                   (list->priv->nfd + 2));
  list->priv->fds[list->priv->nfd++] = new_fd;
  list->priv->fds[list->priv->nfd] = -1;

  return list->priv->nfd - 1;
}

/**
 * g_unix_fd_list_get:
 * @list: a #GUnixFDList
 * @index_: the index into the list
 * @error: a #GError pointer
 *
 * Gets a file descriptor out of @list.
 *
 * @index_ specifies the index of the file descriptor to get.  It is a
 * programmer error for @index_ to be out of range; see
 * g_unix_fd_list_get_length().
 *
 * The file descriptor is duplicated using dup() and set as
 * close-on-exec before being returned.  You must call close() on it
 * when you are done.
 *
 * A possible cause of failure is exceeding the per-process or
 * system-wide file descriptor limit.
 *
 * Returns: the file descriptor, or -1 in case of error
 *
 * Since: 2.24
 **/
gint
g_unix_fd_list_get (GUnixFDList  *list,
                    gint          index_,
                    GError      **error)
{
  g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), -1);
  g_return_val_if_fail (index_ < list->priv->nfd, -1);
  g_return_val_if_fail (error == NULL || *error == NULL, -1);

  return dup_close_on_exec_fd (list->priv->fds[index_], error);
}

/**
 * g_unix_fd_list_get_length:
 * @list: a #GUnixFDList
 *
 * Gets the length of @list (ie: the number of file descriptors
 * contained within).
 *
 * Returns: the length of @list
 *
 * Since: 2.24
 **/
gint
g_unix_fd_list_get_length (GUnixFDList *list)
{
  g_return_val_if_fail (G_IS_UNIX_FD_LIST (list), 0);

  return list->priv->nfd;
}
