-
Notifications
You must be signed in to change notification settings - Fork 1
/
close.ch
66 lines (57 loc) · 1.28 KB
/
close.ch
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
Close any open input files before exiting.
Otherwise they will be closed automatically,
which may result to "Segmentation fault" on
old systems (due to the glibc bug in handling
wide-character streams).
@x
return reset_OK(*f);
@y
if (f->f != NULL) list_add(f->f);
return reset_OK(*f);
@z
@x
{@+close((*f));
@y
{ list_delete(f->f); close(*f);
@z
@x
initialize(); /*set global variables to their starting values*/
@y
atexit(list_close);
initialize(); /*set global variables to their starting values*/
@z
===== Definitions of list_add, list_delete and list_close: =====
@x
@ Appendix: Replacement of the string pool file.
@y
@<Compiler directives@>=
struct node {
void *f;
struct node *n;
};
typedef struct node * node;
node list_head = NULL;
void list_add(void *f)
{
if (f == NULL) return;
node e = (node) malloc(sizeof (struct node));
e->f = f, e->n = list_head, list_head = e;
}
void list_delete(void *f)
{
node c = list_head;
node p = NULL;
if (list_head == NULL) return;
while (c->f != f)
if (c->n == NULL) return;
else p = c, c = c->n;
if (c == list_head) list_head = list_head->n;
else p->n = c->n;
free(c);
}
void list_close(void)
{
for (node c = list_head; c != NULL; c = c->n) fclose(c->f);
}
@ Appendix: Replacement of the string pool file.
@z