root/maint/gnulib/lib/fd-hook.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. execute_close_hooks
  2. execute_all_close_hooks
  3. execute_ioctl_hooks
  4. execute_all_ioctl_hooks
  5. register_fd_hook
  6. unregister_fd_hook

   1 /* Hook for making file descriptor functions close(), ioctl() extensible.
   2    Copyright (C) 2009-2021 Free Software Foundation, Inc.
   3    Written by Bruno Haible <bruno@clisp.org>, 2009.
   4 
   5    This file is free software: you can redistribute it and/or modify
   6    it under the terms of the GNU Lesser General Public License as
   7    published by the Free Software Foundation; either version 2.1 of the
   8    License, or (at your option) any later version.
   9 
  10    This file is distributed in the hope that it will be useful,
  11    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13    GNU Lesser General Public License for more details.
  14 
  15    You should have received a copy of the GNU Lesser General Public License
  16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  17 
  18 #include <config.h>
  19 
  20 /* Specification.  */
  21 #include "fd-hook.h"
  22 
  23 #include <stdlib.h>
  24 
  25 /* Currently, this entire code is only needed for the handling of sockets
  26    on native Windows platforms.  */
  27 #if WINDOWS_SOCKETS
  28 
  29 /* The first and last link in the doubly linked list.
  30    Initially the list is empty.  */
  31 static struct fd_hook anchor = { &anchor, &anchor, NULL, NULL };
  32 
  33 int
  34 execute_close_hooks (const struct fd_hook *remaining_list, gl_close_fn primary,
     /* [previous][next][first][last][top][bottom][index][help] */
  35                      int fd)
  36 {
  37   if (remaining_list == &anchor)
  38     /* End of list reached.  */
  39     return primary (fd);
  40   else
  41     return remaining_list->private_close_fn (remaining_list->private_next,
  42                                              primary, fd);
  43 }
  44 
  45 int
  46 execute_all_close_hooks (gl_close_fn primary, int fd)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   return execute_close_hooks (anchor.private_next, primary, fd);
  49 }
  50 
  51 int
  52 execute_ioctl_hooks (const struct fd_hook *remaining_list, gl_ioctl_fn primary,
     /* [previous][next][first][last][top][bottom][index][help] */
  53                      int fd, int request, void *arg)
  54 {
  55   if (remaining_list == &anchor)
  56     /* End of list reached.  */
  57     return primary (fd, request, arg);
  58   else
  59     return remaining_list->private_ioctl_fn (remaining_list->private_next,
  60                                              primary, fd, request, arg);
  61 }
  62 
  63 int
  64 execute_all_ioctl_hooks (gl_ioctl_fn primary,
     /* [previous][next][first][last][top][bottom][index][help] */
  65                          int fd, int request, void *arg)
  66 {
  67   return execute_ioctl_hooks (anchor.private_next, primary, fd, request, arg);
  68 }
  69 
  70 void
  71 register_fd_hook (close_hook_fn close_hook, ioctl_hook_fn ioctl_hook, struct fd_hook *link)
     /* [previous][next][first][last][top][bottom][index][help] */
  72 {
  73   if (close_hook == NULL)
  74     close_hook = execute_close_hooks;
  75   if (ioctl_hook == NULL)
  76     ioctl_hook = execute_ioctl_hooks;
  77 
  78   if (link->private_next == NULL && link->private_prev == NULL)
  79     {
  80       /* Add the link to the doubly linked list.  */
  81       link->private_next = anchor.private_next;
  82       link->private_prev = &anchor;
  83       link->private_close_fn = close_hook;
  84       link->private_ioctl_fn = ioctl_hook;
  85       anchor.private_next->private_prev = link;
  86       anchor.private_next = link;
  87     }
  88   else
  89     {
  90       /* The link is already in use.  */
  91       if (link->private_close_fn != close_hook
  92           || link->private_ioctl_fn != ioctl_hook)
  93         abort ();
  94     }
  95 }
  96 
  97 void
  98 unregister_fd_hook (struct fd_hook *link)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100   struct fd_hook *next = link->private_next;
 101   struct fd_hook *prev = link->private_prev;
 102 
 103   if (next != NULL && prev != NULL)
 104     {
 105       /* The link is in use.  Remove it from the doubly linked list.  */
 106       prev->private_next = next;
 107       next->private_prev = prev;
 108       /* Clear the link, to mark it unused.  */
 109       link->private_next = NULL;
 110       link->private_prev = NULL;
 111       link->private_close_fn = NULL;
 112       link->private_ioctl_fn = NULL;
 113     }
 114 }
 115 
 116 #endif

/* [previous][next][first][last][top][bottom][index][help] */