Subversion Repositories Kolibri OS

Rev

Rev 4874 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4874 Rev 4921
1
/*
1
/*
2
 * Copyright (c) 1990, 2007 The Regents of the University of California.
2
 * Copyright (c) 1990, 2007 The Regents of the University of California.
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms are permitted
5
 * Redistribution and use in source and binary forms are permitted
6
 * provided that the above copyright notice and this paragraph are
6
 * provided that the above copyright notice and this paragraph are
7
 * duplicated in all such forms and that any documentation,
7
 * duplicated in all such forms and that any documentation,
8
 * advertising materials, and other materials related to such
8
 * advertising materials, and other materials related to such
9
 * distribution and use acknowledge that the software was developed
9
 * distribution and use acknowledge that the software was developed
10
 * by the University of California, Berkeley.  The name of the
10
 * by the University of California, Berkeley.  The name of the
11
 * University may not be used to endorse or promote products derived
11
 * University may not be used to endorse or promote products derived
12
 * from this software without specific prior written permission.
12
 * from this software without specific prior written permission.
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16
 */
16
 */
17
 
17
 
18
/*
18
/*
19
FUNCTION
19
FUNCTION
20
<>---open a file using an existing file descriptor
20
<>---open a file using an existing file descriptor
21
 
21
 
22
INDEX
22
INDEX
23
	freopen
23
	freopen
24
INDEX
24
INDEX
25
	_freopen_r
25
	_freopen_r
26
 
26
 
27
ANSI_SYNOPSIS
27
ANSI_SYNOPSIS
28
	#include 
28
	#include 
29
	FILE *freopen(const char *<[file]>, const char *<[mode]>,
29
	FILE *freopen(const char *restrict <[file]>, const char *restrict <[mode]>,
30
		      FILE *<[fp]>);
30
		      FILE *restrict <[fp]>);
31
	FILE *_freopen_r(struct _reent *<[ptr]>, const char *<[file]>,
31
	FILE *_freopen_r(struct _reent *<[ptr]>, const char *restrict <[file]>,
32
		      const char *<[mode]>, FILE *<[fp]>);
32
		      const char *restrict <[mode]>, FILE *restrict <[fp]>);
33
 
33
 
34
TRAD_SYNOPSIS
34
TRAD_SYNOPSIS
35
	#include 
35
	#include 
36
	FILE *freopen(<[file]>, <[mode]>, <[fp]>)
36
	FILE *freopen(<[file]>, <[mode]>, <[fp]>)
37
	char *<[file]>;
37
	char *<[file]>;
38
	char *<[mode]>;
38
	char *<[mode]>;
39
	FILE *<[fp]>;
39
	FILE *<[fp]>;
40
 
40
 
41
	FILE *_freopen_r(<[ptr]>, <[file]>, <[mode]>, <[fp]>)
41
	FILE *_freopen_r(<[ptr]>, <[file]>, <[mode]>, <[fp]>)
42
	struct _reent *<[ptr]>;
42
	struct _reent *<[ptr]>;
43
	char *<[file]>;
43
	char *<[file]>;
44
	char *<[mode]>;
44
	char *<[mode]>;
45
	FILE *<[fp]>;
45
	FILE *<[fp]>;
46
 
46
 
47
DESCRIPTION
47
DESCRIPTION
48
Use this variant of <> if you wish to specify a particular file
48
Use this variant of <> if you wish to specify a particular file
49
descriptor <[fp]> (notably <>, <>, or <>) for
49
descriptor <[fp]> (notably <>, <>, or <>) for
50
the file.
50
the file.
51
 
51
 
52
If <[fp]> was associated with another file or stream, <>
52
If <[fp]> was associated with another file or stream, <>
53
closes that other file or stream (but ignores any errors while closing
53
closes that other file or stream (but ignores any errors while closing
54
it).
54
it).
55
 
55
 
56
<[file]> and <[mode]> are used just as in <>.
56
<[file]> and <[mode]> are used just as in <>.
57
 
57
 
58
If <[file]> is <>, the underlying stream is modified rather than
58
If <[file]> is <>, the underlying stream is modified rather than
59
closed.  The file cannot be given a more permissive access mode (for
59
closed.  The file cannot be given a more permissive access mode (for
60
example, a <[mode]> of "w" will fail on a read-only file descriptor),
60
example, a <[mode]> of "w" will fail on a read-only file descriptor),
61
but can change status such as append or binary mode.  If modification
61
but can change status such as append or binary mode.  If modification
62
is not possible, failure occurs.
62
is not possible, failure occurs.
63
 
63
 
64
RETURNS
64
RETURNS
65
If successful, the result is the same as the argument <[fp]>.  If the
65
If successful, the result is the same as the argument <[fp]>.  If the
66
file cannot be opened as specified, the result is <>.
66
file cannot be opened as specified, the result is <>.
67
 
67
 
68
PORTABILITY
68
PORTABILITY
69
ANSI C requires <>.
69
ANSI C requires <>.
70
 
70
 
71
Supporting OS subroutines required: <>, <>, <>,
71
Supporting OS subroutines required: <>, <>, <>,
72
<>, <>, <>, <>, <>.
72
<>, <>, <>, <>, <>.
73
*/
73
*/
74
 
74
 
75
#include <_ansi.h>
75
#include <_ansi.h>
76
#include 
76
#include 
77
#include 
77
#include 
78
#include 
78
#include 
79
#include 
79
#include 
80
#include 
80
#include 
81
#include 
81
#include 
82
#include 
82
#include 
83
#include 
83
#include 
84
#include "local.h"
84
#include "local.h"
85
 
85
 
86
/*
86
/*
87
 * Re-direct an existing, open (probably) file to some other file.
87
 * Re-direct an existing, open (probably) file to some other file.
88
 */
88
 */
89
 
89
 
90
FILE *
90
FILE *
91
_DEFUN(_freopen_r, (ptr, file, mode, fp),
91
_DEFUN(_freopen_r, (ptr, file, mode, fp),
92
       struct _reent *ptr _AND
92
       struct _reent *ptr _AND
93
       const char *file _AND
93
       const char *__restrict file _AND
94
       const char *mode _AND
94
       const char *__restrict mode _AND
95
       register FILE *fp)
95
       register FILE *__restrict fp)
96
{
96
{
97
  register int f;
97
  register int f;
98
  int flags, oflags;
98
  int flags, oflags;
99
  int e = 0;
99
  int e = 0;
100
 
100
 
101
  CHECK_INIT (ptr, fp);
101
  CHECK_INIT (ptr, fp);
-
 
102
 
-
 
103
  /* We can't use the _newlib_flockfile_XXX macros here due to the
-
 
104
     interlocked locking with the sfp_lock. */
-
 
105
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
-
 
106
  int __oldcancel;
-
 
107
  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
102
 
108
#endif
103
  _flockfile (fp);
109
  _flockfile (fp);
104
 
110
 
105
  if ((flags = __sflags (ptr, mode, &oflags)) == 0)
111
  if ((flags = __sflags (ptr, mode, &oflags)) == 0)
106
    {
112
    {
107
      _funlockfile (fp);
113
      _funlockfile (fp);
-
 
114
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
-
 
115
      pthread_setcancelstate (__oldcancel, &__oldcancel);
-
 
116
#endif
108
      _fclose_r (ptr, fp);
117
      _fclose_r (ptr, fp);
109
      return NULL;
118
      return NULL;
110
    }
119
    }
111
 
120
 
112
  /*
121
  /*
113
   * Remember whether the stream was open to begin with, and
122
   * Remember whether the stream was open to begin with, and
114
   * which file descriptor (if any) was associated with it.
123
   * which file descriptor (if any) was associated with it.
115
   * If it was attached to a descriptor, defer closing it,
124
   * If it was attached to a descriptor, defer closing it,
116
   * so that, e.g., freopen("/dev/stdin", "r", stdin) works.
125
   * so that, e.g., freopen("/dev/stdin", "r", stdin) works.
117
   * This is unnecessary if it was not a Unix file.
126
   * This is unnecessary if it was not a Unix file.
118
   */
127
   */
119
 
128
 
120
  if (fp->_flags == 0)
129
  if (fp->_flags == 0)
121
    fp->_flags = __SEOF;	/* hold on to it */
130
    fp->_flags = __SEOF;	/* hold on to it */
122
  else
131
  else
123
    {
132
    {
124
      if (fp->_flags & __SWR)
133
      if (fp->_flags & __SWR)
125
	_fflush_r (ptr, fp);
134
	_fflush_r (ptr, fp);
126
      /*
135
      /*
127
       * If close is NULL, closing is a no-op, hence pointless.
136
       * If close is NULL, closing is a no-op, hence pointless.
128
       * If file is NULL, the file should not be closed.
137
       * If file is NULL, the file should not be closed.
129
       */
138
       */
130
      if (fp->_close != NULL && file != NULL)
139
      if (fp->_close != NULL && file != NULL)
131
	fp->_close (ptr, fp->_cookie);
140
	fp->_close (ptr, fp->_cookie);
132
    }
141
    }
133
 
142
 
134
  /*
143
  /*
135
   * Now get a new descriptor to refer to the new file, or reuse the
144
   * Now get a new descriptor to refer to the new file, or reuse the
136
   * existing file descriptor if file is NULL.
145
   * existing file descriptor if file is NULL.
137
   */
146
   */
138
 
147
 
139
  if (file != NULL)
148
  if (file != NULL)
140
    {
149
    {
141
      f = _open_r (ptr, (char *) file, oflags, 0666);
150
      f = _open_r (ptr, (char *) file, oflags, 0666);
142
      e = ptr->_errno;
151
      e = ptr->_errno;
143
    }
152
    }
144
  else
153
  else
145
    {
154
    {
146
#ifdef HAVE_FCNTL
155
#ifdef HAVE_FCNTL
147
      int oldflags;
156
      int oldflags;
148
      /*
157
      /*
149
       * Reuse the file descriptor, but only if the new access mode is
158
       * Reuse the file descriptor, but only if the new access mode is
150
       * equal or less permissive than the old.  F_SETFL correctly
159
       * equal or less permissive than the old.  F_SETFL correctly
151
       * ignores creation flags.
160
       * ignores creation flags.
152
       */
161
       */
153
      f = fp->_file;
162
      f = fp->_file;
154
      if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1
163
      if ((oldflags = _fcntl_r (ptr, f, F_GETFL, 0)) == -1
155
	  || ! ((oldflags & O_ACCMODE) == O_RDWR
164
	  || ! ((oldflags & O_ACCMODE) == O_RDWR
156
		|| ((oldflags ^ oflags) & O_ACCMODE) == 0)
165
		|| ((oldflags ^ oflags) & O_ACCMODE) == 0)
157
	  || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
166
	  || _fcntl_r (ptr, f, F_SETFL, oflags) == -1)
158
	f = -1;
167
	f = -1;
159
#else
168
#else
160
      /* We cannot modify without fcntl support.  */
169
      /* We cannot modify without fcntl support.  */
161
      f = -1;
170
      f = -1;
162
#endif
171
#endif
163
 
172
 
164
#ifdef __SCLE
173
#ifdef __SCLE
165
      /*
174
      /*
166
       * F_SETFL doesn't change textmode.  Don't mess with modes of ttys.
175
       * F_SETFL doesn't change textmode.  Don't mess with modes of ttys.
167
       */
176
       */
168
      if (0 <= f && ! _isatty_r (ptr, f)
177
      if (0 <= f && ! _isatty_r (ptr, f)
169
	  && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
178
	  && setmode (f, oflags & (O_BINARY | O_TEXT)) == -1)
170
	f = -1;
179
	f = -1;
171
#endif
180
#endif
172
 
181
 
173
      if (f < 0)
182
      if (f < 0)
174
	{
183
	{
175
	  e = EBADF;
184
	  e = EBADF;
176
	  if (fp->_close != NULL)
185
	  if (fp->_close != NULL)
177
	    fp->_close (ptr, fp->_cookie);
186
	    fp->_close (ptr, fp->_cookie);
178
	}
187
	}
179
    }
188
    }
180
 
189
 
181
  /*
190
  /*
182
   * Finish closing fp.  Even if the open succeeded above,
191
   * Finish closing fp.  Even if the open succeeded above,
183
   * we cannot keep fp->_base: it may be the wrong size.
192
   * we cannot keep fp->_base: it may be the wrong size.
184
   * This loses the effect of any setbuffer calls,
193
   * This loses the effect of any setbuffer calls,
185
   * but stdio has always done this before.
194
   * but stdio has always done this before.
186
   */
195
   */
187
 
196
 
188
  if (fp->_flags & __SMBF)
197
  if (fp->_flags & __SMBF)
189
    _free_r (ptr, (char *) fp->_bf._base);
198
    _free_r (ptr, (char *) fp->_bf._base);
190
  fp->_w = 0;
199
  fp->_w = 0;
191
  fp->_r = 0;
200
  fp->_r = 0;
192
  fp->_p = NULL;
201
  fp->_p = NULL;
193
  fp->_bf._base = NULL;
202
  fp->_bf._base = NULL;
194
  fp->_bf._size = 0;
203
  fp->_bf._size = 0;
195
  fp->_lbfsize = 0;
204
  fp->_lbfsize = 0;
196
  if (HASUB (fp))
205
  if (HASUB (fp))
197
    FREEUB (ptr, fp);
206
    FREEUB (ptr, fp);
198
  fp->_ub._size = 0;
207
  fp->_ub._size = 0;
199
  if (HASLB (fp))
208
  if (HASLB (fp))
200
    FREELB (ptr, fp);
209
    FREELB (ptr, fp);
201
  fp->_lb._size = 0;
210
  fp->_lb._size = 0;
202
  fp->_flags & ~__SORD;
211
  fp->_flags &= ~__SORD;
203
  fp->_flags2 = 0;
212
  fp->_flags2 = 0;
204
  memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
213
  memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
205
 
214
 
206
  if (f < 0)
215
  if (f < 0)
207
    {				/* did not get it after all */
216
    {				/* did not get it after all */
208
      __sfp_lock_acquire ();
217
      __sfp_lock_acquire ();
209
      fp->_flags = 0;		/* set it free */
218
      fp->_flags = 0;		/* set it free */
210
      ptr->_errno = e;		/* restore in case _close clobbered */
219
      ptr->_errno = e;		/* restore in case _close clobbered */
211
      _funlockfile (fp);
220
      _funlockfile (fp);
212
#ifndef __SINGLE_THREAD__
221
#ifndef __SINGLE_THREAD__
213
      __lock_close_recursive (fp->_lock);
222
      __lock_close_recursive (fp->_lock);
214
#endif
223
#endif
215
      __sfp_lock_release ();
224
      __sfp_lock_release ();
-
 
225
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
-
 
226
      pthread_setcancelstate (__oldcancel, &__oldcancel);
-
 
227
#endif
216
      return NULL;
228
      return NULL;
217
    }
229
    }
218
 
230
 
219
  fp->_flags = flags;
231
  fp->_flags = flags;
220
  fp->_file = f;
232
  fp->_file = f;
221
  fp->_cookie = (_PTR) fp;
233
  fp->_cookie = (_PTR) fp;
222
  fp->_read = __sread;
234
  fp->_read = __sread;
223
  fp->_write = __swrite;
235
  fp->_write = __swrite;
224
  fp->_seek = __sseek;
236
  fp->_seek = __sseek;
225
  fp->_close = __sclose;
237
  fp->_close = __sclose;
226
 
238
 
227
#ifdef __SCLE
239
#ifdef __SCLE
228
  if (__stextmode (fp->_file))
240
  if (__stextmode (fp->_file))
229
    fp->_flags |= __SCLE;
241
    fp->_flags |= __SCLE;
230
#endif
242
#endif
231
 
243
 
232
  _funlockfile (fp);
244
  _funlockfile (fp);
-
 
245
#ifdef _STDIO_WITH_THREAD_CANCELLATION_SUPPORT
-
 
246
  pthread_setcancelstate (__oldcancel, &__oldcancel);
-
 
247
#endif
233
  return fp;
248
  return fp;
234
}
249
}
235
 
250
 
236
#ifndef _REENT_ONLY
251
#ifndef _REENT_ONLY
237
 
252
 
238
FILE *
253
FILE *
239
_DEFUN(freopen, (file, mode, fp),
254
_DEFUN(freopen, (file, mode, fp),
240
       _CONST char *file _AND
255
       _CONST char *__restrict file _AND
241
       _CONST char *mode _AND
256
       _CONST char *__restrict mode _AND
242
       register FILE *fp)
257
       register FILE *__restrict fp)
243
{
258
{
244
  return _freopen_r (_REENT, file, mode, fp);
259
  return _freopen_r (_REENT, file, mode, fp);
245
}
260
}
246
 
261
 
247
#endif /*!_REENT_ONLY */
262
#endif /*!_REENT_ONLY */