1 /*=============================================================================
4 Copyright © 2008 Bruno Santos <nayart3@gmail.com>
5 =============================================================================*/
16 ///////////////////////////////////////////////////////////////////////////////
18 unsigned int get_disposition(int oflags
)
23 else if (oflags
& O_TRUNC
)
30 return TRUNCATE_EXISTING
;
35 HANDLE
sys_open(const char* filename
, int oflags
, mode_t mode
)
37 tcrt::buffer
<wchar_t> wname
;
42 if (oflags
& O_RDONLY
)
43 access
|= GENERIC_READ
;
44 if (oflags
& O_WRONLY
)
45 access
|= GENERIC_WRITE
;
48 if (oflags
& O_SYMLINK
)
49 flags
|= FILE_FLAG_OPEN_REPARSE_POINT
;
50 if ((oflags
& O_CREAT
) && !(mode
& S_IWUSR
))
51 flags
|= FILE_ATTRIBUTE_READONLY
;
52 if (!(oflags
& O_BINARY
))
53 flags
|= FILE_FLAG_BACKUP_SEMANTICS
;
54 if (oflags
& O_DELETE
) {
55 access
|= DELETE
| FILE_WRITE_ATTRIBUTES
;
56 //flags |= FILE_FLAG_DELETE_ON_CLOSE;
59 len
= strlen(filename
) + 1;
60 if (!wname
.resize(len
))
62 tcrt_utf8_to_utf16(filename
, len
, wname
.get(), len
);
63 handle
= CreateFileW(wname
.get(), access
,
64 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
65 NULL
, get_disposition(oflags
), flags
, NULL
);
66 if (handle
== INVALID_HANDLE_VALUE
) {
67 tcrt_set_errno_win32();
70 LARGE_INTEGER off
= { 0 };
71 if ((oflags
& O_APPEND
) && !SetFilePointerEx(handle
, off
, NULL
, FILE_END
)) {
72 tcrt_set_errno_win32();
80 ssize_t
sys_console_read(HANDLE handle
, void* buf
, size_t bufsize
)
82 tcrt::buffer
<wchar_t> wbuf
;
86 if (!wbuf
.resize(bufsize
))
89 if (!ReadConsoleW(handle
, wbuf
.get(), bufsize
* sizeof(wchar_t), &rd
, NULL
)) {
90 tcrt_set_errno_win32();
94 return tcrt_utf16_to_utf8(wbuf
.get(), rd
, (char*) buf
, bufsize
);
97 ssize_t
sys_console_write(HANDLE handle
, const void* buf
, size_t bufsize
)
99 tcrt::buffer
<wchar_t> wbuf
;
102 if (!wbuf
.resize(bufsize
))
105 bufsize
= tcrt_utf8_to_utf16((char*) buf
, bufsize
, wbuf
.get(), wbuf
.length());
106 if (!WriteConsoleW(handle
, wbuf
.get(), truncate_cast
<DWORD
>(bufsize
), &written
, NULL
)) {
107 tcrt_set_errno_win32();
113 static ssize_t
sys_read(HANDLE handle
, void *buf
, size_t bufsize
, off_t
* offset
)
115 IO_STATUS_BLOCK iostatus
;
118 ntstatus
= NtReadFile( handle
,
124 truncate_cast
<ULONG
>(bufsize
),
125 (LARGE_INTEGER
*) offset
,
127 if (ntstatus
== STATUS_END_OF_FILE
) {
130 } else if (!NTSUCCESS(ntstatus
)) {
131 //tcrt_set_errno_winnt(ntstatus);
135 return iostatus
.Information
;
138 static ssize_t
sys_write(HANDLE handle
, const void *buf
, size_t bufsize
, off_t
* offset
)
140 IO_STATUS_BLOCK iostatus
;
143 ntstatus
= NtWriteFile( handle
,
149 truncate_cast
<ULONG
>(bufsize
),
150 (LARGE_INTEGER
*) offset
,
152 if (!NTSUCCESS(ntstatus
)) {
153 //tcrt_set_errno_winnt(ntstatus);
157 return iostatus
.Information
;
162 int open(const char *filename
, int oflags
, ...)
168 va_start(args
, oflags
);
169 mode
= va_arg(args
, int);
172 if (!strcmp(filename
, "/dev/null"))
175 handle
= sys_open(filename
, oflags
, mode
);
179 } else if ((size_t) handle
> FOPEN_MAX
) {
184 } else if ((size_t) handle
< 3) {
190 int close(int fildes
)
192 HANDLE handle
= tcrt::fildes_to_handle(fildes
);
195 SetStdHandle(STD_INPUT_HANDLE
- fildes
, NULL
);
197 if (tcrt::is_socket_fildes(fildes
)) {
198 if (Ws2_Close(handle
)) {
199 errno
= Ws2_GetLastError();
204 if (!CloseHandle(handle
)) {
205 tcrt_set_errno_win32();
212 int fcntl(int fildes
, int cmd
, ...)
214 if (cmd
== F_GETFD
|| cmd
== F_SETFD
)
228 oldh
= tcrt::fildes_to_handle(fildes
);
229 is_sock
= tcrt::is_socket_fildes(fildes
);
231 process
= GetCurrentProcess();
232 if (!DuplicateHandle(process
, oldh
, process
, &newh
, 0, FALSE
, DUPLICATE_SAME_ACCESS
)) {
233 tcrt_set_errno_win32();
237 WSAPROTOCOL_INFOW pinfo
;
239 if (Ws2_Duplicate(oldh
, GetCurrentProcessId(), &pinfo
)) {
240 errno
= Ws2_GetLastError();
243 newh
= Ws2_Socket(0, 0, 0, &pinfo
, NULL
, 0x01);
244 if (newh
== INVALID_HANDLE_VALUE
) {
245 errno
= Ws2_GetLastError();
249 if ((size_t) newh
> FOPEN_MAX
) {
257 return (int) newh
| ((is_sock
) ? SOCKET_FILDES
: 0);
260 ssize_t
read(int fildes
, void *buf
, size_t bufsize
)
262 HANDLE handle
= tcrt::fildes_to_handle(fildes
);
264 if (tcrt::is_console_handle(handle
))
265 return sys_console_read(handle
, buf
, bufsize
);
267 if (tcrt::is_socket_fildes(fildes
))
268 return recv(fildes
, buf
, bufsize
, 0);
270 return sys_read(handle
, buf
, bufsize
, NULL
);
274 ssize_t
pread(int fildes
, void *buf
, size_t bufsize
, off_t offset
)
276 HANDLE handle
= tcrt::fildes_to_handle(fildes
);
278 if (tcrt::is_console_handle(handle
))
279 return sys_console_read(handle
, buf
, bufsize
);
281 return sys_read(handle
, buf
, bufsize
, &offset
);
284 ssize_t
write(int fildes
, const void *buf
, size_t bufsize
)
286 HANDLE handle
= tcrt::fildes_to_handle(fildes
);
288 if (tcrt::is_console_handle(handle
))
289 return sys_console_write(handle
, buf
, bufsize
);
291 if (tcrt::is_socket_fildes(fildes
))
292 return send(fildes
, buf
, bufsize
, 0);
294 return sys_write(handle
, buf
, bufsize
, NULL
);
297 ssize_t
pwrite(int fildes
, const void *buf
, size_t bufsize
, off_t offset
)
299 HANDLE handle
= tcrt::fildes_to_handle(fildes
);
301 if (tcrt::is_console_handle(handle
))
302 return sys_console_write(handle
, buf
, bufsize
);
304 return sys_write(tcrt::fildes_to_handle(fildes
), buf
, bufsize
, &offset
);
307 int isatty(int fildes
)
309 if (!tcrt::is_console_handle(tcrt::fildes_to_handle(fildes
)))
315 int fsync(int fildes
)
317 if (!FlushFileBuffers(tcrt::fildes_to_handle(fildes
))) {
318 tcrt_set_errno_win32();
324 int ftruncate(int fildes
, off_t length
)
326 FILE_END_OF_FILE_INFO eof
;
329 eof
.EndOfFile
.QuadPart
= length
;
330 if (!SetFileInformationByHandle(tcrt::fildes_to_handle(fildes
), FileEndOfFileInfo
, &eof
, sizeof(eof
))) {
331 tcrt_set_errno_win32();
337 off_t
lseek(int fildes
, off_t offset
, int whence
)
341 TCRT_STATIC_ASSERT(SEEK_SET
== FILE_BEGIN
);
342 TCRT_STATIC_ASSERT(SEEK_CUR
== FILE_CURRENT
);
343 TCRT_STATIC_ASSERT(SEEK_END
== FILE_END
);
345 off
.QuadPart
= offset
;
346 if (!SetFilePointerEx(tcrt::fildes_to_handle(fildes
), off
, &off
, whence
)) {
347 tcrt_set_errno_win32();
353 ///////////////////////////////////////////////////////////////////////////////
354 int access(const char* path
, int amode
)
358 if ( ((amode
& (R_OK
| W_OK
| X_OK
)) && (amode
& F_OK
))
359 || (amode
& ~(R_OK
| W_OK
| X_OK
| F_OK
))
365 if (stat(path
, &st
)) {
366 if ((errno
== ENOENT
) && (amode
& F_OK
))
370 if ((amode
& W_OK
) && !(st
.st_mode
& S_IWUSR
)) {
378 int chdir(const char* path
)
380 tcrt::buffer
<wchar_t> wpath
;
382 if (!wpath
.resize(strlen(path
) + 1))
385 tcrt::utf8_to_utf16(path
, wpath
.length(), wpath
.get(), wpath
.length());
386 if (!SetCurrentDirectoryW(wpath
.get())) {
387 tcrt_set_errno_win32();
393 int execv(const char* path
, const char* argv
[])
400 int execl(const char* path
, const char* arg0
, ... /*, (char *)0 */)
407 int execlp(const char* file
, const char* arg0
, ... /*, (char *)0 */)
414 int execvp(const char* file
, char* const argv
[])
428 char* getcwd(char* buf
, size_t size
)
430 tcrt::buffer
<wchar_t> name
;
431 DWORD len
= size
- 1;
438 if (!name
.resize(len
))
440 len
= GetCurrentDirectoryW(len
, name
.get());
443 } else if (len
> (size
- 1)
444 || !WideCharToMultiByte(CP_UTF8
, 0, name
.get(), len
+ 1, buf
, size
, NULL
, NULL
)) {
451 int getpagesize(void)
455 GetSystemInfo(&sysinfo
);
456 return sysinfo
.dwAllocationGranularity
;
461 return GetCurrentProcessId();
471 int pipe(int fildes
[2])
475 if (!CreatePipe(handle
+ 0, handle
+ 1, NULL
, 0)) {
476 tcrt_set_errno_win32();
479 if ((size_t) handle
[0] > FOPEN_MAX
|| (size_t) handle
[1] > FOPEN_MAX
) {
480 CloseHandle(handle
[0]);
481 CloseHandle(handle
[1]);
485 fildes
[0] = (int) handle
[0];
486 fildes
[1] = (int) handle
[1];
490 int rmdir(const char* path
)
492 tcrt::buffer
<wchar_t> wpath
;
494 if (!wpath
.resize(strlen(path
) + 1))
497 tcrt::utf8_to_utf16(path
, wpath
.length(), wpath
.get(), wpath
.length());
498 if (!RemoveDirectoryW(wpath
.get())) {
499 tcrt_set_errno_win32();
505 unsigned sleep(unsigned seconds
)
507 Sleep(seconds
* 1000);
511 int symlink(const char *path1
, const char *path2
)
517 int readlink(const char* path
, char* buf
, size_t bufsize
)
523 int link(const char* oldpath
, const char* newpath
)
525 tcrt::buffer
<wchar_t> woldpath
;
526 tcrt::buffer
<wchar_t> wnewpath
;
528 if (!woldpath
.resize(strlen(oldpath
) + 1))
530 if (!wnewpath
.resize(strlen(newpath
) + 1))
533 tcrt::utf8_to_utf16(oldpath
, woldpath
.length(), woldpath
.get(), woldpath
.length());
534 tcrt::utf8_to_utf16(newpath
, wnewpath
.length(), wnewpath
.get(), wnewpath
.length());
535 if (!CreateHardLinkW(wnewpath
.get(), woldpath
.get(), NULL
)) {
536 tcrt_set_errno_win32();
542 int unlink(const char* path
)
544 FILE_DISPOSITION_INFO del
= { TRUE
};
545 FILE_BASIC_INFO binfo
;
548 fh
= sys_open(path
, O_BINARY
| O_SYMLINK
| O_DELETE
, 0);
551 if (!SetFileInformationByHandle(fh
, FileDispositionInfo
, &del
, sizeof(del
))) {
552 GetFileInformationByHandleEx(fh
, FileBasicInfo
, &binfo
, sizeof(binfo
));
553 binfo
.FileAttributes
&= ~FILE_ATTRIBUTE_READONLY
;
554 SetFileInformationByHandle(fh
, FileBasicInfo
, &binfo
, sizeof(binfo
));
555 if (!SetFileInformationByHandle(fh
, FileDispositionInfo
, &del
, sizeof(del
))) {
557 tcrt_set_errno_win32();
565 // EOF ////////////////////////////////////////////////////////////////////////