DCL 3.7.4
Loading...
Searching...
No Matches
File.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4 #include <windows.h>
5 #include <wchar.h> // _wmktemp
6 #include <errno.h> // EINVAL
7#else
8 #include <stdlib.h> // mkstemp
9 #include <sys/ioctl.h> // available
10 #include <dcl/_fcntl.h>
11 #include <dcl/_stat.h>
12 #include <dcl/_unistd.h>
13#endif
14#ifdef __sun__
15 #include <sys/filio.h> // FIONREAD
16#endif
17
18#include <dcl/File.h>
19
20#if __DCL_HAVE_ALLOC_DEBUG
21#undef __DCL_ALLOC_LEVEL
22#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
23#endif
24
25#if __DCL_HAVE_THIS_FILE__
26#undef __THIS_FILE__
27static const char_t __THIS_FILE__[] = __T("dcl/File.cpp");
28#endif
29
30__DCL_BEGIN_NAMESPACE
31
33
34#ifndef INVALID_HANDLE_VALUE
35#define INVALID_HANDLE_VALUE -1
36#endif
37
38String File::toString() const
39{
40 StringBuilder r = className();
42 r += __T(" closed");
43 else
44 r += __T(" ") + __path;
45
46 return r;
47}
48
50{
52 try {
53 close();
54 }
55 catch (Exception* e) {
56 __DCL_TRACE1(__T("Error! File::~File %ls\n"), e->toString().data());
57 e->destroy();
58 }
59 }
60}
61
63{
65 __closeOnClose = true;
66#ifdef __WINNT__
67 __fileType = UNKNOWN;
68 __readEvent = NULL;
69 __writeEvent = NULL;
70#endif
71}
72
73File::File(const String& _path, int _oflags, int _mode)
75{
77 open(_path, _oflags, _mode);
78}
79
80void File::open(const String& _path, int _oflags, int _mode)
82{
84 close();
85
86 __closeOnClose = true;
87#ifdef __WINNT__
88 __fileType = UNKNOWN;
89 __readEvent = NULL;
90 __writeEvent = NULL;
91
92 FileType fileType = UNKNOWN;
93 // Console, COMM 을 검사한다.
94 HANDLE handle = CreateFileW(_path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
96 DWORD dw;
97 DCB dcb;
98 if (GetNamedPipeInfo(handle, NULL, NULL, NULL, NULL))
99 fileType = PIPE;
100 else if (GetConsoleMode(handle, &dw))
101 fileType = CONSOLE;
102 else if (GetCommState(handle, &dcb))
103 fileType = COMM;
104 else
105 fileType = REGULAR;
106
107 CloseHandle(handle);
109 }
110
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;
116
117 switch (_oflags & (READONLY | WRITEONLY | READWRITE)) {
118 default:
119 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
120 case READONLY:
121 dwDesiredAccess = GENERIC_READ;
122 break;
123 case WRITEONLY:
124 if (_oflags & APPEND)
125 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
126 else
127 dwDesiredAccess = GENERIC_WRITE;
128 break;
129 case READWRITE:
130 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
131 break;
132 }
133
134 if (_oflags & EXCLUSIVE) {
135 dwShareMode = 0;
136 }
137
138 switch (_oflags & (CREATE | EXCLUSIVE | TRUNCATE)) {
139 default:
140 case EXCLUSIVE:
141 dwCreationDisposition = OPEN_EXISTING;
142 break;
143 case CREATE:
144 case CREATE | TRUNCATE:
145 dwCreationDisposition = OPEN_ALWAYS;
146 break;
147 case CREATE | EXCLUSIVE:
148 case CREATE | EXCLUSIVE | TRUNCATE:
149 dwCreationDisposition = CREATE_NEW;
150 break;
151 case TRUNCATE:
152 case TRUNCATE | EXCLUSIVE:
153 dwCreationDisposition = TRUNCATE_EXISTING;
154 break;
155 }
156
157 if (_oflags & NONBLOCK)
158 dwFlagsAndAttributes |= FILE_FLAG_OVERLAPPED;
159
160 if (_oflags & SYNC)
161 dwFlagsAndAttributes |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
162
163 if (fileType == CONSOLE || fileType == PIPE) {
164
165 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
166 OPEN_EXISTING, dwFlagsAndAttributes, NULL);
167 }
168 else if (fileType == COMM) {
169 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode, &securityAttributes,
170 OPEN_EXISTING, dwFlagsAndAttributes, NULL);
171 }
172 else {
173 // UNKNOWN, maybe REGULAR
174 switch (dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) {
175 case GENERIC_READ:
176 dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
177 break;
178 case GENERIC_READ | GENERIC_WRITE:
179 dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
180 break;
181 }
182
183 if ((_oflags & TRUNCATE) && ((dwDesiredAccess & GENERIC_WRITE) == GENERIC_WRITE))
184 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
185 &securityAttributes, TRUNCATE_EXISTING, dwFlagsAndAttributes, NULL);
186
188 handle = CreateFileW(_path, dwDesiredAccess, dwShareMode,
189 &securityAttributes, dwCreationDisposition, dwFlagsAndAttributes, NULL);
190
192 && (_oflags & APPEND) && ((dwDesiredAccess & GENERIC_READ) == GENERIC_READ)) {
193 fileType = REGULAR;
194 if (SetFilePointer(handle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER) {
195 DWORD dwSaveError = GetLastError();
196 CloseHandle(handle);
198 SetLastError(dwSaveError);
199 }
200 }
201 }
202
203 // _oflags에 NONBLOCK이 있으면 read, write Overrlapped Io 하도록 Event 객체를 생성한다.
204 HANDLE readEvent = NULL, writeEvent = NULL;
205 if (handle != INVALID_HANDLE_VALUE && _oflags & NONBLOCK) {
206 __DCL_ASSERT(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED);
207 if (_oflags & (WRITEONLY | READWRITE))
208 writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
209
210 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
211 if (_oflags & (READONLY | READWRITE) || writeEvent == NULL)
212 readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
213
214 if (readEvent == NULL && writeEvent == NULL) {
215 DWORD dwSaveError = GetLastError();
216 if (readEvent)
217 CloseHandle(readEvent);
218 if (writeEvent)
219 CloseHandle(writeEvent);
220
221 CloseHandle(handle);
223 SetLastError(dwSaveError);
224 }
225 }
226
228 throw new IOException(_path, GetLastError());
229
230 __fileType = fileType;
231 __readEvent = readEvent;
232 __writeEvent = writeEvent;
233#else
234 int oflags = 0;
235 if (_oflags & READONLY)
236 oflags |= O_RDONLY;
237 if (_oflags & WRITEONLY)
238 oflags |= O_WRONLY;
239 if (_oflags & READWRITE)
240 oflags |= O_RDWR;
241 if (_oflags & CREATE)
242 oflags |= O_CREAT;
243 if (_oflags & EXCLUSIVE)
244 oflags |= O_EXCL;
245 if (_oflags & NOCTTY)
246 oflags |= O_NOCTTY;
247 if (_oflags & APPEND)
248 oflags |= O_APPEND;
249 if (_oflags & TRUNCATE)
250 oflags |= O_TRUNC;
251 if (_oflags & NONBLOCK)
252 oflags |= O_NONBLOCK;
253 if (_oflags & SYNC)
254 oflags |= O_SYNC;
255
256 int handle = __open(_path, oflags, _mode);
257 if (handle == -1)
258 throw new IOException(_path, errno);
259#endif
261 __path = _path;
262}
263
264File::File(HandleType _handle, const String& _path)
265{
266 __handle = _handle;
267 __path = _path;
268 __closeOnClose = true;
269}
270
271File::File(HandleType _handle, int _ohints, bool _closeOnClose)
273{
275 open(_handle, _ohints, _closeOnClose);
276}
277
278void File::open(HandleType _handle, int _ohints, bool _closeOnClose)
280{
282 close();
283
284#ifdef __WINNT__
285 __fileType = UNKNOWN;
286 __readEvent = NULL;
287 __writeEvent = NULL;
288
289 StringBuilder path;
290 FileType fileType = UNKNOWN;
291
292 wchar_t nameInfo[PATH_MAX + 1 + 4] = { L'\0' };
293 DWORD dwConsoleMode;
294 DCB dcb;
295 if (GetFileInformationByHandleEx(_handle, FileNameInfo, nameInfo, sizeof(nameInfo))) {
296 fileType = REGULAR;
297 path.assign(((FILE_NAME_INFO*)nameInfo)->FileName);
298 }
299 else if (GetNamedPipeInfo(_handle, NULL, NULL, NULL, NULL)) {
300 path.format(__T("(pipe: %d)"), _handle);
301 fileType = PIPE;
302 }
303 else if (GetConsoleMode(_handle, &dwConsoleMode)) {
304 path = __T("CON");
305 fileType = CONSOLE;
306 }
307 else if (GetCommState(_handle, &dcb)) {
308 path = __T("COM#N");
309 fileType = COMM;
310 }
311 else {
312 path.format(__T("(HANDLE: %p)"), _handle);
313 throw new IOException(path, ERROR_INVALID_HANDLE);
314 }
315
316 HANDLE readEvent = NULL, writeEvent = NULL;
317 if (_ohints & NONBLOCK) {
318 if (_ohints & (WRITEONLY | READWRITE))
319 writeEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
320
321 // _oflags == 0 이면 READONLY 인 것으로 간주한다.
322 if (_ohints & (READONLY | READWRITE) || writeEvent == NULL)
323 readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
324
325 if (readEvent == NULL && writeEvent == NULL) {
326 DWORD dwSaveError = GetLastError();
327 if (readEvent)
328 CloseHandle(readEvent);
329 if (writeEvent)
330 CloseHandle(writeEvent);
331
332 throw new IOException(path, dwSaveError);
333 }
334 }
335
336 __path = path.toString();
337 __fileType = fileType;
338 __readEvent = readEvent;
339 __writeEvent = writeEvent;
340#else
341 if (isatty(_handle)) {
342 if (__ttyname(_handle, __path) != 0)
343 throw new IOException(className(), errno);
344 }
345 else
346 __path = String::format(__T("(fd: %d)"), _handle);
347#endif
348
349 __handle = _handle;
350 __closeOnClose = _closeOnClose;
351}
352
355{
357
358#ifdef __WINNT__
359 if (!FlushFileBuffers(__handle))
360 // 콘솔과 같이 버러링을 하지 않는 장치
361 throw new IOException(__path, GetLastError());
362#else
363 if (fsync(__handle) == -1)
364 // EINVAL, EBADF, EROFS, EIO
365 throw new IOException(__path, errno);
366#endif
367}
368
371
372{
374
375#ifdef __WINNT__
376 if (__fileType == COMM)
377 PurgeComm(__handle, PURGE_RXABORT | PURGE_RXCLEAR
378 | PURGE_TXABORT | PURGE_TXCLEAR);
379 __fileType = UNKNOWN;
380 if (__readEvent) {
381 CloseHandle(__readEvent);
382 __readEvent = NULL;
383 }
384 if (__writeEvent) {
385 CloseHandle(__writeEvent);
386 __writeEvent = NULL;
387 }
388#endif
389
390 if (!__closeOnClose)
391 return;
392
393 HandleType handle = __handle;
394 String path = __path;
396 __path.clear();
397
398#ifdef __WINNT__
399 if (!CloseHandle(handle))
400 throw new IOException(path, GetLastError());
401#else
402 if (::close(handle))
403 throw(new IOException(path, errno));
404#endif
405}
406
407size_t File::available() const
409{
411
412#ifdef __WINNT__
413 size_t nbytes = 0;
414 switch (__fileType) {
415 case REGULAR: {
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);
423 }
424 break;
425 }
426 case PIPE: {
427 DWORD dwTotalBytesAvail;
428 if (PeekNamedPipe(__handle, NULL, 0, NULL, &dwTotalBytesAvail, NULL))
429 nbytes = (size_t)dwTotalBytesAvail;
430 break;
431 }
432 case CONSOLE: {
433 INPUT_RECORD buf[200]; // 200 * (sizeof(INPUT_RECORD) == 20) 4000
434 DWORD dwEvents = 0;
435 if (PeekConsoleInput(__handle, buf, __countof(buf, INPUT_RECORD), &dwEvents)) {
436 size_t n = 0;
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) {
442 nbytes = n + 2; // ReadFile에서 \r\n으로 변환되어 읽힌다.
443 break;
444 }
445 n += ev.wRepeatCount;
446 }
447 }
448 }
449 // NONBLOCK
450 if (nbytes == 0 && __readEvent)
451 nbytes = n;
452 }
453 break;
454 }
455 case COMM: {
456 DWORD dwErrors;
457 COMSTAT stat;
458 if (ClearCommError(__handle, &dwErrors, &stat))
459 nbytes = (size_t)stat.cbInQue;
460 break;
461 }
462 case SOCKET: {
463 u_long n = 0;
464 if (ioctlsocket((::SOCKET)__handle, FIONREAD, &n))
465 throw new IOException(__path, WSAGetLastError());
466 nbytes = (size_t)n;
467 break;
468 }
469 default: {
470 __DCL_ASSERT(false);
471 }
472 }
473 return nbytes;
474#else
475 // x64 nbytes를 off_t(long long int)로 하면 안된다.
476 unsigned int nbytes = 0;
477 ioctl(__handle, FIONREAD, &nbytes);
478 return (size_t)nbytes;
479#endif
480}
481
482size_t File::read(void* _buf, size_t _n)
484{
486 __DCL_ASSERT_PARAM(_buf != NULL);
487
488#ifdef __WINNT__
489 DWORD n = 0;
490 if (__readEvent) {
491 // NONBLOCK, Overrapped Read
492 OVERLAPPED ov;
493 ZeroMemory(&ov, sizeof(ov)); // cf. memset(&ov, 0, sizeof(ov));
494 ov.hEvent = __readEvent;
495 if (ReadFile(__handle, _buf, (DWORD)_n, &n, &ov)) {
496 // GetOverlappedResult가 성공하면 이벤트는 Set 된다.
497 SetEvent(ov.hEvent);
498
499 // 다른 스레드에서 WriteFile을 호출했을 경우 n == 0일 수 있다.
500 return n;
501 }
502 if (GetLastError() == ERROR_IO_PENDING) {
503 // 읽기가 진행중이다. 마칠때까지 기다린 후 결과를 확인한다.
504 switch (WaitForSingleObject(ov.hEvent, INFINITE)) {
505 case WAIT_OBJECT_0:
506 if (GetOverlappedResult(__handle, &ov, &n, FALSE))
507 return n;
508 break;
509 case WAIT_TIMEOUT: // 이것은 결코 도달하지 않는다. INFINITE
510 CancelIo(__handle);
511 SetLastError(ERROR_TIMEOUT);
512 break;
513 default:
514 __DCL_ASSERT(false);
515 }
516 }
517 // ERROR!
518 throw new IOException(__path, GetLastError());
519 }
520 else {
521 // __readEvent == NULL, Blocked Read
522 if (!ReadFile(__handle, _buf, (DWORD)_n, &n, NULL))
523 throw new IOException(__path, GetLastError());
524 }
525 return n;
526#else
527 ssize_t n = 0;
528 while ((n = ::read(__handle, _buf, _n)) == -1) {
529 // errno가 EAGAIN or EWOULDBLOCK인 경우
530 // fd가 O_NONBLOCK으로 열렸고, 읽기가 차단되었다.
531 // EAGAIN이면 0바이트를 읽었고, 읽기를 다시 시도한다.
532 // 그 외에는 오류이다.
533 if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
534 throw new IOException(__path, errno);
535 }
536 }
537 return n;
538#endif
539}
540
541size_t File::write(const void* _buf, size_t _n)
543{
545 __DCL_ASSERT_PARAM(_buf != NULL);
546
547#ifdef __WINNT__
548 DWORD n = 0;
549 if (__writeEvent) {
550 // NONBLOCK, Overrapped Write
551 OVERLAPPED ov;
552 ZeroMemory(&ov, sizeof(ov)); // cf. memset(&ov, 0, sizeof(ov));
553 ov.hEvent = __writeEvent;
554 if (WriteFile(__handle, _buf, (DWORD)_n, &n, &ov)) {
555 // GetOverlappedResult가 성공하면 이벤트는 Set 된다.
556 SetEvent(ov.hEvent);
557 // 다른 스레드에서 ReadFile을 호출했을 경우 n == 0일 수 있다.
558 return n;
559 }
560 if (GetLastError() == ERROR_IO_PENDING) {
561 // 쓰기가 진행중이다. 마칠때까지 기다린 후 결과를 확인한다.
562 switch (WaitForSingleObject(ov.hEvent, INFINITE)) {
563 case WAIT_OBJECT_0:
564 if (GetOverlappedResult(__handle, &ov, &n, FALSE))
565 return n;
566 break;
567 case WAIT_TIMEOUT: // 이것은 결코 도달하지 않는다. INFINITE
568 CancelIo(__handle);
569 SetLastError(ERROR_TIMEOUT);
570 default:
571 __DCL_ASSERT(false);
572 }
573 }
574 // ERROR!
575 throw new IOException(__path, GetLastError());
576 }
577 else {
578 // __writeEvent == NULL, Blocked Write
579 if (!WriteFile(__handle, _buf, (DWORD)_n, &n, NULL))
580 throw new IOException(__path, GetLastError());
581 }
582 return n;
583#else
584 ssize_t n = ::write(__handle, _buf, _n);
585 if (n == -1) {
586 // 파일이 nonblocking으로 표시되었고 오퍼레이션이 블록되었다.
587 if (errno == EAGAIN || errno == EWOULDBLOCK)
588 return 0;
589 else
590 throw new IOException(__path, errno);
591 }
592 return n;
593#endif
594}
595
596File::off_t File::seek(off_t _offset, int _whence)
598{
600
601#ifdef __WINNT__
602 DWORD dwMoveMethod = FILE_BEGIN;
603 switch (_whence) {
604 case BEGIN:
605 dwMoveMethod = FILE_BEGIN;
606 break;
607 case CURRENT:
608 dwMoveMethod = FILE_CURRENT;
609 break;
610 case END:
611 dwMoveMethod = FILE_END;
612 break;
613 default:
614 __DCL_ASSERT(false);
615 }
616 LARGE_INTEGER distanceToMove;
617 LARGE_INTEGER newFilePointer;
618 distanceToMove.QuadPart = _offset;
619 if (!SetFilePointerEx(__handle, distanceToMove, &newFilePointer, dwMoveMethod))
620 throw new IOException(__path, GetLastError());
621 return newFilePointer.QuadPart;
622#else
623 int whence = 0;
624 switch (_whence) {
625 case BEGIN :
626 whence = SEEK_SET;
627 break;
628 case CURRENT :
629 whence = SEEK_CUR;
630 break;
631 case END :
632 whence = SEEK_END;
633 break;
634 default :
635 __DCL_ASSERT(false);
636 }
637
638 off_t r = lseek(__handle, _offset, whence);
639 if (r == (off_t)-1)
640 throw (new IOException(__path, errno));
641 return r;
642#endif
643}
644
645File::off_t File::size() const
647{
649
650#ifdef __WINNT__
651 LARGE_INTEGER fileSize;
652 if (!GetFileSizeEx(__handle, &fileSize))
653 throw new IOException(__path, GetLastError());
654 return fileSize.QuadPart;
655#else
656 struct stat st;
657 int r = fstat(__handle, &st);
658 if (r == -1)
659 throw (new IOException(__path, errno));
660
661 return st.st_size;
662#endif
663}
664
667{
668 time_t mtime;
669 if (!time((time_t * )NULL, &mtime, (time_t * )NULL)) {
670#ifdef __WINNT__
671 throw new IOException(__path, GetLastError());
672#else
673 throw (new IOException(__path, errno));
674#endif
675 }
676 return DateTime(mtime);
677}
678
679bool File::time(time_t* _atime, time_t* _mtime, time_t* _ctime) const
680{
682
683#ifdef __WINNT__
684 FILETIME atime;
685 FILETIME mtime;
686 FILETIME ctime;
687 if (!GetFileTime(__handle, &atime, &mtime, &ctime)) {
688 return false;
689 }
690
691 ULARGE_INTEGER n;
692 if (_atime) {
693 n.HighPart = atime.dwHighDateTime;
694 n.LowPart = atime.dwLowDateTime;
695 *_atime = n.QuadPart;
696 }
697 if (_mtime) {
698 n.HighPart = mtime.dwHighDateTime;
699 n.LowPart = mtime.dwLowDateTime;
700 *_mtime = n.QuadPart;
701 }
702 if (_ctime) {
703 n.HighPart = ctime.dwHighDateTime;
704 n.LowPart = ctime.dwLowDateTime;
705 *_ctime = n.QuadPart;
706 }
707#else
708 struct stat sb;
709 int r = fstat(__handle, &sb);
710 if (r == -1) {
711 return false;
712 }
713 if (_atime) {
714 *_atime = sb.st_atime;
715 }
716 if (_mtime) {
717 *_mtime = sb.st_mtime;
718 }
719 if (_ctime) {
720 *_ctime = sb.st_ctime;
721 }
722#endif
723 return true;
724}
725
726// "dir/prefixXXXXX" 이름의 파일을 생성하여 파일 기술자를 리턴
728 const String& _dirname,
729 const String& _prefix,
730 unsigned int _mode // = 0666
732{
733 File* r = NULL;
734
735 StringBuilder sbTemplate;
736 if (!_dirname.isEmpty()) {
737 sbTemplate = _dirname;
738 if (!_dirname.endsWith(L"/")) {
739 sbTemplate += L"/";
740 }
741 }
742
743 if (!_prefix.isEmpty()) {
744 sbTemplate += _prefix;
745 }
746 else {
747 sbTemplate += L"dcl";
748 }
749
750 sbTemplate += L"XXXXXX";
751
752#ifdef __WINNT__
753 if (::_wmktemp((wchar_t*)sbTemplate.data())) {
754 r = new File(sbTemplate, READWRITE | CREATE | EXCLUSIVE, _mode);
755 }
756 else {
757 throw new IOException(sbTemplate, EINVAL);
758 }
759#else
760 ByteString bsbTemplate = UTF8Encoder::encode(sbTemplate.toString());
761 int handle = ::mkstemp((char*)bsbTemplate.data());
762 if (handle == -1) {
763 throw new IOException(sbTemplate, errno);
764 }
765
766 struct stat st;
767 if (::fstat(handle, &st)) {
768 throw new IOException(sbTemplate, errno);
769 }
770
771 if (st.st_mode != _mode) {
772 if (::fchmod(handle, _mode)) {
773 throw new IOException(sbTemplate, errno);
774 }
775 }
776
777 r = new File(handle, UTF8Decoder::decode(bsbTemplate));
778#endif
779 return r;
780}
781
782__DCL_END_NAMESPACE
DCLCAPI int __open(const String &_path, int _oflags,...)
Definition _fcntl.cpp:31
#define __THIS_FILE__
Definition _trace.h:14
DCLCAPI int __ttyname(int fd, String &_r)
Definition _unistd.cpp:60
#define NULL
Definition Config.h:312
#define __countof(array, type)
Definition Config.h:336
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
#define INVALID_HANDLE_VALUE
Definition Dir.cpp:34
#define TRUE
#define FALSE
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT_PARAM(expr)
Definition Object.h:409
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:408
#define ioctlsocket(s, cmd, argp)
Definition Socket.cpp:47
#define INFINITE
Definition Thread.h:34
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74
Definition File.h:42
HandleType handle() const
Definition File.h:246
void open(const String &_path, int _oflags=READONLY, int _mode=0666) __DCL_THROWS1(IOException *)
Definition File.cpp:80
@ CURRENT
Definition File.h:210
@ END
Definition File.h:211
@ BEGIN
Definition File.h:209
HandleType __handle
Definition File.h:255
virtual void close() __DCL_THROWS1(IOException *)
Definition File.cpp:369
virtual ~File()
bool time(time_t *_atime, time_t *_mtime, time_t *_ctime) const
Definition File.cpp:679
DateTime mtime() const __DCL_THROWS1(IOException *)
Definition File.cpp:665
String __path
Definition File.h:254
off_t seek(off_t _offset, int _whence) __DCL_THROWS1(IOException *)
Definition File.cpp:596
virtual size_t read(void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:482
static File * openTempFile(const String &_dirname, const String &_prefix, unsigned int _mode=0666) __DCL_THROWS1(IOException *)
Definition File.cpp:727
virtual String toString() const
const String & path() const
Definition File.h:251
virtual void sync() __DCL_THROWS1(IOException *)
Definition File.cpp:353
virtual size_t write(const void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:541
bool __closeOnClose
Definition File.h:256
virtual size_t available() const __DCL_THROWS1(IOException *)
Definition File.cpp:407
File()
Definition File.cpp:62
off_t size() const __DCL_THROWS1(IOException *)
Definition File.cpp:645
String className() const
Definition Object.cpp:163