Subversion Repositories Kolibri OS

Rev

Rev 4921 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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. <<fclose>>---close a file
  21.  
  22. INDEX
  23.         fclose
  24. INDEX
  25.         _fclose_r
  26.  
  27. ANSI_SYNOPSIS
  28.         #include <stdio.h>
  29.         int fclose(FILE *<[fp]>);
  30.         int _fclose_r(struct _reent *<[reent]>, FILE *<[fp]>);
  31.  
  32. TRAD_SYNOPSIS
  33.         #include <stdio.h>
  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, <<fclose>> closes
  43. it, after first ensuring that any pending data is written (by calling
  44. <<fflush(<[fp]>)>>).
  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. <<fclose>> returns <<0>> if successful (including when <[fp]> is
  51. <<NULL>> or not an open file); otherwise, it returns <<EOF>>.
  52.  
  53. PORTABILITY
  54. <<fclose>> is required by ANSI C.
  55.  
  56. Required OS subroutines: <<close>>, <<fstat>>, <<isatty>>, <<lseek>>,
  57. <<read>>, <<sbrk>>, <<write>>.
  58. */
  59.  
  60. #include <_ansi.h>
  61. #include <reent.h>
  62. #include <stdio.h>
  63. #include <stdlib.h>
  64. #include <sys/lock.h>
  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.  
  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
  85.   if (!(fp->_flags2 & __SNLK))
  86.     _flockfile (fp);
  87.  
  88.   if (fp->_flags == 0)          /* not open! */
  89.     {
  90.       if (!(fp->_flags2 & __SNLK))
  91.         _funlockfile (fp);
  92. #ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
  93.       pthread_setcancelstate (__oldcancel, &__oldcancel);
  94. #endif
  95.       return (0);
  96.     }
  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
  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 */
  116.   if (!(fp->_flags2 & __SNLK))
  117.     _funlockfile (fp);
  118. #ifndef __SINGLE_THREAD__
  119.   __lock_close_recursive (fp->_lock);
  120. #endif
  121.  
  122.   __sfp_lock_release ();
  123. #ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
  124.   pthread_setcancelstate (__oldcancel, &__oldcancel);
  125. #endif
  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
  140.