22 #undef __STRICT_ANSI__
53 #define isdirsep(x) ((x) == '/' || (x) == '\\')
55 #if defined _MSC_VER && _MSC_VER <= 1200
56 # define CharNextExA(cp, p, flags) CharNextExA((WORD)(cp), (p), (flags))
63 #define DLN_FIND_EXTRA_ARG_DECL ,UINT cp
64 #define DLN_FIND_EXTRA_ARG ,cp
65 #define rb_w32_stati64(path, st) w32_stati64(path, st, cp)
66 #define getenv(name) w32_getenv(name, cp)
67 #define dln_find_exe_r rb_w32_udln_find_exe_r
68 #define dln_find_file_r rb_w32_udln_find_file_r
74 #undef dln_find_file_r
75 #define dln_find_exe_r(fname, path, buf, size) rb_w32_udln_find_exe_r(fname, path, buf, size, cp)
76 #define dln_find_file_r(fname, path, buf, size) rb_w32_udln_find_file_r(fname, path, buf, size, cp)
84 #if defined __BORLANDC__
85 # define _filbuf _fgetc
86 # define _flsbuf _fputc
87 # define enough_to_get(n) (--(n) >= 0)
88 # define enough_to_put(n) (++(n) < 0)
90 # define enough_to_get(n) (--(n) >= 0)
91 # define enough_to_put(n) (--(n) >= 0)
95 #define Debug(something) something
97 #define Debug(something)
100 #define TO_SOCKET(x) _get_osfhandle(x)
109 #define RUBY_CRITICAL(expr) do { expr; } while (0)
116 { ERROR_INVALID_FUNCTION, EINVAL },
117 { ERROR_FILE_NOT_FOUND, ENOENT },
118 { ERROR_PATH_NOT_FOUND, ENOENT },
119 { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
120 { ERROR_ACCESS_DENIED, EACCES },
121 { ERROR_INVALID_HANDLE, EBADF },
122 { ERROR_ARENA_TRASHED, ENOMEM },
123 { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
124 { ERROR_INVALID_BLOCK, ENOMEM },
125 { ERROR_BAD_ENVIRONMENT, E2BIG },
126 { ERROR_BAD_FORMAT, ENOEXEC },
127 { ERROR_INVALID_ACCESS, EINVAL },
128 { ERROR_INVALID_DATA, EINVAL },
129 { ERROR_INVALID_DRIVE, ENOENT },
130 { ERROR_CURRENT_DIRECTORY, EACCES },
131 { ERROR_NOT_SAME_DEVICE, EXDEV },
132 { ERROR_NO_MORE_FILES, ENOENT },
133 { ERROR_WRITE_PROTECT, EROFS },
134 { ERROR_BAD_UNIT, ENODEV },
135 { ERROR_NOT_READY, ENXIO },
136 { ERROR_BAD_COMMAND, EACCES },
137 { ERROR_CRC, EACCES },
138 { ERROR_BAD_LENGTH, EACCES },
140 { ERROR_NOT_DOS_DISK, EACCES },
141 { ERROR_SECTOR_NOT_FOUND, EACCES },
142 { ERROR_OUT_OF_PAPER, EACCES },
143 { ERROR_WRITE_FAULT, EIO },
144 { ERROR_READ_FAULT, EIO },
145 { ERROR_GEN_FAILURE, EACCES },
146 { ERROR_LOCK_VIOLATION, EACCES },
147 { ERROR_SHARING_VIOLATION, EACCES },
148 { ERROR_WRONG_DISK, EACCES },
149 { ERROR_SHARING_BUFFER_EXCEEDED, EACCES },
150 { ERROR_BAD_NETPATH, ENOENT },
151 { ERROR_NETWORK_ACCESS_DENIED, EACCES },
152 { ERROR_BAD_NET_NAME, ENOENT },
153 { ERROR_FILE_EXISTS, EEXIST },
154 { ERROR_CANNOT_MAKE, EACCES },
155 { ERROR_FAIL_I24, EACCES },
156 { ERROR_INVALID_PARAMETER, EINVAL },
157 { ERROR_NO_PROC_SLOTS, EAGAIN },
158 { ERROR_DRIVE_LOCKED, EACCES },
159 { ERROR_BROKEN_PIPE, EPIPE },
160 { ERROR_DISK_FULL, ENOSPC },
161 { ERROR_INVALID_TARGET_HANDLE, EBADF },
162 { ERROR_INVALID_HANDLE, EINVAL },
163 { ERROR_WAIT_NO_CHILDREN, ECHILD },
164 { ERROR_CHILD_NOT_COMPLETE, ECHILD },
165 { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
166 { ERROR_NEGATIVE_SEEK, EINVAL },
167 { ERROR_SEEK_ON_DEVICE, EACCES },
168 { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
169 { ERROR_DIRECTORY, ENOTDIR },
170 { ERROR_NOT_LOCKED, EACCES },
171 { ERROR_BAD_PATHNAME, ENOENT },
172 { ERROR_MAX_THRDS_REACHED, EAGAIN },
173 { ERROR_LOCK_FAILED, EACCES },
174 { ERROR_ALREADY_EXISTS, EEXIST },
175 { ERROR_INVALID_STARTING_CODESEG, ENOEXEC },
176 { ERROR_INVALID_STACKSEG, ENOEXEC },
177 { ERROR_INVALID_MODULETYPE, ENOEXEC },
178 { ERROR_INVALID_EXE_SIGNATURE, ENOEXEC },
179 { ERROR_EXE_MARKED_INVALID, ENOEXEC },
180 { ERROR_BAD_EXE_FORMAT, ENOEXEC },
181 { ERROR_ITERATED_DATA_EXCEEDS_64k,ENOEXEC },
182 { ERROR_INVALID_MINALLOCSIZE, ENOEXEC },
183 { ERROR_DYNLINK_FROM_INVALID_RING,ENOEXEC },
184 { ERROR_IOPL_NOT_ENABLED, ENOEXEC },
185 { ERROR_INVALID_SEGDPL, ENOEXEC },
186 { ERROR_AUTODATASEG_EXCEEDS_64k, ENOEXEC },
187 { ERROR_RING2SEG_MUST_BE_MOVABLE, ENOEXEC },
188 { ERROR_RELOC_CHAIN_XEEDS_SEGLIM, ENOEXEC },
189 { ERROR_INFLOOP_IN_RELOC_CHAIN, ENOEXEC },
190 { ERROR_FILENAME_EXCED_RANGE, ENOENT },
191 { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
192 #ifndef ERROR_PIPE_LOCAL
193 #define ERROR_PIPE_LOCAL 229L
196 { ERROR_BAD_PIPE, EPIPE },
197 { ERROR_PIPE_BUSY, EAGAIN },
198 { ERROR_NO_DATA, EPIPE },
199 { ERROR_PIPE_NOT_CONNECTED, EPIPE },
200 { ERROR_OPERATION_ABORTED, EINTR },
201 { ERROR_NOT_ENOUGH_QUOTA, ENOMEM },
202 { ERROR_MOD_NOT_FOUND, ENOENT },
205 { WSAEACCES, EACCES },
206 { WSAEFAULT, EFAULT },
207 { WSAEINVAL, EINVAL },
208 { WSAEMFILE, EMFILE },
237 { WSAENAMETOOLONG, ENAMETOOLONG },
241 { WSAENOTEMPTY, ENOTEMPTY },
259 if (
errmap[i].winerr == winerr) {
264 if (winerr >= WSABASEERR) {
270 #define map_errno rb_w32_map_errno
281 osver.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
282 GetVersionEx(&
osver);
290 return osver.dwPlatformId;
298 return osver.dwMajorVersion;
304 #define LK_ERR(f,i) \
309 DWORD err = GetLastError(); \
310 if (err == ERROR_LOCK_VIOLATION || err == ERROR_IO_PENDING) \
311 errno = EWOULDBLOCK; \
312 else if (err == ERROR_NOT_LOCKED) \
315 errno = map_errno(err); \
318 #define LK_LEN ULONG_MAX
326 const HANDLE fh = (HANDLE)
self;
327 const int oper =
argc;
343 LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
371 static inline WCHAR *
386 if ((
unsigned char)*p == from)
388 p = CharNextExA(cp, p, 0);
393 #ifndef CSIDL_LOCAL_APPDATA
394 #define CSIDL_LOCAL_APPDATA 28
396 #ifndef CSIDL_COMMON_APPDATA
397 #define CSIDL_COMMON_APPDATA 35
399 #ifndef CSIDL_WINDOWS
400 #define CSIDL_WINDOWS 36
403 #define CSIDL_SYSTEM 37
405 #ifndef CSIDL_PROFILE
406 #define CSIDL_PROFILE 40
416 if (SHGetSpecialFolderLocation(
NULL, n, &pidl) == 0) {
417 f = SHGetPathFromIDListW(pidl, env);
419 alloc->lpVtbl->Free(alloc, pidl);
420 alloc->lpVtbl->Release(alloc);
430 if (p - path == 2 && path[1] == L
':') {
444 h = LoadLibrary(module);
446 h = GetModuleHandle(module);
450 ptr = GetProcAddress(h, func);
464 typedef UINT WINAPI wgetdir_func(WCHAR*, UINT);
468 return (*(wgetdir_func *)ptr)(
path,
len);
469 return GetWindowsDirectoryW(path, len);
476 WCHAR
path[_MAX_PATH];
487 static const WCHAR temp[] = L
"temp";
494 if (*(p - 1) != L
'/') *p++ = L
'/';
495 if ((UINT)(p - path +
numberof(temp)) >= len)
return 0;
496 memcpy(p, temp,
sizeof(temp));
497 return (UINT)(p - path +
numberof(temp) - 1);
504 static const WCHAR TMPDIR[] = L
"TMPDIR";
505 struct {WCHAR
name[6],
eq,
val[_MAX_PATH];} wk;
509 #define set_env_val(vname) do { \
510 typedef char wk_name_offset[(numberof(wk.name) - (numberof(vname) - 1)) * 2 + 1]; \
511 WCHAR *const buf = wk.name + sizeof(wk_name_offset) / 2; \
512 MEMCPY(buf, vname, WCHAR, numberof(vname) - 1); \
524 if (GetEnvironmentVariableW(L
"HOMEPATH",
env + len,
numberof(
env) - len) || len) {
527 else if (GetEnvironmentVariableW(L
"USERPROFILE",
env,
numberof(
env))) {
581 #if RUBY_MSVCRT_VERSION >= 80
584 invalid_parameter(
const wchar_t *
expr,
const wchar_t *
func,
const wchar_t *file,
unsigned int line,
uintptr_t dummy)
589 int ruby_w32_rtc_error;
593 rtc_error_handler(
int e,
const char *
src,
int line,
const char *exe,
const char *
fmt, ...)
598 if (!ruby_w32_rtc_error)
return 0;
613 #define conlist_disabled ((st_table *)-1)
650 if (NtSocketsInitialized) {
656 DeleteCriticalSection(&select_mutex);
657 NtSocketsInitialized = 0;
665 FreeEnvironmentStrings(envarea);
685 version = MAKEWORD(2, 0);
686 if (WSAStartup(version, &retdata))
687 rb_fatal (
"Unable to locate winsock library!\n");
688 if (LOBYTE(retdata.wVersion) != 2)
689 rb_fatal(
"could not find version 2 of winsock dll\n");
691 InitializeCriticalSection(&select_mutex);
693 NtSocketsInitialized = 1;
696 #define MAKE_SOCKDATA(af, fl) ((int)((((int)af)<<4)|((fl)&0xFFFF)))
697 #define GET_FAMILY(v) ((int)(((v)>>4)&0xFFFF))
698 #define GET_FLAGS(v) ((int)((v)&0xFFFF))
740 *sockp = (SOCKET)key;
755 #if RUBY_MSVCRT_VERSION >= 80
756 static void set_pioinfo_extra(
void);
758 _CrtSetReportMode(_CRT_ASSERT, 0);
759 _set_invalid_parameter_handler(invalid_parameter);
760 _RTC_SetErrorFunc(rtc_error_handler);
763 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX);
797 #define MAXCHILDNUM 256
806 #define FOREACH_CHILD(v) do { \
807 struct ChildRecord* v; \
808 for (v = ChildRecord; v < ChildRecord + sizeof(ChildRecord) / sizeof(ChildRecord[0]); ++v)
809 #define END_FOREACH_CHILD } while (0)
817 if (child->pid == pid) {
830 if (child->hProcess == h) {
854 child->hProcess =
NULL;
924 return strcmp(key, (*(
const char *
const *)elem) + 1);
933 if ((i == 0 || i > 0 &&
isdirsep(interp[i-1])) &&
946 char cmdname[9], *
b = cmdname,
c;
949 if (!(c = *cmd++))
return 0;
950 }
while (isspace(c));
955 if (b == cmdname +
sizeof(cmdname))
return 0;
958 if (c ==
'.') c = *
cmd;
960 case '<':
case '>':
case '|':
962 case '\0':
case ' ':
case '\t':
case '\n':
977 nm = bsearch(cmdname, szInternalCmds,
978 sizeof(szInternalCmds) /
sizeof(*szInternalCmds),
979 sizeof(*szInternalCmds),
981 if (!nm || !(nm[0][0] & (nt ? 2 : 1)))
990 return _get_osfhandle(fh);
999 int len,
n, bs, quote;
1001 for (t = argv, q = cmd, len = 0; p = *
t; t++) {
1004 if (!*p || strpbrk(p,
" \t\"'")) {
1009 for (bs = 0; *
p; ++
p) {
1028 case '<':
case '>':
case '|':
case '^':
1029 if (escape && !quote) {
1030 len += (n = p -
s) + 1;
1041 p = CharNextExA(cp, p, 0) - 1;
1045 len += (n = p -
s) + 1;
1049 if (backslash > 0) {
1055 if (quote) *q++ =
'"';
1067 #ifdef HAVE_SYS_PARAM_H
1068 # include <sys/param.h>
1070 # define MAXPATHLEN 512
1074 #define STRNDUPV(ptr, v, src, len) \
1075 (((char *)memcpy(((ptr) = ALLOCV((v), (len) + 1)), (src), (len)))[len] = 0)
1101 if (mode == P_OVERLAY) {
1102 WaitForSingleObject(child->
hProcess, INFINITE);
1103 GetExitCodeProcess(child->
hProcess, &exitcode);
1113 HANDLE hInput, HANDLE hOutput, HANDLE hError,
DWORD dwCreationFlags)
1116 STARTUPINFOW aStartupInfo;
1117 PROCESS_INFORMATION aProcessInformation;
1118 SECURITY_ATTRIBUTES sa;
1121 if (!cmd && !prog) {
1133 sa.nLength =
sizeof (SECURITY_ATTRIBUTES);
1134 sa.lpSecurityDescriptor =
NULL;
1135 sa.bInheritHandle =
TRUE;
1139 memset(&aStartupInfo, 0,
sizeof(aStartupInfo));
1140 memset(&aProcessInformation, 0,
sizeof(aProcessInformation));
1141 aStartupInfo.cb =
sizeof(aStartupInfo);
1142 aStartupInfo.dwFlags = STARTF_USESTDHANDLES;
1144 aStartupInfo.hStdInput = hInput;
1147 aStartupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
1150 aStartupInfo.hStdOutput = hOutput;
1153 aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
1156 aStartupInfo.hStdError = hError;
1159 aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
1162 dwCreationFlags |= NORMAL_PRIORITY_CLASS;
1164 if (lstrlenW(cmd) > 32767) {
1171 fRet = CreateProcessW(prog, (WCHAR *)cmd, psa, psa,
1172 psa->bInheritHandle, dwCreationFlags,
NULL,
NULL,
1173 &aStartupInfo, &aProcessInformation);
1182 CloseHandle(aProcessInformation.hThread);
1184 child->
hProcess = aProcessInformation.hProcess;
1185 child->
pid = (rb_pid_t)aProcessInformation.dwProcessId;
1195 if (len <= 4)
return 0;
1197 if (*cmd++ !=
'.')
return 0;
1203 static UINT
filecp(
void);
1204 #define mbstr_to_wstr rb_w32_mbstr_to_wstr
1205 #define wstr_to_mbstr rb_w32_wstr_to_mbstr
1206 #define acp_to_wstr(str, plen) mbstr_to_wstr(CP_ACP, str, -1, plen)
1207 #define wstr_to_acp(str, plen) wstr_to_mbstr(CP_ACP, str, -1, plen)
1208 #define filecp_to_wstr(str, plen) mbstr_to_wstr(filecp(), str, -1, plen)
1209 #define wstr_to_filecp(str, plen) wstr_to_mbstr(filecp(), str, -1, plen)
1210 #define utf8_to_wstr(str, plen) mbstr_to_wstr(CP_UTF8, str, -1, plen)
1211 #define wstr_to_utf8(str, plen) wstr_to_mbstr(CP_UTF8, str, -1, plen)
1220 WCHAR *wcmd =
NULL, *wshell =
NULL;
1226 char *cmd_sep =
NULL;
1244 size_t shell_len =
strlen(shell);
1246 memcpy(tmp, shell, shell_len + 1);
1248 sprintf(tmp + shell_len,
" -c \"%s\"", cmd);
1251 else if ((shell =
getenv(
"COMSPEC")) &&
1256 sprintf(tmp, nt ?
"%s /c \"%s\"" :
"%s /c %s", shell, cmd);
1260 int len = 0, quote = (*cmd ==
'"') ?
'"' : (*cmd ==
'\'') ?
'\'' : 0;
1262 for (prog = cmd + !!quote;; prog = CharNextExA(cp, prog, 0)) {
1263 if (*prog ==
'/') slash = 1;
1273 if ((
unsigned char)*prog == quote) {
1274 len = prog++ - cmd - 1;
1279 if (quote)
continue;
1285 sep = *(cmd_sep = &p[
len]);
1295 shell = p ? p :
cmd;
1299 if (
strchr(shell,
' ')) quote = -1;
1300 if (shell == fbuf) {
1303 else if (shell != p &&
strchr(shell,
'/')) {
1310 cmd = p =
ALLOCV(v, len + alen + (quote ? 2 : 0) + 1);
1311 if (quote) *p++ =
'"';
1314 if (quote) *p++ =
'"';
1315 memcpy(p, prog, alen + 1);
1323 if (cmd_sep) *cmd_sep = sep;
1349 return w32_spawn(mode, cmd, prog, CP_UTF8);
1358 BOOL ntcmd =
FALSE, tmpnt;
1368 if (!prog) prog = argv[0];
1369 if ((shell =
getenv(
"COMSPEC")) &&
1376 if (cmd == prog)
strlcpy(cmd = fbuf, prog,
sizeof(fbuf));
1380 else if (
strchr(prog,
'/')) {
1382 if (len <
sizeof(fbuf))
1383 strlcpy(cmd = fbuf, prog,
sizeof(fbuf));
1391 progs[0] = (
char *)prog;
1394 if (c_switch) len += 3;
1399 if (c_switch)
strlcat(cmd,
" /c", len);
1401 prog = c_switch ? shell : 0;
1463 #define NTGLOB 0x1 // element contains a wildcard
1464 #define NTMALLOC 0x2 // string in element was malloc'ed
1465 #define NTSTRING 0x4 // element contains a quoted string
1475 if (!tmpcurr)
return -1;
1479 if (!tmpcurr->
str)
return -1;
1482 *tail = &tmpcurr->
next;
1497 if (!(buf =
malloc(patt->
len + 1)))
return 0;
1500 buf[patt->
len] =
'\0';
1508 if (status || last == tail)
return 0;
1532 for (ptr = cmd; *
ptr;) {
1538 else if (quote == *ptr)
1554 if (*++ptr !=
'_' && !
ISALPHA(*ptr))
break;
1555 while (*++ptr ==
'_' ||
ISALNUM(*ptr));
1556 if (*ptr++ ==
'%')
return TRUE;
1562 ptr = CharNextExA(cp, ptr, 0);
1570 static inline char *
1583 int elements, strsz,
done;
1584 int slashes, escape;
1585 char *
ptr, *base, *buffer, *cmdline;
1602 ptr = cmdline =
strdup(cmd);
1615 quote = slashes = globbing = escape = 0;
1616 for (done = 0; !done && *
ptr; ) {
1625 if (quote !=
'\'') slashes++;
1665 if (!(slashes & 1)) {
1668 else if (quote == *ptr) {
1669 if (quote ==
'"' && quote == ptr[1])
1702 slashes = quote = 0;
1703 while (p < base + len) {
1707 if (quote !=
'\'') slashes++;
1712 if (!(slashes & 1) && quote && quote != c) {
1717 memcpy(p - ((slashes + 1) >> 1), p + (~slashes & 1),
1719 len -= ((slashes + 1) >> 1) + (~slashes & 1);
1720 p -= (slashes + 1) >> 1;
1721 if (!(slashes & 1)) {
1723 if (quote ==
'"' && quote == *p)
1744 if (!curr)
goto do_nothing;
1748 if (globbing && (tail =
cmdglob(curr, cmdtail))) {
1753 cmdtail = &curr->
next;
1763 for (elements = 0, strsz = 0, curr = cmdhead; curr; curr = curr->
next) {
1765 strsz += (curr->
len + 1);
1768 len = (elements+1)*
sizeof(
char *) + strsz;
1769 buffer = (
char *)
malloc(len);
1772 while (curr = cmdhead) {
1773 cmdhead = curr->
next;
1778 for (vptr = *vec; *vptr; ++vptr);
1794 vptr = (
char **) buffer;
1796 ptr = buffer + (elements+1) *
sizeof(
char *);
1798 while (curr = cmdhead) {
1801 ptr += curr->
len + 1;
1802 cmdhead = curr->
next;
1808 *vec = (
char **) buffer;
1824 #define GetBit(bits, i) ((bits)[(i) / CHAR_BIT] & (1 << (i) % CHAR_BIT))
1825 #define SetBit(bits, i) ((bits)[(i) / CHAR_BIT] |= (1 << (i) % CHAR_BIT))
1827 #define BitOfIsDir(n) ((n) * 2)
1828 #define BitOfIsRep(n) ((n) * 2 + 1)
1829 #define DIRENT_PER_CHAR (CHAR_BIT / 2)
1836 static const WCHAR wildcard[] = L
"\\*";
1845 len = lstrlenW(filename);
1846 scanname =
ALLOCV_N(WCHAR, v, len +
sizeof(wildcard) /
sizeof(WCHAR));
1847 lstrcpyW(scanname, filename);
1848 p = CharPrevW(scanname, scanname + len);
1849 if (*p == L
'/' || *p == L
'\\' || *p == L
':')
1850 lstrcatW(scanname, wildcard + 1);
1852 lstrcatW(scanname, wildcard);
1857 fh = FindFirstFileW(scanname, fd);
1859 if (fh == INVALID_HANDLE_VALUE) {
1869 struct stati64 sbuf;
1870 WIN32_FIND_DATAW fd;
1884 if (!(sbuf.st_mode & S_IFDIR) &&
1885 (!
ISALPHA(filename[0]) || filename[1] !=
':' || filename[2] !=
'\0' ||
1886 ((1 << ((filename[0] & 0x5f) -
'A')) & GetLogicalDrives()) == 0)) {
1891 if (fh == INVALID_HANDLE_VALUE) {
1911 len = lstrlenW(fd.cFileName) + 1;
1927 memcpy(&p->
start[idx], fd.cFileName, len *
sizeof(WCHAR));
1936 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1938 if (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1943 }
while (FindNextFileW(fh, &fd));
1954 UINT
cp = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
1963 int len = WideCharToMultiByte(cp, 0, wstr, clen,
NULL, 0,
NULL,
NULL);
1964 if (!(ptr =
malloc(len)))
return 0;
1965 WideCharToMultiByte(cp, 0, wstr, clen, ptr, len,
NULL,
NULL);
1968 if (clen == -1) --
len;
1979 int len = MultiByteToWideChar(cp, 0, str, clen,
NULL, 0);
1980 if (!(ptr =
malloc(
sizeof(WCHAR) * len)))
return 0;
1981 MultiByteToWideChar(cp, 0, str, clen, ptr, len);
1984 if (clen == -1) --
len;
2026 dirp->
curr += lstrlenW(dirp->
curr) + 1;
2051 long len = lstrlenW(wstr);
2058 #if SIZEOF_INT < SIZEOF_LONG
2059 # error long should equal to int on Windows
2062 len = WideCharToMultiByte(CP_UTF8, 0, wstr, clen,
NULL, 0,
NULL,
NULL);
2105 static int dummy = 0;
2171 while (dirp->
curr && dirp->
loc < loc) {
2207 #if (defined _MT || defined __MSVCRT__) && !defined __BORLANDC__
2208 #define MSVCRT_THREADS
2210 #ifdef MSVCRT_THREADS
2211 # define MTHREAD_ONLY(x) x
2212 # define STHREAD_ONLY(x)
2213 #elif defined(__BORLANDC__)
2214 # define MTHREAD_ONLY(x)
2215 # define STHREAD_ONLY(x)
2217 # define MTHREAD_ONLY(x)
2218 # define STHREAD_ONLY(x) x
2226 #ifdef MSVCRT_THREADS
2228 CRITICAL_SECTION lock;
2230 #if RUBY_MSVCRT_VERSION >= 80
2236 #if !defined _CRTIMP || defined __MINGW32__
2238 #define _CRTIMP __declspec(dllimport)
2241 #if !defined(__BORLANDC__)
2245 #define IOINFO_L2E 5
2246 #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
2247 #define _osfhnd(i) (_pioinfo(i)->osfhnd)
2248 #define _osfile(i) (_pioinfo(i)->osfile)
2249 #define _pipech(i) (_pioinfo(i)->pipech)
2251 #if RUBY_MSVCRT_VERSION >= 80
2256 set_pioinfo_extra(
void)
2260 fd = _open(
"NUL", O_RDONLY);
2261 for (pioinfo_extra = 0; pioinfo_extra <= 64; pioinfo_extra +=
sizeof(
void *)) {
2262 if (
_osfhnd(fd) == _get_osfhandle(fd)) {
2268 if (pioinfo_extra > 64) {
2274 #define pioinfo_extra 0
2280 const size_t sizeof_ioinfo =
sizeof(
ioinfo) + pioinfo_extra;
2285 #define _set_osfhnd(fh, osfh) (void)(_osfhnd(fh) = osfh)
2286 #define _set_osflags(fh, flags) (_osfile(fh) = (flags))
2289 #define FEOFLAG 0x02
2291 #define FNOINHERIT 0x10
2292 #define FAPPEND 0x20
2317 if (flags & O_APPEND)
2323 if (flags & O_NOINHERIT)
2327 hF = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
2328 fh = _open_osfhandle((
intptr_t)hF, 0);
2354 #define open_null(fd) \
2356 (nullfd = open("NUL", O_RDWR)) : 0), \
2357 ((nullfd == (fd)) ? (keep = 1) : dup2(nullfd, fd)), \
2366 if (
fileno(stdout) < 0) {
2369 if (
fileno(stderr) < 0) {
2372 if (nullfd >= 0 && !keep) close(nullfd);
2373 setvbuf(stderr,
NULL, _IONBF, 0);
2377 #define _set_osfhnd(fh, osfh) (void)((fh), (osfh))
2378 #define _set_osflags(fh, flags) (void)((fh), (flags))
2392 int fd = _open_osfhandle(osfhandle, flags);
2432 static char buffer[512];
2436 #if defined __BORLANDC__ && defined ENOTEMPTY // _sys_errlist is broken
2439 return "Filename too long";
2441 return "Directory not empty";
2448 #if WSAEWOULDBLOCK != EWOULDBLOCK
2456 for (i = s; i < (
int)(
sizeof(
errmap)/
sizeof(*errmap)); i++)
2463 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
2464 FORMAT_MESSAGE_IGNORE_INSERTS, &source, e,
2465 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
2466 buffer,
sizeof(buffer),
NULL) == 0 &&
2467 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
2468 FORMAT_MESSAGE_IGNORE_INSERTS, &source, e, 0,
2469 buffer,
sizeof(buffer),
NULL) == 0)
2470 strlcpy(buffer,
"Unknown Error",
sizeof(buffer));
2476 while ((p = strpbrk(p,
"\r\n")) !=
NULL) {
2565 for (i = 0; i < set->fd_count; i++) {
2566 if (set->fd_array[i] == s) {
2567 memmove(&set->fd_array[i], &set->fd_array[i+1],
2568 sizeof(set->fd_array[0]) * (--set->fd_count - i));
2582 if (s == (SOCKET)INVALID_HANDLE_VALUE)
2592 max =
min(src->fd_count, (UINT)max);
2593 if ((UINT)dst->capa < (UINT)max) {
2594 dst->capa = (src->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2595 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2598 memcpy(dst->fdset->fd_array, src->fd_array,
2599 max *
sizeof(src->fd_array[0]));
2600 dst->fdset->fd_count = src->fd_count;
2607 if ((UINT)dst->capa < src->fdset->fd_count) {
2608 dst->capa = (src->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2609 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2612 memcpy(dst->fdset->fd_array, src->fdset->fd_array,
2613 src->fdset->fd_count *
sizeof(src->fdset->fd_array[0]));
2614 dst->fdset->fd_count = src->fdset->fd_count;
2633 while (s < src->fd_count) {
2634 SOCKET fd = src->fd_array[
s];
2640 for (d = 0; d < dst->fdset->fd_count; d++) {
2641 if (dst->fdset->fd_array[d] == fd)
2644 if (d == dst->fdset->fd_count) {
2645 if ((
int)dst->fdset->fd_count >= dst->capa) {
2646 dst->capa = (dst->fdset->fd_count / FD_SETSIZE + 1) * FD_SETSIZE;
2647 dst->fdset =
xrealloc(dst->fdset,
sizeof(
unsigned int) +
sizeof(SOCKET) * dst->capa);
2649 dst->fdset->fd_array[dst->fdset->fd_count++] = fd;
2653 &src->fd_array[s+1],
2654 sizeof(src->fd_array[0]) * (--src->fd_count - s));
2664 return dst ? dst->fdset->fd_count :
m;
2672 if (!src || !dst)
return 0;
2674 for (s = 0; s < src->fd_count; ++
s) {
2675 SOCKET fd = src->fd_array[
s];
2677 for (d = 0; d < dst->fd_count; ++
d) {
2678 if (dst->fd_array[d] == fd)
2681 if (d == dst->fd_count && d < FD_SETSIZE) {
2682 dst->fd_array[dst->fd_count++] = fd;
2686 return dst->fd_count;
2703 ret = (GetFileType((HANDLE)sock) == FILE_TYPE_PIPE);
2717 if (PeekNamedPipe((HANDLE)sock,
NULL, 0,
NULL, &n,
NULL)) {
2721 ret = (GetLastError() == ERROR_BROKEN_PIPE);
2737 ret = (PeekConsoleInput((HANDLE)sock, &ir, 1, &n))
2752 if (PeekConsoleInput((HANDLE)sock, &ir, 1, &n) && n > 0) {
2753 if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&
2754 ir.Event.KeyEvent.uChar.AsciiChar) {
2758 ReadConsoleInput((HANDLE)sock, &ir, 1, &n);
2770 return (HANDLE)sock == INVALID_HANDLE_VALUE;
2787 if (!NtSocketsInitialized)
2791 EnterCriticalSection(&select_mutex);
2792 r =
select(nfds, rd, wr, ex, timeout);
2793 LeaveCriticalSection(&select_mutex);
2794 if (r == SOCKET_ERROR) {
2859 struct timeval limit = {0, 0};
2861 if (nfds < 0 || (timeout && (timeout->
tv_sec < 0 || timeout->
tv_usec < 0))) {
2867 if (timeout->
tv_sec < 0 ||
2869 timeout->
tv_usec >= 1000000) {
2876 if (limit.
tv_usec >= 1000000) {
2913 if (rd && (
int)rd->fd_count > r) r = (
int)rd->fd_count;
2914 if (wr && (
int)wr->fd_count >
r) r = (
int)wr->fd_count;
2915 if (ex && (
int)ex->fd_count >
r) r = (
int)ex->fd_count;
2916 if (nfds > r) nfds =
r;
2920 const struct timeval wait = {0, 10 * 1000};
2934 if (else_rd.fdset->fd_count || else_wr.fdset->fd_count) {
2937 r +=
copy_fd(rd, else_rd.fdset);
2938 r +=
copy_fd(wr, else_wr.fdset);
2954 if (rd)
copy_fd(&orig_rd, rd);
2955 if (wr)
copy_fd(&orig_wr, wr);
2956 if (ex)
copy_fd(&orig_ex, ex);
2959 if (rd)
copy_fd(rd, &orig_rd);
2960 if (wr)
copy_fd(wr, &orig_wr);
2961 if (ex)
copy_fd(ex, &orig_ex);
2968 if (
compare(&rest, &wait) < 0) dowait = &rest;
2970 Sleep(dowait->
tv_sec * 1000 + (dowait->
tv_usec + 999) / 1000);
2999 WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, guid,
sizeof(*guid),
3000 &ptr,
sizeof(ptr), &dmy,
NULL,
NULL);
3015 if (!NtSocketsInitialized) {
3019 HANDLE h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
3022 r = accept(
TO_SOCKET(s), addr, addrlen);
3023 if (r != INVALID_SOCKET) {
3024 SetHandleInformation((HANDLE)r, HANDLE_FLAG_INHERIT, 0);
3051 if (!NtSocketsInitialized) {
3056 if (r == SOCKET_ERROR)
3069 if (!NtSocketsInitialized) {
3073 r = connect(
TO_SOCKET(s), addr, addrlen);
3074 if (r == SOCKET_ERROR) {
3075 int err = WSAGetLastError();
3076 if (err != WSAEWOULDBLOCK)
3093 if (!NtSocketsInitialized) {
3097 r = getpeername(
TO_SOCKET(s), addr, addrlen);
3098 if (r == SOCKET_ERROR)
3112 if (!NtSocketsInitialized) {
3117 r = getsockname(sock, addr, addrlen);
3118 if (r == SOCKET_ERROR) {
3119 DWORD wsaerror = WSAGetLastError();
3120 if (wsaerror == WSAEINVAL) {
3125 memset(addr, 0, *addrlen);
3126 addr->sa_family = af;
3144 if (!NtSocketsInitialized) {
3148 r = getsockopt(
TO_SOCKET(s), level, optname, optval, optlen);
3149 if (r == SOCKET_ERROR)
3162 if (!NtSocketsInitialized) {
3166 r = ioctlsocket(
TO_SOCKET(s), cmd, argp);
3167 if (r == SOCKET_ERROR)
3180 if (!NtSocketsInitialized) {
3185 if (r == SOCKET_ERROR)
3203 if (result != SOCKET_ERROR)
3205 else if ((err = WSAGetLastError()) == WSA_IO_PENDING) {
3209 result = WSAGetOverlappedResult(s, wol, &size,
TRUE, &flg)
3217 if ((err = WSAGetLastError()) == WSAECONNABORTED && !input)
3222 case WAIT_OBJECT_0 + 1:
3230 if (err == WSAECONNABORTED && !input)
3236 CloseHandle(wol->hEvent);
3244 struct sockaddr *addr,
int *addrlen)
3254 if (!NtSocketsInitialized)
3262 if (addr && addrlen)
3263 r = recvfrom(s, buf, len, flags, addr, addrlen);
3265 r = recv(s, buf, len, flags);
3266 if (r == SOCKET_ERROR)
3270 if (addr && addrlen)
3271 r = sendto(s, buf, len, flags, addr, *addrlen);
3273 r = send(s, buf, len, flags);
3274 if (r == SOCKET_ERROR) {
3276 if (err == WSAECONNABORTED)
3289 memset(&wol, 0,
sizeof(wol));
3294 if (addr && addrlen)
3295 ret = WSARecvFrom(s, &wbuf, 1, &size, &flg, addr, addrlen,
3298 ret = WSARecv(s, &wbuf, 1, &size, &flg, &wol,
NULL);
3301 if (addr && addrlen)
3302 ret = WSASendTo(s, &wbuf, 1, &size, flags, addr, *addrlen,
3305 ret = WSASend(s, &wbuf, 1, &size, flags, &wol,
NULL);
3326 struct sockaddr *from,
int *fromlen)
3341 const struct sockaddr *to,
int tolen)
3344 (
struct sockaddr *)to, &tolen);
3347 #if !defined(MSG_TRUNC) && !defined(__MINGW32__)
3358 #ifndef WSAID_WSARECVMSG
3359 #define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}
3361 #ifndef WSAID_WSASENDMSG
3362 #define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}}
3366 #define msghdr_to_wsamsg(msg, wsamsg) \
3369 (wsamsg)->name = (msg)->msg_name; \
3370 (wsamsg)->namelen = (msg)->msg_namelen; \
3371 (wsamsg)->lpBuffers = ALLOCA_N(WSABUF, (msg)->msg_iovlen); \
3372 (wsamsg)->dwBufferCount = (msg)->msg_iovlen; \
3373 for (i = 0; i < (msg)->msg_iovlen; ++i) { \
3374 (wsamsg)->lpBuffers[i].buf = (msg)->msg_iov[i].iov_base; \
3375 (wsamsg)->lpBuffers[i].len = (msg)->msg_iov[i].iov_len; \
3377 (wsamsg)->Control.buf = (msg)->msg_control; \
3378 (wsamsg)->Control.len = (msg)->msg_controllen; \
3379 (wsamsg)->dwFlags = (msg)->msg_flags; \
3386 typedef int (WSAAPI *WSARecvMsg_t)(SOCKET,
WSAMSG *,
DWORD *, WSAOVERLAPPED *, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
3387 static WSARecvMsg_t pWSARecvMsg =
NULL;
3394 if (!NtSocketsInitialized)
3412 if ((ret = pWSARecvMsg(s, &wsamsg, &len,
NULL,
NULL)) == SOCKET_ERROR) {
3421 memset(&wol, 0,
sizeof(wol));
3424 ret = pWSARecvMsg(s, &wsamsg, &size, &wol,
NULL);
3429 if (ret == SOCKET_ERROR)
3444 typedef int (WSAAPI *WSASendMsg_t)(SOCKET,
const WSAMSG *,
DWORD, DWORD *, WSAOVERLAPPED *, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
3445 static WSASendMsg_t pWSASendMsg =
NULL;
3452 if (!NtSocketsInitialized)
3469 if ((ret = pWSASendMsg(s, &wsamsg, flags, &len,
NULL,
NULL)) == SOCKET_ERROR) {
3478 memset(&wol, 0,
sizeof(wol));
3481 ret = pWSASendMsg(s, &wsamsg, flags, &size, &wol,
NULL);
3497 if (!NtSocketsInitialized) {
3501 r = setsockopt(
TO_SOCKET(s), level, optname, optval, optlen);
3502 if (r == SOCKET_ERROR)
3515 if (!NtSocketsInitialized) {
3520 if (r == SOCKET_ERROR)
3530 unsigned long proto_buffers_len = 0;
3532 SOCKET
out = INVALID_SOCKET;
3534 if (WSAEnumProtocols(
NULL,
NULL, &proto_buffers_len) == SOCKET_ERROR) {
3535 error_code = WSAGetLastError();
3536 if (error_code == WSAENOBUFS) {
3537 WSAPROTOCOL_INFO *proto_buffers;
3538 int protocols_available = 0;
3540 proto_buffers = (WSAPROTOCOL_INFO *)
malloc(proto_buffers_len);
3541 if (!proto_buffers) {
3542 WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
3543 return INVALID_SOCKET;
3546 protocols_available =
3547 WSAEnumProtocols(
NULL, proto_buffers, &proto_buffers_len);
3548 if (protocols_available != SOCKET_ERROR) {
3550 for (i = 0; i < protocols_available; i++) {
3551 if ((af !=
AF_UNSPEC && af != proto_buffers[i].iAddressFamily) ||
3552 (type != proto_buffers[i].iSocketType) ||
3553 (protocol != 0 && protocol != proto_buffers[i].iProtocol))
3556 if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0)
3559 out = WSASocket(af, type, protocol, &(proto_buffers[i]), 0,
3560 WSA_FLAG_OVERLAPPED);
3563 if (out == INVALID_SOCKET)
3564 out = WSASocket(af, type, protocol,
NULL, 0, 0);
3565 if (out != INVALID_SOCKET)
3566 SetHandleInformation((HANDLE)out, HANDLE_FLAG_INHERIT, 0);
3569 free(proto_buffers);
3585 if (!NtSocketsInitialized) {
3590 if (s == INVALID_SOCKET) {
3605 #undef gethostbyaddr
3608 struct hostent * WSAAPI
3612 if (!NtSocketsInitialized) {
3616 r = gethostbyaddr(addr, len, type);
3623 #undef gethostbyname
3626 struct hostent * WSAAPI
3630 if (!NtSocketsInitialized) {
3634 r = gethostbyname(name);
3648 if (!NtSocketsInitialized) {
3652 r = gethostname(name, len);
3653 if (r == SOCKET_ERROR)
3659 #undef getprotobyname
3662 struct protoent * WSAAPI
3666 if (!NtSocketsInitialized) {
3670 r = getprotobyname(name);
3677 #undef getprotobynumber
3680 struct protoent * WSAAPI
3684 if (!NtSocketsInitialized) {
3688 r = getprotobynumber(num);
3695 #undef getservbyname
3698 struct servent * WSAAPI
3702 if (!NtSocketsInitialized) {
3706 r = getservbyname(name, proto);
3713 #undef getservbyport
3716 struct servent * WSAAPI
3720 if (!NtSocketsInitialized) {
3724 r = getservbyport(port, proto);
3735 SOCKET svr = INVALID_SOCKET,
r = INVALID_SOCKET, w = INVALID_SOCKET;
3736 struct sockaddr_in sock_in4;
3738 struct sockaddr_in6 sock_in6;
3740 struct sockaddr *addr;
3744 if (!NtSocketsInitialized) {
3750 #if defined PF_INET && PF_INET != AF_INET
3753 sock_in4.sin_family = AF_INET;
3754 sock_in4.sin_port = 0;
3755 sock_in4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
3756 addr = (
struct sockaddr *)&sock_in4;
3757 len =
sizeof(sock_in4);
3761 memset(&sock_in6, 0,
sizeof(sock_in6));
3762 sock_in6.sin6_family = AF_INET6;
3763 sock_in6.sin6_addr = IN6ADDR_LOOPBACK_INIT;
3764 addr = (
struct sockaddr *)&sock_in6;
3765 len =
sizeof(sock_in6);
3772 if (type != SOCK_STREAM) {
3777 sv[0] = (SOCKET)INVALID_HANDLE_VALUE;
3778 sv[1] = (SOCKET)INVALID_HANDLE_VALUE;
3782 if (svr == INVALID_SOCKET)
3784 if (bind(svr, addr, len) < 0)
3786 if (getsockname(svr, addr, &len) < 0)
3788 if (type == SOCK_STREAM)
3792 if (w == INVALID_SOCKET)
3794 if (connect(w, addr, len) < 0)
3797 r = accept(svr, addr, &len);
3798 if (r == INVALID_SOCKET)
3800 SetHandleInformation((HANDLE)r, HANDLE_FLAG_INHERIT, 0);
3807 if (r != INVALID_SOCKET)
3809 if (w != INVALID_SOCKET)
3816 if (svr != INVALID_SOCKET)
3833 closesocket(pair[0]);
3834 closesocket(pair[1]);
3840 closesocket(pair[1]);
3849 #if !defined(_MSC_VER) || _MSC_VER >= 1400
3854 #define hex2byte(str) \
3855 ((isdigit(*(str)) ? *(str) - '0' : toupper(*(str)) - 'A' + 10) << 4 | (isdigit(*((str) + 1)) ? *((str) + 1) - '0' : toupper(*((str) + 1)) - 'A' + 10))
3858 if (*str ==
'{') str++;
3859 guid->Data1 = (long)strtoul(str, &end, 16);
3861 guid->Data2 = (
unsigned short)strtoul(str, &end, 16);
3863 guid->Data3 = (
unsigned short)strtoul(str, &end, 16);
3869 for (i = 0; i < 6; i++) {
3870 guid->Data4[i + 2] =
hex2byte(str);
3876 #ifndef HAVE_TYPE_NET_LUID
3896 IP_ADAPTER_ADDRESSES *root, *addr;
3900 if (ret != ERROR_BUFFER_OVERFLOW) {
3905 ret = GetAdaptersAddresses(
AF_UNSPEC, 0,
NULL, root, &size);
3906 if (ret != ERROR_SUCCESS) {
3912 if (!pConvertInterfaceGuidToLuid)
3913 pConvertInterfaceGuidToLuid =
3915 "ConvertInterfaceGuidToLuid",
NULL);
3916 if (!pConvertInterfaceLuidToNameA)
3917 pConvertInterfaceLuidToNameA =
3919 "ConvertInterfaceLuidToNameA",
NULL);
3921 for (prev =
NULL, addr = root; addr; addr = addr->Next) {
3932 str2guid(addr->AdapterName, &guid);
3933 if (pConvertInterfaceGuidToLuid && pConvertInterfaceLuidToNameA &&
3941 lstrcpy(ifa->
ifa_name, addr->AdapterName);
3944 if (addr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
3946 if (addr->OperStatus == IfOperStatusUp) {
3949 if (addr->FirstUnicastAddress) {
3950 IP_ADAPTER_UNICAST_ADDRESS *cur;
3952 for (cur = addr->FirstUnicastAddress; cur; cur = cur->Next) {
3953 if (cur->Flags & IP_ADAPTER_ADDRESS_TRANSIENT ||
3954 cur->DadState == IpDadStateDeprecated) {
3968 cur->Address.iSockaddrLength);
4039 flag &= ~O_NONBLOCK;
4043 ret = ioctlsocket(sock, FIONBIO, &ioctlArg);
4055 dupfd(HANDLE hDup,
char flags,
int minfd)
4065 goto close_fds_and_return;
4068 goto close_fds_and_return;
4070 fds[filled++] =
ret;
4071 }
while (filled < (
int)
numberof(fds));
4073 ret =
dupfd(hDup, flags, minfd);
4075 close_fds_and_return:
4077 while (filled > 0) {
4078 int fd = fds[--filled];
4102 arg = va_arg(va,
int);
4104 return setfl(sock, arg);
4109 if (!(DuplicateHandle(GetCurrentProcess(), (HANDLE)_get_osfhandle(fd),
4110 GetCurrentProcess(), &hDup, 0L,
4112 DUPLICATE_SAME_ACCESS))) {
4118 arg = va_arg(va,
int);
4142 if (!GetExitCodeProcess(child->
hProcess, &exitcode)) {
4145 err = GetLastError();
4147 case ERROR_INVALID_PARAMETER:
4150 case ERROR_INVALID_HANDLE:
4160 if (exitcode != STILL_ACTIVE) {
4169 *stat_loc = exitcode << 8;
4170 if (exitcode & 0xC0000000) {
4171 static const struct {
4175 {STATUS_ACCESS_VIOLATION, SIGSEGV},
4176 {STATUS_ILLEGAL_INSTRUCTION, SIGILL},
4177 {STATUS_PRIVILEGED_INSTRUCTION, SIGILL},
4178 {STATUS_FLOAT_DENORMAL_OPERAND, SIGFPE},
4179 {STATUS_FLOAT_DIVIDE_BY_ZERO, SIGFPE},
4180 {STATUS_FLOAT_INEXACT_RESULT, SIGFPE},
4181 {STATUS_FLOAT_INVALID_OPERATION, SIGFPE},
4182 {STATUS_FLOAT_OVERFLOW, SIGFPE},
4183 {STATUS_FLOAT_STACK_CHECK, SIGFPE},
4184 {STATUS_FLOAT_UNDERFLOW, SIGFPE},
4185 #ifdef STATUS_FLOAT_MULTIPLE_FAULTS
4186 {STATUS_FLOAT_MULTIPLE_FAULTS, SIGFPE},
4188 #ifdef STATUS_FLOAT_MULTIPLE_TRAPS
4189 {STATUS_FLOAT_MULTIPLE_TRAPS, SIGFPE},
4191 {STATUS_CONTROL_C_EXIT,
SIGINT},
4196 *stat_loc |=
table[
i].sig;
4202 *stat_loc |= SIGSEGV;
4232 if (!child->pid || child->pid < 0)
continue;
4234 events[count++] = child->hProcess;
4242 if (ret == WAIT_TIMEOUT)
return 0;
4243 if ((ret -= WAIT_OBJECT_0) == count) {
4269 if (ret == WAIT_OBJECT_0 + 1)
return -1;
4270 if (ret != WAIT_OBJECT_0) {
4279 if (pid == -1 && retried) pid = 0;
4285 #include <sys/timeb.h>
4292 unsigned LONG_LONG
lt;
4294 tmp.LowPart = ft->dwLowDateTime;
4295 tmp.HighPart = ft->dwHighDateTime;
4303 lt -= (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60 * 1000 * 1000;
4305 tv->
tv_sec = (long)(lt / (1000 * 1000));
4306 tv->
tv_usec = (long)(lt % (1000 * 1000));
4308 return tv->
tv_sec > 0 ? 0 : -1;
4317 GetSystemTimeAsFileTime(&ft);
4339 LARGE_INTEGER
count;
4340 if (!QueryPerformanceFrequency(&freq)) {
4344 if (!QueryPerformanceCounter(&count)) {
4348 sp->
tv_sec = count.QuadPart / freq.QuadPart;
4349 if (freq.QuadPart < 1000000000)
4350 sp->
tv_nsec = (count.QuadPart % freq.QuadPart) * 1000000000 / freq.QuadPart;
4352 sp->
tv_nsec = (
long)((count.QuadPart % freq.QuadPart) * (1000000000.0 / freq.QuadPart));
4375 if (!QueryPerformanceFrequency(&freq)) {
4380 sp->
tv_nsec = (long)(1000000000.0 / freq.QuadPart);
4396 len = GetCurrentDirectory(0,
NULL);
4417 if (!GetCurrentDirectory(size, p)) {
4450 if (pid < 0 || pid == 0 && sig !=
SIGINT) {
4455 if ((
unsigned int)pid == GetCurrentProcessId() &&
4456 (sig != 0 && sig !=
SIGKILL)) {
4457 if ((ret =
raise(sig)) != 0) {
4468 OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE, (
DWORD)pid);
4469 if (hProc ==
NULL || hProc == INVALID_HANDLE_VALUE) {
4470 if (GetLastError() == ERROR_INVALID_PARAMETER) {
4486 DWORD ctrlEvent = CTRL_C_EVENT;
4490 ctrlEvent = CTRL_BREAK_EVENT;
4492 if (!GenerateConsoleCtrlEvent(ctrlEvent, (
DWORD)pid)) {
4493 if ((err = GetLastError()) == 0)
4510 hProc = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION,
FALSE, (
DWORD)pid);
4512 if (hProc ==
NULL || hProc == INVALID_HANDLE_VALUE) {
4513 if (GetLastError() == ERROR_INVALID_PARAMETER) {
4523 if (!GetExitCodeProcess(hProc, &status)) {
4527 else if (status == STILL_ACTIVE) {
4528 if (!TerminateProcess(hProc, 0)) {
4555 wlink(
const WCHAR *from,
const WCHAR *to)
4557 typedef BOOL (WINAPI link_func)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
4558 static link_func *pCreateHardLinkW =
NULL;
4559 static int myerrno = 0;
4561 if (!pCreateHardLinkW && !myerrno) {
4563 if (!pCreateHardLinkW)
4566 if (!pCreateHardLinkW) {
4571 if (!pCreateHardLinkW(to, from,
NULL)) {
4593 ret =
wlink(wfrom, wto);
4601 link(
const char *from,
const char *to)
4613 ret =
wlink(wfrom, wto);
4623 return waitpid(-1, status, 0);
4630 WCHAR *wenvarea, *wenv;
4635 if (len == 0)
return NULL;
4642 FreeEnvironmentStrings(envarea);
4645 wenvarea = GetEnvironmentStringsW();
4650 for (wenv = wenvarea, wlen = 1; *wenv; wenv += lstrlenW(wenv) + 1)
4651 wlen += lstrlenW(wenv) + 1;
4653 FreeEnvironmentStringsW(wenvarea);
4657 for (env = uenvarea; *
env; env +=
strlen(env) + 1)
4659 return env + len + 1;
4682 const DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
4683 const DWORD creation = OPEN_EXISTING;
4684 const DWORD flags = FILE_FLAG_BACKUP_SEMANTICS;
4685 BY_HANDLE_FILE_INFORMATION
st = {0};
4686 HANDLE h = CreateFileW(path, 0, share_mode,
NULL, creation, flags,
NULL);
4689 if (h == INVALID_HANDLE_VALUE)
return 0;
4690 ret = GetFileInformationByHandle(h, &st);
4693 return st.dwVolumeSerialNumber;
4705 wrename(
const WCHAR *oldpath,
const WCHAR *newpath)
4711 oldatts = GetFileAttributesW(oldpath);
4712 newatts = GetFileAttributesW(newpath);
4714 if (oldatts == -1) {
4720 if (newatts != -1 && newatts & FILE_ATTRIBUTE_READONLY)
4721 SetFileAttributesW(newpath, newatts & ~ FILE_ATTRIBUTE_READONLY);
4723 if (!MoveFileExW(oldpath, newpath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
4727 DWORD e = GetLastError();
4728 if ((e == ERROR_ACCESS_DENIED) && (oldatts & FILE_ATTRIBUTE_DIRECTORY) &&
4735 SetFileAttributesW(newpath, oldatts);
4783 if (path[0] == L
'\\' && path[1] == L
'\\') {
4784 const WCHAR *
p = path + 2;
4785 if (p[0] == L
'?' && p[1] == L
'\\') {
4793 for (p++; *
p; p++) {
4797 if (!p[0] || !p[1] || (p[1] == L
'.' && !p[2]))
4804 #define COPY_STAT(src, dest, size_cast) do { \
4805 (dest).st_dev = (src).st_dev; \
4806 (dest).st_ino = (src).st_ino; \
4807 (dest).st_mode = (src).st_mode; \
4808 (dest).st_nlink = (src).st_nlink; \
4809 (dest).st_uid = (src).st_uid; \
4810 (dest).st_gid = (src).st_gid; \
4811 (dest).st_rdev = (src).st_rdev; \
4812 (dest).st_size = size_cast(src).st_size; \
4813 (dest).st_atime = (src).st_atime; \
4814 (dest).st_mtime = (src).st_mtime; \
4815 (dest).st_ctime = (src).st_ctime; \
4825 BY_HANDLE_FILE_INFORMATION
info;
4828 if (ret)
return ret;
4832 if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) {
4834 if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
4849 BY_HANDLE_FILE_INFORMATION
info;
4853 if (ret)
return ret;
4858 if (GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &info)) {
4860 if (!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
4864 st->st_size = ((__int64)info.nFileSizeHigh << 32) | info.nFileSizeLow;
4890 if (attr & FILE_ATTRIBUTE_READONLY) {
4894 mode |= S_IREAD | S_IWRITE |
S_IWUSR;
4897 if (attr & FILE_ATTRIBUTE_DIRECTORY) {
4898 mode |= S_IFDIR | S_IEXEC;
4904 if (path && (mode & S_IFREG)) {
4905 const WCHAR *
end = path + lstrlenW(path);
4906 while (path < end) {
4907 end = CharPrevW(path, end);
4909 if ((_wcsicmp(end, L
".bat") == 0) ||
4910 (_wcsicmp(end, L
".cmd") == 0) ||
4911 (_wcsicmp(end, L
".com") == 0) ||
4912 (_wcsicmp(end, L
".exe") == 0)) {
4920 mode |= (mode & 0700) >> 3;
4921 mode |= (mode & 0700) >> 6;
4930 WIN32_FIND_DATAW fd;
4932 WCHAR full[MAX_PATH];
4938 if (!(p = wcsstr(path, L
"...")))
4940 q = p + wcsspn(p, L
".");
4941 if ((p == path || wcschr(L
":/\\", *(p - 1))) &&
4942 (!*q || wcschr(L
":/\\", *q))) {
4949 if (!GetFullPathNameW(path,
sizeof(full) /
sizeof(WCHAR), full, &dmy)) {
4953 if (full[1] == L
':' && !full[3] && GetDriveTypeW(full) != DRIVE_NO_ROOT_DIR)
4957 if (fh == INVALID_HANDLE_VALUE)
4968 WIN32_FIND_DATAW wfd;
4969 WIN32_FILE_ATTRIBUTE_DATA wfa;
4970 const WCHAR *
p =
path;
4972 memset(st, 0,
sizeof(*st));
4975 if (wcsncmp(p, L
"\\\\?\\", 4) == 0) p += 4;
4976 if (wcspbrk(p, L
"?*")) {
4980 if (GetFileAttributesExW(path, GetFileExInfoStandard, (
void*)&wfa)) {
4981 if (wfa.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
4986 st->st_size = ((__int64)wfa.nFileSizeHigh << 32) | wfa.nFileSizeLow;
4995 int e = GetLastError();
4997 if ((e == ERROR_FILE_NOT_FOUND) || (e == ERROR_INVALID_NAME)
4998 || (e == ERROR_PATH_NOT_FOUND || (e == ERROR_BAD_NETPATH))) {
5004 h = FindFirstFileW(path, &wfd);
5005 if (h != INVALID_HANDLE_VALUE) {
5011 st->st_size = ((__int64)wfd.nFileSizeHigh << 32) | wfd.nFileSizeLow;
5019 st->st_dev = st->st_rdev = (iswalpha(path[0]) && path[1] == L
':') ?
5020 towupper(path[0]) - L
'A' : _getdrive() - 1;
5041 WCHAR *buf1, *
s, *
end;
5050 size = lstrlenW(path) + 2;
5052 for (p = path, s = buf1; *
p; p++, s++) {
5060 if (!len || L
'\"' == *(--s)) {
5064 end = buf1 + len - 1;
5069 else if (*end != L
'\\')
5070 lstrcatW(buf1, L
"\\");
5072 else if (*end == L
'\\' || (buf1 + 1 == end && *end == L
':'))
5073 lstrcatW(buf1, L
".");
5117 struct stati64 stat;
5121 if ((stat.st_mode & mode) != mode) {
5132 struct stati64 stat;
5136 if ((stat.st_mode & mode) != mode) {
5147 long upos, lpos, usize, lsize;
5151 if ((lpos = SetFilePointer(h, 0, (upos = 0, &upos),
SEEK_CUR)) == -1L &&
5152 (e = GetLastError())) {
5156 usize = (long)(size >> 32);
5158 if (SetFilePointer(h, lsize, &usize,
SEEK_SET) == (
DWORD)-1L &&
5159 (e = GetLastError())) {
5162 else if (!SetEndOfFile(h)) {
5168 SetFilePointer(h, lpos, &upos,
SEEK_SET);
5178 h = CreateFile(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
5179 if (h == INVALID_HANDLE_VALUE) {
5194 h = (HANDLE)_get_osfhandle(fd);
5195 if (h == (HANDLE)-1)
return -1;
5202 _filelengthi64(
int fd)
5207 l = GetFileSize((HANDLE)_get_osfhandle(fd), &u);
5208 if (l == (
DWORD)-1L && (e = GetLastError())) {
5212 return ((
off_t)u << 32) | l;
5217 _lseeki64(
int fd,
off_t offset,
int whence)
5221 HANDLE h = (HANDLE)_get_osfhandle(fd);
5227 u = (long)(offset >> 32);
5228 if ((l = SetFilePointer(h, (
long)offset, &u, whence)) == -1L &&
5229 (e = GetLastError())) {
5233 return ((
off_t)u << 32) | l;
5241 __int64 qw = ft->dwHighDateTime;
5243 qw |= ft->dwLowDateTime;
5252 FILETIME create, exit, kernel, user;
5254 if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
5269 #define yield_once() Sleep(0)
5270 #define yield_until(condition) do yield_once(); while (!(condition))
5280 #if defined __BORLANDC__
5284 read(
int fd,
void *
buf,
size_t size)
5286 int ret = _read(fd, buf, size);
5287 if ((ret < 0) && (
errno == EPIPE)) {
5297 #define FILE_COUNT _cnt
5298 #define FILE_READPTR _ptr
5307 c = (
unsigned char)*stream->FILE_READPTR++;
5310 c = _filbuf(stream);
5311 #if defined __BORLANDC__
5312 if ((c ==
EOF) && (
errno == EPIPE)) {
5327 c = (
unsigned char)(*stream->FILE_READPTR++ = (
char)
c);
5330 c = _flsbuf(c, stream);
5367 BOOL interrupted =
FALSE;
5388 if (TerminateThread(thr, intrval)) {
5393 GetExitCodeThread(thr, &val);
5398 MEMORY_BASIC_INFORMATION
m;
5400 memset(&m, 0,
sizeof(m));
5401 if (!VirtualQuery(arg.
stackaddr, &m,
sizeof(m))) {
5402 Debug(fprintf(stderr,
"couldn't get stack base:%p:%d\n",
5405 else if (!VirtualFree(m.AllocationBase, 0, MEM_RELEASE)) {
5406 Debug(fprintf(stderr,
"couldn't release stack:%p:%d\n",
5407 m.AllocationBase, GetLastError()));
5418 rb_fatal(
"failed to launch waiter thread:%ld", GetLastError());
5428 WCHAR *envtop, *
env;
5429 char **myenvtop, **myenv;
5442 envtop = GetEnvironmentStringsW();
5443 for (env = envtop, num = 0; *
env; env += lstrlenW(env) + 1)
5444 if (*env !=
'=') num++;
5446 myenvtop = (
char **)
malloc(
sizeof(
char *) * (num + 1));
5447 for (env = envtop, myenv = myenvtop; *
env; env += lstrlenW(env) + 1) {
5456 FreeEnvironmentStringsW(envtop);
5467 while (*t)
free(*t++);
5475 return GetCurrentProcessId();
5483 typedef long (WINAPI query_func)(HANDLE,
int,
void *,
ULONG, ULONG *);
5484 static query_func *pNtQueryInformationProcess =
NULL;
5488 if (!pNtQueryInformationProcess)
5489 pNtQueryInformationProcess = (query_func *)
get_proc_address(
"ntdll.dll",
"NtQueryInformationProcess",
NULL);
5490 if (pNtQueryInformationProcess) {
5493 void* PebBaseAddress;
5500 long ret = pNtQueryInformationProcess(GetCurrentProcess(), 0, &pbi,
sizeof(pbi), &len);
5502 ppid = pbi.ParentProcessId;
5510 STATIC_ASSERT(std_handle, (STD_OUTPUT_HANDLE-STD_INPUT_HANDLE)==(STD_ERROR_HANDLE-STD_OUTPUT_HANDLE));
5513 #define set_new_std_handle(newfd, handle) do { \
5514 if ((unsigned)(newfd) > 2) break; \
5515 SetStdHandle(STD_INPUT_HANDLE+(STD_OUTPUT_HANDLE-STD_INPUT_HANDLE)*(newfd), \
5518 #define set_new_std_fd(newfd) set_new_std_handle(newfd, (HANDLE)rb_w32_get_osfhandle(newfd))
5526 if (oldfd == newfd)
return newfd;
5527 ret =
dup2(oldfd, newfd);
5541 va_start(arg, oflag);
5542 pmode = va_arg(arg,
int);
5556 DWORD attr = GetFileAttributesW(wfile);
5557 if (attr == (
DWORD)-1L ||
5558 !(attr & FILE_ATTRIBUTE_DIRECTORY) ||
5589 va_start(arg, oflag);
5590 pmode = va_arg(arg,
int);
5593 if ((oflag & O_TEXT) || !(oflag &
O_BINARY)) {
5594 ret = _open(file, oflag, pmode);
5613 DWORD attr = FILE_ATTRIBUTE_NORMAL;
5614 SECURITY_ATTRIBUTES sec;
5617 if ((oflag & O_TEXT) || !(oflag &
O_BINARY)) {
5620 va_start(arg, oflag);
5621 pmode = va_arg(arg,
int);
5623 fd = _wopen(file, oflag, pmode);
5628 sec.nLength =
sizeof(sec);
5629 sec.lpSecurityDescriptor =
NULL;
5630 if (oflag & O_NOINHERIT) {
5631 sec.bInheritHandle =
FALSE;
5635 sec.bInheritHandle =
TRUE;
5637 oflag &= ~O_NOINHERIT;
5640 oflag &= ~(O_BINARY | O_TEXT);
5642 switch (oflag & (O_RDWR | O_RDONLY | O_WRONLY)) {
5644 access = GENERIC_READ | GENERIC_WRITE;
5647 access = GENERIC_READ;
5650 access = GENERIC_WRITE;
5656 oflag &= ~(O_RDWR | O_RDONLY | O_WRONLY);
5658 switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
5660 create = OPEN_ALWAYS;
5664 create = OPEN_EXISTING;
5666 case O_CREAT | O_EXCL:
5667 case O_CREAT | O_EXCL | O_TRUNC:
5668 create = CREATE_NEW;
5671 case O_TRUNC | O_EXCL:
5672 create = TRUNCATE_EXISTING;
5674 case O_CREAT | O_TRUNC:
5675 create = CREATE_ALWAYS;
5681 if (oflag & O_CREAT) {
5684 va_start(arg, oflag);
5685 pmode = va_arg(arg,
int);
5688 if (!(pmode & S_IWRITE))
5689 attr = FILE_ATTRIBUTE_READONLY;
5691 oflag &= ~(O_CREAT | O_EXCL | O_TRUNC);
5693 if (oflag & O_TEMPORARY) {
5694 attr |= FILE_FLAG_DELETE_ON_CLOSE;
5697 oflag &= ~O_TEMPORARY;
5699 if (oflag & _O_SHORT_LIVED)
5700 attr |= FILE_ATTRIBUTE_TEMPORARY;
5701 oflag &= ~_O_SHORT_LIVED;
5703 switch (oflag & (O_SEQUENTIAL | O_RANDOM)) {
5707 attr |= FILE_FLAG_SEQUENTIAL_SCAN;
5710 attr |= FILE_FLAG_RANDOM_ACCESS;
5716 oflag &= ~(O_SEQUENTIAL | O_RANDOM);
5718 if (oflag & ~O_APPEND) {
5725 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5726 fd = _open_osfhandle((
intptr_t)h, 0);
5738 h = CreateFileW(file, access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
5739 create, attr,
NULL);
5740 if (h == INVALID_HANDLE_VALUE) {
5741 DWORD e = GetLastError();
5749 switch (GetFileType(h)) {
5750 case FILE_TYPE_CHAR:
5753 case FILE_TYPE_PIPE:
5756 case FILE_TYPE_UNKNOWN:
5763 if (!(flags & (
FDEV |
FPIPE)) && (oflag & O_APPEND))
5783 int save_errno =
errno;
5785 if (fflush(fp))
return -1;
5793 if (closesocket(sock) == SOCKET_ERROR) {
5804 static DWORD serial = 0;
5805 static const char prefix[] =
"\\\\.\\pipe\\ruby";
5807 width_of_prefix = (
int)
sizeof(prefix) - 1,
5808 width_of_pid = (
int)
sizeof(rb_pid_t) * 2,
5809 width_of_serial = (
int)
sizeof(serial) * 2,
5810 width_of_ids = width_of_pid + 1 + width_of_serial + 1
5812 char name[
sizeof(prefix) + width_of_ids];
5813 SECURITY_ATTRIBUTES sec;
5814 HANDLE hRead, hWrite, h;
5815 int fdRead, fdWrite;
5820 return _pipe(fds, 65536L, _O_NOINHERIT);
5823 snprintf(
name + width_of_prefix, width_of_ids,
"%.*"PRI_PIDT_PREFIX
"x-%.*lx",
5826 sec.nLength =
sizeof(sec);
5827 sec.lpSecurityDescriptor =
NULL;
5828 sec.bInheritHandle =
FALSE;
5831 hRead = CreateNamedPipe(
name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
5832 0, 2, 65536, 65536, 0, &sec);
5834 if (hRead == INVALID_HANDLE_VALUE) {
5836 if (err == ERROR_PIPE_BUSY)
5844 hWrite = CreateFile(
name, GENERIC_READ | GENERIC_WRITE, 0, &sec,
5845 OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
NULL);
5847 if (hWrite == INVALID_HANDLE_VALUE) {
5855 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5856 fdRead = _open_osfhandle((
intptr_t)h, 0);
5860 CloseHandle(hWrite);
5875 h = CreateFile(
"NUL", 0, 0,
NULL, OPEN_ALWAYS, 0,
NULL);
5876 fdWrite = _open_osfhandle((
intptr_t)h, 0);
5878 if (fdWrite == -1) {
5880 CloseHandle(hWrite);
5907 const void *
const func = WriteConsoleW;
5909 MEMORY_BASIC_INFORMATION
m;
5911 memset(&m, 0,
sizeof(m));
5912 if (!VirtualQuery(func, &m,
sizeof(m))) {
5915 k = GetModuleHandle(
"kernel32.dll");
5916 if (!k)
return FALSE;
5917 return (HMODULE)m.AllocationBase != k;
5941 CONSOLE_SCREEN_BUFFER_INFO csbi;
5944 p->
vt100.
attr = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
5946 if (GetConsoleScreenBufferInfo(h, &csbi)) {
5970 #define FOREGROUND_MASK (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)
5971 #define BACKGROUND_MASK (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)
5972 WORD bold = attr & (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
5975 if (!count)
return attr;
5976 while (count-- > 0) {
5979 attr = default_attr;
5984 bold |= rev ? BACKGROUND_INTENSITY : FOREGROUND_INTENSITY;
5987 #ifndef COMMON_LVB_UNDERSCORE
5988 #define COMMON_LVB_UNDERSCORE 0x8000
5997 attr &= ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
6001 attr = attr & ~(FOREGROUND_BLUE | FOREGROUND_GREEN) | FOREGROUND_RED;
6005 attr = attr & ~(FOREGROUND_BLUE | FOREGROUND_RED) | FOREGROUND_GREEN;
6009 attr = attr & ~FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
6013 attr = attr & ~(FOREGROUND_GREEN | FOREGROUND_RED) | FOREGROUND_BLUE;
6017 attr = attr & ~FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED;
6021 attr = attr & ~FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN;
6025 attr |= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
6029 attr &= ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
6032 attr = attr & ~(BACKGROUND_BLUE | BACKGROUND_GREEN) | BACKGROUND_RED;
6035 attr = attr & ~(BACKGROUND_BLUE | BACKGROUND_RED) | BACKGROUND_GREEN;
6038 attr = attr & ~BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
6041 attr = attr & ~(BACKGROUND_GREEN | BACKGROUND_RED) | BACKGROUND_BLUE;
6044 attr = attr & ~BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED;
6047 attr = attr & ~BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
6050 attr |= BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
6066 CONSOLE_SCREEN_BUFFER_INFO csbi;
6073 if (!GetConsoleScreenBufferInfo(handle, &csbi))
return;
6074 if (count > 0 && seq[0] > 0) arg1 = seq[0];
6080 csbi.dwCursorPosition.X = 0;
6082 csbi.dwCursorPosition.Y -= arg1;
6083 if (csbi.dwCursorPosition.Y < 0)
6084 csbi.dwCursorPosition.Y = 0;
6085 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6088 csbi.dwCursorPosition.X = 0;
6091 csbi.dwCursorPosition.Y += arg1;
6092 if (csbi.dwCursorPosition.Y >= csbi.dwSize.Y)
6093 csbi.dwCursorPosition.Y = csbi.dwSize.Y;
6094 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6097 csbi.dwCursorPosition.X += arg1;
6098 if (csbi.dwCursorPosition.X >= csbi.dwSize.X)
6099 csbi.dwCursorPosition.X = csbi.dwSize.X;
6100 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6103 csbi.dwCursorPosition.X -= arg1;
6104 if (csbi.dwCursorPosition.X < 0)
6105 csbi.dwCursorPosition.X = 0;
6106 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6110 csbi.dwCursorPosition.X = (arg1 > csbi.dwSize.X ? csbi.dwSize.X : arg1) - 1;
6111 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6114 csbi.dwCursorPosition.Y = (arg1 > csbi.dwSize.Y ? csbi.dwSize.Y : arg1) - 1;
6115 SetConsoleCursorPosition(handle, csbi.dwCursorPosition);
6119 pos.Y = (arg1 > csbi.dwSize.Y ? csbi.dwSize.Y : arg1) - 1;
6120 if (count < 2 || (arg1 = seq[1]) <= 0) arg1 = 1;
6121 pos.X = (arg1 > csbi.dwSize.X ? csbi.dwSize.X : arg1) - 1;
6122 SetConsoleCursorPosition(handle, pos);
6127 FillConsoleOutputCharacterW(handle, L
' ',
6128 csbi.dwSize.X * (csbi.dwSize.Y - csbi.dwCursorPosition.Y) - csbi.dwCursorPosition.X,
6129 csbi.dwCursorPosition, &written);
6133 pos.Y = csbi.dwCursorPosition.Y;
6134 FillConsoleOutputCharacterW(handle, L
' ',
6135 csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X,
6141 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X * csbi.dwSize.Y, pos, &written);
6148 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X - csbi.dwCursorPosition.X, csbi.dwCursorPosition, &written);
6152 pos.Y = csbi.dwCursorPosition.Y;
6153 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwCursorPosition.X, pos, &written);
6157 pos.Y = csbi.dwCursorPosition.Y;
6158 FillConsoleOutputCharacterW(handle, L
' ', csbi.dwSize.X, pos, &written);
6166 SetConsoleCursorPosition(handle, s->
vt100.
saved);
6169 if (count >= 2 && seq[0] == -1 && seq[1] == 25) {
6170 CONSOLE_CURSOR_INFO cci;
6171 GetConsoleCursorInfo(handle, &cci);
6172 cci.bVisible =
TRUE;
6173 SetConsoleCursorInfo(handle, &cci);
6177 if (count >= 2 && seq[0] == -1 && seq[1] == 25) {
6178 CONSOLE_CURSOR_INFO cci;
6179 GetConsoleCursorInfo(handle, &cci);
6180 cci.bVisible =
FALSE;
6181 SetConsoleCursorInfo(handle, &cci);
6191 const WCHAR *
ptr = *ptrp;
6192 long rest,
len = *lenp;
6196 rest = *lenp - len - 1;
6201 if (len > 0 && *ptr != L
'[')
continue;
6210 rest = *lenp - len - 1;
6211 if (rest > 0) --rest;
6216 if (wc >= L
'0' && wc <= L
'9') {
6219 *seq = (*seq * 10) + (wc - L
'0');
6260 int save_errno =
errno;
6271 if (closesocket(sock) == SOCKET_ERROR) {
6281 memset(ol, 0,
sizeof(*ol));
6289 DWORD low = SetFilePointer((HANDLE)
_osfhnd(fd), 0, &high, method);
6290 #ifndef INVALID_SET_FILE_POINTER
6291 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
6295 if (err != NO_ERROR) {
6301 ol->OffsetHigh = high;
6314 CloseHandle(ol->hEvent);
6317 LONG high = ol->OffsetHigh;
6319 if (low < ol->Offset)
6321 SetFilePointer((HANDLE)
_osfhnd(fd), low, &high, FILE_BEGIN);
6336 OVERLAPPED ol, *pol =
NULL;
6338 BOOL islineinput =
FALSE;
6345 if (_get_osfhandle(fd) == -1) {
6350 return _read(fd, buf, size);
6365 GetConsoleMode((HANDLE)
_osfhnd(fd),&mode);
6366 islineinput = (mode & ENABLE_LINE_INPUT) != 0;
6393 if (!ReadFile((HANDLE)
_osfhnd(fd), buf, len, &read, pol)) {
6394 err = GetLastError();
6395 if (err != ERROR_IO_PENDING) {
6396 if (pol) CloseHandle(ol.hEvent);
6397 if (err == ERROR_ACCESS_DENIED)
6399 else if (err == ERROR_BROKEN_PIPE || err == ERROR_HANDLE_EOF) {
6412 if (wait != WAIT_OBJECT_0) {
6413 if (wait == WAIT_OBJECT_0 + 1)
6417 CloseHandle(ol.hEvent);
6423 if (!GetOverlappedResult((HANDLE)
_osfhnd(fd), &ol, &read,
TRUE) &&
6424 (err = GetLastError()) != ERROR_HANDLE_EOF) {
6426 if (err != ERROR_BROKEN_PIPE) {
6430 CloseHandle(ol.hEvent);
6438 err = GetLastError();
6448 buf = (
char *)buf + read;
6449 if (err != ERROR_OPERATION_ABORTED &&
6450 !(isconsole && len == 1 && (!islineinput || *((
char *)buf - 1) ==
'\n')) && size > 0)
6473 OVERLAPPED ol, *pol =
NULL;
6479 if (_get_osfhandle(fd) == -1) {
6485 return _write(fd, buf, size);
6511 if (!WriteFile((HANDLE)
_osfhnd(fd), buf, len, &written, pol)) {
6512 err = GetLastError();
6513 if (err != ERROR_IO_PENDING) {
6514 if (pol) CloseHandle(ol.hEvent);
6515 if (err == ERROR_ACCESS_DENIED)
6526 if (wait != WAIT_OBJECT_0) {
6527 if (wait == WAIT_OBJECT_0 + 1)
6531 CloseHandle(ol.hEvent);
6537 if (!GetOverlappedResult((HANDLE)
_osfhnd(fd), &ol, &written,
6540 CloseHandle(ol.hEvent);
6553 if (written == len) {
6554 buf = (
const char *)buf + len;
6570 DWORD dwMode, reslen;
6574 const WCHAR *
ptr, *next;
6578 if (disable)
return -1L;
6580 if (!GetConsoleMode(handle, &dwMode))
6598 if (!ptr)
return -1L;
6606 long curlen =
constat_parse(handle, s, (next = ptr, &next), &len);
6608 if (!WriteConsoleW(handle, ptr, curlen, &reslen,
NULL)) {
6609 if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
6611 reslen = (
DWORD)-1L;
6618 if (wbuffer)
free(wbuffer);
6619 return (
long)reslen;
6628 tmp.QuadPart = ((LONG_LONG)time + (LONG_LONG)((1970-1601)*365.2425) * 24 * 60 * 60) * 10 * 1000 * 1000;
6629 ft->dwLowDateTime = tmp.LowPart;
6630 ft->dwHighDateTime = tmp.HighPart;
6639 FILETIME atime,
mtime;
6640 struct stati64 stat;
6656 GetSystemTimeAsFileTime(&atime);
6661 const DWORD attr = GetFileAttributesW(path);
6662 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))
6663 SetFileAttributesW(path, attr & ~FILE_ATTRIBUTE_READONLY);
6664 hFile = CreateFileW(path, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
6665 FILE_FLAG_BACKUP_SEMANTICS, 0);
6666 if (hFile == INVALID_HANDLE_VALUE) {
6671 if (!SetFileTime(hFile,
NULL, &atime, &mtime)) {
6677 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY))
6678 SetFileAttributesW(path, attr);
6693 ret =
wutime(wpath, times);
6707 ret =
wutime(wpath, times);
6721 ret = _wchdir(wpath);
6733 if (CreateDirectoryW(wpath,
NULL) ==
FALSE) {
6737 if (_wchmod(wpath, mode) == -1) {
6738 RemoveDirectoryW(wpath);
6755 ret =
wmkdir(wpath, mode);
6769 ret =
wmkdir(wpath, mode);
6780 const DWORD attr = GetFileAttributesW(wpath);
6781 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6782 SetFileAttributesW(wpath, attr & ~FILE_ATTRIBUTE_READONLY);
6784 if (RemoveDirectoryW(wpath) ==
FALSE) {
6787 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6788 SetFileAttributesW(wpath, attr);
6829 const DWORD attr = GetFileAttributesW(path);
6830 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6831 SetFileAttributesW(path, attr & ~FILE_ATTRIBUTE_READONLY);
6833 if (!DeleteFileW(path)) {
6836 if (attr != (
DWORD)-1 && (attr & FILE_ATTRIBUTE_READONLY)) {
6837 SetFileAttributesW(path, attr);
6881 ret = _wchmod(wpath, mode);
6886 #if !defined(__BORLANDC__)
6894 if (_get_osfhandle(fd) == -1) {
6897 if (!GetConsoleMode((HANDLE)
_osfhnd(fd), &mode)) {
6912 too_many_files(
void)
6915 for (f = _streams; f < _streams + _nfile; f++) {
6916 if (f->fd < 0)
return 0;
6924 rb_w32_fopen(
const char *
path,
const char *
mode)
6926 FILE *f = (
errno = 0, fopen(path, mode));
6928 if (too_many_files())
6936 rb_w32_fdopen(
int handle,
const char *
type)
6938 FILE *f = (
errno = 0, _fdopen(handle, (
char *)type));
6942 else if (too_many_files())
6950 rb_w32_fsopen(
const char *path,
const char *mode,
int shflags)
6952 FILE *f = (
errno = 0, _fsopen(path, mode, shflags));
6954 if (too_many_files())
6961 #if defined(_MSC_VER) && RUBY_MSVCRT_VERSION <= 60
6962 extern long _ftol(
double);
6972 _ftol2_sse(
double d)
6983 int *
ip = (
int *)(&x + 1) - 1;
6992 typedef char *(WSAAPI inet_ntop_t)(
int,
void *,
char *,
size_t);
6993 inet_ntop_t *pInetNtop;
6996 return pInetNtop(af, (
void *)addr, numaddr, numaddr_len);
7000 memcpy(&in.s_addr, addr,
sizeof(in.s_addr));
7001 snprintf(numaddr, numaddr_len,
"%s", inet_ntoa(in));
7010 typedef int (WSAAPI inet_pton_t)(
int,
const char*,
void *);
7011 inet_pton_t *pInetPton;
7014 return pInetPton(af, src, dst);
7026 #if RUBY_MSVCRT_VERSION < 80 && !defined(HAVE__GMTIME64_S)
7033 if (!FileTimeToSystemTime(&ft, st))
return -1;
7041 int y = st->wYear,
m = st->wMonth,
d = st->wDay;
7042 t->tm_sec = st->wSecond;
7043 t->tm_min = st->wMinute;
7044 t->tm_hour = st->wHour;
7045 t->tm_mday = st->wDay;
7046 t->tm_mon = st->wMonth - 1;
7047 t->tm_year = y - 1900;
7048 t->tm_wday = st->wDayOfWeek;
7056 d += 31 + 28 + (!(y % 4) && ((y % 100) || !(y % 400)));
7057 d += ((
m - 3) * 153 + 2) / 5;
7067 TIME_ZONE_INFORMATION stdtz;
7070 if (!SystemTimeToTzSpecificLocalTime(tz, gst, lst))
return -1;
7072 GetTimeZoneInformation(&stdtz);
7075 if (tz->StandardBias == tz->DaylightBias)
return 0;
7076 if (!tz->StandardDate.wMonth)
return 0;
7077 if (!tz->DaylightDate.wMonth)
return 0;
7078 if (tz != &stdtz) stdtz = *tz;
7080 stdtz.StandardDate.wMonth = stdtz.DaylightDate.wMonth = 0;
7081 if (!SystemTimeToTzSpecificLocalTime(&stdtz, gst, &sst))
return 0;
7082 if (lst->wMinute == sst.wMinute && lst->wHour == sst.wHour)
7088 #ifdef HAVE__GMTIME64_S
7089 # ifndef HAVE__LOCALTIME64_S
7091 # define HAVE__LOCALTIME64_S 1
7093 # ifndef MINGW_HAS_SECURE_API
7094 _CRTIMP errno_t __cdecl _gmtime64_s(
struct tm* tm,
const __time64_t *
time);
7095 _CRTIMP errno_t __cdecl _localtime64_s(
struct tm* tm,
const __time64_t *
time);
7097 # define gmtime_s _gmtime64_s
7098 # define localtime_s _localtime64_s
7111 #if RUBY_MSVCRT_VERSION >= 80 || defined(HAVE__GMTIME64_S)
7112 e = gmtime_s(rp, tp);
7113 if (e != 0)
goto error;
7135 #if RUBY_MSVCRT_VERSION >= 80 || defined(HAVE__LOCALTIME64_S)
7136 e = localtime_s(rp, tp);
7140 SYSTEMTIME gst, lst;
7155 int r = getsockopt((SOCKET)h, SOL_SOCKET, SO_DEBUG, (
char *)&tmp, &len);
7156 if (r != SOCKET_ERROR || WSAGetLastError() != WSAENOTSOCK) {
7159 flags &= ~O_NONBLOCK;
7187 #if !defined(__MINGW64__) && defined(__MINGW64_VERSION_MAJOR)
7193 rb_w32_pow(
double x,
double y)
7197 unsigned int default_control = _controlfp(0, 0);
7198 _controlfp(_PC_64, _MCW_PC);
7201 _controlfp(default_control, _MCW_PC);
static const char * NTLoginName
void setnetent(int stayopen)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
RUBY_EXTERN int flock(int, int)
static void regulate_path(WCHAR *path)
static int free_conlist(st_data_t key, st_data_t val, st_data_t arg)
static rb_pid_t w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UINT cp)
static DWORD get_volume_serial_number(const WCHAR *path)
static struct ChildRecord * FindFreeChildSlot(void)
char * rb_w32_wstr_to_mbstr(UINT, const WCHAR *, int, long *)
static time_t filetime_to_unixtime(const FILETIME *ft)
static char * skipspace(char *ptr)
char * rb_w32_ugetenv(const char *)
int gettimeofday(struct timeval *, struct timezone *)
static struct @194 errmap[]
int rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
static void init_stdhandle(void)
size_t strlen(const char *)
#define rb_w32_stati64(path, st)
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
#define CSIDL_LOCAL_APPDATA
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)
DWORD(WINAPI * cilnA_t)(const NET_LUID *, char *, size_t)
rb_pid_t rb_w32_getppid(void)
static int max(int a, int b)
int st_lookup(st_table *, st_data_t, st_data_t *)
static void StartSockets(void)
ssize_t rb_w32_write(int, const void *, size_t)
static FARPROC get_wsa_extension_function(SOCKET s, GUID *guid)
int rb_w32_fstat(int, struct stat *)
#define access(path, mode)
static void init_func(void)
int sendmsg(int, const struct msghdr *, int)
int WSAAPI rb_w32_connect(int, const struct sockaddr *, int)
static ioinfo * _pioinfo(int)
static void catch_interrupt(void)
int WSAAPI rb_w32_bind(int, const struct sockaddr *, int)
static void get_version(void)
int WSAAPI rb_w32_sendto(int, const char *, int, int, const struct sockaddr *, int)
st_table * st_init_numtable(void)
static struct direct * readdir_internal(DIR *dirp, BOOL(*conv)(const WCHAR *, struct direct *, rb_encoding *), rb_encoding *enc)
static int Tcl_Interp * interp
static int compare(const struct timeval *t1, const struct timeval *t2)
SSL_METHOD *(* func)(void)
static rb_pid_t poll_child_status(struct ChildRecord *child, int *stat_loc)
static int NtSocketsInitialized
RUBY_EXTERN int signbit(double x)
RUBY_EXTERN void * memmove(void *, const void *, size_t)
int rb_w32_dup2(int, int)
int rb_w32_ustati64(const char *, struct stati64 *)
int rb_w32_wrap_io_handle(HANDLE, int)
static unsigned fileattr_to_unixmode(DWORD attr, const WCHAR *path)
static void constat_apply(HANDLE handle, struct constat *s, WCHAR w)
SOCKET rb_w32_get_osfhandle(int)
static st_table * socklist
int rb_w32_umkdir(const char *, int)
static int is_batch(const char *cmd)
#define INVALID_SET_FILE_POINTER
ssize_t rb_w32_read(int, void *, size_t)
rb_pid_t rb_w32_aspawn_flags(int, const char *, char *const *, DWORD)
DIR * rb_w32_uopendir(const char *)
static struct tm * localtime_r(const time_t *t, struct tm *tm)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
rb_pid_t rb_w32_uaspawn_flags(int, const char *, char *const *, DWORD)
int WSAAPI rb_w32_getsockopt(int, int, int, char *, int *)
static int extract_fd(rb_fdset_t *dst, fd_set *src, int(*func)(SOCKET))
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)
int rb_w32_urename(const char *, const char *)
static int check_if_dir(const char *file)
static int is_invalid_handle(SOCKET sock)
static WCHAR * translate_wchar(WCHAR *p, int from, int to)
#define STRNDUPV(ptr, v, src, len)
DIR * rb_w32_opendir(const char *)
int rb_w32_fdisset(int, fd_set *)
static void exit_handler(void)
struct servent *WSAAPI rb_w32_getservbyname(const char *, const char *)
struct _NtCmdLineElement * next
int rb_w32_open(const char *, int,...)
int WSAAPI rb_w32_select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
void rb_w32_free_environ(char **)
int WSAAPI rb_w32_accept(int, struct sockaddr *, int *)
long rb_w32_telldir(DIR *)
struct sockaddr * ifa_addr
struct protoent *WSAAPI rb_w32_getprotobynumber(int)
rb_pid_t rb_w32_getpid(void)
#define msghdr_to_wsamsg(msg, wsamsg)
int rb_w32_uaccess(const char *, int)
int rb_w32_map_errno(DWORD)
struct protoent * getprotoent(void)
static FARPROC get_proc_address(const char *module, const char *func, HANDLE *mh)
int recvmsg(int, struct msghdr *, int)
int rb_econv_has_convpath_p(const char *from_encoding, const char *to_encoding)
static int socklist_insert(SOCKET sock, int flag)
char * rb_w32_conv_from_wstr(const WCHAR *wstr, long *lenp, rb_encoding *enc)
static struct tm * gmtime_r(const time_t *t, struct tm *tm)
#define filecp_to_wstr(str, plen)
void freeifaddrs(struct ifaddrs *)
void rb_w32_fdclr(int, fd_set *)
static SOCKET open_ifs_socket(int af, int type, int protocol)
int rb_w32_times(struct tms *)
int WSAAPI rb_w32_socket(int, int, int)
#define ENCODING_GET(obj)
int rb_w32_is_socket(int)
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
static BOOL ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
int rb_w32_cmdvector(const char *, char ***)
int WSAAPI rb_w32_getsockname(int, struct sockaddr *, int *)
#define RUBY_CRITICAL(expr)
static uintptr_t flock_winnt(uintptr_t self, int argc, uintptr_t *argv)
#define MEMZERO(p, type, n)
const char *WSAAPI rb_w32_inet_ntop(int, const void *, char *, size_t)
static BOOL win32_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *dummy)
int st_delete(st_table *, st_data_t *, st_data_t *)
struct hostent *WSAAPI rb_w32_gethostbyaddr(const char *, int, int)
void * ruby_xcalloc(size_t n, size_t size)
RUBY_EXTERN size_t strlcat(char *, const char *, size_t)
static int internal_cmd_match(const char *cmdname, int nt)
#define wstr_to_utf8(str, plen)
#define STATIC_ASSERT(name, expr)
struct hostent *WSAAPI rb_w32_gethostbyname(const char *)
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
int getifaddrs(struct ifaddrs **)
unsigned long long uint64_t
VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
int rb_w32_wopen(const WCHAR *, int,...)
BOOL(WINAPI * cancel_io_t)(HANDLE)
struct ifaddrs * ifa_next
static int is_pipe(SOCKET sock)
uintptr_t(* asynchronous_func_t)(uintptr_t self, int argc, uintptr_t *argv)
#define END_FOREACH_CHILD
int WSAAPI rb_w32_send(int, const char *, int, int)
#define wstr_to_filecp(str, plen)
rb_pid_t rb_w32_spawn(int, const char *, const char *)
static void Tcl_Interp * ip
static rb_pid_t w32_spawn(int mode, const char *cmd, const char *prog, UINT cp)
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 WSAAPI rb_w32_recvfrom(int, char *, int, int, struct sockaddr *, int *)
static char * w32_getenv(const char *name, UINT cp)
#define IOINFO_ARRAY_ELTS
void rb_w32_fd_copy(rb_fdset_t *dst, const fd_set *src, int max)
int chown(const char *, int, int)
struct netent * getnetbyname(const char *name)
int WSAAPI rb_w32_listen(int, int)
static int wutime(const WCHAR *path, const struct utimbuf *times)
static HANDLE open_dir_handle(const WCHAR *filename, WIN32_FIND_DATAW *fd)
int rb_w32_sleep(unsigned long msec)
UINT rb_w32_system_tmpdir(WCHAR *path, UINT len)
DWORD(WINAPI * cigl_t)(const GUID *, NET_LUID *)
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_mkdir(const char *, int)
unsigned char buf[MIME_BUF_SIZE]
struct direct * rb_w32_readdir(DIR *, rb_encoding *)
sprintf(psz,"E%"PRIdSIZE, ex)
int rb_w32_uutime(const char *, const struct utimbuf *)
static int socklist_lookup(SOCKET sock, int *flagp)
int rb_w32_rmdir(const char *)
uintptr_t(* func)(uintptr_t self, int argc, uintptr_t *argv)
int link(const char *, const char *)
void sethostent(int stayopen)
struct servent * getservent(void)
static int check_spawn_mode(int mode)
static cancel_io_t cancel_io
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
int rb_w32_unwrap_io_handle(int)
static cilnA_t pConvertInterfaceLuidToNameA
static void init_env(void)
static int filetime_to_timeval(const FILETIME *ft, struct timeval *tv)
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
static int is_not_socket(SOCKET sock)
int rb_w32_putc(int, FILE *)
int rb_w32_fstati64(int, struct stati64 *)
int rb_w32_time_subtract(struct timeval *rest, const struct timeval *wait)
int rb_w32_unlink(const char *)
static int do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout)
static const char *const szInternalCmds[]
static int w32_stati64(const char *path, struct stati64 *st, UINT cp)
VALUE rb_sprintf(const char *format,...)
int rb_w32_truncate(const char *path, off_t length)
void setservent(int stayopen)
static long constat_parse(HANDLE h, struct constat *s, const WCHAR **ptrp, long *lenp)
static int has_redirection(const char *, UINT)
void rb_w32_sysinit(int *argc, char ***argv)
void rb_fatal(const char *fmt,...)
static struct ChildRecord * FindChildSlot(rb_pid_t pid)
static cigl_t pConvertInterfaceGuidToLuid
static char * translate_char(char *p, int from, int to, UINT cp)
static int console_emulator_p(void)
static int finish_overlapped_socket(BOOL input, SOCKET s, WSAOVERLAPPED *wol, int result, DWORD *len, DWORD size)
static CRITICAL_SECTION select_mutex
int rb_w32_urmdir(const char *)
struct netent * getnetent(void)
void setprotoent(int stayopen)
static int unixtime_to_systemtime(const time_t t, SYSTEMTIME *st)
char ** rb_w32_get_environ(void)
static int rb_chsize(HANDLE h, off_t size)
static int min(int a, int b)
static int join_argv(char *cmd, char *const *argv, BOOL escape, UINT cp, int backslash)
int rb_w32_uopen(const char *, int,...)
static int unixtime_to_filetime(time_t time, FILETIME *ft)
int rb_w32_uchmod(const char *, int)
char * rb_w32_getenv(const char *)
void rb_w32_closedir(DIR *)
rb_pid_t rb_w32_uaspawn(int, const char *, char *const *)
char * strchr(char *, char)
struct protoent *WSAAPI rb_w32_getprotobyname(const char *)
#define utf8_to_wstr(str, plen)
int clock_gettime(clockid_t, struct timespec *)
static int insert(const char *path, VALUE vinfo, void *enc)
static int isUNCRoot(const WCHAR *path)
static rb_pid_t child_result(struct ChildRecord *child, int mode)
int WSAAPI rb_w32_setsockopt(int, int, int, const char *, int)
static int internal_match(const void *key, const void *elem)
static UINT get_system_directory(WCHAR *path, UINT len)
static int is_internal_cmd(const char *cmd, int nt)
int rb_w32_access(const char *, int)
RUBY_EXTERN char * strerror(int)
static int different_device_p(const WCHAR *oldpath, const WCHAR *newpath)
rb_pid_t rb_w32_aspawn(int, const char *, char *const *)
void rb_write_error2(const char *, long)
void * ruby_xmalloc(size_t size)
static void constat_delete(HANDLE h)
VALUE rb_str_cat(VALUE, const char *, long)
#define ECONV_INVALID_REPLACE
int rb_w32_uchdir(const char *)
int rb_w32_ulink(const char *, const char *)
static int wstati64(const WCHAR *path, struct stati64 *st)
static struct ChildRecord * FindChildSlotByHandle(HANDLE h)
static NtCmdLineElement ** cmdglob(NtCmdLineElement *patt, NtCmdLineElement **tail)
static DIR * opendir_internal(WCHAR *wpath, const char *filename)
#define set_new_std_fd(newfd)
static int wlink(const WCHAR *from, const WCHAR *to)
static WORD constat_attr(int count, const int *seq, WORD attr, WORD default_attr)
VALUE rb_w32_special_folder(int type)
static int socklist_delete(SOCKET *sockp, int *flagp)
static DWORD WINAPI call_asynchronous(PVOID argp)
static int wrmdir(const WCHAR *wpath)
void rb_w32_rewinddir(DIR *)
static struct constat * constat_handle(HANDLE h)
long rb_w32_write_console(uintptr_t, int)
#define _set_osfhnd(fh, osfh)
static int systemtime_to_localtime(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *gst, SYSTEMTIME *lst)
char * rb_w32_strerror(int)
int clock_getres(clockid_t, struct timespec *)
static int is_console(SOCKET)
static int is_readable_pipe(SOCKET sock)
static void str2guid(const char *str, GUID *guid)
int WSAAPI rb_w32_ioctlsocket(int, long, u_long *)
VALUE rb_str_vcatf(VALUE, const char *, va_list)
rb_encoding * rb_filesystem_encoding(void)
struct _NtCmdLineElement NtCmdLineElement
struct servent *WSAAPI rb_w32_getservbyport(int, const char *)
int WSAAPI rb_w32_gethostname(char *, int)
RUBY_EXTERN int dup2(int, int)
int ruby_brace_glob(const char *str, int flags, ruby_glob_func *func, VALUE arg)
int st_insert(st_table *, st_data_t, st_data_t)
#define set_env_val(vname)
WCHAR * rb_w32_mbstr_to_wstr(UINT, const char *, int, long *)
static int check_if_wdir(const WCHAR *wfile)
int rb_w32_ftruncate(int fd, off_t length)
void rb_w32_fdset(int, fd_set *)
static int setfl(SOCKET sock, int arg)
int WSAAPI rb_w32_shutdown(int, int)
int WSAAPI rb_w32_inet_pton(int, const char *, void *)
static int wrename(const WCHAR *oldpath, const WCHAR *newpath)
static int dupfd(HANDLE hDup, char flags, int minfd)
#define COMMON_LVB_UNDERSCORE
int WSAAPI rb_w32_getpeername(int, struct sockaddr *, int *)
char * rb_w32_getcwd(char *, int)
static void move_to_next_entry(DIR *dirp)
static void systemtime_to_tm(const SYSTEMTIME *st, struct tm *t)
rb_encoding * rb_ascii8bit_encoding(void)
struct constat::@196 vt100
#define yield_until(condition)
int rb_w32_fclose(FILE *)
static int setup_overlapped(OVERLAPPED *ol, int fd, int iswrite)
static int overlapped_socket_io(BOOL input, int fd, char *buf, int len, int flags, struct sockaddr *addr, int *addrlen)
static void version(void)
void rb_w32_seekdir(DIR *, long)
struct netent * getnetbyaddr(long net, int type)
static struct ChildRecord * CreateChild(const WCHAR *, const WCHAR *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE, DWORD)
expr expr keyword_or expr
int socketpair(int, int, int, int *)
char rb_w32_fd_is_text(int)
static int socketpair_internal(int af, int type, int protocol, SOCKET *sv)
static void finish_overlapped(OVERLAPPED *ol, int fd, DWORD size)
static OSVERSIONINFO osver
rb_pid_t rb_w32_uspawn(int, const char *, const char *)
#define ECONV_UNDEF_REPLACE
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags)
static int is_readable_console(SOCKET sock)
#define ENC_TO_ENCINDEX(enc)
int WSAAPI rb_w32_recv(int, char *, int, int)
static BOOL get_special_folder(int n, WCHAR *env)
int rb_w32_io_cancelable_p(int)
static int eq(VALUE x, VALUE y)
static ULONG(STDMETHODCALLTYPE AddRef)(IDispatch __RPC_FAR *This)
uintptr_t rb_w32_asynchronize(asynchronous_func_t func, uintptr_t self, int argc, uintptr_t *argv, uintptr_t intrval)
int rb_w32_check_interrupt(void *)
#define ALLOCV_N(type, v, n)
int select(int num_fds, fd_set *in_fds, fd_set *out_fds, fd_set *ex_fds, struct timeval *timeout)
int rb_w32_uunlink(const char *)
int rb_w32_stat(const char *, struct stat *)
void st_free_table(st_table *)
int rb_w32_utime(const char *, const struct utimbuf *)
rb_pid_t waitpid(rb_pid_t, int *, int)
static int check_valid_dir(const WCHAR *path)
int rb_w32_uchown(const char *, int, int)
static st_table * conlist
int rb_w32_rename(const char *, const char *)
STATIC void unsigned char * cp
#define _set_osflags(fh, flags)
rb_encoding * rb_enc_from_index(int index)
static void constat_reset(HANDLE h)
static int wunlink(const WCHAR *path)