~ubuntu-branches/ubuntu/feisty/trickle/feisty

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);
}