/* 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: (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;

  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) (allow-none): 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) (allow-none): 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;
}
