1/* -*- buffer-read-only: t -*- vi: set ro: */ 2/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ 3#line 1 4/* Hook for making the close() function extensible. 5 Copyright (C) 2009, 2010 Free Software Foundation, Inc. 6 Written by Bruno Haible <bruno@clisp.org>, 2009. 7 8 This program is free software: you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published 10 by the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Lesser General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20 21#include <config.h> 22 23/* Specification. */ 24#include "close-hook.h" 25 26#include <stdlib.h> 27#include <unistd.h> 28 29#undef close 30 31 32/* Currently, this entire code is only needed for the handling of sockets 33 on native Windows platforms. */ 34#if WINDOWS_SOCKETS 35 36/* The first and last link in the doubly linked list. 37 Initially the list is empty. */ 38static struct close_hook anchor = { &anchor, &anchor, NULL }; 39 40int 41execute_close_hooks (int fd, const struct close_hook *remaining_list) 42{ 43 if (remaining_list == &anchor) 44 /* End of list reached. */ 45 return close (fd); 46 else 47 return remaining_list->private_fn (fd, remaining_list->private_next); 48} 49 50int 51execute_all_close_hooks (int fd) 52{ 53 return execute_close_hooks (fd, anchor.private_next); 54} 55 56void 57register_close_hook (close_hook_fn hook, struct close_hook *link) 58{ 59 if (link->private_next == NULL && link->private_prev == NULL) 60 { 61 /* Add the link to the doubly linked list. */ 62 link->private_next = anchor.private_next; 63 link->private_prev = &anchor; 64 link->private_fn = hook; 65 anchor.private_next->private_prev = link; 66 anchor.private_next = link; 67 } 68 else 69 { 70 /* The link is already in use. */ 71 if (link->private_fn != hook) 72 abort (); 73 } 74} 75 76void 77unregister_close_hook (struct close_hook *link) 78{ 79 struct close_hook *next = link->private_next; 80 struct close_hook *prev = link->private_prev; 81 82 if (next != NULL && prev != NULL) 83 { 84 /* The link is in use. Remove it from the doubly linked list. */ 85 prev->private_next = next; 86 next->private_prev = prev; 87 /* Clear the link, to mark it unused. */ 88 link->private_next = NULL; 89 link->private_prev = NULL; 90 link->private_fn = NULL; 91 } 92} 93 94#endif 95