25b4d9eb54bc4694ab9f7e7e5d2ffeee2d91086b
[util-vserver.git] / vserver-start / undo.c
1 // $Id: undo.c,v 1.1 2004/08/19 15:02:57 ensc Exp $    --*- c -*--
2
3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
8 //  
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //  
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "undo.h"
24
25 #include <lib_internal/util.h>
26 #include <ensc_vector/vector.h>
27
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <assert.h>
31
32 struct FuncData
33 {
34     ExitFunction                fn;
35     void const *                args;
36 };
37
38 struct Undo
39 {
40     pid_t               pid_;
41     struct Vector       funcs;
42 };
43
44
45 static struct Undo      undo_data = {
46   .pid_ = -1
47 };
48
49 static void
50 atexitHandler()
51 {
52   struct FuncData const *       ptr;
53
54   if (undo_data.pid_ != getpid())
55     return;     // skip 'exit()' from forked processes
56
57   for (ptr=Vector_end(&undo_data.funcs);
58        ptr!=Vector_begin(&undo_data.funcs);
59        --ptr)
60     (ptr[-1].fn)(ptr[-1].args);
61 }
62
63 void
64 Undo_init()
65 {
66   if (undo_data.pid_!=-1) {
67     WRITE_MSG(2, "Undo already initialized; internal error...\n");
68     _exit(1);
69   }
70
71   undo_data.pid_ = getpid();
72   Vector_init(&undo_data.funcs, sizeof(struct FuncData));
73   
74   atexit(&atexitHandler);
75 }
76
77 void
78 Undo_addTask(ExitFunction fn, void const *args)
79 {
80   struct FuncData       *tmp = Vector_pushback(&undo_data.funcs);
81   assert(tmp!=0); // Vector_pushback never returns a null-pointer
82
83   tmp->fn   = fn;
84   tmp->args = args;
85 }
86
87 void
88 Undo_detach()
89 {
90   Vector_free(&undo_data.funcs);
91   undo_data.pid_ = -1;
92 }