80void File::open(
const String& _path,
int _oflags,
int _mode)
92 FileType fileType = UNKNOWN;
94 HANDLE
handle = CreateFileW(_path, GENERIC_READ, 0,
NULL, OPEN_EXISTING, 0,
NULL);
100 else if (GetConsoleMode(
handle, &dw))
102 else if (GetCommState(
handle, &dcb))
111 DWORD dwDesiredAccess = GENERIC_READ;
112 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
113 SECURITY_ATTRIBUTES securityAttributes = {
sizeof(SECURITY_ATTRIBUTES),
NULL,
TRUE };
114 DWORD dwCreationDisposition = OPEN_EXISTING;
115 DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
117 switch (_oflags & (READONLY | WRITEONLY | READWRITE)) {
121 dwDesiredAccess = GENERIC_READ;
124 if (_oflags & APPEND)
125 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
127 dwDesiredAccess = GENERIC_WRITE;
130 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
134 if (_oflags & EXCLUSIVE) {
138 switch (_oflags & (CREATE | EXCLUSIVE | TRUNCATE)) {
141 dwCreationDisposition = OPEN_EXISTING;
144 case CREATE | TRUNCATE:
145 dwCreationDisposition = OPEN_ALWAYS;
147 case CREATE | EXCLUSIVE:
148 case CREATE | EXCLUSIVE | TRUNCATE:
149 dwCreationDisposition = CREATE_NEW;
152 case TRUNCATE | EXCLUSIVE:
153 dwCreationDisposition = TRUNCATE_EXISTING;
157 if (_oflags & NONBLOCK)
158 dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
161 dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
163 if (fileType == CONSOLE || fileType == PIPE) {
165 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
166 OPEN_EXISTING, dwFlagsAndAttributes,
NULL);
168 else if (fileType == COMM) {
169 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
170 OPEN_EXISTING, dwFlagsAndAttributes,
NULL);
174 switch (dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) {
176 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
178 case GENERIC_READ | GENERIC_WRITE:
179 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
183 if ((_oflags & TRUNCATE) && ((dwDesiredAccess & GENERIC_WRITE) == GENERIC_WRITE))
184 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
185 &securityAttributes, TRUNCATE_EXISTING, dwFlagsAndAttributes,
NULL);
188 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
189 &securityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
NULL);
192 && (_oflags & APPEND) && ((dwDesiredAccess & GENERIC_READ) == GENERIC_READ)) {
194 if (SetFilePointer(
handle, 0,
NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
195 DWORD dwSaveError = GetLastError();
198 SetLastError(dwSaveError);
204 HANDLE readEvent =
NULL, writeEvent =
NULL;
206 __DCL_ASSERT(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED);
207 if (_oflags & (WRITEONLY | READWRITE))
211 if (_oflags & (READONLY | READWRITE) || writeEvent ==
NULL)
214 if (readEvent ==
NULL && writeEvent ==
NULL) {
215 DWORD dwSaveError = GetLastError();
217 CloseHandle(readEvent);
219 CloseHandle(writeEvent);
223 SetLastError(dwSaveError);
230 __fileType = fileType;
231 __readEvent = readEvent;
232 __writeEvent = writeEvent;
235 if (_oflags & READONLY)
237 if (_oflags & WRITEONLY)
239 if (_oflags & READWRITE)
241 if (_oflags & CREATE)
243 if (_oflags & EXCLUSIVE)
245 if (_oflags & NOCTTY)
247 if (_oflags & APPEND)
249 if (_oflags & TRUNCATE)
251 if (_oflags & NONBLOCK)
252 oflags |= O_NONBLOCK;
278void File::open(HandleType _handle,
int _ohints,
bool _closeOnClose)
285 __fileType = UNKNOWN;
290 FileType fileType = UNKNOWN;
292 wchar_t nameInfo[PATH_MAX + 1 + 4] = { L
'\0' };
295 if (GetFileInformationByHandleEx(_handle, FileNameInfo, nameInfo,
sizeof(nameInfo))) {
297 path.assign(((FILE_NAME_INFO*)nameInfo)->FileName);
300 path.format(
__T(
"(pipe: %d)"), _handle);
303 else if (GetConsoleMode(_handle, &dwConsoleMode)) {
307 else if (GetCommState(_handle, &dcb)) {
312 path.format(
__T(
"(HANDLE: %p)"), _handle);
316 HANDLE readEvent =
NULL, writeEvent =
NULL;
317 if (_ohints & NONBLOCK) {
318 if (_ohints & (WRITEONLY | READWRITE))
322 if (_ohints & (READONLY | READWRITE) || writeEvent ==
NULL)
325 if (readEvent ==
NULL && writeEvent ==
NULL) {
326 DWORD dwSaveError = GetLastError();
328 CloseHandle(readEvent);
330 CloseHandle(writeEvent);
337 __fileType = fileType;
338 __readEvent = readEvent;
339 __writeEvent = writeEvent;
341 if (isatty(_handle)) {
346 __path = String::format(
__T(
"(fd: %d)"), _handle);
414 switch (__fileType) {
416 LARGE_INTEGER fileSize;
417 if (GetFileSizeEx(
__handle, &fileSize)) {
418 LARGE_INTEGER distanceToMove;
419 LARGE_INTEGER newFilePointer;
420 distanceToMove.QuadPart = 0;
421 if (SetFilePointerEx(
__handle, distanceToMove, &newFilePointer, FILE_CURRENT))
422 nbytes = (size_t)(fileSize.QuadPart - newFilePointer.QuadPart);
427 DWORD dwTotalBytesAvail;
429 nbytes = (size_t)dwTotalBytesAvail;
433 INPUT_RECORD buf[200];
437 for (
size_t i = 0; i <
__countof(buf, INPUT_RECORD); i++) {
438 if (buf[i].EventType == KEY_EVENT) {
439 KEY_EVENT_RECORD& ev = buf[i].Event.KeyEvent;
440 if (ev.bKeyDown && ev.uChar.AsciiChar != 0) {
441 if (ev.uChar.AsciiChar == 13) {
445 n += ev.wRepeatCount;
450 if (nbytes == 0 && __readEvent)
458 if (ClearCommError(
__handle, &dwErrors, &stat))
459 nbytes = (size_t)stat.cbInQue;
476 unsigned int nbytes = 0;
478 return (
size_t)nbytes;