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
11 // rember to interlock the allocation of fileno when making this thread safe
13 // possibly store extra information at the handle
16 #if !defined(NDEBUG) && defined(DBG)
17 #include <msvcrt/stdarg.h>
19 #include <msvcrt/io.h>
20 #include <msvcrt/fcntl.h>
21 #include <msvcrt/sys/stat.h>
22 #include <msvcrt/stdlib.h>
23 #include <msvcrt/internal/file.h>
24 #include <msvcrt/string.h>
25 #include <msvcrt/share.h>
26 #include <msvcrt/errno.h>
29 #include <msvcrt/msvcrtdbg.h>
31 typedef struct _fileno_modes_type
38 fileno_modes_type
*fileno_modes
= NULL
;
43 char __is_text_file(FILE *p
)
45 if ( p
== NULL
|| fileno_modes
== NULL
)
47 return (!((p
)->_flag
&_IOSTRG
) && (fileno_modes
[(p
)->_file
].mode
&O_TEXT
));
51 int _open(const char *_path
, int _oflag
,...)
53 #if !defined(NDEBUG) && defined(DBG)
58 DWORD dwDesiredAccess
= 0;
59 DWORD dwShareMode
= 0;
60 DWORD dwCreationDistribution
= 0;
61 DWORD dwFlagsAndAttributes
= 0;
64 #if !defined(NDEBUG) && defined(DBG)
65 va_start(arg
, _oflag
);
66 pmode
= va_arg(arg
, int);
69 DPRINT("_open('%s', %x, (%x))\n", _path
, _oflag
, pmode
);
71 if (( _oflag
& S_IREAD
) == S_IREAD
)
72 dwShareMode
= FILE_SHARE_READ
;
73 else if ( ( _oflag
& S_IWRITE
) == S_IWRITE
) {
74 dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
79 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
80 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
82 * _O_APPEND Moves file pointer to end of file before every write operation.
84 if (( _oflag
& _O_RDWR
) == _O_RDWR
)
85 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
;
86 else if (( _oflag
& O_RDONLY
) == O_RDONLY
)
87 dwDesiredAccess
|= GENERIC_READ
;
88 else if (( _oflag
& _O_WRONLY
) == _O_WRONLY
)
89 dwDesiredAccess
|= GENERIC_WRITE
;
91 if (( _oflag
& S_IREAD
) == S_IREAD
)
92 dwShareMode
|= FILE_SHARE_READ
;
94 if (( _oflag
& S_IWRITE
) == S_IWRITE
)
95 dwShareMode
|= FILE_SHARE_WRITE
;
97 if (( _oflag
& (_O_CREAT
| _O_EXCL
) ) == (_O_CREAT
| _O_EXCL
) )
98 dwCreationDistribution
|= CREATE_NEW
;
100 else if (( _oflag
& O_TRUNC
) == O_TRUNC
) {
101 if (( _oflag
& O_CREAT
) == O_CREAT
)
102 dwCreationDistribution
|= CREATE_ALWAYS
;
103 else if (( _oflag
& O_RDONLY
) != O_RDONLY
)
104 dwCreationDistribution
|= TRUNCATE_EXISTING
;
106 else if (( _oflag
& _O_APPEND
) == _O_APPEND
)
107 dwCreationDistribution
|= OPEN_EXISTING
;
108 else if (( _oflag
& _O_CREAT
) == _O_CREAT
)
109 dwCreationDistribution
|= OPEN_ALWAYS
;
111 dwCreationDistribution
|= OPEN_EXISTING
;
113 if (( _oflag
& _O_RANDOM
) == _O_RANDOM
)
114 dwFlagsAndAttributes
|= FILE_FLAG_RANDOM_ACCESS
;
115 if (( _oflag
& _O_SEQUENTIAL
) == _O_SEQUENTIAL
)
116 dwFlagsAndAttributes
|= FILE_FLAG_SEQUENTIAL_SCAN
;
118 if (( _oflag
& _O_TEMPORARY
) == _O_TEMPORARY
)
120 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
121 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
124 if (( _oflag
& _O_SHORT_LIVED
) == _O_SHORT_LIVED
)
126 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
127 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
130 hFile
= CreateFileA(_path
,
134 dwCreationDistribution
,
135 dwFlagsAndAttributes
,
137 if (hFile
== (HANDLE
)-1)
139 dwLastError
= GetLastError();
140 if (dwLastError
== ERROR_ALREADY_EXISTS
)
142 DPRINT("ERROR_ALREADY_EXISTS\n");
147 DPRINT("%x\n", dwLastError
);
148 __set_errno(ENOFILE
);
153 return __fileno_alloc(hFile
,_oflag
);
157 int _wopen(const wchar_t *_path
, int _oflag
,...)
159 #if !defined(NDEBUG) && defined(DBG)
164 DWORD dwDesiredAccess
= 0;
165 DWORD dwShareMode
= 0;
166 DWORD dwCreationDistribution
= 0;
167 DWORD dwFlagsAndAttributes
= 0;
169 #if !defined(NDEBUG) && defined(DBG)
170 va_start(arg
, _oflag
);
171 pmode
= va_arg(arg
, int);
174 DPRINT("_wopen('%S', %x, (%x))\n", _path
, _oflag
, pmode
);
176 if (( _oflag
& S_IREAD
) == S_IREAD
)
177 dwShareMode
= FILE_SHARE_READ
;
178 else if ( ( _oflag
& S_IWRITE
) == S_IWRITE
) {
179 dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
184 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
185 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
187 * _O_APPEND Moves file pointer to end of file before every write operation.
189 if (( _oflag
& _O_RDWR
) == _O_RDWR
)
190 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
| FILE_READ_DATA
|
191 FILE_WRITE_DATA
| FILE_READ_ATTRIBUTES
|
192 FILE_WRITE_ATTRIBUTES
;
193 else if (( _oflag
& O_RDONLY
) == O_RDONLY
)
194 dwDesiredAccess
|= GENERIC_READ
| FILE_READ_DATA
| FILE_READ_ATTRIBUTES
195 | FILE_WRITE_ATTRIBUTES
;
196 else if (( _oflag
& _O_WRONLY
) == _O_WRONLY
)
197 dwDesiredAccess
|= GENERIC_WRITE
| FILE_WRITE_DATA
|
198 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
;
200 if (( _oflag
& S_IREAD
) == S_IREAD
)
201 dwShareMode
|= FILE_SHARE_READ
;
203 if (( _oflag
& S_IWRITE
) == S_IWRITE
)
204 dwShareMode
|= FILE_SHARE_WRITE
;
206 if (( _oflag
& (_O_CREAT
| _O_EXCL
) ) == (_O_CREAT
| _O_EXCL
) )
207 dwCreationDistribution
|= CREATE_NEW
;
209 else if (( _oflag
& O_TRUNC
) == O_TRUNC
) {
210 if (( _oflag
& O_CREAT
) == O_CREAT
)
211 dwCreationDistribution
|= CREATE_ALWAYS
;
212 else if (( _oflag
& O_RDONLY
) != O_RDONLY
)
213 dwCreationDistribution
|= TRUNCATE_EXISTING
;
215 else if (( _oflag
& _O_APPEND
) == _O_APPEND
)
216 dwCreationDistribution
|= OPEN_EXISTING
;
217 else if (( _oflag
& _O_CREAT
) == _O_CREAT
)
218 dwCreationDistribution
|= OPEN_ALWAYS
;
220 dwCreationDistribution
|= OPEN_EXISTING
;
222 if (( _oflag
& _O_RANDOM
) == _O_RANDOM
)
223 dwFlagsAndAttributes
|= FILE_FLAG_RANDOM_ACCESS
;
224 if (( _oflag
& _O_SEQUENTIAL
) == _O_SEQUENTIAL
)
225 dwFlagsAndAttributes
|= FILE_FLAG_SEQUENTIAL_SCAN
;
227 if (( _oflag
& _O_TEMPORARY
) == _O_TEMPORARY
)
228 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
230 if (( _oflag
& _O_SHORT_LIVED
) == _O_SHORT_LIVED
)
231 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
233 hFile
= CreateFileW(_path
,
237 dwCreationDistribution
,
238 dwFlagsAndAttributes
,
240 if (hFile
== (HANDLE
)-1)
242 return __fileno_alloc(hFile
,_oflag
);
247 __fileno_alloc(HANDLE hFile
, int mode
)
250 /* Check for bogus values */
254 for(i
=minfno
;i
<maxfno
;i
++) {
255 if (fileno_modes
[i
].fd
== -1 ) {
256 fileno_modes
[i
].fd
= i
;
257 fileno_modes
[i
].mode
= mode
;
258 fileno_modes
[i
].hFile
= hFile
;
263 /* See if we need to expand the tables. Check this BEFORE it might fail,
264 so that when we hit the count'th request, we've already up'd it. */
267 int oldcount
= maxfno
;
268 fileno_modes_type
*old_fileno_modes
= fileno_modes
;
270 fileno_modes
= (fileno_modes_type
*)malloc(maxfno
* sizeof(fileno_modes_type
));
271 if ( old_fileno_modes
!= NULL
)
273 memcpy(fileno_modes
, old_fileno_modes
, oldcount
* sizeof(fileno_modes_type
));
274 free ( old_fileno_modes
);
276 memset(fileno_modes
+ oldcount
, -1, (maxfno
-oldcount
)*sizeof(fileno_modes
));
279 /* Fill in the value */
280 fileno_modes
[i
].fd
= i
;
281 fileno_modes
[i
].mode
= mode
;
282 fileno_modes
[i
].hFile
= hFile
;
286 void *filehnd(int fileno
)
290 #define STD_AUX_HANDLE 3
291 #define STD_PRINTER_HANDLE 4
296 return GetStdHandle(STD_INPUT_HANDLE
);
298 return GetStdHandle(STD_OUTPUT_HANDLE
);
300 return GetStdHandle(STD_ERROR_HANDLE
);
302 return GetStdHandle(STD_AUX_HANDLE
);
304 return GetStdHandle(STD_PRINTER_HANDLE
);
309 if ( fileno
>= maxfno
)
312 if ( fileno_modes
[fileno
].fd
== -1 )
314 return fileno_modes
[fileno
].hFile
;
317 int __fileno_dup2( int handle1
, int handle2
)
319 if ( handle1
>= maxfno
)
324 if ( handle2
>= maxfno
)
330 memcpy(&fileno_modes
[handle1
],&fileno_modes
[handle2
],sizeof(fileno_modes
));
335 int __fileno_setmode(int _fd
, int _newmode
)
344 m
= fileno_modes
[_fd
].mode
;
345 fileno_modes
[_fd
].mode
= _newmode
;
349 int __fileno_getmode(int _fd
)
357 return fileno_modes
[_fd
].mode
;
362 int __fileno_close(int _fd
)
370 fileno_modes
[_fd
].fd
= -1;
371 fileno_modes
[_fd
].hFile
= (HANDLE
)-1;
375 int _open_osfhandle (void *osfhandle
, int flags
)
377 return __fileno_alloc((HANDLE
)osfhandle
, flags
);
380 void *_get_osfhandle( int fileno
)
382 return filehnd(fileno
);