1 /* Hook for making the close() function extensible.
2 Copyright (C) 2009-2011 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2009.
5 This program is free software: you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program 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 GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "close-hook.h"
29 /* Currently, this entire code is only needed for the handling of sockets
30 on native Windows platforms. */
33 /* The first and last link in the doubly linked list.
34 Initially the list is empty. */
35 static struct close_hook anchor
= { &anchor
, &anchor
, NULL
};
38 execute_close_hooks (int fd
, const struct close_hook
*remaining_list
)
40 if (remaining_list
== &anchor
)
41 /* End of list reached. */
44 return remaining_list
->private_fn (fd
, remaining_list
->private_next
);
48 execute_all_close_hooks (int fd
)
50 return execute_close_hooks (fd
, anchor
.private_next
);
54 register_close_hook (close_hook_fn hook
, struct close_hook
*link
)
56 if (link
->private_next
== NULL
&& link
->private_prev
== NULL
)
58 /* Add the link to the doubly linked list. */
59 link
->private_next
= anchor
.private_next
;
60 link
->private_prev
= &anchor
;
61 link
->private_fn
= hook
;
62 anchor
.private_next
->private_prev
= link
;
63 anchor
.private_next
= link
;
67 /* The link is already in use. */
68 if (link
->private_fn
!= hook
)
74 unregister_close_hook (struct close_hook
*link
)
76 struct close_hook
*next
= link
->private_next
;
77 struct close_hook
*prev
= link
->private_prev
;
79 if (next
!= NULL
&& prev
!= NULL
)
81 /* The link is in use. Remove it from the doubly linked list. */
82 prev
->private_next
= next
;
83 next
->private_prev
= prev
;
84 /* Clear the link, to mark it unused. */
85 link
->private_next
= NULL
;
86 link
->private_prev
= NULL
;
87 link
->private_fn
= NULL
;