Subversion Repositories Kolibri OS

Rev

Rev 4921 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/*
2
 * Copyright (c) 1990 The Regents of the University of California.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
17
 
18
/*
19
FUNCTION
20
<>---close a file
21
 
22
INDEX
23
	fclose
24
INDEX
25
	_fclose_r
26
 
27
ANSI_SYNOPSIS
28
	#include 
29
	int fclose(FILE *<[fp]>);
30
	int _fclose_r(struct _reent *<[reent]>, FILE *<[fp]>);
31
 
32
TRAD_SYNOPSIS
33
	#include 
34
	int fclose(<[fp]>)
35
	FILE *<[fp]>;
36
 
37
	int fclose(<[fp]>)
38
        struct _reent *<[reent]>
39
	FILE *<[fp]>;
40
 
41
DESCRIPTION
42
If the file or stream identified by <[fp]> is open, <> closes
43
it, after first ensuring that any pending data is written (by calling
44
<)>>).
45
 
46
The alternate function <<_fclose_r>> is a reentrant version.
47
The extra argument <[reent]> is a pointer to a reentrancy structure.
48
 
49
RETURNS
50
<> returns <<0>> if successful (including when <[fp]> is
51
<> or not an open file); otherwise, it returns <>.
52
 
53
PORTABILITY
54
<> is required by ANSI C.
55
 
56
Required OS subroutines: <>, <>, <>, <>,
57
<>, <>, <>.
58
*/
59
 
60
#include <_ansi.h>
61
#include 
62
#include 
63
#include 
64
#include 
65
#include "local.h"
66
 
67
int
68
_DEFUN(_fclose_r, (rptr, fp),
69
      struct _reent *rptr _AND
70
      register FILE * fp)
71
{
72
  int r;
73
 
74
  if (fp == NULL)
75
    return (0);			/* on NULL */
76
 
77
  CHECK_INIT (rptr, fp);
78
 
4921 Serge 79
  /* We can't use the _newlib_flockfile_XXX macros here due to the
80
     interlocked locking with the sfp_lock. */
81
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
82
  int __oldcancel;
83
  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
84
#endif
6099 serge 85
  if (!(fp->_flags2 & __SNLK))
86
    _flockfile (fp);
4349 Serge 87
 
88
  if (fp->_flags == 0)		/* not open! */
89
    {
6099 serge 90
      if (!(fp->_flags2 & __SNLK))
91
	_funlockfile (fp);
4921 Serge 92
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
93
      pthread_setcancelstate (__oldcancel, &__oldcancel);
94
#endif
4349 Serge 95
      return (0);
96
    }
6099 serge 97
#ifdef _STDIO_BSD_SEMANTICS
98
  /* BSD and Glibc systems only flush streams which have been written to. */
99
  r = (fp->_flags & __SWR) ? __sflush_r (rptr, fp) : 0;
100
#else
101
  /* Follow POSIX semantics exactly.  Unconditionally flush to allow
102
     special handling for seekable read files to reposition file to last
103
     byte processed as opposed to last byte read ahead into the buffer. */
104
  r = __sflush_r (rptr, fp);
105
#endif
4349 Serge 106
  if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0)
107
    r = EOF;
108
  if (fp->_flags & __SMBF)
109
    _free_r (rptr, (char *) fp->_bf._base);
110
  if (HASUB (fp))
111
    FREEUB (rptr, fp);
112
  if (HASLB (fp))
113
    FREELB (rptr, fp);
114
  __sfp_lock_acquire ();
115
  fp->_flags = 0;		/* release this FILE for reuse */
6099 serge 116
  if (!(fp->_flags2 & __SNLK))
117
    _funlockfile (fp);
4349 Serge 118
#ifndef __SINGLE_THREAD__
119
  __lock_close_recursive (fp->_lock);
120
#endif
121
 
122
  __sfp_lock_release ();
4921 Serge 123
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
124
  pthread_setcancelstate (__oldcancel, &__oldcancel);
125
#endif
4349 Serge 126
 
127
  return (r);
128
}
129
 
130
#ifndef _REENT_ONLY
131
 
132
int
133
_DEFUN(fclose, (fp),
134
       register FILE * fp)
135
{
136
  return _fclose_r(_REENT, fp);
137
}
138
 
139
#endif