*** empty log message ***
[reactos.git] / reactos / lib / crtdll / io / open.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/crtdll/io/open.c
5 * PURPOSE: Opens a file and translates handles to fileno
6 * PROGRAMER: Boudewijn Dekker
7 * UPDATE HISTORY:
8 * 28/12/98: Created
9 */
10 #include <crtdll/io.h>
11 #include <windows.h>
12 #include <crtdll/fcntl.h>
13 #include <crtdll/sys/stat.h>
14 #include <crtdll/stdlib.h>
15 #include <crtdll/internal/file.h>
16 #include <crtdll/string.h>
17 #include <crtdll/share.h>
18
19 typedef struct _fileno_modes_type
20 {
21 HANDLE hFile;
22 int mode;
23 int fd;
24 } fileno_modes_type;
25
26 fileno_modes_type *fileno_modes = NULL;
27
28 int maxfno = 5;
29 int minfno = 5;
30
31 char __is_text_file(FILE *p)
32 {
33 if ( p == NULL || fileno_modes == NULL )
34 return FALSE;
35 return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT));
36 }
37
38
39
40
41 int __fileno_alloc(HANDLE hFile, int mode);
42
43
44 int _open(const char *_path, int _oflag,...)
45 {
46 HANDLE hFile;
47 DWORD dwDesiredAccess = 0;
48 DWORD dwShareMode = 0;
49 DWORD dwCreationDistribution = 0;
50 DWORD dwFlagsAndAttributes = 0;
51
52 if (( _oflag & S_IREAD ) == S_IREAD)
53 dwShareMode = FILE_SHARE_READ;
54 else if ( ( _oflag & S_IWRITE) == S_IWRITE ) {
55 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
56 }
57
58 /*
59 *
60 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
61 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
62 *
63 */
64 if (( _oflag & _O_RDWR ) == _O_RDWR )
65 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA |
66 FILE_WRITE_DATA | FILE_READ_ATTRIBUTES |
67 FILE_WRITE_ATTRIBUTES;
68 else if (( _oflag & O_RDONLY ) == O_RDONLY )
69 dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES
70 | FILE_WRITE_ATTRIBUTES;
71 else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
72 dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA |
73 FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES;
74
75 if (( _oflag & S_IREAD ) == S_IREAD )
76 dwShareMode |= FILE_SHARE_READ;
77
78 if (( _oflag & S_IWRITE ) == S_IWRITE )
79 dwShareMode |= FILE_SHARE_WRITE;
80
81 if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
82 dwCreationDistribution |= CREATE_NEW;
83
84 else if (( _oflag & O_TRUNC ) == O_TRUNC ) {
85 if (( _oflag & O_CREAT ) == O_CREAT )
86 dwCreationDistribution |= CREATE_ALWAYS;
87 else if (( _oflag & O_RDONLY ) != O_RDONLY )
88 dwCreationDistribution |= TRUNCATE_EXISTING;
89 }
90 else if (( _oflag & _O_APPEND ) == _O_APPEND )
91 dwCreationDistribution |= OPEN_EXISTING;
92 else if (( _oflag & _O_CREAT ) == _O_CREAT )
93 dwCreationDistribution |= OPEN_ALWAYS;
94 else
95 dwCreationDistribution |= OPEN_EXISTING;
96
97 if (( _oflag & _O_RANDOM ) == _O_RANDOM )
98 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
99 if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL )
100 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
101
102 if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY )
103 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
104
105 if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
106 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
107
108 hFile = CreateFileA(_path,
109 dwDesiredAccess,
110 dwShareMode,
111 NULL,
112 dwCreationDistribution,
113 dwFlagsAndAttributes,
114 NULL);
115 if (hFile == (HANDLE)-1)
116 return -1;
117 return __fileno_alloc(hFile,_oflag);
118
119 // _O_APPEND Moves file pointer to end of file before every write operation.
120
121 }
122
123
124
125
126 int
127 __fileno_alloc(HANDLE hFile, int mode)
128 {
129
130 int i;
131 /* Check for bogus values */
132 if (hFile < 0)
133 return -1;
134
135 for(i=minfno;i<maxfno;i++) {
136 if (fileno_modes[i].fd == -1 ) {
137 fileno_modes[i].fd = i;
138 fileno_modes[i].mode = mode;
139 fileno_modes[i].hFile = hFile;
140 return i;
141 }
142 }
143
144
145 /* See if we need to expand the tables. Check this BEFORE it might fail,
146 so that when we hit the count'th request, we've already up'd it. */
147 if ( i == maxfno)
148 {
149 int oldcount = maxfno;
150 fileno_modes_type *old_fileno_modes = fileno_modes;
151 maxfno += 255;
152 fileno_modes = (fileno_modes_type *)malloc(maxfno * sizeof(fileno_modes_type));
153 if ( old_fileno_modes != NULL )
154 memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
155 memset(fileno_modes + oldcount, 0, (maxfno-oldcount)*sizeof(fileno_modes));
156 free ( old_fileno_modes );
157
158 }
159
160 /* Fill in the value */
161 fileno_modes[i].fd = i;
162 fileno_modes[i].mode = mode;
163 fileno_modes[i].hFile = hFile;
164 return i;
165 }
166
167 void *filehnd(int fileno)
168 {
169
170
171
172 if ( fileno < 0 )
173 return (void *)-1;
174 #define STD_AUX_HANDLE 3
175 #define STD_PRINTER_HANDLE 4
176
177 switch(fileno)
178 {
179 case 0:
180 return GetStdHandle(STD_INPUT_HANDLE);
181 case 1:
182 return GetStdHandle(STD_OUTPUT_HANDLE);
183 case 2:
184 return GetStdHandle(STD_ERROR_HANDLE);
185 case 3:
186 return GetStdHandle(STD_AUX_HANDLE);
187 case 4:
188 return GetStdHandle(STD_PRINTER_HANDLE);
189 default:
190 break;
191 }
192
193 if ( fileno >= maxfno )
194 return (void *)-1;
195
196 if ( fileno_modes[fileno].fd == -1 )
197 return (void *)-1;
198 return fileno_modes[fileno].hFile;
199 }
200
201 int __fileno_dup2( int handle1, int handle2 )
202 {
203 if ( handle1 >= maxfno )
204 return -1;
205
206 if ( handle1 < 0 )
207 return -1;
208 if ( handle2 >= maxfno )
209 return -1;
210
211 if ( handle2 < 0 )
212 return -1;
213
214 memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));
215
216
217 return handle1;
218 }
219
220 int __fileno_setmode(int _fd, int _newmode)
221 {
222 int m;
223 if ( _fd < minfno )
224 return -1;
225
226 if ( _fd >= maxfno )
227 return -1;
228
229 m = fileno_modes[_fd].mode;
230 fileno_modes[_fd].mode = _newmode;
231 return m;
232 }
233
234 int __fileno_close(int _fd)
235 {
236 if ( _fd < 0 )
237 return -1;
238
239 if ( _fd >= maxfno )
240 return -1;
241
242 fileno_modes[_fd].fd = -1;
243 fileno_modes[_fd].hFile = (HANDLE)-1;
244 return 0;
245 }
246
247 int _open_osfhandle (void *osfhandle, int flags )
248 {
249 return __fileno_alloc((HANDLE)osfhandle, flags);
250 }
251
252 void *_get_osfhandle( int fileno )
253 {
254 return filehnd(fileno);
255 }