Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/sfio/sfclose.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#include "sfhdr.h"
23
24
/* Close a stream. A file stream is synced before closing.
25
**
26
** Written by Kiem-Phong Vo
27
*/
28
29
#if __STD_C
30
int sfclose(Sfio_t* f)
31
#else
32
int sfclose(f)
33
Sfio_t* f;
34
#endif
35
{
36
reg int local, ex, rv;
37
Void_t* data = NIL(Void_t*);
38
SFMTXDECL(f); /* declare a local stream variable for multithreading */
39
40
SFMTXENTER(f, -1);
41
42
GETLOCAL(f,local);
43
44
if(!(f->mode&SF_INIT) &&
45
SFMODE(f,local) != (f->mode&SF_RDWR) &&
46
SFMODE(f,local) != (f->mode&(SF_READ|SF_SYNCED)) &&
47
_sfmode(f,SF_SYNCED,local) < 0)
48
SFMTXRETURN(f,-1);
49
50
/* closing a stack of streams */
51
while(f->push)
52
{ reg Sfio_t* pop;
53
54
if(!(pop = (*_Sfstack)(f,NIL(Sfio_t*))) )
55
SFMTXRETURN(f,-1);
56
57
if(sfclose(pop) < 0)
58
{ (*_Sfstack)(f,pop);
59
SFMTXRETURN(f,-1);
60
}
61
}
62
63
rv = 0;
64
if(f->disc == _Sfudisc) /* closing the ungetc stream */
65
f->disc = NIL(Sfdisc_t*);
66
else if(f->file >= 0) /* sync file pointer */
67
{ f->bits |= SF_ENDING;
68
rv = sfsync(f);
69
}
70
71
SFLOCK(f,0);
72
73
/* raise discipline exceptions */
74
if(f->disc && (ex = SFRAISE(f,local ? SF_NEW : SF_CLOSING,NIL(Void_t*))) != 0)
75
SFMTXRETURN(f,ex);
76
77
if(!local && f->pool)
78
{ /* remove from pool */
79
if(f->pool == &_Sfpool)
80
{ reg int n;
81
82
POOLMTXLOCK(&_Sfpool);
83
for(n = 0; n < _Sfpool.n_sf; ++n)
84
{ if(_Sfpool.sf[n] != f)
85
continue;
86
/* found it */
87
_Sfpool.n_sf -= 1;
88
for(; n < _Sfpool.n_sf; ++n)
89
_Sfpool.sf[n] = _Sfpool.sf[n+1];
90
break;
91
}
92
POOLMTXUNLOCK(&_Sfpool);
93
}
94
else
95
{ f->mode &= ~SF_LOCK; /**/ASSERT(_Sfpmove);
96
if((*_Sfpmove)(f,-1) < 0)
97
{ SFOPEN(f,0);
98
SFMTXRETURN(f,-1);
99
}
100
f->mode |= SF_LOCK;
101
}
102
f->pool = NIL(Sfpool_t*);
103
}
104
105
if(f->data && (!local || (f->flags&SF_STRING) || (f->bits&SF_MMAP) ) )
106
{ /* free buffer */
107
#ifdef MAP_TYPE
108
if(f->bits&SF_MMAP)
109
SFMUNMAP(f,f->data,f->endb-f->data);
110
else
111
#endif
112
if(f->flags&SF_MALLOC)
113
data = (Void_t*)f->data;
114
115
f->data = NIL(uchar*);
116
f->size = -1;
117
}
118
119
/* zap the file descriptor */
120
if(_Sfnotify)
121
(*_Sfnotify)(f, SF_CLOSING, (void*)((long)f->file));
122
if(f->file >= 0 && !(f->flags&SF_STRING))
123
{ while(sysclosef(f->file) < 0 )
124
{ if(errno == EINTR)
125
errno = 0;
126
else
127
{ rv = -1;
128
break;
129
}
130
}
131
}
132
f->file = -1;
133
134
SFKILL(f);
135
f->flags &= SF_STATIC;
136
f->here = 0;
137
f->extent = -1;
138
f->endb = f->endr = f->endw = f->next = f->data;
139
140
/* zap any associated auxiliary buffer */
141
if(f->rsrv)
142
{ free(f->rsrv);
143
f->rsrv = NIL(Sfrsrv_t*);
144
}
145
146
/* delete any associated sfpopen-data */
147
if(f->proc)
148
rv = _sfpclose(f);
149
150
/* destroy the mutex */
151
if(f->mutex)
152
{ (void)vtmtxclrlock(f->mutex);
153
if(f != sfstdin && f != sfstdout && f != sfstderr)
154
{ (void)vtmtxclose(f->mutex);
155
f->mutex = NIL(Vtmutex_t*);
156
}
157
}
158
159
if(!local)
160
{ if(f->disc && (ex = SFRAISE(f,SF_FINAL,NIL(Void_t*))) != 0 )
161
{ rv = ex;
162
goto done;
163
}
164
165
if(!(f->flags&SF_STATIC) )
166
free(f);
167
else
168
{ f->disc = NIL(Sfdisc_t*);
169
f->stdio = NIL(Void_t*);
170
f->mode = SF_AVAIL;
171
}
172
}
173
174
done:
175
if(data)
176
free(data);
177
return rv;
178
}
179
180