Subversion Repositories Kolibri OS

Rev

Rev 4874 | Go to most recent revision | 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.   _flockfile (fp);
  86.  
  87.   if (fp->_flags == 0)          /* not open! */
  88.     {
  89.       _funlockfile (fp);
  90. #ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
  91.       pthread_setcancelstate (__oldcancel, &__oldcancel);
  92. #endif
  93.       return (0);
  94.     }
  95.   /* Unconditionally flush to allow special handling for seekable read
  96.      files to reposition file to last byte processed as opposed to
  97.      last byte read ahead into the buffer.  */
  98.   r = _fflush_r (rptr, fp);
  99.   if (fp->_close != NULL && fp->_close (rptr, fp->_cookie) < 0)
  100.     r = EOF;
  101.   if (fp->_flags & __SMBF)
  102.     _free_r (rptr, (char *) fp->_bf._base);
  103.   if (HASUB (fp))
  104.     FREEUB (rptr, fp);
  105.   if (HASLB (fp))
  106.     FREELB (rptr, fp);
  107.   __sfp_lock_acquire ();
  108.   fp->_flags = 0;               /* release this FILE for reuse */
  109.   _funlockfile (fp);
  110. #ifndef __SINGLE_THREAD__
  111.   __lock_close_recursive (fp->_lock);
  112. #endif
  113.  
  114.   __sfp_lock_release ();
  115. #ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
  116.   pthread_setcancelstate (__oldcancel, &__oldcancel);
  117. #endif
  118.  
  119.   return (r);
  120. }
  121.  
  122. #ifndef _REENT_ONLY
  123.  
  124. int
  125. _DEFUN(fclose, (fp),
  126.        register FILE * fp)
  127. {
  128.   return _fclose_r(_REENT, fp);
  129. }
  130.  
  131. #endif
  132.