-
Notifications
You must be signed in to change notification settings - Fork 64
/
cleanup.c
122 lines (92 loc) · 1.83 KB
/
cleanup.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* cleanup.c
*
* Copyright (c) 2002 Marius Aamodt Eriksen <marius@monkey.org>
* All rights reserved.
*
* $Id: cleanup.c,v 1.2 2003/03/06 05:49:36 marius Exp $
*/
#include <sys/types.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <sys/queue.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
struct cleanupq {
void (*f)(void *);
void *handler;
TAILQ_ENTRY(cleanupq) next;
};
TAILQ_HEAD(cleanupqh, cleanupq);
struct cleanup {
struct cleanupqh head;
};
struct cleanup *
cleanup_new(void)
{
struct cleanup *clup;
if ((clup = calloc(1, sizeof(*clup))) == NULL)
return (NULL);
TAILQ_INIT(&clup->head);
return (clup);
}
struct cleanup *
cleanup_free(struct cleanup *clup)
{
struct cleanupq *cq;
while ((cq = TAILQ_FIRST(&clup->head)) != NULL) {
TAILQ_REMOVE(&clup->head, cq, next);
free(cq);
}
free(clup);
return (NULL);
}
int
cleanup_add(struct cleanup *clup, void (*f)(void *), void *handler)
{
struct cleanupq *cq;
if ((cq = malloc(sizeof(*cq))) == NULL)
return (-1);
cq->f = f;
cq->handler = handler;
TAILQ_INSERT_HEAD(&clup->head, cq, next);
return (0);
}
int
cleanup_remove(struct cleanup *clup, void (*f)(void *), void *handler)
{
struct cleanupq *search;
TAILQ_FOREACH(search, &clup->head, next)
if (search->f == f && search->handler == handler)
break;
if (search != NULL) {
TAILQ_REMOVE(&clup->head, search, next);
free(search);
return (0);
}
return (-1);
}
void
cleanup_cleanup(struct cleanup *clup)
{
struct cleanupq *cq;
while ((cq = TAILQ_FIRST(&clup->head)) != NULL) {
(*cq->f)(cq->handler);
TAILQ_REMOVE(&clup->head, cq, next);
free(cq);
}
}
void
cleanupcb_close(void *_fd)
{
int fd = *(int *)_fd;
close(fd);
}
void
cleanupcb_unlink(void *_fname)
{
char *fname = (char *)_fname;
unlink(fname);
}