OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [stdio/] [fflush.c] - Blame information for rev 171

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
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
<<fflush>>---flush buffered file output
21
 
22
INDEX
23
        fflush
24
INDEX
25
        _fflush_r
26
 
27
ANSI_SYNOPSIS
28
        #include <stdio.h>
29
        int fflush(FILE *<[fp]>);
30
 
31
        int _fflush_r(struct _reent *<[reent]>, FILE *<[fp]>);
32
 
33
DESCRIPTION
34
The <<stdio>> output functions can buffer output before delivering it
35
to the host system, in order to minimize the overhead of system calls.
36
 
37
Use <<fflush>> to deliver any such pending output (for the file
38
or stream identified by <[fp]>) to the host system.
39
 
40
If <[fp]> is <<NULL>>, <<fflush>> delivers pending output from all
41
open files.
42
 
43
Additionally, if <[fp]> is a seekable input stream visiting a file
44
descriptor, set the position of the file descriptor to match next
45
unread byte, useful for obeying POSIX semantics when ending a process
46
without consuming all input from the stream.
47
 
48
The alternate function <<_fflush_r>> is a reentrant version, where the
49
extra argument <[reent]> is a pointer to a reentrancy structure, and
50
<[fp]> must not be NULL.
51
 
52
RETURNS
53
<<fflush>> returns <<0>> unless it encounters a write error; in that
54
situation, it returns <<EOF>>.
55
 
56
PORTABILITY
57
ANSI C requires <<fflush>>.  The behavior on input streams is only
58
specified by POSIX, and not all implementations follow POSIX rules.
59
 
60
No supporting OS subroutines are required.
61
*/
62
 
63
#include <_ansi.h>
64
#include <stdio.h>
65
#include <errno.h>
66
#include "local.h"
67
 
68
/* Flush a single file, or (if fp is NULL) all files.  */
69
 
70
int
71
_DEFUN(_fflush_r, (ptr, fp),
72
       struct _reent *ptr _AND
73
       register FILE * fp)
74
{
75
  register unsigned char *p;
76
  register int n, t;
77
 
78
#ifdef _REENT_SMALL
79
  /* For REENT_SMALL platforms, it is possible we are being
80
     called for the first time on a std stream.  This std
81
     stream can belong to a reentrant struct that is not
82
     _REENT.  If CHECK_INIT gets called below based on _REENT,
83
     we will end up changing said file pointers to the equivalent
84
     std stream off of _REENT.  This causes unexpected behavior if
85
     there is any data to flush on the _REENT std stream.  There
86
     are two alternatives to fix this:  1) make a reentrant fflush
87
     or 2) simply recognize that this file has nothing to flush
88
     and return immediately before performing a CHECK_INIT.  Choice
89
     2 is implemented here due to its simplicity.  */
90
  if (fp->_bf._base == NULL)
91
    return 0;
92
#endif /* _REENT_SMALL  */
93
 
94
  CHECK_INIT (ptr, fp);
95
 
96
  _flockfile (fp);
97
 
98
  t = fp->_flags;
99
  if ((t & __SWR) == 0)
100
    {
101
      /* For a read stream, an fflush causes the next seek to be
102
         unoptimized (i.e. forces a system-level seek).  This conforms
103
         to the POSIX and SUSv3 standards.  */
104
      fp->_flags |= __SNPT;
105
 
106
      /* For a seekable stream with buffered read characters, we will attempt
107
         a seek to the current position now.  A subsequent read will then get
108
         the next byte from the file rather than the buffer.  This conforms
109
         to the POSIX and SUSv3 standards.  Note that the standards allow
110
         this seek to be deferred until necessary, but we choose to do it here
111
         to make the change simpler, more contained, and less likely
112
         to miss a code scenario.  */
113
      if ((fp->_r > 0 || fp->_ur > 0) && fp->_seek != NULL)
114
        {
115
          int tmp;
116
#ifdef __LARGE64_FILES
117
          _fpos64_t curoff;
118
#else
119
          _fpos_t curoff;
120
#endif
121
 
122
          /* Get the physical position we are at in the file.  */
123
          if (fp->_flags & __SOFF)
124
            curoff = fp->_offset;
125
          else
126
            {
127
              /* We don't know current physical offset, so ask for it.
128
                 Only ESPIPE is ignorable.  */
129
#ifdef __LARGE64_FILES
130
              if (fp->_flags & __SL64)
131
                curoff = fp->_seek64 (ptr, fp->_cookie, 0, SEEK_CUR);
132
              else
133
#endif
134
                curoff = fp->_seek (ptr, fp->_cookie, 0, SEEK_CUR);
135
              if (curoff == -1L)
136
                {
137
                  int result = EOF;
138
                  if (ptr->_errno == ESPIPE)
139
                    result = 0;
140
                  else
141
                    fp->_flags |= __SERR;
142
                  _funlockfile (fp);
143
                  return result;
144
                }
145
            }
146
          if (fp->_flags & __SRD)
147
            {
148
              /* Current offset is at end of buffer.  Compensate for
149
                 characters not yet read.  */
150
              curoff -= fp->_r;
151
              if (HASUB (fp))
152
                curoff -= fp->_ur;
153
            }
154
          /* Now physically seek to after byte last read.  */
155
#ifdef __LARGE64_FILES
156
          if (fp->_flags & __SL64)
157
            tmp = (fp->_seek64 (ptr, fp->_cookie, curoff, SEEK_SET) == curoff);
158
          else
159
#endif
160
            tmp = (fp->_seek (ptr, fp->_cookie, curoff, SEEK_SET) == curoff);
161
          if (tmp)
162
            {
163
              /* Seek successful.  We can clear read buffer now.  */
164
              fp->_flags &= ~__SNPT;
165
              fp->_r = 0;
166
              fp->_p = fp->_bf._base;
167
              if (fp->_flags & __SOFF)
168
                fp->_offset = curoff;
169
              if (HASUB (fp))
170
                FREEUB (ptr, fp);
171
            }
172
          else
173
            {
174
              fp->_flags |= __SERR;
175
              _funlockfile (fp);
176
              return EOF;
177
            }
178
        }
179
      _funlockfile (fp);
180
      return 0;
181
    }
182
  if ((p = fp->_bf._base) == NULL)
183
    {
184
      /* Nothing to flush.  */
185
      _funlockfile (fp);
186
      return 0;
187
    }
188
  n = fp->_p - p;               /* write this much */
189
 
190
  /*
191
   * Set these immediately to avoid problems with longjmp
192
   * and to allow exchange buffering (via setvbuf) in user
193
   * write function.
194
   */
195
  fp->_p = p;
196
  fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
197
 
198
  while (n > 0)
199
    {
200
      t = fp->_write (ptr, fp->_cookie, (char *) p, n);
201
      if (t <= 0)
202
        {
203
          fp->_flags |= __SERR;
204
          _funlockfile (fp);
205
          return EOF;
206
        }
207
      p += t;
208
      n -= t;
209
    }
210
  _funlockfile (fp);
211
  return 0;
212
}
213
 
214
#ifndef _REENT_ONLY
215
 
216
int
217
_DEFUN(fflush, (fp),
218
       register FILE * fp)
219
{
220
  if (fp == NULL)
221
    return _fwalk_reent (_GLOBAL_REENT, _fflush_r);
222
 
223
  return _fflush_r (_REENT, fp);
224
}
225
 
226
#endif /* _REENT_ONLY */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.