1 /* $Id: open.c,v 1.14 2002/12/26 17:26:41 robd Exp $
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
));
94 int _open(const char* _path
, int _oflag
,...)
96 #if !defined(NDEBUG) && defined(DBG)
101 DWORD dwDesiredAccess
= 0;
102 DWORD dwShareMode
= 0;
103 DWORD dwCreationDistribution
= 0;
104 DWORD dwFlagsAndAttributes
= 0;
106 SECURITY_ATTRIBUTES sa
= {sizeof(SECURITY_ATTRIBUTES
), NULL
, TRUE
};
108 #if !defined(NDEBUG) && defined(DBG)
109 va_start(arg
, _oflag
);
110 pmode
= va_arg(arg
, int);
113 // DPRINT("_open('%s', %x, (%x))\n", _path, _oflag, pmode);
115 if ((_oflag
& S_IREAD
) == S_IREAD
)
116 dwShareMode
= FILE_SHARE_READ
;
117 else if ((_oflag
& S_IWRITE
) == S_IWRITE
) {
118 dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
122 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
123 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
125 * _O_APPEND Moves file pointer to end of file before every write operation.
128 if ((_oflag
& _O_RDWR
) == _O_RDWR
)
129 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
;
130 else if ((_oflag
& O_RDONLY
) == O_RDONLY
)
131 dwDesiredAccess
|= GENERIC_READ
;
132 else if ((_oflag
& _O_WRONLY
) == _O_WRONLY
)
133 dwDesiredAccess
|= GENERIC_WRITE
;
135 if ((_oflag
& _O_WRONLY
) == _O_WRONLY
)
136 dwDesiredAccess
|= GENERIC_WRITE
;
137 else if ((_oflag
& _O_RDWR
) == _O_RDWR
)
138 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
;
139 else //if ((_oflag & O_RDONLY) == O_RDONLY)
140 dwDesiredAccess
|= GENERIC_READ
;
142 if (( _oflag
& S_IREAD
) == S_IREAD
)
143 dwShareMode
|= FILE_SHARE_READ
;
145 if (( _oflag
& S_IWRITE
) == S_IWRITE
)
146 dwShareMode
|= FILE_SHARE_WRITE
;
148 if (( _oflag
& (_O_CREAT
| _O_EXCL
)) == (_O_CREAT
| _O_EXCL
))
149 dwCreationDistribution
|= CREATE_NEW
;
151 else if ((_oflag
& O_TRUNC
) == O_TRUNC
) {
152 if ((_oflag
& O_CREAT
) == O_CREAT
)
153 dwCreationDistribution
|= CREATE_ALWAYS
;
154 else if ((_oflag
& O_RDONLY
) != O_RDONLY
)
155 dwCreationDistribution
|= TRUNCATE_EXISTING
;
157 else if ((_oflag
& _O_APPEND
) == _O_APPEND
)
158 dwCreationDistribution
|= OPEN_EXISTING
;
159 else if ((_oflag
& _O_CREAT
) == _O_CREAT
)
160 dwCreationDistribution
|= OPEN_ALWAYS
;
162 dwCreationDistribution
|= OPEN_EXISTING
;
164 if ((_oflag
& _O_RANDOM
) == _O_RANDOM
)
165 dwFlagsAndAttributes
|= FILE_FLAG_RANDOM_ACCESS
;
166 if ((_oflag
& _O_SEQUENTIAL
) == _O_SEQUENTIAL
)
167 dwFlagsAndAttributes
|= FILE_FLAG_SEQUENTIAL_SCAN
;
168 if ((_oflag
& _O_TEMPORARY
) == _O_TEMPORARY
) {
169 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
170 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
172 if ((_oflag
& _O_SHORT_LIVED
) == _O_SHORT_LIVED
) {
173 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
174 DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
176 if (_oflag
& _O_NOINHERIT
)
177 sa
.bInheritHandle
= FALSE
;
178 hFile
= CreateFileA(_path
,
182 dwCreationDistribution
,
183 dwFlagsAndAttributes
,
185 if (hFile
== (HANDLE
)-1) {
186 dwLastError
= GetLastError();
187 if (dwLastError
== ERROR_ALREADY_EXISTS
) {
188 DPRINT("ERROR_ALREADY_EXISTS\n");
191 DPRINT("%x\n", dwLastError
);
192 __set_errno(ENOFILE
);
197 if (!(_oflag
& (_O_TEXT
|_O_BINARY
))) {
200 return __fileno_alloc(hFile
,_oflag
);
204 int __fileno_alloc(HANDLE hFile
, int mode
)
207 /* Check for bogus values */
211 for (i
= 5; i
< maxfno
; i
++) {
212 if (__pioinfo
[i
].fd
== -1 ) {
214 __pioinfo
[i
].mode
= mode
;
215 __pioinfo
[i
].hFile
= hFile
;
220 /* See if we need to expand the tables. Check this BEFORE it might fail,
221 so that when we hit the count'th request, we've already up'd it. */
223 int oldcount
= maxfno
;
224 fileno_modes_type
* old_fileno_modes
= __pioinfo
;
226 __pioinfo
= (fileno_modes_type
*)malloc(maxfno
* sizeof(fileno_modes_type
));
227 if (old_fileno_modes
!= NULL
) {
228 memcpy(__pioinfo
, old_fileno_modes
, oldcount
* sizeof(fileno_modes_type
));
229 free(old_fileno_modes
);
231 memset(__pioinfo
+ oldcount
, -1, (maxfno
-oldcount
)*sizeof(fileno_modes_type
));
234 /* Fill in the value */
236 __pioinfo
[i
].mode
= mode
;
237 __pioinfo
[i
].hFile
= hFile
;
241 void* filehnd(int fileno
)
243 if (fileno
< 0 || fileno
>= maxfno
|| __pioinfo
[fileno
].fd
== -1) {
246 return __pioinfo
[fileno
].hFile
;
249 int __fileno_setmode(int _fd
, int _newmode
)
252 if (_fd
< 0 || _fd
>= maxfno
) {
256 m
= __pioinfo
[_fd
].mode
;
257 __pioinfo
[_fd
].mode
= _newmode
;
261 int __fileno_getmode(int _fd
)
263 if (_fd
< 0 || _fd
>= maxfno
) {
267 return __pioinfo
[_fd
].mode
;
271 int __fileno_close(int _fd
)
273 if (_fd
< 0 || _fd
>= maxfno
) {
277 __pioinfo
[_fd
].fd
= -1;
278 __pioinfo
[_fd
].hFile
= (HANDLE
)-1;
282 int _open_osfhandle(void* osfhandle
, int flags
)
284 return __fileno_alloc((HANDLE
)osfhandle
, flags
);
287 void* _get_osfhandle( int fileno
)
289 return filehnd(fileno
);
292 int __fileno_dup2(int handle1
, int handle2
)
296 if (handle1
>= maxfno
|| handle1
< 0 || handle2
>= maxfno
|| handle2
< 0) {
300 if (__pioinfo
[handle1
].fd
== -1) {
304 if (handle1
== handle2
)
306 if (__pioinfo
[handle2
].fd
!= -1) {
309 hProcess
= GetCurrentProcess();
310 result
= DuplicateHandle(hProcess
,
311 __pioinfo
[handle1
].hFile
,
313 &__pioinfo
[handle2
].hFile
,
316 DUPLICATE_SAME_ACCESS
);
318 __pioinfo
[handle2
].fd
= handle2
;
319 __pioinfo
[handle2
].mode
= __pioinfo
[handle1
].mode
;
322 SetStdHandle(STD_INPUT_HANDLE
, __pioinfo
[handle2
].hFile
);
325 SetStdHandle(STD_OUTPUT_HANDLE
, __pioinfo
[handle2
].hFile
);
328 SetStdHandle(STD_ERROR_HANDLE
, __pioinfo
[handle2
].hFile
);
331 SetStdHandle(STD_AUX_HANDLE
, __pioinfo
[handle2
].hFile
);
334 SetStdHandle(STD_AUX_HANDLE
, __pioinfo
[handle2
].hFile
);
339 __set_errno(EMFILE
); // Is this the correct error no.?
345 void* malloc(size_t sizeObject
);
347 BOOL
__fileno_init(void)
354 GetStartupInfoA(&StInfo
);
355 if (StInfo
.lpReserved2
&& StInfo
.cbReserved2
>= sizeof(ULONG
)) {
356 count
= *(ULONG
*)StInfo
.lpReserved2
;
358 if (sizeof(ULONG) + count * (sizeof(HANDLE) + sizeof(char)) != StInfo.cbReserved2)
365 while(count
>= maxfno
)
370 // why was this here ???? - robd.
375 //__pioinfo = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno);
376 __pioinfo
= malloc(sizeof(fileno_modes_type
) * maxfno
);
377 if (__pioinfo
== NULL
) {
380 memset(__pioinfo
, -1, sizeof(fileno_modes_type
) * maxfno
);
382 pFile
= (HANDLE
*)(StInfo
.lpReserved2
+ sizeof(ULONG
) + count
* sizeof(char));
383 pmode
= (char*)(StInfo
.lpReserved2
+ sizeof(ULONG
));
384 for (i
= 0; i
< count
; i
++) {
385 if (*pFile
!= INVALID_HANDLE_VALUE
) {
387 __pioinfo
[i
].mode
= ((*pmode
<< 8) & (_O_TEXT
|_O_BINARY
)) | (*pmode
& _O_ACCMODE
);
388 __pioinfo
[i
].hFile
= *pFile
;
394 if (__pioinfo
[0].fd
== -1) {
396 __pioinfo
[0].hFile
= GetStdHandle(STD_INPUT_HANDLE
);
397 __pioinfo
[0].mode
= _O_RDONLY
|_O_TEXT
;
399 if (__pioinfo
[1].fd
== -1) {
401 __pioinfo
[1].hFile
= GetStdHandle(STD_OUTPUT_HANDLE
);
402 __pioinfo
[1].mode
= _O_WRONLY
|_O_TEXT
;
404 if (__pioinfo
[2].fd
== -1) {
406 __pioinfo
[2].hFile
= GetStdHandle(STD_ERROR_HANDLE
);
407 __pioinfo
[2].mode
= _O_WRONLY
|_O_TEXT
;
409 if (__pioinfo
[3].fd
== -1) {
411 __pioinfo
[3].hFile
= GetStdHandle(STD_AUX_HANDLE
);
412 __pioinfo
[3].mode
= _O_WRONLY
|_O_TEXT
;
414 if (__pioinfo
[4].fd
== -1) {
416 __pioinfo
[4].hFile
= GetStdHandle(STD_PRINTER_HANDLE
);
417 __pioinfo
[4].mode
= _O_WRONLY
|_O_TEXT
;