77void File::open(
const String& _path,
int _oflags,
int _mode)
89 FileType fileType = UNKNOWN;
91 HANDLE
handle = CreateFileW(_path, GENERIC_READ, 0,
NULL, OPEN_EXISTING, 0,
NULL);
97 else if (GetConsoleMode(
handle, &dw))
99 else if (GetCommState(
handle, &dcb))
105 DWORD dwDesiredAccess = GENERIC_READ;
106 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
107 SECURITY_ATTRIBUTES securityAttributes = {
sizeof(SECURITY_ATTRIBUTES),
NULL,
TRUE };
108 DWORD dwCreationDisposition = OPEN_EXISTING;
109 DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
111 switch (_oflags & (READONLY | WRITEONLY | READWRITE)) {
115 dwDesiredAccess = GENERIC_READ;
118 if (_oflags & APPEND)
119 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
121 dwDesiredAccess = GENERIC_WRITE;
124 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
128 if (_oflags & EXCLUSIVE) {
132 switch (_oflags & (CREATE | EXCLUSIVE | TRUNCATE)) {
135 dwCreationDisposition = OPEN_EXISTING;
138 case CREATE | TRUNCATE:
139 dwCreationDisposition = OPEN_ALWAYS;
141 case CREATE | EXCLUSIVE:
142 case CREATE | EXCLUSIVE | TRUNCATE:
143 dwCreationDisposition = CREATE_NEW;
146 case TRUNCATE | EXCLUSIVE:
147 dwCreationDisposition = TRUNCATE_EXISTING;
151 if (_oflags & NONBLOCK)
152 dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
155 dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
157 if (fileType == CONSOLE || fileType == PIPE) {
159 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
160 OPEN_EXISTING, dwFlagsAndAttributes,
NULL);
162 else if (fileType == COMM) {
163 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
164 OPEN_EXISTING, dwFlagsAndAttributes,
NULL);
168 switch (dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) {
170 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
172 case GENERIC_READ | GENERIC_WRITE:
173 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
177 if ((_oflags & TRUNCATE) && ((dwDesiredAccess & GENERIC_WRITE) == GENERIC_WRITE))
178 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
179 &securityAttributes, TRUNCATE_EXISTING, dwFlagsAndAttributes,
NULL);
182 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
183 &securityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
NULL);
186 && (_oflags & APPEND) && ((dwDesiredAccess & GENERIC_READ) == GENERIC_READ)) {
188 if (SetFilePointer(
handle, 0,
NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
189 DWORD dwSaveError = GetLastError();
192 SetLastError(dwSaveError);
198 HANDLE readEvent =
NULL, writeEvent =
NULL;
200 __DCL_ASSERT(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED);
201 if (_oflags & (WRITEONLY | READWRITE))
205 if (_oflags & (READONLY | READWRITE) || writeEvent ==
NULL)
208 if (readEvent ==
NULL && writeEvent ==
NULL) {
209 DWORD dwSaveError = GetLastError();
211 CloseHandle(readEvent);
213 CloseHandle(writeEvent);
217 SetLastError(dwSaveError);
224 __fileType = fileType;
225 __readEvent = readEvent;
226 __writeEvent = writeEvent;
229 if (_oflags & READONLY)
231 if (_oflags & WRITEONLY)
233 if (_oflags & READWRITE)
235 if (_oflags & CREATE)
237 if (_oflags & EXCLUSIVE)
239 if (_oflags & NOCTTY)
241 if (_oflags & APPEND)
243 if (_oflags & TRUNCATE)
245 if (_oflags & NONBLOCK)
246 oflags |= O_NONBLOCK;
272void File::open(HandleType _handle,
int _ohints,
bool _closeOnClose)
279 __fileType = UNKNOWN;
284 FileType fileType = UNKNOWN;
286 wchar_t nameInfo[PATH_MAX + 1 + 4] = { L
'\0' };
289 if (GetFileInformationByHandleEx(_handle, FileNameInfo, nameInfo,
sizeof(nameInfo))) {
291 path.assign(((FILE_NAME_INFO*)nameInfo)->FileName);
294 path.format(
__T(
"(pipe: %d)"), _handle);
297 else if (GetConsoleMode(_handle, &dwConsoleMode)) {
301 else if (GetCommState(_handle, &dcb)) {
306 path.format(
__T(
"(HANDLE: %p)"), _handle);
310 HANDLE readEvent =
NULL, writeEvent =
NULL;
311 if (_ohints & NONBLOCK) {
312 if (_ohints & (WRITEONLY | READWRITE))
316 if (_ohints & (READONLY | READWRITE) || writeEvent ==
NULL)
319 if (readEvent ==
NULL && writeEvent ==
NULL) {
320 DWORD dwSaveError = GetLastError();
322 CloseHandle(readEvent);
324 CloseHandle(writeEvent);
331 __fileType = fileType;
332 __readEvent = readEvent;
333 __writeEvent = writeEvent;
335 if (isatty(_handle)) {
340 __path = String::format(
__T(
"(fd: %d)"), _handle);
408 switch (__fileType) {
410 LARGE_INTEGER fileSize;
411 if (GetFileSizeEx(
__handle, &fileSize)) {
412 LARGE_INTEGER distanceToMove;
413 LARGE_INTEGER newFilePointer;
414 distanceToMove.QuadPart = 0;
415 if (SetFilePointerEx(
__handle, distanceToMove, &newFilePointer, FILE_CURRENT))
416 nbytes = (size_t)(fileSize.QuadPart - newFilePointer.QuadPart);
421 DWORD dwTotalBytesAvail;
423 nbytes = (size_t)dwTotalBytesAvail;
427 INPUT_RECORD
buf[200];
431 for (
int i = 0; i <
__countof(
buf, INPUT_RECORD); i++) {
432 if (
buf[i].EventType == KEY_EVENT) {
433 KEY_EVENT_RECORD& ev =
buf[i].Event.KeyEvent;
434 if (ev.bKeyDown && ev.uChar.AsciiChar != 0) {
435 if (ev.uChar.AsciiChar == 13) {
439 n += ev.wRepeatCount;
444 if (nbytes == 0 && __readEvent)
452 if (ClearCommError(
__handle, &dwErrors, &stat))
453 nbytes = (size_t)stat.cbInQue;
470 unsigned int nbytes = 0;
472 return (
size_t)nbytes;