1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Close a stream. A file stream is synced before closing.
26 ** Written by Kiem-Phong Vo
30 int sfclose(Sfio_t
* f
)
36 reg
int local
, ex
, rv
;
37 Void_t
* data
= NIL(Void_t
*);
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)
50 /* closing a stack of streams */
54 if(!(pop
= (*_Sfstack
)(f
,NIL(Sfio_t
*))) )
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
;
73 /* raise discipline exceptions */
74 if(f
->disc
&& (ex
= SFRAISE(f
,local
? SF_NEW
: SF_CLOSING
,NIL(Void_t
*))) != 0)
78 { /* remove from pool */
79 if(f
->pool
== &_Sfpool
)
82 POOLMTXLOCK(&_Sfpool
);
83 for(n
= 0; n
< _Sfpool
.n_sf
; ++n
)
84 { if(_Sfpool
.sf
[n
] != f
)
88 for(; n
< _Sfpool
.n_sf
; ++n
)
89 _Sfpool
.sf
[n
] = _Sfpool
.sf
[n
+1];
92 POOLMTXUNLOCK(&_Sfpool
);
95 { f
->mode
&= ~SF_LOCK
; /**/ASSERT(_Sfpmove
);
96 if((*_Sfpmove
)(f
,-1) < 0)
102 f
->pool
= NIL(Sfpool_t
*);
105 if(f
->data
&& (!local
|| (f
->flags
&SF_STRING
) || (f
->bits
&SF_MMAP
) ) )
109 SFMUNMAP(f
,f
->data
,f
->endb
-f
->data
);
112 if(f
->flags
&SF_MALLOC
)
113 data
= (Void_t
*)f
->data
;
115 f
->data
= NIL(uchar
*);
119 /* zap the file descriptor */
121 (*_Sfnotify
)(f
, SF_CLOSING
, (void*)((long)f
->file
));
122 if(f
->file
>= 0 && !(f
->flags
&SF_STRING
))
127 f
->flags
&= SF_STATIC
;
130 f
->endb
= f
->endr
= f
->endw
= f
->next
= f
->data
;
132 /* zap any associated auxiliary buffer */
135 f
->rsrv
= NIL(Sfrsrv_t
*);
138 /* delete any associated sfpopen-data */
142 /* destroy the mutex */
144 { (void)vtmtxclrlock(f
->mutex
);
145 if(f
!= sfstdin
&& f
!= sfstdout
&& f
!= sfstderr
)
146 { (void)vtmtxclose(f
->mutex
);
147 f
->mutex
= NIL(Vtmutex_t
*);
152 { if(f
->disc
&& (ex
= SFRAISE(f
,SF_FINAL
,NIL(Void_t
*))) != 0 )
157 if(!(f
->flags
&SF_STATIC
) )
160 { f
->disc
= NIL(Sfdisc_t
*);
161 f
->stdio
= NIL(Void_t
*);