Back to index

nagios-plugins  1.4.16
close-hook.c
Go to the documentation of this file.
00001 /* Hook for making the close() function extensible.
00002    Copyright (C) 2009, 2010 Free Software Foundation, Inc.
00003    Written by Bruno Haible <bruno@clisp.org>, 2009.
00004 
00005    This program is free software: you can redistribute it and/or modify it
00006    under the terms of the GNU General Public License as published
00007    by the Free Software Foundation; either version 3 of the License, or
00008    (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00017 
00018 #include <config.h>
00019 
00020 /* Specification.  */
00021 #include "close-hook.h"
00022 
00023 #include <stdlib.h>
00024 #include <unistd.h>
00025 
00026 #undef close
00027 
00028 
00029 /* Currently, this entire code is only needed for the handling of sockets
00030    on native Windows platforms.  */
00031 #if WINDOWS_SOCKETS
00032 
00033 /* The first and last link in the doubly linked list.
00034    Initially the list is empty.  */
00035 static struct close_hook anchor = { &anchor, &anchor, NULL };
00036 
00037 int
00038 execute_close_hooks (int fd, const struct close_hook *remaining_list)
00039 {
00040   if (remaining_list == &anchor)
00041     /* End of list reached.  */
00042     return close (fd);
00043   else
00044     return remaining_list->private_fn (fd, remaining_list->private_next);
00045 }
00046 
00047 int
00048 execute_all_close_hooks (int fd)
00049 {
00050   return execute_close_hooks (fd, anchor.private_next);
00051 }
00052 
00053 void
00054 register_close_hook (close_hook_fn hook, struct close_hook *link)
00055 {
00056   if (link->private_next == NULL && link->private_prev == NULL)
00057     {
00058       /* Add the link to the doubly linked list.  */
00059       link->private_next = anchor.private_next;
00060       link->private_prev = &anchor;
00061       link->private_fn = hook;
00062       anchor.private_next->private_prev = link;
00063       anchor.private_next = link;
00064     }
00065   else
00066     {
00067       /* The link is already in use.  */
00068       if (link->private_fn != hook)
00069         abort ();
00070     }
00071 }
00072 
00073 void
00074 unregister_close_hook (struct close_hook *link)
00075 {
00076   struct close_hook *next = link->private_next;
00077   struct close_hook *prev = link->private_prev;
00078 
00079   if (next != NULL && prev != NULL)
00080     {
00081       /* The link is in use.  Remove it from the doubly linked list.  */
00082       prev->private_next = next;
00083       next->private_prev = prev;
00084       /* Clear the link, to mark it unused.  */
00085       link->private_next = NULL;
00086       link->private_prev = NULL;
00087       link->private_fn = NULL;
00088     }
00089 }
00090 
00091 #endif