/* Hook for making file descriptor functions close(), ioctl() extensible.
   Copyright (C) 2009-2022 Free Software Foundation, Inc.
   Written by Bruno Haible <bruno@clisp.org>, 2009.

   This file 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 file 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 program.  If not, see <https://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include "fd-hook.h"

#include <stdlib.h>

/* Currently, this entire code is only needed for the handling of sockets
   on native Windows platforms.  */
#if WINDOWS_SOCKETS

/* The first and last link in the doubly linked list.
   Initially the list is empty.  */
static struct fd_hook anchor = { &anchor, &anchor, NULL, NULL };

int
execute_close_hooks (const struct fd_hook *remaining_list, gl_close_fn primary,
                     int fd)
{
  if (remaining_list == &anchor)
    /* End of list reached.  */
    return primary (fd);
  else
    return remaining_list->private_close_fn (remaining_list->private_next,
                                             primary, fd);
}

int
execute_all_close_hooks (gl_close_fn primary, int fd)
{
  return execute_close_hooks (anchor.private_next, primary, fd);
}

int
execute_ioctl_hooks (const struct fd_hook *remaining_list, gl_ioctl_fn primary,
                     int fd, int request, void *arg)
{
  if (remaining_list == &anchor)
    /* End of list reached.  */
    return primary (fd, request, arg);
  else
    return remaining_list->private_ioctl_fn (remaining_list->private_next,
                                             primary, fd, request, arg);
}

int
execute_all_ioctl_hooks (gl_ioctl_fn primary,
                         int fd, int request, void *arg)
{
  return execute_ioctl_hooks (anchor.private_next, primary, fd, request, arg);
}

void
register_fd_hook (close_hook_fn close_hook, ioctl_hook_fn ioctl_hook, struct fd_hook *link)
{
  if (close_hook == NULL)
    close_hook = execute_close_hooks;
  if (ioctl_hook == NULL)
    ioctl_hook = execute_ioctl_hooks;

  if (link->private_next == NULL && link->private_prev == NULL)
    {
      /* Add the link to the doubly linked list.  */
      link->private_next = anchor.private_next;
      link->private_prev = &anchor;
      link->private_close_fn = close_hook;
      link->private_ioctl_fn = ioctl_hook;
      anchor.private_next->private_prev = link;
      anchor.private_next = link;
    }
  else
    {
      /* The link is already in use.  */
      if (link->private_close_fn != close_hook
          || link->private_ioctl_fn != ioctl_hook)
        abort ();
    }
}

void
unregister_fd_hook (struct fd_hook *link)
{
  struct fd_hook *next = link->private_next;
  struct fd_hook *prev = link->private_prev;

  if (next != NULL && prev != NULL)
    {
      /* The link is in use.  Remove it from the doubly linked list.  */
      prev->private_next = next;
      next->private_prev = prev;
      /* Clear the link, to mark it unused.  */
      link->private_next = NULL;
      link->private_prev = NULL;
      link->private_close_fn = NULL;
      link->private_ioctl_fn = NULL;
    }
}

#endif
