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