3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/crtdll/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
18 #include <msvcrt/io.h>
19 #include <msvcrt/fcntl.h>
20 #include <msvcrt/sys/stat.h>
21 #include <msvcrt/stdlib.h>
22 #include <msvcrt/internal/file.h>
23 #include <msvcrt/string.h>
24 #include <msvcrt/share.h>
26 #define STD_AUX_HANDLE 3
27 #define STD_PRINTER_HANDLE 4
29 typedef struct _fileno_modes_type
36 int __fileno_alloc(HANDLE hFile, int mode);
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));
50 int _open(const char* _path, int _oflag,...)
53 DWORD dwDesiredAccess = 0;
54 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
55 DWORD dwCreationDistribution = 0;
56 DWORD dwFlagsAndAttributes = 0;
60 va_start(arg, _oflag);
61 mode = va_arg(arg,int);
63 if ((mode == S_IWRITE) || (mode == 0))
64 dwFlagsAndAttributes = FILE_ATTRIBUTE_READONLY;
67 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
68 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
71 if (( _oflag & _O_RDWR ) == _O_RDWR )
72 dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ ;
73 else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
74 dwDesiredAccess |= GENERIC_WRITE ;
76 dwDesiredAccess |= GENERIC_READ ;
78 if ((_oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL))
79 dwCreationDistribution |= CREATE_NEW;
81 else if ((_oflag & O_TRUNC) == O_TRUNC) {
82 if ((_oflag & O_CREAT) == O_CREAT)
83 dwCreationDistribution |= CREATE_ALWAYS;
84 else if ((_oflag & O_RDONLY ) != O_RDONLY)
85 dwCreationDistribution |= TRUNCATE_EXISTING;
87 else if ((_oflag & _O_APPEND) == _O_APPEND)
88 dwCreationDistribution |= OPEN_EXISTING;
89 else if ((_oflag & _O_CREAT) == _O_CREAT)
90 dwCreationDistribution |= OPEN_ALWAYS;
92 dwCreationDistribution |= OPEN_EXISTING;
94 if ((_oflag & _O_RANDOM) == _O_RANDOM)
95 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
96 if ((_oflag & _O_SEQUENTIAL) == _O_SEQUENTIAL)
97 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
99 if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY)
100 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
102 if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED)
103 dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
105 hFile = CreateFileA(_path,
109 dwCreationDistribution,
110 dwFlagsAndAttributes,
112 if (hFile == (HANDLE)-1)
114 return __fileno_alloc(hFile,_oflag);
116 // _O_APPEND Moves file pointer to end of file before every write operation.
122 __fileno_alloc(HANDLE hFile, int mode)
125 /* Check for bogus values */
129 for(i=minfno;i<maxfno;i++) {
130 if (fileno_modes[i].fd == -1 ) {
131 fileno_modes[i].fd = i;
132 fileno_modes[i].mode = mode;
133 fileno_modes[i].hFile = hFile;
138 /* See if we need to expand the tables. Check this BEFORE it might fail,
139 so that when we hit the count'th request, we've already up'd it. */
142 int oldcount = maxfno;
143 fileno_modes_type *old_fileno_modes = fileno_modes;
145 fileno_modes = (fileno_modes_type *)malloc(maxfno * sizeof(fileno_modes_type));
146 if ( old_fileno_modes != NULL )
148 memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
149 free ( old_fileno_modes );
151 memset(fileno_modes + oldcount, 0, (maxfno-oldcount)*sizeof(fileno_modes));
154 /* Fill in the value */
155 fileno_modes[i].fd = i;
156 fileno_modes[i].mode = mode;
157 fileno_modes[i].hFile = hFile;
161 void *filehnd(int fileno)
167 return GetStdHandle(STD_INPUT_HANDLE);
169 return GetStdHandle(STD_OUTPUT_HANDLE);
171 return GetStdHandle(STD_ERROR_HANDLE);
173 return GetStdHandle(STD_AUX_HANDLE);
175 return GetStdHandle(STD_PRINTER_HANDLE);
179 if (fileno >= maxfno)
181 if (fileno_modes[fileno].fd == -1)
183 return fileno_modes[fileno].hFile;
186 int __fileno_setmode(int _fd, int _newmode)
195 m = fileno_modes[_fd].mode;
196 fileno_modes[_fd].mode = _newmode;
200 int __fileno_getmode(int _fd)
207 return fileno_modes[_fd].mode;
210 int __fileno_close(int _fd)
217 fileno_modes[_fd].fd = -1;
218 fileno_modes[_fd].hFile = (HANDLE)-1;
222 int _open_osfhandle(void *osfhandle, int flags)
224 return __fileno_alloc((HANDLE)osfhandle, flags);
227 void *_get_osfhandle(int fileno)
229 return filehnd(fileno);
232 int __fileno_dup2(int handle1, int handle2)
234 if (handle1 >= maxfno) {
239 if (handle2 >= maxfno)
243 memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));