/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright © 2009 Codethink Limited
 *
 * This program 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 of the licence 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_ADDRESS_UNIX family by using g_socket_send_message()
 * and received using g_socket_receive_message().
 *
 * Note that <filename>&lt;gio/gunixfdlist.h&gt;</filename> belongs to
 * the UNIX-specific GIO interfaces, thus you have to use the
 * <filename>gio-unix-2.0.pc</filename> pkg-config file when using it.
 */

#define _GNU_SOURCE /* for F_DUPFD_CLOEXEC */

#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

#include "gunixfdlist.h"
#include "gioerror.h"



G_DEFINE_TYPE (GUnixFDList, g_unix_fd_list, G_TYPE_OBJECT)

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

static void
g_unix_fd_list_init (GUnixFDList *list)
{
  list->priv = G_TYPE_INSTANCE_GET_PRIVATE (list,
                                               G_TYPE_UNIX_FD_LIST,
                                               GUnixFDListPrivate);
}

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++)
    close (list->priv->fds[i]);
  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);

  g_type_class_add_private (class, sizeof (GUnixFDListPrivate));
  object_class->finalize = g_unix_fd_list_finalize;
}

static int
dup_close_on_exec_fd (gint     fd,
                      GError **error)
{
  gint new_fd;
  gint s;

#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));
      close (new_fd);

      return -1;
    }

  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));
      close (new_fd);

      return -1;
    }

  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: 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;

  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: 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: 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: 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: 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;
}
