3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/msvcrt/io/open.c
6 * PURPOSE: Opens a file and translates handles to fileno
7 * PROGRAMER: Boudewijn Dekker
12 // rember to interlock the allocation of fileno when making this thread safe
14 // possibly store extra information at the handle
17 #if !defined(NDEBUG) && defined(DBG)
18 #include <msvcrt/stdarg.h>
20 #include <msvcrt/io.h>
21 #include <msvcrt/fcntl.h>
22 #include <msvcrt/sys/stat.h>
23 #include <msvcrt/stdlib.h>
24 #include <msvcrt/internal/file.h>
25 #include <msvcrt/string.h>
26 #include <msvcrt/share.h>
27 #include <msvcrt/errno.h>
30 #include <msvcrt/msvcrtdbg.h>
34 #define STD_AUX_HANDLE 3
35 #define STD_PRINTER_HANDLE 4
38 /////////////////////////////////////////
39 #if 0 // from perl sources
41 #ifndef _INTPTR_T_DEFINED
43 #define _INTPTR_T_DEFINED
46 #ifndef _UINTPTR_T_DEFINED
47 typedef unsigned int uintptr_t;
48 #define _UINTPTR_T_DEFINED
52 * Control structure for lowio file handles
55 intptr_t osfhnd;/* underlying OS file HANDLE */
56 char osfile; /* attributes of file (e.g., open in text mode?) */
57 char pipech; /* one char buffer for handles opened on pipes */
59 //CRITICAL_SECTION lock;
63 * Array of arrays of control structures for lowio files.
65 //ioinfo* __pioinfo[];
66 //ioinfo* __pioinfo[] = { NULL };
69 /////////////////////////////////////////
71 typedef struct _fileno_modes_type
75 char pipech; /* one char buffer for handles opened on pipes */
77 /*CRITICAL_SECTION*/int lock;
81 //static fileno_modes_type* fileno_modes = NULL;
82 fileno_modes_type* __pioinfo = NULL;
84 /////////////////////////////////////////
87 char __is_text_file(FILE* p)
89 if ( p == NULL || __pioinfo == NULL )
91 return (!((p)->_flag&_IOSTRG) && (__pioinfo[(p)->_file].mode&O_TEXT));
97 int _open(const char* _path, int _oflag,...)
99 #if !defined(NDEBUG) && defined(DBG)
104 DWORD dwDesiredAccess = 0;
105 DWORD dwShareMode = 0;
106 DWORD dwCreationDistribution = 0;
107 DWORD dwFlagsAndAttributes = 0;
109 SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
111 #if !defined(NDEBUG) && defined(DBG)
112 va_start(arg, _oflag);
113 pmode = va_arg(arg, int);
116 // DPRINT("_open('%s', %x, (%x))\n", _path, _oflag, pmode);
118 if ((_oflag & S_IREAD ) == S_IREAD)
119 dwShareMode = FILE_SHARE_READ;
120 else if ((_oflag & S_IWRITE) == S_IWRITE) {
121 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
125 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
126 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
128 * _O_APPEND Moves file pointer to end of file before every write operation.
131 if ((_oflag & _O_RDWR) == _O_RDWR)
132 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ;
133 else if ((_oflag & O_RDONLY) == O_RDONLY)
134 dwDesiredAccess |= GENERIC_READ;
135 else if ((_oflag & _O_WRONLY) == _O_WRONLY)
136 dwDesiredAccess |= GENERIC_WRITE ;
138 if ((_oflag & _O_WRONLY) == _O_WRONLY )
139 dwDesiredAccess |= GENERIC_WRITE ;
140 else if ((_oflag & _O_RDWR) == _O_RDWR )
141 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ;
142 else //if ((_oflag & O_RDONLY) == O_RDONLY)
143 dwDesiredAccess |= GENERIC_READ;
145 if (( _oflag & S_IREAD ) == S_IREAD)
146 dwShareMode |= FILE_SHARE_READ;
148 if (( _oflag & S_IWRITE ) == S_IWRITE)
149 dwShareMode |= FILE_SHARE_WRITE;
151 if (( _oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
152 dwCreationDistribution |= CREATE_NEW;
154 else if ((_oflag & O_TRUNC ) == O_TRUNC) {
155 if ((_oflag & O_CREAT ) == O_CREAT)
156 dwCreationDistribution |= CREATE_ALWAYS;
157 else if ((_oflag & O_RDONLY ) != O_RDONLY)
158 dwCreationDistribution |= TRUNCATE_EXISTING;
160 else if ((_oflag & _O_APPEND) == _O_APPEND)
161 dwCreationDistribution |= OPEN_EXISTING;
162 else if ((_oflag & _O_CREAT) == _O_CREAT)
163 dwCreationDistribution |= OPEN_ALWAYS;
165 dwCreationDistribution |= OPEN_EXISTING;
167 if ((_oflag & _O_RANDOM) == _O_RANDOM )
168 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
169 if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL)
170 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
171 if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) {
172 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
173 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
175 if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) {
176 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
177 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
179 if (_oflag & _O_NOINHERIT)
180 sa.bInheritHandle = FALSE;
181 hFile = CreateFileA(_path,
185 dwCreationDistribution,
186 dwFlagsAndAttributes,
188 if (hFile == (HANDLE)-1) {
189 dwLastError = GetLastError();
190 if (dwLastError == ERROR_ALREADY_EXISTS) {
191 DPRINT("ERROR_ALREADY_EXISTS\n");
194 DPRINT("%x\n", dwLastError);
195 __set_errno(ENOFILE);
200 if (!(_oflag & (_O_TEXT|_O_BINARY))) {
203 return __fileno_alloc(hFile,_oflag);
207 int __fileno_alloc(HANDLE hFile, int mode)
210 /* Check for bogus values */
214 for (i = 5; i < maxfno; i++) {
215 if (__pioinfo[i].fd == -1 ) {
217 __pioinfo[i].mode = mode;
218 __pioinfo[i].hFile = hFile;
223 /* See if we need to expand the tables. Check this BEFORE it might fail,
224 so that when we hit the count'th request, we've already up'd it. */
226 int oldcount = maxfno;
227 fileno_modes_type* old_fileno_modes = __pioinfo;
229 __pioinfo = (fileno_modes_type*)malloc(maxfno * sizeof(fileno_modes_type));
230 if (old_fileno_modes != NULL) {
231 memcpy(__pioinfo, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
232 free(old_fileno_modes);
234 memset(__pioinfo + oldcount, -1, (maxfno-oldcount)*sizeof(fileno_modes_type));
237 /* Fill in the value */
239 __pioinfo[i].mode = mode;
240 __pioinfo[i].hFile = hFile;
244 void* filehnd(int fileno)
246 if (fileno < 0 || fileno >= maxfno || __pioinfo[fileno].fd == -1) {
249 return __pioinfo[fileno].hFile;
252 int __fileno_setmode(int _fd, int _newmode)
255 if (_fd < 0 || _fd >= maxfno) {
259 m = __pioinfo[_fd].mode;
260 __pioinfo[_fd].mode = _newmode;
264 int __fileno_getmode(int _fd)
266 if (_fd < 0 || _fd >= maxfno) {
270 return __pioinfo[_fd].mode;
274 int __fileno_close(int _fd)
276 if (_fd < 0 || _fd >= maxfno) {
280 __pioinfo[_fd].fd = -1;
281 __pioinfo[_fd].hFile = (HANDLE)-1;
288 int _open_osfhandle(void* osfhandle, int flags)
290 return __fileno_alloc((HANDLE)osfhandle, flags);
296 void* _get_osfhandle( int fileno )
298 return filehnd(fileno);
301 int __fileno_dup2(int handle1, int handle2)
305 if (handle1 >= maxfno || handle1 < 0 || handle2 >= maxfno || handle2 < 0) {
309 if (__pioinfo[handle1].fd == -1) {
313 if (handle1 == handle2)
315 if (__pioinfo[handle2].fd != -1) {
318 hProcess = GetCurrentProcess();
319 result = DuplicateHandle(hProcess,
320 __pioinfo[handle1].hFile,
322 &__pioinfo[handle2].hFile,
325 DUPLICATE_SAME_ACCESS);
327 __pioinfo[handle2].fd = handle2;
328 __pioinfo[handle2].mode = __pioinfo[handle1].mode;
331 SetStdHandle(STD_INPUT_HANDLE, __pioinfo[handle2].hFile);
334 SetStdHandle(STD_OUTPUT_HANDLE, __pioinfo[handle2].hFile);
337 SetStdHandle(STD_ERROR_HANDLE, __pioinfo[handle2].hFile);
340 SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile);
343 SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile);
348 __set_errno(EMFILE); // Is this the correct error no.?
354 void* malloc(size_t sizeObject);
356 BOOL __fileno_init(void)
363 GetStartupInfoA(&StInfo);
364 if (StInfo.lpReserved2 && StInfo.cbReserved2 >= sizeof(ULONG)) {
365 count = *(ULONG*)StInfo.lpReserved2;
367 if (sizeof(ULONG) + count * (sizeof(HANDLE) + sizeof(char)) != StInfo.cbReserved2)
374 while(count >= maxfno)
379 // why was this here ???? - robd.
384 //__pioinfo = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno);
385 __pioinfo = malloc(sizeof(fileno_modes_type) * maxfno);
386 if (__pioinfo == NULL) {
389 memset(__pioinfo, -1, sizeof(fileno_modes_type) * maxfno);
391 pFile = (HANDLE*)(StInfo.lpReserved2 + sizeof(ULONG) + count * sizeof(char));
392 pmode = (char*)(StInfo.lpReserved2 + sizeof(ULONG));
393 for (i = 0; i < count; i++) {
394 if (*pFile != INVALID_HANDLE_VALUE) {
396 __pioinfo[i].mode = ((*pmode << 8) & (_O_TEXT|_O_BINARY)) | (*pmode & _O_ACCMODE);
397 __pioinfo[i].hFile = *pFile;
403 if (__pioinfo[0].fd == -1) {
405 __pioinfo[0].hFile = GetStdHandle(STD_INPUT_HANDLE);
406 __pioinfo[0].mode = _O_RDONLY|_O_TEXT;
408 if (__pioinfo[1].fd == -1) {
410 __pioinfo[1].hFile = GetStdHandle(STD_OUTPUT_HANDLE);
411 __pioinfo[1].mode = _O_WRONLY|_O_TEXT;
413 if (__pioinfo[2].fd == -1) {
415 __pioinfo[2].hFile = GetStdHandle(STD_ERROR_HANDLE);
416 __pioinfo[2].mode = _O_WRONLY|_O_TEXT;
418 if (__pioinfo[3].fd == -1) {
420 __pioinfo[3].hFile = GetStdHandle(STD_AUX_HANDLE);
421 __pioinfo[3].mode = _O_WRONLY|_O_TEXT;
423 if (__pioinfo[4].fd == -1) {
425 __pioinfo[4].hFile = GetStdHandle(STD_PRINTER_HANDLE);
426 __pioinfo[4].mode = _O_WRONLY|_O_TEXT;