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
));
53 int _open(const char* _path
, int _oflag
,...)
56 DWORD dwDesiredAccess
= 0;
57 DWORD dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
58 DWORD dwCreationDistribution
= 0;
59 DWORD dwFlagsAndAttributes
= 0;
63 va_start(arg
, _oflag
);
64 mode
= va_arg(arg
,int);
66 if ((mode
== S_IWRITE
) || (mode
== 0))
67 dwFlagsAndAttributes
= FILE_ATTRIBUTE_READONLY
;
70 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
71 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
74 if (( _oflag
& _O_RDWR
) == _O_RDWR
)
75 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
;
76 else if (( _oflag
& _O_WRONLY
) == _O_WRONLY
)
77 dwDesiredAccess
|= GENERIC_WRITE
;
79 dwDesiredAccess
|= GENERIC_READ
;
81 if ((_oflag
& (_O_CREAT
| _O_EXCL
) ) == (_O_CREAT
| _O_EXCL
))
82 dwCreationDistribution
|= CREATE_NEW
;
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
;
90 else if ((_oflag
& _O_APPEND
) == _O_APPEND
)
91 dwCreationDistribution
|= OPEN_EXISTING
;
92 else if ((_oflag
& _O_CREAT
) == _O_CREAT
)
93 dwCreationDistribution
|= OPEN_ALWAYS
;
95 dwCreationDistribution
|= OPEN_EXISTING
;
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
;
102 if ((_oflag
& _O_TEMPORARY
) == _O_TEMPORARY
)
103 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
105 if ((_oflag
& _O_SHORT_LIVED
) == _O_SHORT_LIVED
)
106 dwFlagsAndAttributes
|= FILE_FLAG_DELETE_ON_CLOSE
;
108 hFile
= CreateFileA(_path
,
112 dwCreationDistribution
,
113 dwFlagsAndAttributes
,
115 if (hFile
== (HANDLE
)-1)
117 return __fileno_alloc(hFile
,_oflag
);
119 // _O_APPEND Moves file pointer to end of file before every write operation.
125 __fileno_alloc(HANDLE hFile
, int mode
)
128 /* Check for bogus values */
132 for(i
=minfno
;i
<maxfno
;i
++) {
133 if (fileno_modes
[i
].fd
== -1 ) {
134 fileno_modes
[i
].fd
= i
;
135 fileno_modes
[i
].mode
= mode
;
136 fileno_modes
[i
].hFile
= hFile
;
141 /* See if we need to expand the tables. Check this BEFORE it might fail,
142 so that when we hit the count'th request, we've already up'd it. */
145 int oldcount
= maxfno
;
146 fileno_modes_type
*old_fileno_modes
= fileno_modes
;
148 fileno_modes
= (fileno_modes_type
*)malloc(maxfno
* sizeof(fileno_modes_type
));
149 if ( old_fileno_modes
!= NULL
)
151 memcpy(fileno_modes
, old_fileno_modes
, oldcount
* sizeof(fileno_modes_type
));
152 free ( old_fileno_modes
);
154 memset(fileno_modes
+ oldcount
, 0, (maxfno
-oldcount
)*sizeof(fileno_modes
));
157 /* Fill in the value */
158 fileno_modes
[i
].fd
= i
;
159 fileno_modes
[i
].mode
= mode
;
160 fileno_modes
[i
].hFile
= hFile
;
164 void *filehnd(int fileno
)
170 return GetStdHandle(STD_INPUT_HANDLE
);
172 return GetStdHandle(STD_OUTPUT_HANDLE
);
174 return GetStdHandle(STD_ERROR_HANDLE
);
176 return GetStdHandle(STD_AUX_HANDLE
);
178 return GetStdHandle(STD_PRINTER_HANDLE
);
182 if (fileno
>= maxfno
)
184 if (fileno_modes
[fileno
].fd
== -1)
186 return fileno_modes
[fileno
].hFile
;
189 int __fileno_setmode(int _fd
, int _newmode
)
198 m
= fileno_modes
[_fd
].mode
;
199 fileno_modes
[_fd
].mode
= _newmode
;
203 int __fileno_getmode(int _fd
)
210 return fileno_modes
[_fd
].mode
;
213 int __fileno_close(int _fd
)
220 fileno_modes
[_fd
].fd
= -1;
221 fileno_modes
[_fd
].hFile
= (HANDLE
)-1;
228 int _open_osfhandle(void *osfhandle
, int flags
)
230 return __fileno_alloc((HANDLE
)osfhandle
, flags
);
236 void *_get_osfhandle(int fileno
)
238 return filehnd(fileno
);
241 int __fileno_dup2(int handle1
, int handle2
)
243 if (handle1
>= maxfno
) {
248 if (handle2
>= maxfno
)
252 memcpy(&fileno_modes
[handle1
],&fileno_modes
[handle2
],sizeof(fileno_modes
));