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 | < |
20 | < |
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 < |
48 | Use this variant of < |
49 | descriptor <[fp]> (notably < |
49 | descriptor <[fp]> (notably < |
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 < |
58 | If <[file]> is < |
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 */>>=> |