50 #define isdirsep(x) ((x) == '/' || (x) == '\\') 57 #if defined __BORLANDC__ 58 # define _filbuf _fgetc 59 # define _flsbuf _fputc 60 # define enough_to_get(n) (--(n) >= 0) 61 # define enough_to_put(n) (++(n) < 0) 63 # define enough_to_get(n) (--(n) >= 0) 64 # define enough_to_put(n) (--(n) >= 0) 68 #define Debug(something) something 70 #define Debug(something) 73 #define TO_SOCKET(x) _get_osfhandle(x) 79 static int wstati64(
const WCHAR *path,
struct stati64 *st);
82 #define RUBY_CRITICAL(expr) do { expr; } while (0) 89 { ERROR_INVALID_FUNCTION, EINVAL },
90 { ERROR_FILE_NOT_FOUND, ENOENT },
91 { ERROR_PATH_NOT_FOUND, ENOENT },
92 { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
93 { ERROR_ACCESS_DENIED, EACCES },
94 { ERROR_INVALID_HANDLE, EBADF },
95 { ERROR_ARENA_TRASHED, ENOMEM },
96 { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
97 { ERROR_INVALID_BLOCK, ENOMEM },
98 { ERROR_BAD_ENVIRONMENT, E2BIG },
99 { ERROR_BAD_FORMAT, ENOEXEC },
100 { ERROR_INVALID_ACCESS, EINVAL },
101 { ERROR_INVALID_DATA, EINVAL },
102 { ERROR_INVALID_DRIVE, ENOENT },
103 { ERROR_CURRENT_DIRECTORY, EACCES },
104 { ERROR_NOT_SAME_DEVICE, EXDEV },
105 { ERROR_NO_MORE_FILES, ENOENT },
106 { ERROR_WRITE_PROTECT, EROFS },
107 { ERROR_BAD_UNIT, ENODEV },
108 { ERROR_NOT_READY, ENXIO },
109 { ERROR_BAD_COMMAND, EACCES },
110 { ERROR_CRC, EACCES },
111 { ERROR_BAD_LENGTH, EACCES },
113 { ERROR_NOT_DOS_DISK, EACCES },
114 { ERROR_SECTOR_NOT_FOUND, EACCES },
115 { ERROR_OUT_OF_PAPER, EACCES },
116 { ERROR_WRITE_FAULT, EIO },
117 { ERROR_READ_FAULT, EIO },
118 { ERROR_GEN_FAILURE, EACCES },
119 { ERROR_LOCK_VIOLATION, EACCES },
120 { ERROR_SHARING_VIOLATION, EACCES },
121 { ERROR_WRONG_DISK, EACCES },
122 { ERROR_SHARING_BUFFER_EXCEEDED, EACCES },
123 { ERROR_BAD_NETPATH, ENOENT },
124 { ERROR_NETWORK_ACCESS_DENIED, EACCES },
125 { ERROR_BAD_NET_NAME, ENOENT },
126 { ERROR_FILE_EXISTS, EEXIST },
127 { ERROR_CANNOT_MAKE, EACCES },
128 { ERROR_FAIL_I24, EACCES },
129 { ERROR_INVALID_PARAMETER, EINVAL },
130 { ERROR_NO_PROC_SLOTS, EAGAIN },
131 { ERROR_DRIVE_LOCKED, EACCES },
132 { ERROR_BROKEN_PIPE, EPIPE },
133 { ERROR_DISK_FULL, ENOSPC },
134 { ERROR_INVALID_TARGET_HANDLE, EBADF },
135 { ERROR_INVALID_HANDLE, EINVAL },
136 { ERROR_WAIT_NO_CHILDREN, ECHILD },
137 { ERROR_CHILD_NOT_COMPLETE, ECHILD },
138 { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
139 { ERROR_NEGATIVE_SEEK, EINVAL },
140 { ERROR_SEEK_ON_DEVICE, EACCES },
141 { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
142 { ERROR_DIRECTORY, ENOTDIR },
143 { ERROR_NOT_LOCKED, EACCES },
144 { ERROR_BAD_PATHNAME, ENOENT },
145 { ERROR_MAX_THRDS_REACHED, EAGAIN },
146 { ERROR_LOCK_FAILED, EACCES },
147 { ERROR_ALREADY_EXISTS, EEXIST },
148 { ERROR_INVALID_STARTING_CODESEG, ENOEXEC },
149 { ERROR_INVALID_STACKSEG, ENOEXEC },
150 { ERROR_INVALID_MODULETYPE, ENOEXEC },
151 { ERROR_INVALID_EXE_SIGNATURE, ENOEXEC },
152 { ERROR_EXE_MARKED_INVALID, ENOEXEC },
153 { ERROR_BAD_EXE_FORMAT, ENOEXEC },
154 { ERROR_ITERATED_DATA_EXCEEDS_64k,ENOEXEC },
155 { ERROR_INVALID_MINALLOCSIZE, ENOEXEC },
156 { ERROR_DYNLINK_FROM_INVALID_RING,ENOEXEC },
157 { ERROR_IOPL_NOT_ENABLED, ENOEXEC },
158 { ERROR_INVALID_SEGDPL, ENOEXEC },
159 { ERROR_AUTODATASEG_EXCEEDS_64k, ENOEXEC },
160 { ERROR_RING2SEG_MUST_BE_MOVABLE, ENOEXEC },
161 { ERROR_RELOC_CHAIN_XEEDS_SEGLIM, ENOEXEC },
162 { ERROR_INFLOOP_IN_RELOC_CHAIN, ENOEXEC },
163 { ERROR_FILENAME_EXCED_RANGE, ENOENT },
164 { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
165 #ifndef ERROR_PIPE_LOCAL 166 #define ERROR_PIPE_LOCAL 229L 169 { ERROR_BAD_PIPE, EPIPE },
170 { ERROR_PIPE_BUSY, EAGAIN },
171 { ERROR_NO_DATA, EPIPE },
172 { ERROR_PIPE_NOT_CONNECTED, EPIPE },
173 { ERROR_OPERATION_ABORTED, EINTR },
174 { ERROR_NOT_ENOUGH_QUOTA, ENOMEM },
175 { ERROR_MOD_NOT_FOUND, ENOENT },
178 { WSAEACCES, EACCES },
179 { WSAEFAULT, EFAULT },
180 { WSAEINVAL, EINVAL },
181 { WSAEMFILE, EMFILE },
210 { WSAENAMETOOLONG, ENAMETOOLONG },
214 { WSAENOTEMPTY, ENOTEMPTY },
237 if (
winerr >= WSABASEERR) {
243 #define map_errno rb_w32_map_errno 253 memset(&
osver, 0,
sizeof(OSVERSIONINFO));
254 osver.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
255 GetVersionEx(&
osver);
263 return osver.dwPlatformId;
271 return osver.dwMajorVersion;
277 #define LK_ERR(f,i) \ 282 DWORD err = GetLastError(); \ 283 if (err == ERROR_LOCK_VIOLATION || err == ERROR_IO_PENDING) \ 284 errno = EWOULDBLOCK; \ 285 else if (err == ERROR_NOT_LOCKED) \ 288 errno = map_errno(err); \ 291 #define LK_LEN ULONG_MAX 299 const HANDLE fh = (HANDLE)
self;
300 const int oper =
argc;
302 memset(&o, 0,
sizeof(o));
316 LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
344 static inline WCHAR *
359 if ((
unsigned char)*
p == from)
366 #ifndef CSIDL_LOCAL_APPDATA 367 #define CSIDL_LOCAL_APPDATA 28 369 #ifndef CSIDL_COMMON_APPDATA 370 #define CSIDL_COMMON_APPDATA 35 372 #ifndef CSIDL_WINDOWS 373 #define CSIDL_WINDOWS 36 376 #define CSIDL_SYSTEM 37 378 #ifndef CSIDL_PROFILE 379 #define CSIDL_PROFILE 40 389 if (SHGetSpecialFolderLocation(
NULL, n, &pidl) == 0) {
390 f = SHGetPathFromIDListW(pidl,
env);
392 alloc->lpVtbl->Free(alloc, pidl);
393 alloc->lpVtbl->Release(alloc);
403 if (
p - path == 2 && path[1] == L
':') {
417 h = LoadLibrary(module);
419 h = GetModuleHandle(module);
423 ptr = GetProcAddress(h,
func);
437 typedef UINT WINAPI wgetdir_func(WCHAR*, UINT);
441 return (*(wgetdir_func *)ptr)(path, len);
442 return GetWindowsDirectoryW(path, len);
445 #define numberof(array) (sizeof(array) / sizeof(*array)) 451 WCHAR path[_MAX_PATH];
462 static const WCHAR temp[] = L
"temp";
469 if (*(
p - 1) != L
'/') *
p++ = L
'/';
470 if (
p - path +
numberof(temp) >= len)
return 0;
471 memcpy(
p, temp,
sizeof(temp));
476 static WCHAR *
mbstr_to_wstr(UINT,
const char *,
int,
long *);
477 static char *
wstr_to_mbstr(UINT,
const WCHAR *,
int,
long *);
478 #define acp_to_wstr(str, plen) mbstr_to_wstr(CP_ACP, str, -1, plen) 479 #define wstr_to_acp(str, plen) wstr_to_mbstr(CP_ACP, str, -1, plen) 480 #define filecp_to_wstr(str, plen) mbstr_to_wstr(filecp(), str, -1, plen) 481 #define wstr_to_filecp(str, plen) wstr_to_mbstr(filecp(), str, -1, plen) 482 #define utf8_to_wstr(str, plen) mbstr_to_wstr(CP_UTF8, str, -1, plen) 483 #define wstr_to_utf8(str, plen) wstr_to_mbstr(CP_UTF8, str, -1, plen) 489 static const WCHAR TMPDIR[] = L
"TMPDIR";
490 struct {WCHAR
name[6],
eq,
val[_MAX_PATH];} wk;
494 #define set_env_val(vname) do { \ 495 typedef char namesizecheck[numberof(wk.name) < numberof(vname) - 1 ? -1 : 1]; \ 496 WCHAR *const buf = wk.name + numberof(wk.name) - numberof(vname) + 1; \ 497 MEMCPY(buf, vname, WCHAR, numberof(vname) - 1); \ 509 if (GetEnvironmentVariableW(L
"HOMEPATH",
env + len,
numberof(
env) - len) || len) {
512 else if (GetEnvironmentVariableW(L
"USERPROFILE",
env,
numberof(
env))) {
566 #if RUBY_MSVCRT_VERSION >= 80 569 invalid_parameter(
const wchar_t *expr,
const wchar_t *
func,
const wchar_t *file,
unsigned int line,
uintptr_t dummy)
574 int ruby_w32_rtc_error;
578 rtc_error_handler(
int e,
const char *src,
int line,
const char *exe,
const char *fmt, ...)
583 if (!ruby_w32_rtc_error)
return 0;
649 FreeEnvironmentStrings(
envarea);
670 if (WSAStartup(
version, &retdata))
671 rb_fatal (
"Unable to locate winsock library!\n");
672 if (LOBYTE(retdata.wVersion) != 2)
673 rb_fatal(
"could not find version 2 of winsock dll\n");
680 #define MAKE_SOCKDATA(af, fl) ((int)((((int)af)<<4)|((fl)&0xFFFF))) 681 #define GET_FAMILY(v) ((int)(((v)>>4)&0xFFFF)) 682 #define GET_FLAGS(v) ((int)((v)&0xFFFF)) 724 *sockp = (SOCKET)
key;
739 #if RUBY_MSVCRT_VERSION >= 80 740 static void set_pioinfo_extra(
void);
742 _CrtSetReportMode(_CRT_ASSERT, 0);
743 _set_invalid_parameter_handler(invalid_parameter);
744 _RTC_SetErrorFunc(rtc_error_handler);
747 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
781 #define MAXCHILDNUM 256 790 #define FOREACH_CHILD(v) do { \ 791 struct ChildRecord* v; \ 792 for (v = ChildRecord; v < ChildRecord + sizeof(ChildRecord) / sizeof(ChildRecord[0]); ++v) 793 #define END_FOREACH_CHILD } while (0) 801 if (child->pid ==
pid) {
814 if (child->hProcess == h) {
838 child->hProcess =
NULL;
908 return strcmp(
key, (*(
const char *
const *)elem) + 1);
930 char cmdname[9], *b = cmdname, c;
933 if (!(c = *cmd++))
return 0;
934 }
while (isspace(c));
939 if (b == cmdname +
sizeof(cmdname))
return 0;
942 if (c ==
'.') c = *cmd;
944 case '<':
case '>':
case '|':
946 case '\0':
case ' ':
case '\t':
case '\n':
965 if (!nm || !(nm[0][0] & (nt ? 2 : 1)))
974 return _get_osfhandle(fh);
983 int len, n, bs, quote;
985 for (t =
argv, q = cmd, len = 0;
p = *t; t++) {
988 if (!*
p || strpbrk(
p,
" \t\"'")) {
993 for (bs = 0; *
p; ++
p) {
1007 memset(q,
'\\', bs);
1012 case '<':
case '>':
case '|':
case '^':
1013 if (escape && !quote) {
1014 len += (n =
p - s) + 1;
1029 len += (n =
p - s) + 1;
1034 if (quote) *q++ =
'"';
1046 #ifdef HAVE_SYS_PARAM_H 1047 # include <sys/param.h> 1049 # define MAXPATHLEN 512 1053 #define STRNDUPV(ptr, v, src, len) \ 1054 (((char *)memcpy(((ptr) = ALLOCV((v), (len) + 1)), (src), (len)))[len] = 0) 1080 if (mode == P_OVERLAY) {
1081 WaitForSingleObject(child->
hProcess, INFINITE);
1082 GetExitCodeProcess(child->
hProcess, &exitcode);
1091 CreateChild(
const WCHAR *cmd,
const WCHAR *prog, SECURITY_ATTRIBUTES *psa,
1092 HANDLE hInput, HANDLE hOutput, HANDLE hError,
DWORD dwCreationFlags)
1095 STARTUPINFOW aStartupInfo;
1096 PROCESS_INFORMATION aProcessInformation;
1097 SECURITY_ATTRIBUTES sa;
1100 if (!cmd && !prog) {
1112 sa.nLength =
sizeof (SECURITY_ATTRIBUTES);
1113 sa.lpSecurityDescriptor =
NULL;
1114 sa.bInheritHandle =
TRUE;
1118 memset(&aStartupInfo, 0,
sizeof(aStartupInfo));
1119 memset(&aProcessInformation, 0,
sizeof(aProcessInformation));
1120 aStartupInfo.cb =
sizeof(aStartupInfo);
1121 aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
1123 aStartupInfo.hStdInput = hInput;
1126 aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
1129 aStartupInfo.hStdOutput = hOutput;
1132 aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1135 aStartupInfo.hStdError = hError;
1138 aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
1141 dwCreationFlags |= NORMAL_PRIORITY_CLASS;
1143 if (lstrlenW(cmd) > 32767) {
1150 fRet = CreateProcessW(prog, (WCHAR *)cmd, psa, psa,
1151 psa->bInheritHandle, dwCreationFlags,
NULL,
NULL,
1152 &aStartupInfo, &aProcessInformation);
1161 CloseHandle(aProcessInformation.hThread);
1163 child->
hProcess = aProcessInformation.hProcess;
1164 child->
pid = (rb_pid_t)aProcessInformation.dwProcessId;
1174 if (len <= 4)
return 0;
1176 if (*cmd++ !=
'.')
return 0;
1188 const char *shell =
NULL;
1189 WCHAR *wcmd =
NULL, *wshell =
NULL;
1212 sprintf(tmp,
"%s -c \"%s\"", shell, cmd);
1215 else if ((shell =
getenv(
"COMSPEC")) &&
1220 sprintf(tmp, nt ?
"%s /c \"%s\"" :
"%s /c %s", shell, cmd);
1224 int len = 0, quote = (*cmd ==
'"') ?
'"' : (*cmd ==
'\'') ?
'\'' : 0;
1225 for (prog = cmd + !!quote;; prog =
CharNext(prog)) {
1231 if ((
unsigned char)*prog == quote) {
1232 len = prog++ - cmd - 1;
1237 if (quote)
continue;
1247 shell =
p ?
p : cmd;
1251 if (
strchr(shell,
' ')) quote = -1;
1252 if (shell ==
fbuf) {
1255 else if (shell !=
p &&
strchr(shell,
'/')) {
1262 cmd =
p =
ALLOCV(
v, len + alen + (quote ? 2 : 0) + 1);
1263 if (quote) *
p++ =
'"';
1264 memcpy(
p, shell, len);
1266 if (quote) *
p++ =
'"';
1267 memcpy(
p, prog, alen + 1);
1295 BOOL ntcmd =
FALSE, tmpnt;
1305 if (!prog) prog =
argv[0];
1306 if ((shell =
getenv(
"COMSPEC")) &&
1317 else if (
strchr(prog,
'/')) {
1319 if (len <
sizeof(
fbuf))
1328 progs[0] = (
char *)prog;
1331 if (c_switch) len += 3;
1336 if (c_switch)
strlcat(cmd,
" /c", len);
1338 prog = c_switch ? shell : 0;
1378 #define NTGLOB 0x1 // element contains a wildcard 1379 #define NTMALLOC 0x2 // string in element was malloc'ed 1380 #define NTSTRING 0x4 // element contains a quoted string 1390 if (!tmpcurr)
return -1;
1394 if (!tmpcurr->
str)
return -1;
1425 if (status ||
last ==
tail)
return 0;
1449 for (ptr = cmd; *ptr;) {
1455 else if (quote == *ptr)
1471 if (*++ptr !=
'_' && !
ISALPHA(*ptr))
break;
1472 while (*++ptr ==
'_' ||
ISALNUM(*ptr));
1473 if (*ptr++ ==
'%')
return TRUE;
1487 static inline char *
1500 int elements, strsz, done;
1501 int slashes, escape;
1502 char *ptr, *base, *buffer, *cmdline;
1519 ptr = cmdline =
strdup(cmd);
1532 quote = slashes = globbing = escape = 0;
1533 for (done = 0; !done && *ptr; ) {
1542 if (quote !=
'\'') slashes++;
1582 if (!(slashes & 1)) {
1585 else if (quote == *ptr) {
1586 if (quote ==
'"' && quote == ptr[1])
1619 slashes = quote = 0;
1620 while (
p < base +
len) {
1624 if (quote !=
'\'') slashes++;
1629 if (!(slashes & 1) && quote && quote != c) {
1634 memcpy(
p - ((slashes + 1) >> 1),
p + (~slashes & 1),
1636 len -= ((slashes + 1) >> 1) + (~slashes & 1);
1637 p -= (slashes + 1) >> 1;
1638 if (!(slashes & 1)) {
1640 if (quote ==
'"' && quote == *
p)
1661 if (!curr)
goto do_nothing;
1665 if (globbing && (
tail =
cmdglob(curr, cmdtail))) {
1670 cmdtail = &curr->
next;
1680 for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->
next) {
1682 strsz += (curr->
len + 1);
1685 len = (elements+1)*
sizeof(
char *) + strsz;
1689 while (curr = cmdhead) {
1690 cmdhead = curr->
next;
1695 for (vptr = *vec; *vptr; ++vptr);
1711 vptr = (
char **) buffer;
1713 ptr = buffer + (elements+1) *
sizeof(
char *);
1715 while (curr = cmdhead) {
1718 ptr += curr->
len + 1;
1719 cmdhead = curr->
next;
1725 *vec = (
char **) buffer;
1734 #define PATHLEN 1024 1743 #define GetBit(bits, i) ((bits)[(i) / CHAR_BIT] & (1 << (i) % CHAR_BIT)) 1744 #define SetBit(bits, i) ((bits)[(i) / CHAR_BIT] |= (1 << (i) % CHAR_BIT)) 1746 #define BitOfIsDir(n) ((n) * 2) 1747 #define BitOfIsRep(n) ((n) * 2 + 1) 1748 #define DIRENT_PER_CHAR (CHAR_BIT / 2) 1755 static const WCHAR wildcard[] = L
"\\*";
1764 len = lstrlenW(filename);
1765 scanname =
ALLOCV_N(WCHAR,
v,
len +
sizeof(wildcard) /
sizeof(WCHAR));
1766 lstrcpyW(scanname, filename);
1767 p = CharPrevW(scanname, scanname +
len);
1768 if (*
p == L
'/' || *
p == L
'\\' || *
p == L
':')
1769 lstrcatW(scanname, wildcard + 1);
1771 lstrcatW(scanname, wildcard);
1776 fh = FindFirstFileW(scanname, fd);
1778 if (fh == INVALID_HANDLE_VALUE) {
1788 struct stati64 sbuf;
1789 WIN32_FIND_DATAW fd;
1803 if (!(sbuf.st_mode & S_IFDIR) &&
1804 (!
ISALPHA(filename[0]) || filename[1] !=
':' || filename[2] !=
'\0' ||
1805 ((1 << ((filename[0] & 0x5f) -
'A')) & GetLogicalDrives()) == 0)) {
1810 if (fh == INVALID_HANDLE_VALUE) {
1830 len = lstrlenW(fd.cFileName) + 1;
1836 tmpW =
realloc(
p->start, (idx + len) *
sizeof(WCHAR));
1846 memcpy(&
p->start[idx], fd.cFileName, len *
sizeof(WCHAR));
1855 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1857 if (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1862 }
while (FindNextFileW(fh, &fd));
1873 UINT cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
1882 int len = WideCharToMultiByte(cp, 0, wstr, clen,
NULL, 0,
NULL,
NULL) - 1;
1883 if (!(ptr =
malloc(len + 1)))
return 0;
1884 WideCharToMultiByte(cp, 0, wstr, clen, ptr, len + 1,
NULL,
NULL);
1885 if (plen) *plen = len;
1894 int len = MultiByteToWideChar(cp, 0, str, clen,
NULL, 0) - 1;
1895 if (!(ptr =
malloc(
sizeof(WCHAR) * (len + 1))))
return 0;
1896 MultiByteToWideChar(cp, 0, str, clen, ptr, len + 1);
1897 if (plen) *plen = len;
1937 dirp->
curr += lstrlenW(dirp->
curr) + 1;
1973 src =
rb_enc_str_new((
char *)wstr, lstrlenW(wstr) *
sizeof(WCHAR), utf16);
2005 static int dummy = 0;
2071 while (dirp->
curr && dirp->
loc < loc) {
2107 #if (defined _MT || defined __MSVCRT__) && !defined __BORLANDC__ 2108 #define MSVCRT_THREADS 2110 #ifdef MSVCRT_THREADS 2111 # define MTHREAD_ONLY(x) x 2112 # define STHREAD_ONLY(x) 2113 #elif defined(__BORLANDC__) 2114 # define MTHREAD_ONLY(x) 2115 # define STHREAD_ONLY(x) 2117 # define MTHREAD_ONLY(x) 2118 # define STHREAD_ONLY(x) x 2126 #ifdef MSVCRT_THREADS 2128 CRITICAL_SECTION lock;
2130 #if RUBY_MSVCRT_VERSION >= 80 2136 #if !defined _CRTIMP || defined __MINGW32__ 2138 #define _CRTIMP __declspec(dllimport) 2141 #if !defined(__BORLANDC__) 2145 #define IOINFO_L2E 5 2146 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 2147 #define _osfhnd(i) (_pioinfo(i)->osfhnd) 2148 #define _osfile(i) (_pioinfo(i)->osfile) 2149 #define _pipech(i) (_pioinfo(i)->pipech) 2151 #if RUBY_MSVCRT_VERSION >= 80 2156 set_pioinfo_extra(
void)
2160 fd = _open(
"NUL", O_RDONLY);
2162 if (
_osfhnd(fd) == _get_osfhandle(fd)) {
2174 #define pioinfo_extra 0 2185 #define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh) 2186 #define _set_osflags(fh, flags) (_osfile(fh) = (flags)) 2189 #define FEOFLAG 0x02 2191 #define FNOINHERIT 0x10 2192 #define FAPPEND 0x20 2217 if (flags & O_APPEND)
2223 if (flags & O_NOINHERIT)
2227 hF = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
2228 fh = _open_osfhandle((
intptr_t)hF, 0);
2254 #define open_null(fd) \ 2256 (nullfd = open("NUL", O_RDWR)) : 0), \ 2257 ((nullfd == (fd)) ? (keep = 1) : dup2(nullfd, fd)), \ 2266 if (
fileno(stdout) < 0) {
2269 if (
fileno(stderr) < 0) {
2272 if (nullfd >= 0 && !keep) close(nullfd);
2273 setvbuf(stderr,
NULL, _IONBF, 0);
2277 #define _set_osfhnd(fh, osfh) (void)((fh), (osfh)) 2278 #define _set_osflags(fh, flags) (void)((fh), (flags)) 2292 int fd = _open_osfhandle(osfhandle, flags);
2332 static char buffer[512];
2336 #if defined __BORLANDC__ && defined ENOTEMPTY // _sys_errlist is broken 2339 return "Filename too long";
2341 return "Directory not empty";
2348 #if WSAEWOULDBLOCK != EWOULDBLOCK 2353 for (s = 0; s < (int)(
sizeof(
errmap)/
sizeof(*
errmap)); s++)
2356 for (
i = s;
i < (int)(
sizeof(
errmap)/
sizeof(*errmap));
i++)
2363 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
2364 FORMAT_MESSAGE_IGNORE_INSERTS, &source, e,
2365 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
2366 buffer,
sizeof(buffer),
NULL) == 0 &&
2367 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
2368 FORMAT_MESSAGE_IGNORE_INSERTS, &source, e, 0,
2369 buffer,
sizeof(buffer),
NULL) == 0)
2370 strlcpy(buffer,
"Unknown Error",
sizeof(buffer));
2376 while ((
p = strpbrk(
p,
"\r\n")) !=
NULL) {
2465 for (
i = 0;
i <
set->fd_count;
i++) {
2466 if (set->fd_array[
i] == s) {
2467 memmove(&set->fd_array[
i], &set->fd_array[
i+1],
2468 sizeof(set->fd_array[0]) * (--set->fd_count -
i));
2482 if (s == (SOCKET)INVALID_HANDLE_VALUE)
2492 max = min(src->fd_count, (UINT)
max);
2493 if ((UINT)dst->capa < (UINT)
max) {
2494 dst->capa = (src->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2495 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2498 memcpy(dst->fdset->fd_array, src->fd_array,
2499 max *
sizeof(src->fd_array[0]));
2500 dst->fdset->fd_count = src->fd_count;
2507 if ((UINT)dst->capa < src->fdset->fd_count) {
2508 dst->capa = (src->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2509 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2512 memcpy(dst->fdset->fd_array, src->fdset->fd_array,
2513 src->fdset->fd_count *
sizeof(src->fdset->fd_array[0]));
2514 dst->fdset->fd_count = src->fdset->fd_count;
2533 while (s < src->fd_count) {
2534 SOCKET fd = src->fd_array[s];
2540 for (d = 0; d < dst->fdset->fd_count; d++) {
2541 if (dst->fdset->fd_array[d] == fd)
2544 if (d == dst->fdset->fd_count) {
2545 if ((
int)dst->fdset->fd_count >= dst->capa) {
2546 dst->capa = (dst->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2547 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2549 dst->fdset->fd_array[dst->fdset->fd_count++] = fd;
2553 &src->fd_array[s+1],
2554 sizeof(src->fd_array[0]) * (--src->fd_count - s));
2564 return dst ? dst->fdset->fd_count : m;
2572 if (!src || !dst)
return 0;
2574 for (s = 0; s < src->fd_count; ++s) {
2575 SOCKET fd = src->fd_array[s];
2577 for (d = 0; d < dst->fd_count; ++d) {
2578 if (dst->fd_array[d] == fd)
2581 if (d == dst->fd_count && d < FD_SETSIZE) {
2582 dst->fd_array[dst->fd_count++] = fd;
2586 return dst->fd_count;
2603 ret = (GetFileType((HANDLE)sock) == FILE_TYPE_PIPE);
2617 if (PeekNamedPipe((HANDLE)sock,
NULL, 0,
NULL, &n,
NULL)) {
2621 ret = (GetLastError() == ERROR_BROKEN_PIPE);
2637 ret = (PeekConsoleInput((HANDLE)sock, &ir, 1, &n))
2652 if (PeekConsoleInput((HANDLE)sock, &ir, 1, &n) && n > 0) {
2653 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&
2654 ir.Event.KeyEvent.uChar.AsciiChar) {
2658 ReadConsoleInput((HANDLE)sock, &ir, 1, &n);
2670 return (HANDLE)sock == INVALID_HANDLE_VALUE;
2692 r =
select(nfds, rd, wr, ex, timeout);
2694 if (r == SOCKET_ERROR) {
2750 struct timeval *timeout,
void *th)
2759 struct timeval limit = {0, 0};
2761 if (nfds < 0 || (timeout && (timeout->
tv_sec < 0 || timeout->
tv_usec < 0))) {
2767 if (timeout->
tv_sec < 0 ||
2769 timeout->
tv_usec >= 1000000) {
2776 if (limit.
tv_usec >= 1000000) {
2813 if (rd && (
int)rd->fd_count > r) r = (int)rd->fd_count;
2814 if (wr && (
int)wr->fd_count > r) r = (
int)wr->fd_count;
2815 if (ex && (
int)ex->fd_count > r) r = (
int)ex->fd_count;
2816 if (nfds > r) nfds = r;
2822 wait.tv_sec = 0;
wait.tv_usec = 10 * 1000;
2836 if (else_rd.fdset->fd_count || else_wr.fdset->fd_count) {
2839 r +=
copy_fd(rd, else_rd.fdset);
2840 r +=
copy_fd(wr, else_wr.fdset);
2856 if (rd)
copy_fd(&orig_rd, rd);
2857 if (wr)
copy_fd(&orig_wr, wr);
2858 if (ex)
copy_fd(&orig_ex, ex);
2861 if (rd)
copy_fd(rd, &orig_rd);
2862 if (wr)
copy_fd(wr, &orig_wr);
2863 if (ex)
copy_fd(ex, &orig_ex);
2901 WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, guid,
sizeof(*guid),
2902 &ptr,
sizeof(ptr), &dmy,
NULL,
NULL);
2921 HANDLE h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
2924 r = accept(
TO_SOCKET(s), addr, addrlen);
2925 if (r != INVALID_SOCKET) {
2926 SetHandleInformation((HANDLE)r, HANDLE_FLAG_INHERIT, 0);
2958 if (r == SOCKET_ERROR)
2975 r = connect(
TO_SOCKET(s), addr, addrlen);
2976 if (r == SOCKET_ERROR) {
2977 int err = WSAGetLastError();
2978 if (
err != WSAEWOULDBLOCK)
2999 r = getpeername(
TO_SOCKET(s), addr, addrlen);
3000 if (r == SOCKET_ERROR)
3019 r = getsockname(sock, addr, addrlen);
3020 if (r == SOCKET_ERROR) {
3021 DWORD wsaerror = WSAGetLastError();
3022 if (wsaerror == WSAEINVAL) {
3027 memset(addr, 0, *addrlen);
3028 addr->sa_family = af;
3051 if (r == SOCKET_ERROR)
3068 r = ioctlsocket(
TO_SOCKET(s), cmd, argp);
3069 if (r == SOCKET_ERROR)
3087 if (r == SOCKET_ERROR)
3105 if (
result != SOCKET_ERROR)
3107 else if ((
err = WSAGetLastError()) == WSA_IO_PENDING) {
3119 if ((
err = WSAGetLastError()) == WSAECONNABORTED && !
input)
3124 case WAIT_OBJECT_0 + 1:
3132 if (
err == WSAECONNABORTED && !
input)
3138 CloseHandle(wol->hEvent);
3146 struct sockaddr *addr,
int *addrlen)
3164 if (addr && addrlen)
3165 r = recvfrom(s,
buf, len, flags, addr, addrlen);
3167 r = recv(s,
buf, len, flags);
3168 if (r == SOCKET_ERROR)
3172 if (addr && addrlen)
3173 r = sendto(s,
buf, len, flags, addr, *addrlen);
3175 r = send(s,
buf, len, flags);
3176 if (r == SOCKET_ERROR) {
3178 if (
err == WSAECONNABORTED)
3191 memset(&wol, 0,
sizeof(wol));
3196 if (addr && addrlen)
3197 ret = WSARecvFrom(s, &wbuf, 1, &
size, &flg, addr, addrlen,
3200 ret = WSARecv(s, &wbuf, 1, &
size, &flg, &wol,
NULL);
3203 if (addr && addrlen)
3204 ret = WSASendTo(s, &wbuf, 1, &
size, flags, addr, *addrlen,
3207 ret = WSASend(s, &wbuf, 1, &
size, flags, &wol,
NULL);
3228 struct sockaddr *from,
int *fromlen)
3243 const struct sockaddr *to,
int tolen)
3246 (
struct sockaddr *)to, &tolen);
3249 #if !defined(MSG_TRUNC) && !defined(__MINGW32__) 3260 #ifndef WSAID_WSARECVMSG 3261 #define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}} 3263 #ifndef WSAID_WSASENDMSG 3264 #define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}} 3268 #define msghdr_to_wsamsg(msg, wsamsg) \ 3271 (wsamsg)->name = (msg)->msg_name; \ 3272 (wsamsg)->namelen = (msg)->msg_namelen; \ 3273 (wsamsg)->lpBuffers = ALLOCA_N(WSABUF, (msg)->msg_iovlen); \ 3274 (wsamsg)->dwBufferCount = (msg)->msg_iovlen; \ 3275 for (i = 0; i < (msg)->msg_iovlen; ++i) { \ 3276 (wsamsg)->lpBuffers[i].buf = (msg)->msg_iov[i].iov_base; \ 3277 (wsamsg)->lpBuffers[i].len = (msg)->msg_iov[i].iov_len; \ 3279 (wsamsg)->Control.buf = (msg)->msg_control; \ 3280 (wsamsg)->Control.len = (msg)->msg_controllen; \ 3281 (wsamsg)->dwFlags = (msg)->msg_flags; \ 3288 typedef int (WSAAPI *WSARecvMsg_t)(SOCKET,
WSAMSG *,
DWORD *, WSAOVERLAPPED *, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
3289 static WSARecvMsg_t pWSARecvMsg =
NULL;
3314 if ((ret = pWSARecvMsg(s, &wsamsg, &len,
NULL,
NULL)) == SOCKET_ERROR) {
3323 memset(&wol, 0,
sizeof(wol));
3326 ret = pWSARecvMsg(s, &wsamsg, &
size, &wol,
NULL);
3331 if (ret == SOCKET_ERROR)
3346 typedef int (WSAAPI *WSASendMsg_t)(SOCKET,
const WSAMSG *,
DWORD,
DWORD *, WSAOVERLAPPED *, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
3347 static WSASendMsg_t pWSASendMsg =
NULL;
3371 if ((ret = pWSASendMsg(s, &wsamsg, flags, &len,
NULL,
NULL)) == SOCKET_ERROR) {
3380 memset(&wol, 0,
sizeof(wol));
3383 ret = pWSASendMsg(s, &wsamsg, flags, &
size, &wol,
NULL);
3404 if (r == SOCKET_ERROR)
3422 if (r == SOCKET_ERROR)
3432 unsigned long proto_buffers_len = 0;
3434 SOCKET out = INVALID_SOCKET;
3436 if (WSAEnumProtocols(
NULL,
NULL, &proto_buffers_len) == SOCKET_ERROR) {
3437 error_code = WSAGetLastError();
3438 if (error_code == WSAENOBUFS) {
3439 WSAPROTOCOL_INFO *proto_buffers;
3440 int protocols_available = 0;
3442 proto_buffers = (WSAPROTOCOL_INFO *)
malloc(proto_buffers_len);
3443 if (!proto_buffers) {
3444 WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
3445 return INVALID_SOCKET;
3448 protocols_available =
3449 WSAEnumProtocols(
NULL, proto_buffers, &proto_buffers_len);
3450 if (protocols_available != SOCKET_ERROR) {
3452 for (
i = 0;
i < protocols_available;
i++) {
3453 if ((af !=
AF_UNSPEC && af != proto_buffers[
i].iAddressFamily) ||
3454 (
type != proto_buffers[
i].iSocketType) ||
3455 (protocol != 0 && protocol != proto_buffers[
i].iProtocol))
3458 if ((proto_buffers[
i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
3461 out = WSASocket(af,
type, protocol, &(proto_buffers[
i]), 0,
3462 WSA_FLAG_OVERLAPPED);
3465 if (out == INVALID_SOCKET)
3466 out = WSASocket(af,
type, protocol,
NULL, 0, 0);
3467 if (out != INVALID_SOCKET)
3468 SetHandleInformation((HANDLE)out, HANDLE_FLAG_INHERIT, 0);
3471 free(proto_buffers);
3492 if (s == INVALID_SOCKET) {
3507 #undef gethostbyaddr 3510 struct hostent * WSAAPI
3518 r = gethostbyaddr(addr, len,
type);
3525 #undef gethostbyname 3528 struct hostent * WSAAPI
3536 r = gethostbyname(
name);
3554 r = gethostname(
name, len);
3555 if (r == SOCKET_ERROR)
3561 #undef getprotobyname 3564 struct protoent * WSAAPI
3572 r = getprotobyname(
name);
3579 #undef getprotobynumber 3582 struct protoent * WSAAPI
3590 r = getprotobynumber(num);
3597 #undef getservbyname 3600 struct servent * WSAAPI
3615 #undef getservbyport 3618 struct servent * WSAAPI
3626 r = getservbyport(port,
proto);
3637 SOCKET svr = INVALID_SOCKET, r = INVALID_SOCKET, w = INVALID_SOCKET;
3638 struct sockaddr_in sock_in4;
3640 struct sockaddr_in6 sock_in6;
3642 struct sockaddr *addr;
3652 #if defined PF_INET && PF_INET != AF_INET 3655 sock_in4.sin_family = AF_INET;
3656 sock_in4.sin_port = 0;
3657 sock_in4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3658 addr = (
struct sockaddr *)&sock_in4;
3659 len =
sizeof(sock_in4);
3663 memset(&sock_in6, 0,
sizeof(sock_in6));
3664 sock_in6.sin6_family = AF_INET6;
3665 sock_in6.sin6_addr = IN6ADDR_LOOPBACK_INIT;
3666 addr = (
struct sockaddr *)&sock_in6;
3667 len =
sizeof(sock_in6);
3674 if (
type != SOCK_STREAM) {
3679 sv[0] = (SOCKET)INVALID_HANDLE_VALUE;
3680 sv[1] = (SOCKET)INVALID_HANDLE_VALUE;
3684 if (svr == INVALID_SOCKET)
3686 if (bind(svr, addr, len) < 0)
3688 if (getsockname(svr, addr, &len) < 0)
3690 if (
type == SOCK_STREAM)
3694 if (w == INVALID_SOCKET)
3696 if (connect(w, addr, len) < 0)
3699 r = accept(svr, addr, &len);
3700 if (r == INVALID_SOCKET)
3702 SetHandleInformation((HANDLE)r, HANDLE_FLAG_INHERIT, 0);
3709 if (r != INVALID_SOCKET)
3711 if (w != INVALID_SOCKET)
3718 if (svr != INVALID_SOCKET)
3735 closesocket(pair[0]);
3736 closesocket(pair[1]);
3742 closesocket(pair[1]);
3799 ret = ioctlsocket(sock, FIONBIO, &ioctlArg);
3811 dupfd(HANDLE hDup,
char flags,
int minfd)
3821 goto close_fds_and_return;
3824 goto close_fds_and_return;
3826 fds[filled++] = ret;
3827 }
while (filled < (
int)
numberof(fds));
3829 ret =
dupfd(hDup, flags, minfd);
3831 close_fds_and_return:
3833 while (filled > 0) {
3834 int fd = fds[--filled];
3858 arg = va_arg(va,
int);
3860 return setfl(sock, arg);
3865 if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
3866 GetCurrentProcess(), &hDup, 0L,
3868 DUPLICATE_SAME_ACCESS))) {
3874 arg = va_arg(va,
int);
3898 if (!GetExitCodeProcess(child->
hProcess, &exitcode)) {
3901 err = GetLastError();
3902 if (
err == ERROR_INVALID_PARAMETER)
3905 if (GetLastError() == ERROR_INVALID_HANDLE)
3913 if (exitcode != STILL_ACTIVE) {
3921 if (stat_loc) *stat_loc = exitcode << 8;
3949 if (!child->pid || child->pid < 0)
continue;
3951 events[
count++] = child->hProcess;
3959 if (ret == WAIT_TIMEOUT)
return 0;
3960 if ((ret -= WAIT_OBJECT_0) ==
count) {
3995 #include <sys/timeb.h> 4002 unsigned LONG_LONG
lt;
4004 tmp.LowPart = ft->dwLowDateTime;
4005 tmp.HighPart = ft->dwHighDateTime;
4013 lt -= (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60 * 1000 * 1000;
4015 tv->
tv_sec = (long)(
lt / (1000 * 1000));
4016 tv->
tv_usec = (long)(
lt % (1000 * 1000));
4018 return tv->
tv_sec > 0 ? 0 : -1;
4027 GetSystemTimeAsFileTime(&ft);
4040 len = GetCurrentDirectory(0,
NULL);
4061 if (!GetCurrentDirectory(
size,
p)) {
4075 chown(
const char *path,
int owner,
int group)
4099 if ((
unsigned int)
pid == GetCurrentProcessId() &&
4100 (sig != 0 && sig !=
SIGKILL)) {
4101 if ((ret =
raise(sig)) != 0) {
4113 if (hProc ==
NULL || hProc == INVALID_HANDLE_VALUE) {
4114 if (GetLastError() == ERROR_INVALID_PARAMETER) {
4130 DWORD ctrlEvent = CTRL_C_EVENT;
4134 ctrlEvent = CTRL_BREAK_EVENT;
4136 if (!GenerateConsoleCtrlEvent(ctrlEvent, (
DWORD)
pid)) {
4137 if ((
err = GetLastError()) == 0)
4154 hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION,
FALSE, (
DWORD)
pid);
4156 if (hProc ==
NULL || hProc == INVALID_HANDLE_VALUE) {
4157 if (GetLastError() == ERROR_INVALID_PARAMETER) {
4167 if (!GetExitCodeProcess(hProc, &status)) {
4171 else if (status == STILL_ACTIVE) {
4172 if (!TerminateProcess(hProc, 0)) {
4199 wlink(
const WCHAR *from,
const WCHAR *to)
4201 typedef BOOL (WINAPI link_func)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
4202 static link_func *pCreateHardLinkW =
NULL;
4203 static int myerrno = 0;
4205 if (!pCreateHardLinkW && !myerrno) {
4207 if (!pCreateHardLinkW)
4210 if (!pCreateHardLinkW) {
4215 if (!pCreateHardLinkW(to, from,
NULL)) {
4237 ret =
wlink(wfrom, wto);
4245 link(
const char *from,
const char *to)
4257 ret =
wlink(wfrom, wto);
4267 return waitpid(-1, status, 0);
4274 WCHAR *wenvarea, *wenv;
4279 if (len == 0)
return NULL;
4286 FreeEnvironmentStrings(
envarea);
4289 wenvarea = GetEnvironmentStringsW();
4294 for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1)
4295 wlen += lstrlenW(wenv) + 1;
4297 FreeEnvironmentStringsW(wenvarea);
4303 return env + len + 1;
4315 if (len == 0)
return NULL;
4321 FreeEnvironmentStrings(
envarea);
4324 envarea = GetEnvironmentStrings();
4332 return env + len + 1;
4339 wrename(
const WCHAR *oldpath,
const WCHAR *newpath)
4345 oldatts = GetFileAttributesW(oldpath);
4346 newatts = GetFileAttributesW(newpath);
4348 if (oldatts == -1) {
4354 if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
4355 SetFileAttributesW(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
4357 if (!MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
4363 SetFileAttributesW(newpath, oldatts);
4411 if (path[0] == L
'\\' && path[1] == L
'\\') {
4412 const WCHAR *
p = path + 2;
4413 if (
p[0] == L
'?' &&
p[1] == L
'\\') {
4421 for (
p++; *
p;
p++) {
4425 if (!
p[0] || !
p[1] || (
p[1] == L
'.' && !
p[2]))
4432 #define COPY_STAT(src, dest, size_cast) do { \ 4433 (dest).st_dev = (src).st_dev; \ 4434 (dest).st_ino = (src).st_ino; \ 4435 (dest).st_mode = (src).st_mode; \ 4436 (dest).st_nlink = (src).st_nlink; \ 4437 (dest).st_uid = (src).st_uid; \ 4438 (dest).st_gid = (src).st_gid; \ 4439 (dest).st_rdev = (src).st_rdev; \ 4440 (dest).st_size = size_cast(src).st_size; \ 4441 (dest).st_atime = (src).st_atime; \ 4442 (dest).st_mtime = (src).st_mtime; \ 4443 (dest).st_ctime = (src).st_ctime; \ 4453 BY_HANDLE_FILE_INFORMATION info;
4454 int ret =
fstat(fd, st);
4456 if (ret)
return ret;
4460 if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) {
4462 if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
4477 BY_HANDLE_FILE_INFORMATION info;
4479 int ret =
fstat(fd, &tmp);
4481 if (ret)
return ret;
4486 if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) {
4488 if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
4492 st->st_size = ((__int64)info.nFileSizeHigh << 32) | info.nFileSizeLow;
4518 if (attr & FILE_ATTRIBUTE_READONLY) {
4522 mode |= S_IREAD | S_IWRITE |
S_IWUSR;
4525 if (attr & FILE_ATTRIBUTE_DIRECTORY) {
4526 mode |= S_IFDIR | S_IEXEC;
4532 if (path && (mode & S_IFREG)) {
4533 const WCHAR *end = path + lstrlenW(path);
4534 while (path < end) {
4535 end = CharPrevW(path, end);
4537 if ((_wcsicmp(end, L
".bat") == 0) ||
4538 (_wcsicmp(end, L
".cmd") == 0) ||
4539 (_wcsicmp(end, L
".com") == 0) ||
4540 (_wcsicmp(end, L
".exe") == 0)) {
4548 mode |= (mode & 0700) >> 3;
4549 mode |= (mode & 0700) >> 6;
4558 WIN32_FIND_DATAW fd;
4560 WCHAR full[MAX_PATH];
4566 if (!(
p = wcsstr(path, L
"...")))
4568 q =
p + wcsspn(
p, L
".");
4569 if ((
p == path || wcschr(L
":/\\", *(
p - 1))) &&
4570 (!*q || wcschr(L
":/\\", *q))) {
4577 if (!GetFullPathNameW(path,
sizeof(full) /
sizeof(WCHAR), full, &dmy)) {
4581 if (full[1] == L
':' && !full[3] && GetDriveTypeW(full) != DRIVE_NO_ROOT_DIR)
4585 if (fh == INVALID_HANDLE_VALUE)
4596 WIN32_FIND_DATAW wfd;
4597 WIN32_FILE_ATTRIBUTE_DATA wfa;
4598 const WCHAR *
p = path;
4600 memset(st, 0,
sizeof(*st));
4603 if (wcsncmp(
p, L
"\\\\?\\", 4) == 0)
p += 4;
4604 if (wcspbrk(
p, L
"?*")) {
4608 if (GetFileAttributesExW(path, GetFileExInfoStandard, (
void*)&wfa)) {
4609 if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
4614 st->st_size = ((__int64)wfa.nFileSizeHigh << 32) | wfa.nFileSizeLow;
4623 int e = GetLastError();
4625 if ((e == ERROR_FILE_NOT_FOUND) || (e == ERROR_INVALID_NAME)
4626 || (e == ERROR_PATH_NOT_FOUND || (e == ERROR_BAD_NETPATH))) {
4632 h = FindFirstFileW(path, &wfd);
4633 if (h != INVALID_HANDLE_VALUE) {
4639 st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow;
4647 st->st_dev = st->st_rdev = (iswalpha(path[0]) && path[1] == L
':') ?
4648 towupper(path[0]) - L
'A' : _getdrive() - 1;
4669 WCHAR *buf1, *s, *end;
4678 size = lstrlenW(path) + 2;
4680 for (
p = path, s = buf1; *
p;
p++, s++) {
4688 if (!len || L
'\"' == *(--s)) {
4692 end = buf1 + len - 1;
4697 else if (*end != L
'\\')
4698 lstrcatW(buf1, L
"\\");
4700 else if (*end == L
'\\' || (buf1 + 1 == end && *end == L
':'))
4701 lstrcatW(buf1, L
".");
4745 struct stati64
stat;
4749 if ((
stat.st_mode & mode) != mode) {
4760 struct stati64
stat;
4764 if ((
stat.st_mode & mode) != mode) {
4775 long upos, lpos, usize, lsize;
4779 if ((lpos = SetFilePointer(h, 0, (upos = 0, &upos),
SEEK_CUR)) == -1L &&
4780 (e = GetLastError())) {
4784 usize = (long)(
size >> 32);
4786 if (SetFilePointer(h, lsize, &usize,
SEEK_SET) == (
DWORD)-1L &&
4787 (e = GetLastError())) {
4790 else if (!SetEndOfFile(h)) {
4796 SetFilePointer(h, lpos, &upos,
SEEK_SET);
4806 h = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
4807 if (h == INVALID_HANDLE_VALUE) {
4822 h = (HANDLE)_get_osfhandle(fd);
4823 if (h == (HANDLE)-1)
return -1;
4830 _filelengthi64(
int fd)
4835 l = GetFileSize((HANDLE)_get_osfhandle(fd), &u);
4836 if (l == (
DWORD)-1L && (e = GetLastError())) {
4840 return ((
off_t)u << 32) | l;
4845 _lseeki64(
int fd,
off_t offset,
int whence)
4849 HANDLE h = (HANDLE)_get_osfhandle(fd);
4855 u = (long)(offset >> 32);
4856 if ((l = SetFilePointer(h, (
long)offset, &u, whence)) == -1L &&
4857 (e = GetLastError())) {
4861 return ((
off_t)u << 32) | l;
4872 if (fgetpos(stream, (fpos_t *)&pos))
4877 if ((pos = _filelengthi64(
fileno(stream))) == (
off_t)-1)
4885 return fsetpos(stream, (fpos_t *)&pos);
4893 if (fgetpos(stream, (fpos_t *)&pos))
return (
off_t)-1;
4901 __int64 qw = ft->dwHighDateTime;
4903 qw |= ft->dwLowDateTime;
4912 FILETIME create, exit, kernel, user;
4914 if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
4929 #define yield_once() Sleep(0) 4930 #define yield_until(condition) do yield_once(); while (!(condition)) 4940 #if defined __BORLANDC__ 4944 read(
int fd,
void *
buf,
size_t size)
4946 int ret = _read(fd,
buf,
size);
4947 if ((ret < 0) && (
errno == EPIPE)) {
4957 #define FILE_COUNT _cnt 4958 #define FILE_READPTR _ptr 4967 c = (
unsigned char)*stream->FILE_READPTR++;
4970 c = _filbuf(stream);
4971 #if defined __BORLANDC__ 4972 if ((c ==
EOF) && (
errno == EPIPE)) {
4987 c = (
unsigned char)(*stream->FILE_READPTR++ = (
char)c);
4990 c = _flsbuf(c, stream);
5027 BOOL interrupted =
FALSE;
5048 if (TerminateThread(thr, intrval)) {
5053 GetExitCodeThread(thr, &
val);
5058 MEMORY_BASIC_INFORMATION m;
5060 memset(&m, 0,
sizeof(m));
5061 if (!VirtualQuery(arg.
stackaddr, &m,
sizeof(m))) {
5062 Debug(fprintf(stderr,
"couldn't get stack base:%p:%d\n",
5065 else if (!VirtualFree(m.AllocationBase, 0, MEM_RELEASE)) {
5066 Debug(fprintf(stderr,
"couldn't release stack:%p:%d\n",
5067 m.AllocationBase, GetLastError()));
5078 rb_fatal(
"failed to launch waiter thread:%ld", GetLastError());
5088 WCHAR *envtop, *
env;
5089 char **myenvtop, **myenv;
5102 envtop = GetEnvironmentStringsW();
5103 for (
env = envtop, num = 0; *
env;
env += lstrlenW(
env) + 1)
5104 if (*
env !=
'=') num++;
5106 myenvtop = (
char **)
malloc(
sizeof(
char *) * (num + 1));
5107 for (
env = envtop, myenv = myenvtop; *
env;
env += lstrlenW(
env) + 1) {
5116 FreeEnvironmentStringsW(envtop);
5127 while (*t)
free(*t++);
5135 return GetCurrentProcessId();
5143 typedef long (WINAPI query_func)(HANDLE, int,
void *,
ULONG,
ULONG *);
5144 static query_func *pNtQueryInformationProcess =
NULL;
5148 if (!pNtQueryInformationProcess)
5149 pNtQueryInformationProcess = (query_func *)
get_proc_address(
"ntdll.dll",
"NtQueryInformationProcess",
NULL);
5150 if (pNtQueryInformationProcess) {
5153 void* PebBaseAddress;
5160 long ret = pNtQueryInformationProcess(GetCurrentProcess(), 0, &pbi,
sizeof(pbi), &len);
5162 ppid = pbi.ParentProcessId;
5179 va_start(arg, oflag);
5180 pmode = va_arg(arg,
int);
5194 DWORD attr = GetFileAttributesW(wfile);
5195 if (attr == (
DWORD)-1L ||
5196 !(attr & FILE_ATTRIBUTE_DIRECTORY) ||
5227 va_start(arg, oflag);
5228 pmode = va_arg(arg,
int);
5231 if ((oflag & O_TEXT) || !(oflag &
O_BINARY)) {
5232 ret = _open(file, oflag, pmode);
5251 DWORD attr = FILE_ATTRIBUTE_NORMAL;
5252 SECURITY_ATTRIBUTES sec;
5255 if ((oflag & O_TEXT) || !(oflag &
O_BINARY)) {
5258 va_start(arg, oflag);
5259 pmode = va_arg(arg,
int);
5261 fd = _wopen(file, oflag, pmode);
5266 sec.nLength =
sizeof(sec);
5267 sec.lpSecurityDescriptor =
NULL;
5268 if (oflag & O_NOINHERIT) {
5269 sec.bInheritHandle =
FALSE;
5273 sec.bInheritHandle =
TRUE;
5275 oflag &= ~O_NOINHERIT;
5280 switch (oflag & (O_RDWR | O_RDONLY | O_WRONLY)) {
5282 access = GENERIC_READ | GENERIC_WRITE;
5294 oflag &= ~(O_RDWR | O_RDONLY | O_WRONLY);
5296 switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
5298 create = OPEN_ALWAYS;
5302 create = OPEN_EXISTING;
5304 case O_CREAT | O_EXCL:
5305 case O_CREAT | O_EXCL | O_TRUNC:
5306 create = CREATE_NEW;
5309 case O_TRUNC | O_EXCL:
5310 create = TRUNCATE_EXISTING;
5312 case O_CREAT | O_TRUNC:
5313 create = CREATE_ALWAYS;
5319 if (oflag & O_CREAT) {
5322 va_start(arg, oflag);
5323 pmode = va_arg(arg,
int);
5326 if (!(pmode & S_IWRITE))
5327 attr = FILE_ATTRIBUTE_READONLY;
5329 oflag &= ~(O_CREAT | O_EXCL | O_TRUNC);
5331 if (oflag & O_TEMPORARY) {
5332 attr |= FILE_FLAG_DELETE_ON_CLOSE;
5335 oflag &= ~O_TEMPORARY;
5337 if (oflag & _O_SHORT_LIVED)
5338 attr |= FILE_ATTRIBUTE_TEMPORARY;
5339 oflag &= ~_O_SHORT_LIVED;
5341 switch (oflag & (O_SEQUENTIAL | O_RANDOM)) {
5345 attr |= FILE_FLAG_SEQUENTIAL_SCAN;
5348 attr |= FILE_FLAG_RANDOM_ACCESS;
5354 oflag &= ~(O_SEQUENTIAL | O_RANDOM);
5356 if (oflag & ~O_APPEND) {
5363 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5364 fd = _open_osfhandle((
intptr_t)h, 0);
5376 h = CreateFileW(file,
access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
5377 create, attr,
NULL);
5378 if (h == INVALID_HANDLE_VALUE) {
5379 DWORD e = GetLastError();
5387 switch (GetFileType(h)) {
5388 case FILE_TYPE_CHAR:
5391 case FILE_TYPE_PIPE:
5394 case FILE_TYPE_UNKNOWN:
5401 if (!(flags & (
FDEV |
FPIPE)) && (oflag & O_APPEND))
5421 int save_errno =
errno;
5423 if (fflush(fp))
return -1;
5431 if (closesocket(sock) == SOCKET_ERROR) {
5442 static DWORD serial = 0;
5443 char name[] =
"\\\\.\\pipe\\ruby0000000000000000-0000000000000000";
5445 SECURITY_ATTRIBUTES sec;
5446 HANDLE hRead, hWrite, h;
5447 int fdRead, fdWrite;
5452 return _pipe(fds, 65536L, _O_NOINHERIT);
5457 sec.nLength =
sizeof(sec);
5458 sec.lpSecurityDescriptor =
NULL;
5459 sec.bInheritHandle =
FALSE;
5462 hRead = CreateNamedPipe(
name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
5463 0, 2, 65536, 65536, 0, &sec);
5465 if (hRead == INVALID_HANDLE_VALUE) {
5467 if (
err == ERROR_PIPE_BUSY)
5475 hWrite = CreateFile(
name, GENERIC_READ | GENERIC_WRITE, 0, &sec,
5476 OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
NULL);
5478 if (hWrite == INVALID_HANDLE_VALUE) {
5486 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5487 fdRead = _open_osfhandle((
intptr_t)h, 0);
5491 CloseHandle(hWrite);
5506 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5507 fdWrite = _open_osfhandle((
intptr_t)h, 0);
5509 if (fdWrite == -1) {
5511 CloseHandle(hWrite);
5544 CONSOLE_SCREEN_BUFFER_INFO csbi;
5547 p->vt100.attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
5548 p->vt100.saved.X =
p->vt100.saved.Y = 0;
5549 if (GetConsoleScreenBufferInfo(h, &csbi)) {
5550 p->vt100.attr = csbi.wAttributes;
5573 #define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) 5574 #define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED) 5575 DWORD bold =
attr & (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
5579 while (
count-- > 0) {
5582 attr = default_attr;
5587 bold |= rev ? BACKGROUND_INTENSITY : FOREGROUND_INTENSITY;
5590 #ifndef COMMON_LVB_UNDERSCORE 5591 #define COMMON_LVB_UNDERSCORE 0x8000 5600 attr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
5604 attr =
attr & ~(FOREGROUND_BLUE | FOREGROUND_GREEN) | FOREGROUND_RED;
5608 attr =
attr & ~(FOREGROUND_BLUE | FOREGROUND_RED) | FOREGROUND_GREEN;
5612 attr =
attr & ~FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
5616 attr =
attr & ~(FOREGROUND_GREEN | FOREGROUND_RED) | FOREGROUND_BLUE;
5620 attr =
attr & ~FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED;
5624 attr =
attr & ~FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
5628 attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
5632 attr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
5635 attr =
attr & ~(BACKGROUND_BLUE | BACKGROUND_GREEN) | BACKGROUND_RED;
5638 attr =
attr & ~(BACKGROUND_BLUE | BACKGROUND_RED) | BACKGROUND_GREEN;
5641 attr =
attr & ~BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
5644 attr =
attr & ~(BACKGROUND_GREEN | BACKGROUND_RED) | BACKGROUND_BLUE;
5647 attr =
attr & ~BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED;
5650 attr =
attr & ~BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
5653 attr |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
5669 CONSOLE_SCREEN_BUFFER_INFO csbi;
5676 if (!GetConsoleScreenBufferInfo(handle, &csbi))
return;
5683 csbi.dwCursorPosition.X = 0;
5685 csbi.dwCursorPosition.Y -= arg1;
5686 if (csbi.dwCursorPosition.Y < 0)
5687 csbi.dwCursorPosition.Y = 0;
5688 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5691 csbi.dwCursorPosition.X = 0;
5694 csbi.dwCursorPosition.Y += arg1;
5695 if (csbi.dwCursorPosition.Y >= csbi.dwSize.Y)
5696 csbi.dwCursorPosition.Y = csbi.dwSize.Y;
5697 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5700 csbi.dwCursorPosition.X += arg1;
5701 if (csbi.dwCursorPosition.X >= csbi.dwSize.X)
5702 csbi.dwCursorPosition.X = csbi.dwSize.X;
5703 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5706 csbi.dwCursorPosition.X -= arg1;
5707 if (csbi.dwCursorPosition.X < 0)
5708 csbi.dwCursorPosition.X = 0;
5709 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5713 csbi.dwCursorPosition.X = (arg1 > csbi.dwSize.X ? csbi.dwSize.X : arg1) - 1;
5714 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5717 csbi.dwCursorPosition.Y = (arg1 > csbi.dwSize.Y ? csbi.dwSize.Y : arg1) - 1;
5718 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
5722 pos.Y = (arg1 > csbi.dwSize.Y ? csbi.dwSize.Y : arg1) - 1;
5723 if (
count < 2 || (arg1 =
seq[1]) <= 0) arg1 = 1;
5724 pos.X = (arg1 > csbi.dwSize.X ? csbi.dwSize.X : arg1) - 1;
5725 SetConsoleCursorPosition(handle, pos);
5730 FillConsoleOutputCharacterW(handle, L
' ',
5731 csbi.dwSize.X * (csbi.dwSize.Y - csbi.dwCursorPosition.Y) - csbi.dwCursorPosition.X,
5732 csbi.dwCursorPosition, &written);
5736 pos.Y = csbi.dwCursorPosition.Y;
5737 FillConsoleOutputCharacterW(handle, L
' ',
5738 csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X,
5744 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X * csbi.dwSize.Y, pos, &written);
5751 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X - csbi.dwCursorPosition.X, csbi.dwCursorPosition, &written);
5755 pos.Y = csbi.dwCursorPosition.Y;
5756 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwCursorPosition.X, pos, &written);
5760 pos.Y = csbi.dwCursorPosition.Y;
5761 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X, pos, &written);
5769 SetConsoleCursorPosition(handle, s->
vt100.
saved);
5773 CONSOLE_CURSOR_INFO cci;
5774 GetConsoleCursorInfo(handle, &cci);
5775 cci.bVisible =
TRUE;
5776 SetConsoleCursorInfo(handle, &cci);
5781 CONSOLE_CURSOR_INFO cci;
5782 GetConsoleCursorInfo(handle, &cci);
5783 cci.bVisible =
FALSE;
5784 SetConsoleCursorInfo(handle, &cci);
5794 const WCHAR *ptr = *ptrp;
5795 long rest, len = *lenp;
5799 rest = *lenp - len - 1;
5803 rest = *lenp - len - 1;
5804 if (rest > 0) --rest;
5809 if (wc >= L
'0' && wc <= L
'9') {
5812 *
seq = (*
seq * 10) + (wc - L
'0');
5853 int save_errno =
errno;
5864 if (closesocket(sock) == SOCKET_ERROR) {
5874 memset(ol, 0,
sizeof(*ol));
5878 DWORD low = SetFilePointer((HANDLE)
_osfhnd(fd), 0, &high, method);
5879 #ifndef INVALID_SET_FILE_POINTER 5880 #define INVALID_SET_FILE_POINTER ((DWORD)-1) 5884 if (
err != NO_ERROR) {
5890 ol->OffsetHigh = high;
5903 CloseHandle(ol->hEvent);
5906 LONG high = ol->OffsetHigh;
5908 if (low < ol->Offset)
5910 SetFilePointer((HANDLE)
_osfhnd(fd), low, &high, FILE_BEGIN);
5925 OVERLAPPED ol, *pol =
NULL;
5927 BOOL islineinput =
FALSE;
5934 if (_get_osfhandle(fd) == -1) {
5954 GetConsoleMode((HANDLE)
_osfhnd(fd),&mode);
5955 islineinput = (mode & ENABLE_LINE_INPUT) != 0;
5982 if (!ReadFile((HANDLE)
_osfhnd(fd),
buf, len, &read, pol)) {
5983 err = GetLastError();
5984 if (
err != ERROR_IO_PENDING) {
5985 if (pol) CloseHandle(ol.hEvent);
5986 if (
err == ERROR_ACCESS_DENIED)
5988 else if (
err == ERROR_BROKEN_PIPE ||
err == ERROR_HANDLE_EOF) {
6001 if (
wait != WAIT_OBJECT_0) {
6002 if (
wait == WAIT_OBJECT_0 + 1)
6006 CloseHandle(ol.hEvent);
6012 if (!GetOverlappedResult((HANDLE)
_osfhnd(fd), &ol, &read,
TRUE) &&
6013 (
err = GetLastError()) != ERROR_HANDLE_EOF) {
6015 if (
err != ERROR_BROKEN_PIPE) {
6019 CloseHandle(ol.hEvent);
6027 err = GetLastError();
6037 buf = (
char *)
buf + read;
6038 if (
err != ERROR_OPERATION_ABORTED &&
6039 !(isconsole && len == 1 && (!islineinput || *((
char *)
buf - 1) ==
'\n')) &&
size > 0)
6062 OVERLAPPED ol, *pol =
NULL;
6068 if (_get_osfhandle(fd) == -1) {
6100 if (!WriteFile((HANDLE)
_osfhnd(fd),
buf, len, &written, pol)) {
6101 err = GetLastError();
6102 if (
err != ERROR_IO_PENDING) {
6103 if (pol) CloseHandle(ol.hEvent);
6104 if (
err == ERROR_ACCESS_DENIED)
6115 if (
wait != WAIT_OBJECT_0) {
6116 if (
wait == WAIT_OBJECT_0 + 1)
6120 CloseHandle(ol.hEvent);
6126 if (!GetOverlappedResult((HANDLE)
_osfhnd(fd), &ol, &written,
6129 CloseHandle(ol.hEvent);
6142 if (written == len) {
6143 buf = (
const char *)
buf + len;
6159 DWORD dwMode, reslen;
6162 const WCHAR *ptr, *next;
6166 if (disable)
return -1L;
6168 if (!GetConsoleMode(handle, &dwMode) ||
6178 long curlen =
constat_parse(handle, s, (next = ptr, &next), &len);
6180 if (!WriteConsoleW(handle, ptr, curlen, &reslen,
NULL)) {
6181 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
6189 return (
long)reslen;
6198 tmp.QuadPart = ((LONG_LONG)time + (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60) * 10 * 1000 * 1000;
6199 ft->dwLowDateTime = tmp.LowPart;
6200 ft->dwHighDateTime = tmp.HighPart;
6209 FILETIME atime, mtime;
6210 struct stati64
stat;
6226 GetSystemTimeAsFileTime(&atime);
6231 const DWORD attr = GetFileAttributesW(path);
6232 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))
6233 SetFileAttributesW(path, attr & ~FILE_ATTRIBUTE_READONLY);
6234 hFile = CreateFileW(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
6235 FILE_FLAG_BACKUP_SEMANTICS, 0);
6236 if (hFile == INVALID_HANDLE_VALUE) {
6241 if (!SetFileTime(hFile,
NULL, &atime, &mtime)) {
6247 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))
6248 SetFileAttributesW(path, attr);
6263 ret =
wutime(wpath, times);
6277 ret =
wutime(wpath, times);
6291 ret = _wchdir(wpath);
6303 if (CreateDirectoryW(wpath,
NULL) ==
FALSE) {
6307 if (_wchmod(wpath, mode) == -1) {
6308 RemoveDirectoryW(wpath);
6325 ret =
wmkdir(wpath, mode);
6339 ret =
wmkdir(wpath, mode);
6350 const DWORD attr = GetFileAttributesW(wpath);
6351 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6352 SetFileAttributesW(wpath, attr & ~FILE_ATTRIBUTE_READONLY);
6354 if (RemoveDirectoryW(wpath) ==
FALSE) {
6357 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6358 SetFileAttributesW(wpath, attr);
6399 const DWORD attr = GetFileAttributesW(path);
6400 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6401 SetFileAttributesW(path, attr & ~FILE_ATTRIBUTE_READONLY);
6403 if (!DeleteFileW(path)) {
6406 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6407 SetFileAttributesW(path, attr);
6451 ret = _wchmod(wpath, mode);
6456 #if !defined(__BORLANDC__) 6464 if (_get_osfhandle(fd) == -1) {
6467 if (!GetConsoleMode((HANDLE)
_osfhnd(fd), &mode)) {
6482 too_many_files(
void)
6485 for (
f = _streams;
f < _streams + _nfile;
f++) {
6486 if (
f->fd < 0)
return 0;
6494 rb_w32_fopen(
const char *path,
const char *mode)
6498 if (too_many_files())
6506 rb_w32_fdopen(
int handle,
const char *
type)
6512 else if (too_many_files())
6520 rb_w32_fsopen(
const char *path,
const char *mode,
int shflags)
6522 FILE *
f = (
errno = 0, _fsopen(path, mode, shflags));
6524 if (too_many_files())
6531 #if defined(_MSC_VER) && RUBY_MSVCRT_VERSION <= 60 6532 extern long _ftol(
double);
6542 _ftol2_sse(
double d)
6553 int *ip = (
int *)(&x + 1) - 1;
6562 typedef char *(WSAAPI inet_ntop_t)(
int,
void *,
char *,
size_t);
6563 inet_ntop_t *pInetNtop;
6566 return pInetNtop(af, (
void *)addr, numaddr, numaddr_len);
6570 memcpy(&in.s_addr, addr,
sizeof(in.s_addr));
6571 snprintf(numaddr, numaddr_len,
"%s", inet_ntoa(in));
6583 #if RUBY_MSVCRT_VERSION < 80 && !defined(__MINGW64__) 6590 if (!FileTimeToSystemTime(&ft, st))
return -1;
6598 int y = st->wYear, m = st->wMonth, d = st->wDay;
6599 t->tm_sec = st->wSecond;
6600 t->tm_min = st->wMinute;
6601 t->tm_hour = st->wHour;
6602 t->tm_mday = st->wDay;
6603 t->tm_mon = st->wMonth - 1;
6604 t->tm_year = y - 1900;
6605 t->tm_wday = st->wDayOfWeek;
6613 d += 31 + 28 + (!(y % 4) && ((y % 100) || !(y % 400)));
6614 d += ((m - 3) * 153 + 2) / 5;
6624 TIME_ZONE_INFORMATION stdtz;
6627 if (!SystemTimeToTzSpecificLocalTime(tz, gst, lst))
return -1;
6629 GetTimeZoneInformation(&stdtz);
6632 if (tz->StandardBias == tz->DaylightBias)
return 0;
6633 if (!tz->StandardDate.wMonth)
return 0;
6634 if (!tz->DaylightDate.wMonth)
return 0;
6635 if (tz != &stdtz) stdtz = *tz;
6637 stdtz.StandardDate.wMonth = stdtz.DaylightDate.wMonth = 0;
6638 if (!SystemTimeToTzSpecificLocalTime(&stdtz, gst, &sst))
return 0;
6639 if (lst->wMinute == sst.wMinute && lst->wHour == sst.wHour)
6646 # ifndef MINGW_HAS_SECURE_API 6647 _CRTIMP errno_t __cdecl _gmtime64_s(
struct tm* tm,
const __time64_t *time);
6648 _CRTIMP errno_t __cdecl _localtime64_s(
struct tm* tm,
const __time64_t *time);
6650 # define gmtime_s _gmtime64_s 6651 # define localtime_s _localtime64_s 6664 #if RUBY_MSVCRT_VERSION >= 80 || defined(__MINGW64__) 6665 e = gmtime_s(rp, tp);
6666 if (e != 0)
goto error;
6688 #if RUBY_MSVCRT_VERSION >= 80 || defined(__MINGW64__) 6689 e = localtime_s(rp, tp);
6693 SYSTEMTIME gst, lst;
6707 int len =
sizeof(tmp);
6708 int r = getsockopt((SOCKET)h, SOL_SOCKET, SO_DEBUG, (
char *)&tmp, &len);
6709 if (r != SOCKET_ERROR || WSAGetLastError() != WSAENOTSOCK) {
struct tm * localtime_r(const time_t *tp, struct tm *rp)
static const char * NTLoginName
void setnetent(int stayopen)
static void regulate_path(WCHAR *path)
static int free_conlist(st_data_t key, st_data_t val, st_data_t arg)
static struct ChildRecord * FindFreeChildSlot(void)
char * rb_w32_ugetenv(const char *name)
rb_pid_t rb_w32_getppid(void)
rb_pid_t rb_w32_getpid(void)
static time_t filetime_to_unixtime(const FILETIME *ft)
static WCHAR * mbstr_to_wstr(UINT, const char *, int, long *)
static char * skipspace(char *ptr)
int _cdecl gettimeofday(struct timeval *tv, struct timezone *tz)
uintptr_t(* func)(uintptr_t self, int argc, uintptr_t *argv)
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
int rb_w32_map_errno(DWORD winerr)
static void init_stdhandle(void)
size_t strlen(const char *)
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
int rb_w32_access(const char *path, int mode)
#define CSIDL_LOCAL_APPDATA
struct servent *WSAAPI rb_w32_getservbyport(int port, const char *proto)
int rb_w32_umkdir(const char *path, int mode)
EXTERN_C _CRTIMP ioinfo * __pioinfo[]
static int is_command_com(const char *interp)
void rb_w32_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
static int max(int a, int b)
static void StartSockets(void)
static FARPROC get_wsa_extension_function(SOCKET s, GUID *guid)
if(dispIdMember==DISPID_VALUE)
#define access(path, mode)
static void init_func(void)
int rb_w32_pipe(int fds[2])
int rb_w32_wopen(const WCHAR *file, int oflag,...)
static ioinfo * _pioinfo(int)
static void catch_interrupt(void)
static void get_version(void)
static struct direct * readdir_internal(DIR *dirp, BOOL(*conv)(const WCHAR *, struct direct *, rb_encoding *), rb_encoding *enc)
static int compare(const struct timeval *t1, const struct timeval *t2)
ssize_t rb_w32_read(int fd, void *buf, size_t size)
VALUE rb_str_cat(VALUE, const char *, long)
static rb_pid_t poll_child_status(struct ChildRecord *child, int *stat_loc)
static int NtSocketsInitialized
int st_insert(st_table *, st_data_t, st_data_t)
int WSAAPI rb_w32_connect(int s, const struct sockaddr *addr, int addrlen)
DIR * rb_w32_uopendir(const char *filename)
void rb_write_error2(const char *, long)
int rb_w32_io_cancelable_p(int fd)
void rb_w32_rewinddir(DIR *dirp)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
static unsigned fileattr_to_unixmode(DWORD attr, const WCHAR *path)
void rb_w32_fdset(int fd, fd_set *set)
int rb_w32_truncate(const char *path, off_t length)
static void constat_apply(HANDLE handle, struct constat *s, WCHAR w)
static st_table * socklist
int rb_w32_unwrap_io_handle(int fd)
int WSAAPI rb_w32_bind(int s, const struct sockaddr *addr, int addrlen)
static int is_batch(const char *cmd)
struct servent *WSAAPI rb_w32_getservbyname(const char *name, const char *proto)
#define INVALID_SET_FILE_POINTER
uintptr_t(* asynchronous_func_t)(uintptr_t self, int argc, uintptr_t *argv)
SSL_METHOD *(* func)(void)
void st_free_table(st_table *)
rb_pid_t rb_w32_aspawn(int mode, const char *prog, char *const *argv)
static int extract_fd(rb_fdset_t *dst, fd_set *src, int(*func)(SOCKET))
int WSAAPI rb_w32_accept(int s, struct sockaddr *addr, int *addrlen)
static int is_socket(SOCKET)
static int wmkdir(const WCHAR *wpath, int mode)
static long filetime_to_clock(FILETIME *ft)
#define COPY_STAT(src, dest, size_cast)
static int check_if_dir(const char *file)
static int is_invalid_handle(SOCKET sock)
void rb_w32_seekdir(DIR *dirp, long loc)
int rb_w32_urmdir(const char *path)
static WCHAR * translate_wchar(WCHAR *p, int from, int to)
#define STRNDUPV(ptr, v, src, len)
static void exit_handler(void)
struct _NtCmdLineElement * next
int rb_w32_fclose(FILE *fp)
int rb_w32_open(const char *file, int oflag,...)
BOOL(WINAPI * cancel_io_t)(HANDLE)
#define msghdr_to_wsamsg(msg, wsamsg)
struct protoent * getprotoent(void)
static FARPROC get_proc_address(const char *module, const char *func, HANDLE *mh)
static int socklist_insert(SOCKET sock, int flag)
char * rb_w32_conv_from_wstr(const WCHAR *wstr, long *lenp, rb_encoding *enc)
ssize_t rb_w32_write(int fd, const void *buf, size_t size)
#define filecp_to_wstr(str, plen)
int WSAAPI rb_w32_sendto(int fd, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
static SOCKET open_ifs_socket(int af, int type, int protocol)
const char *WSAAPI rb_w32_inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
int recvmsg(int fd, struct msghdr *msg, int flags)
struct protoent *WSAAPI rb_w32_getprotobynumber(int num)
static char * translate_char(char *p, int from, int to)
static BOOL ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
int rb_w32_wrap_io_handle(HANDLE h, int flags)
int rb_w32_ustati64(const char *path, struct stati64 *st)
#define RUBY_CRITICAL(expr)
static uintptr_t flock_winnt(uintptr_t self, int argc, uintptr_t *argv)
static BOOL win32_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *dummy)
int fcntl(int fd, int cmd,...)
int WSAAPI rb_w32_socket(int af, int type, int protocol)
static int internal_cmd_match(const char *cmdname, int nt)
int st_lookup(st_table *, st_data_t, st_data_t *)
#define wstr_to_utf8(str, plen)
#define MEMZERO(p, type, n)
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
char * rb_w32_getenv(const char *name)
rb_pid_t waitpid(rb_pid_t pid, int *stat_loc, int options)
static int is_pipe(SOCKET sock)
#define END_FOREACH_CHILD
#define wstr_to_filecp(str, plen)
int rb_w32_stat(const char *path, struct stat *st)
int rb_w32_uaccess(const char *path, int mode)
#define ECONV_INVALID_REPLACE
int rb_w32_stati64(const char *path, struct stati64 *st)
long rb_w32_telldir(DIR *dirp)
int rb_w32_fstat(int fd, struct stat *st)
int rb_econv_has_convpath_p(const char *from_encoding, const char *to_encoding)
static int copy_fd(fd_set *dst, fd_set *src)
static void CloseChildHandle(struct ChildRecord *child)
static int winnt_stat(const WCHAR *path, struct stati64 *st)
int rb_w32_socketpair(int af, int type, int protocol, int *sv)
int rb_w32_uopen(const char *file, int oflag,...)
#define IOINFO_ARRAY_ELTS
int rb_w32_uchdir(const char *path)
void rb_w32_fd_copy(rb_fdset_t *dst, const fd_set *src, int max)
int st_delete(st_table *, st_data_t *, st_data_t *)
int link(const char *from, const char *to)
int WSAAPI rb_w32_ioctlsocket(int s, long cmd, u_long *argp)
struct netent * getnetbyname(const char *name)
static int wutime(const WCHAR *path, const struct utimbuf *times)
static HANDLE open_dir_handle(const WCHAR *filename, WIN32_FIND_DATAW *fd)
static int has_redirection(const char *)
int rb_w32_isatty(int fd)
int rb_w32_sleep(unsigned long msec)
int rb_w32_rename(const char *from, const char *to)
#define ALLOCV_N(type, v, n)
UINT rb_w32_system_tmpdir(WCHAR *path, UINT len)
int rb_w32_select_with_thread(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout, void *th)
#define MAKE_SOCKDATA(af, fl)
int rb_w32_utime(const char *path, const struct utimbuf *times)
static int setup_overlapped(OVERLAPPED *ol, int fd)
static int socklist_lookup(SOCKET sock, int *flagp)
rb_pid_t rb_w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags)
void sethostent(int stayopen)
struct servent * getservent(void)
static int check_spawn_mode(int mode)
static cancel_io_t cancel_io
struct constat::@135 vt100
static void init_env(void)
static int join_argv(char *cmd, char *const *argv, BOOL escape)
static int filetime_to_timeval(const FILETIME *ft, struct timeval *tv)
static int is_not_socket(SOCKET sock)
static DWORD constat_attr(int count, const int *seq, DWORD attr, DWORD default_attr)
static int do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout)
static const char *const szInternalCmds[]
off_t rb_w32_ftello(FILE *stream)
int WSAAPI rb_w32_getpeername(int s, struct sockaddr *addr, int *addrlen)
VALUE rb_sprintf(const char *format,...)
void setservent(int stayopen)
rb_pid_t rb_w32_spawn(int mode, const char *cmd, const char *prog)
DIR * rb_w32_opendir(const char *filename)
static long constat_parse(HANDLE h, struct constat *s, const WCHAR **ptrp, long *lenp)
void rb_w32_sysinit(int *argc, char ***argv)
void rb_fatal(const char *fmt,...)
static struct ChildRecord * FindChildSlot(rb_pid_t pid)
int WSAAPI rb_w32_shutdown(int s, int how)
VALUE rb_str_vcatf(VALUE, const char *, va_list)
static int finish_overlapped_socket(BOOL input, SOCKET s, WSAOVERLAPPED *wol, int result, DWORD *len, DWORD size)
static CRITICAL_SECTION select_mutex
struct netent * getnetent(void)
void setprotoent(int stayopen)
int fseeko(FILE *stream, off_t offset, int whence)
char * dln_find_exe_r(const char *, const char *, char *, size_t)
static int unixtime_to_systemtime(const time_t t, SYSTEMTIME *st)
int sendmsg(int fd, const struct msghdr *msg, int flags)
int ioctl(int i, int u,...)
unsigned char buf[MIME_BUF_SIZE]
static int rb_chsize(HANDLE h, off_t size)
struct tm * gmtime_r(const time_t *tp, struct tm *rp)
int flock(int fd, int oper)
static int options(unsigned char *cp)
static int unixtime_to_filetime(time_t time, FILETIME *ft)
int rb_w32_getc(FILE *stream)
char * strchr(char *, char)
struct protoent *WSAAPI rb_w32_getprotobyname(const char *name)
#define utf8_to_wstr(str, plen)
int rb_w32_mkdir(const char *path, int mode)
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
int rb_w32_unlink(const char *path)
int WSAAPI rb_w32_gethostname(char *name, int len)
static int insert(const char *path, VALUE vinfo, void *enc)
static int isUNCRoot(const WCHAR *path)
int chown(const char *path, int owner, int group)
static rb_pid_t child_result(struct ChildRecord *child, int mode)
static struct @133 errmap[]
st_table * st_init_numtable(void)
int rb_w32_fstati64(int fd, struct stati64 *st)
static int internal_match(const void *key, const void *elem)
int rb_w32_putc(int c, FILE *stream)
static UINT get_system_directory(WCHAR *path, UINT len)
char * rb_w32_strerror(int e)
int rb_w32_time_subtract(struct timeval *rest, const struct timeval *wait)
static int is_internal_cmd(const char *cmd, int nt)
int rb_w32_uchown(const char *path, int owner, int group)
int rb_w32_rmdir(const char *path)
int WSAAPI rb_w32_listen(int s, int backlog)
int kill(int pid, int sig)
static void constat_delete(HANDLE h)
#define ECONV_UNDEF_REPLACE
rb_encoding * rb_enc_get(VALUE obj)
uintptr_t rb_w32_asynchronize(asynchronous_func_t func, uintptr_t self, int argc, uintptr_t *argv, uintptr_t intrval)
static int wstati64(const WCHAR *path, struct stati64 *st)
static struct ChildRecord * FindChildSlotByHandle(HANDLE h)
static NtCmdLineElement ** cmdglob(NtCmdLineElement *patt, NtCmdLineElement **tail)
char ** rb_w32_get_environ(void)
static DIR * opendir_internal(WCHAR *wpath, const char *filename)
void rb_w32_closedir(DIR *dirp)
static int wlink(const WCHAR *from, const WCHAR *to)
VALUE rb_w32_special_folder(int type)
static int socklist_delete(SOCKET *sockp, int *flagp)
int rb_w32_uchmod(const char *path, int mode)
static DWORD WINAPI call_asynchronous(PVOID argp)
int WSAAPI rb_w32_send(int fd, const char *buf, int len, int flags)
static int wrmdir(const WCHAR *wpath)
static struct constat * constat_handle(HANDLE h)
#define _set_osfhnd(fh, osfh)
#define acp_to_wstr(str, plen)
static int systemtime_to_localtime(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *gst, SYSTEMTIME *lst)
struct hostent *WSAAPI rb_w32_gethostbyname(const char *name)
RUBY_EXTERN char * strerror(int)
static int is_console(SOCKET)
static int is_readable_pipe(SOCKET sock)
static char * wstr_to_mbstr(UINT, const WCHAR *, int, long *)
int WSAAPI rb_w32_getsockname(int fd, struct sockaddr *addr, int *addrlen)
rb_encoding * rb_filesystem_encoding(void)
SOCKET rb_w32_get_osfhandle(int fh)
int rb_w32_uutime(const char *path, const struct utimbuf *times)
struct _NtCmdLineElement NtCmdLineElement
int ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg)
#define set_env_val(vname)
int WSAAPI rb_w32_recv(int fd, char *buf, int len, int flags)
static int check_if_wdir(const WCHAR *wfile)
static int setfl(SOCKET sock, int arg)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
int rb_w32_is_socket(int fd)
static int wrename(const WCHAR *oldpath, const WCHAR *newpath)
long rb_w32_write_console(uintptr_t strarg, int fd)
static int dupfd(HANDLE hDup, char flags, int minfd)
RUBY_EXTERN size_t strlcat(char *, const char *, size_t)
#define COMMON_LVB_UNDERSCORE
static char fbuf[MAXPATHLEN]
static void move_to_next_entry(DIR *dirp)
static void systemtime_to_tm(const SYSTEMTIME *st, struct tm *t)
char * rb_w32_getcwd(char *buffer, int size)
rb_encoding * rb_ascii8bit_encoding(void)
#define yield_until(condition)
static int overlapped_socket_io(BOOL input, int fd, char *buf, int len, int flags, struct sockaddr *addr, int *addrlen)
static void version(void)
struct netent * getnetbyaddr(long net, int type)
static struct ChildRecord * CreateChild(const WCHAR *, const WCHAR *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE, DWORD)
int WSAAPI rb_w32_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout)
int rb_w32_ulink(const char *from, const char *to)
int WSAAPI rb_w32_recvfrom(int fd, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
VALUE rb_str_encode(VALUE str, VALUE to, int ecflags, VALUE ecopts)
static int socketpair_internal(int af, int type, int protocol, SOCKET *sv)
int WSAAPI rb_w32_getsockopt(int s, int level, int optname, char *optval, int *optlen)
int rb_w32_urename(const char *from, const char *to)
static void finish_overlapped(OVERLAPPED *ol, int fd, DWORD size)
struct direct * rb_w32_readdir(DIR *dirp, rb_encoding *enc)
void rb_w32_free_environ(char **env)
int WSAAPI rb_w32_setsockopt(int s, int level, int optname, const char *optval, int optlen)
static OSVERSIONINFO osver
int rb_w32_cmdvector(const char *cmd, char ***vec)
int rb_w32_fdisset(int fd, fd_set *set)
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags)
int rb_w32_uunlink(const char *path)
static int is_readable_console(SOCKET sock)
static BOOL get_special_folder(int n, WCHAR *env)
char rb_w32_fd_is_text(int fd)
static int eq(VALUE x, VALUE y)
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
static ULONG(STDMETHODCALLTYPE AddRef)(IDispatch __RPC_FAR *This)
int rb_w32_check_interrupt(void *)
int rb_w32_times(struct tms *tmbuf)
void rb_w32_fdclr(int fd, fd_set *set)
int select(int num_fds, fd_set *in_fds, fd_set *out_fds, fd_set *ex_fds, struct timeval *timeout)
struct hostent *WSAAPI rb_w32_gethostbyaddr(const char *addr, int len, int type)
int rb_w32_ftruncate(int fd, off_t length)
rb_encoding * rb_enc_find(const char *name)
static int check_valid_dir(const WCHAR *path)
static st_table * conlist
#define _set_osflags(fh, flags)
static void constat_reset(HANDLE h)
static int wunlink(const WCHAR *path)