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
10 #include <crtdll/io.h>
12 #include <crtdll/fcntl.h>
13 #include <crtdll/sys/stat.h>
14 #include <crtdll/stdlib.h>
15 #include <crtdll/internal/file.h>
16 #include <crtdll/string.h>
17 #include <crtdll/share.h>
19 typedef struct _fileno_modes_type
26 fileno_modes_type
*fileno_modes
= NULL
;
31 char __is_text_file(FILE *p
)
33 if ( p
== NULL
|| fileno_modes
== NULL
)
35 return (!((p
)->_flag
&_IOSTRG
) && (fileno_modes
[(p
)->_file
].mode
&O_TEXT
));
41 int __fileno_alloc(HANDLE hFile
, int mode
);
44 int _open(const char *_path
, int _oflag
,...)
47 DWORD dwDesiredAccess
= 0;
48 DWORD dwShareMode
= 0;
49 DWORD dwCreationDistribution
= 0;
50 DWORD dwFlagsAndAttributes
= 0;
52 if (( _oflag
& S_IREAD
) == S_IREAD
)
53 dwShareMode
= FILE_SHARE_READ
;
54 else if ( ( _oflag
& S_IWRITE
) == S_IWRITE
) {
55 dwShareMode
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
60 * _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
61 * _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
64 if (( _oflag
& _O_RDWR
) == _O_RDWR
)
65 dwDesiredAccess
|= GENERIC_WRITE
|GENERIC_READ
| FILE_READ_DATA
|
66 FILE_WRITE_DATA
| FILE_READ_ATTRIBUTES
|
67 FILE_WRITE_ATTRIBUTES
;
68 else if (( _oflag
& O_RDONLY
) == O_RDONLY
)
69 dwDesiredAccess
|= GENERIC_READ
| FILE_READ_DATA
| FILE_READ_ATTRIBUTES
70 | FILE_WRITE_ATTRIBUTES
;
71 else if (( _oflag
& _O_WRONLY
) == _O_WRONLY
)
72 dwDesiredAccess
|= GENERIC_WRITE
| FILE_WRITE_DATA
|
73 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
;
75 if (( _oflag
& S_IREAD
) == S_IREAD
)
76 dwShareMode
|= FILE_SHARE_READ
;
78 if (( _oflag
& S_IWRITE
) == S_IWRITE
)
79 dwShareMode
|= FILE_SHARE_WRITE
;
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.
127 __fileno_alloc(HANDLE hFile
, int mode
)
131 /* Check for bogus values */
135 for(i
=minfno
;i
<maxfno
;i
++) {
136 if (fileno_modes
[i
].fd
== -1 ) {
137 fileno_modes
[i
].fd
= i
;
138 fileno_modes
[i
].mode
= mode
;
139 fileno_modes
[i
].hFile
= hFile
;
145 /* See if we need to expand the tables. Check this BEFORE it might fail,
146 so that when we hit the count'th request, we've already up'd it. */
149 int oldcount
= maxfno
;
150 fileno_modes_type
*old_fileno_modes
= fileno_modes
;
152 fileno_modes
= (fileno_modes_type
*)malloc(maxfno
* sizeof(fileno_modes_type
));
153 if ( old_fileno_modes
!= NULL
)
154 memcpy(fileno_modes
, old_fileno_modes
, oldcount
* sizeof(fileno_modes_type
));
155 memset(fileno_modes
+ oldcount
, 0, (maxfno
-oldcount
)*sizeof(fileno_modes
));
156 free ( old_fileno_modes
);
160 /* Fill in the value */
161 fileno_modes
[i
].fd
= i
;
162 fileno_modes
[i
].mode
= mode
;
163 fileno_modes
[i
].hFile
= hFile
;
167 void *filehnd(int fileno
)
174 #define STD_AUX_HANDLE 3
175 #define STD_PRINTER_HANDLE 4
180 return GetStdHandle(STD_INPUT_HANDLE
);
182 return GetStdHandle(STD_OUTPUT_HANDLE
);
184 return GetStdHandle(STD_ERROR_HANDLE
);
186 return GetStdHandle(STD_AUX_HANDLE
);
188 return GetStdHandle(STD_PRINTER_HANDLE
);
193 if ( fileno
>= maxfno
)
196 if ( fileno_modes
[fileno
].fd
== -1 )
198 return fileno_modes
[fileno
].hFile
;
201 int __fileno_dup2( int handle1
, int handle2
)
203 if ( handle1
>= maxfno
)
208 if ( handle2
>= maxfno
)
214 memcpy(&fileno_modes
[handle1
],&fileno_modes
[handle2
],sizeof(fileno_modes
));
220 int __fileno_setmode(int _fd
, int _newmode
)
229 m
= fileno_modes
[_fd
].mode
;
230 fileno_modes
[_fd
].mode
= _newmode
;
234 int __fileno_close(int _fd
)
242 fileno_modes
[_fd
].fd
= -1;
243 fileno_modes
[_fd
].hFile
= (HANDLE
)-1;
247 int _open_osfhandle (void *osfhandle
, int flags
)
249 return __fileno_alloc((HANDLE
)osfhandle
, flags
);
252 void *_get_osfhandle( int fileno
)
254 return filehnd(fileno
);