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 | <<fopen>>---open a file |
---|
21 | |
---|
22 | INDEX |
---|
23 | fopen |
---|
24 | INDEX |
---|
25 | _fopen_r |
---|
26 | |
---|
27 | SYNOPSIS |
---|
28 | #include <stdio.h> |
---|
29 | FILE *fopen(const char *<[file]>, const char *<[mode]>); |
---|
30 | |
---|
31 | FILE *_fopen_r(struct _reent *<[reent]>, |
---|
32 | const char *<[file]>, const char *<[mode]>); |
---|
33 | |
---|
34 | DESCRIPTION |
---|
35 | <<fopen>> initializes the data structures needed to read or write a |
---|
36 | file. Specify the file's name as the string at <[file]>, and the kind |
---|
37 | of access you need to the file with the string at <[mode]>. |
---|
38 | |
---|
39 | The alternate function <<_fopen_r>> is a reentrant version. |
---|
40 | The extra argument <[reent]> is a pointer to a reentrancy structure. |
---|
41 | |
---|
42 | Three fundamental kinds of access are available: read, write, and append. |
---|
43 | <<*<[mode]>>> must begin with one of the three characters `<<r>>', |
---|
44 | `<<w>>', or `<<a>>', to select one of these: |
---|
45 | |
---|
46 | o+ |
---|
47 | o r |
---|
48 | Open the file for reading; the operation will fail if the file does |
---|
49 | not exist, or if the host system does not permit you to read it. |
---|
50 | |
---|
51 | o w |
---|
52 | Open the file for writing @emph{from the beginning} of the file: |
---|
53 | effectively, this always creates a new file. If the file whose name you |
---|
54 | specified already existed, its old contents are discarded. |
---|
55 | |
---|
56 | o a |
---|
57 | Open the file for appending data, that is writing from the end of |
---|
58 | file. When you open a file this way, all data always goes to the |
---|
59 | current end of file; you cannot change this using <<fseek>>. |
---|
60 | o- |
---|
61 | |
---|
62 | Some host systems distinguish between ``binary'' and ``text'' files. |
---|
63 | Such systems may perform data transformations on data written to, or |
---|
64 | read from, files opened as ``text''. |
---|
65 | If your system is one of these, then you can append a `<<b>>' to any |
---|
66 | of the three modes above, to specify that you are opening the file as |
---|
67 | a binary file (the default is to open the file as a text file). |
---|
68 | |
---|
69 | `<<rb>>', then, means ``read binary''; `<<wb>>', ``write binary''; and |
---|
70 | `<<ab>>', ``append binary''. |
---|
71 | |
---|
72 | To make C programs more portable, the `<<b>>' is accepted on all |
---|
73 | systems, whether or not it makes a difference. |
---|
74 | |
---|
75 | Finally, you might need to both read and write from the same file. |
---|
76 | You can also append a `<<+>>' to any of the three modes, to permit |
---|
77 | this. (If you want to append both `<<b>>' and `<<+>>', you can do it |
---|
78 | in either order: for example, <<"rb+">> means the same thing as |
---|
79 | <<"r+b">> when used as a mode string.) |
---|
80 | |
---|
81 | Use <<"r+">> (or <<"rb+">>) to permit reading and writing anywhere in |
---|
82 | an existing file, without discarding any data; <<"w+">> (or <<"wb+">>) |
---|
83 | to create a new file (or begin by discarding all data from an old one) |
---|
84 | that permits reading and writing anywhere in it; and <<"a+">> (or |
---|
85 | <<"ab+">>) to permit reading anywhere in an existing file, but writing |
---|
86 | only at the end. |
---|
87 | |
---|
88 | RETURNS |
---|
89 | <<fopen>> returns a file pointer which you can use for other file |
---|
90 | operations, unless the file you requested could not be opened; in that |
---|
91 | situation, the result is <<NULL>>. If the reason for failure was an |
---|
92 | invalid string at <[mode]>, <<errno>> is set to <<EINVAL>>. |
---|
93 | |
---|
94 | PORTABILITY |
---|
95 | <<fopen>> is required by ANSI C. |
---|
96 | |
---|
97 | Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
---|
98 | <<lseek>>, <<open>>, <<read>>, <<sbrk>>, <<write>>. |
---|
99 | */ |
---|
100 | |
---|
101 | #if defined(LIBC_SCCS) && !defined(lint) |
---|
102 | static char sccsid[] = "%W% (Berkeley) %G%"; |
---|
103 | #endif /* LIBC_SCCS and not lint */ |
---|
104 | |
---|
105 | #include <_ansi.h> |
---|
106 | #include <reent.h> |
---|
107 | #include <stdio.h> |
---|
108 | #include <errno.h> |
---|
109 | #include <sys/lock.h> |
---|
110 | #ifdef __CYGWIN__ |
---|
111 | #include <fcntl.h> |
---|
112 | #endif |
---|
113 | #include "local.h" |
---|
114 | |
---|
115 | FILE * |
---|
116 | _fopen_r (struct _reent *ptr, |
---|
117 | const char *__restrict file, |
---|
118 | const char *__restrict mode) |
---|
119 | { |
---|
120 | register FILE *fp; |
---|
121 | register int f; |
---|
122 | int flags, oflags; |
---|
123 | |
---|
124 | if ((flags = __sflags (ptr, mode, &oflags)) == 0) |
---|
125 | return NULL; |
---|
126 | if ((fp = __sfp (ptr)) == NULL) |
---|
127 | return NULL; |
---|
128 | |
---|
129 | if ((f = _open_r (ptr, file, oflags, 0666)) < 0) |
---|
130 | { |
---|
131 | _newlib_sfp_lock_start (); |
---|
132 | fp->_flags = 0; /* release */ |
---|
133 | #ifndef __SINGLE_THREAD__ |
---|
134 | __lock_close_recursive (fp->_lock); |
---|
135 | #endif |
---|
136 | _newlib_sfp_lock_end (); |
---|
137 | return NULL; |
---|
138 | } |
---|
139 | |
---|
140 | _newlib_flockfile_start (fp); |
---|
141 | |
---|
142 | fp->_file = f; |
---|
143 | fp->_flags = flags; |
---|
144 | fp->_cookie = (void *) fp; |
---|
145 | fp->_read = __sread; |
---|
146 | fp->_write = __swrite; |
---|
147 | fp->_seek = __sseek; |
---|
148 | fp->_close = __sclose; |
---|
149 | |
---|
150 | if (fp->_flags & __SAPP) |
---|
151 | _fseek_r (ptr, fp, 0, SEEK_END); |
---|
152 | |
---|
153 | #ifdef __SCLE |
---|
154 | if (__stextmode (fp->_file)) |
---|
155 | fp->_flags |= __SCLE; |
---|
156 | #endif |
---|
157 | |
---|
158 | _newlib_flockfile_end (fp); |
---|
159 | return fp; |
---|
160 | } |
---|
161 | |
---|
162 | #ifndef _REENT_ONLY |
---|
163 | |
---|
164 | FILE * |
---|
165 | fopen (const char *file, |
---|
166 | const char *mode) |
---|
167 | { |
---|
168 | return _fopen_r (_REENT, file, mode); |
---|
169 | } |
---|
170 | |
---|
171 | #endif |
---|