static void s_gettime(INT typeno, struct timespec *tp) { switch (typeno) { case time_thread: #ifdef CLOCK_THREAD_CPUTIME_ID if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, tp) == 0) return; #endif /* fall through to utc case in case no thread timer */ case time_process: #ifdef CLOCK_PROCESS_CPUTIME_ID if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, tp) == 0) return; #endif /* fall back on getrusage if clock_gettime fails */ { struct rusage rbuf; if (getrusage(RUSAGE_SELF,&rbuf) != 0) S_error1("s_gettime", "failed: ~s", S_strerror(errno)); tp->tv_sec = rbuf.ru_utime.tv_sec + rbuf.ru_stime.tv_sec; tp->tv_nsec = (rbuf.ru_utime.tv_usec + rbuf.ru_stime.tv_usec) * 1000; if (tp->tv_nsec >= 1000000000) { tp->tv_sec += 1; tp->tv_nsec -= 1000000000; } return; } case time_duration: case time_monotonic: #ifdef CLOCK_MONOTONIC_HR if (clock_gettime(CLOCK_MONOTONIC_HR, tp) == 0) return; #endif #ifdef CLOCK_MONOTONIC if (clock_gettime(CLOCK_MONOTONIC, tp) == 0) return; #endif #ifdef CLOCK_HIGHRES if (clock_gettime(CLOCK_HIGHRES, tp) == 0) return; #endif /* fall through to utc case in case no monotonic timer */ case time_utc: #ifdef CLOCK_REALTIME_HR if (clock_gettime(CLOCK_REALTIME_HR, tp) == 0) return; #endif #ifdef CLOCK_REALTIME if (clock_gettime(CLOCK_REALTIME, tp) == 0) return; #endif /* fall back on gettimeofday if clock_gettime fails */ { struct timeval tvtp; if (gettimeofday(&tvtp,NULL) != 0) S_error1("s_gettime", "failed: ~s", S_strerror(errno)); tp->tv_sec = (time_t)tvtp.tv_sec; tp->tv_nsec = (long)(tvtp.tv_usec * 1000); return; } default: S_error1("s_gettime", "unexpected typeno ~s", Sinteger(typeno)); break; } }
oops, no S_flushcache_max_gap or S_doflush #endif /* FLUSHCACHE */ static void SplitRegistryKey(char *who, wchar_t *wholekey, HKEY *key, wchar_t **subkey, wchar_t **last) { wchar_t c, *s; /* Determine the base key */ if (_wcsnicmp(wholekey, L"HKEY_CLASSES_ROOT\\", 18) == 0) { *key = HKEY_CLASSES_ROOT; *subkey = wholekey+18; } else if (_wcsnicmp(wholekey, L"HKEY_CURRENT_USER\\", 18) == 0) { *key = HKEY_CURRENT_USER; *subkey = wholekey+18; } else if (_wcsnicmp(wholekey, L"HKEY_LOCAL_MACHINE\\", 19) == 0) { *key = HKEY_LOCAL_MACHINE; *subkey = wholekey+19; } else if (_wcsnicmp(wholekey, L"HKEY_USERS\\", 11) == 0) { *key = HKEY_USERS; *subkey = wholekey+11; } else if (_wcsnicmp(wholekey, L"HKEY_CURRENT_CONFIG\\", 20) == 0) { *key = HKEY_CURRENT_CONFIG; *subkey = wholekey+20; } else if (_wcsnicmp(wholekey, L"HKEY_DYN_DATA\\", 14) == 0) { *key = HKEY_DYN_DATA; *subkey = wholekey+14; } else { char *wholekey_utf8 = Swide_to_utf8(wholekey); ptr wholekey_scheme = Sstring_utf8(wholekey_utf8, -1); free(wholekey_utf8); S_error1(who, "invalid registry key ~s", wholekey_scheme); } for (*last = s = *subkey, c = *s; c != '\0'; c = *++s) if (c == '\\') *last = s; }
int S_windows_open_exclusive(char *who, char *path, int flags) { HANDLE hfile; int fd; DWORD access = 0; DWORD crdisp = 0; /* could implement this later with more difficulty */ if ((flags & (O_TRUNC|O_CREAT)) == (O_TRUNC|O_CREAT)) S_error("open_exclusive", "O_TRUNC|O_CREAT not supported"); if (flags & O_RDWR) access |= GENERIC_READ|GENERIC_WRITE; if (flags & O_RDONLY) access |= GENERIC_READ; if (flags & O_WRONLY) access |= GENERIC_WRITE; if (flags & O_CREAT) crdisp = OPEN_ALWAYS; if (flags & O_TRUNC) crdisp = TRUNCATE_EXISTING; hfile = CreateFile(path, access, 0, (SECURITY_ATTRIBUTES *)0, crdisp, FILE_ATTRIBUTE_NORMAL, (HANDLE)0); if (hfile == INVALID_HANDLE_VALUE) S_error1(who, "~a", s_ErrorString(GetLastError())); flags &= O_RDONLY|O_WRONLY|O_RDWR|O_APPEND; fd = _open_osfhandle((long)hfile, flags); if (fd == -1) S_error(who, "open_osfhandle failed"); return fd; }
/* Warning: may return pointer to static string */ const char *S_pathname(const char *who, const char *inpath, IBOOL errorp, char *buffer) { const char *path = S_pathname_impl(inpath, buffer); if (path != NULL) return path; if (errorp) S_error1(who, "unable to expand path name ~s", Sstring(inpath)); return inpath; }
static IUnknown *s_CreateInstance(CLSID *pCLSID, IID *iid) { IUnknown *pIface; HRESULT hr; hr = CoCreateInstance(pCLSID, NULL, CLSCTX_INPROC_SERVER, iid, (void **)&pIface); if (SUCCEEDED(hr)) { return (IUnknown *)pIface; } else { S_error1("", "unable to create instance: ~s", s_ErrorString(hr)); return (IUnknown *)0 /* not reached */; } }
static void s_gettime(INT typeno, struct timespec *tp) { switch (typeno) { case time_process: { FILETIME ftKernel, ftUser, ftDummy; if (GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser)) { __int64 kernel, user, total; kernel = ftKernel.dwHighDateTime; kernel <<= 32; kernel |= ftKernel.dwLowDateTime; user = ftUser.dwHighDateTime; user <<= 32; user |= ftUser.dwLowDateTime; total = user + kernel; tp->tv_sec = (time_t)(total / 10000000); tp->tv_nsec = (long)((total % 10000000) * 100); break; } else { clock_t n = clock();; /* if GetProcessTimes fails, we're probably running Windows 95 */ tp->tv_sec = (time_t)(n / CLOCKS_PER_SEC); tp->tv_nsec = (long)((n % CLOCKS_PER_SEC) * (1000000000 / CLOCKS_PER_SEC)); break; } } case time_thread: { FILETIME ftKernel, ftUser, ftDummy; if (GetThreadTimes(GetCurrentThread(), &ftDummy, &ftDummy, &ftKernel, &ftUser)) { __int64 kernel, user, total; kernel = ftKernel.dwHighDateTime; kernel <<= 32; kernel |= ftKernel.dwLowDateTime; user = ftUser.dwHighDateTime; user <<= 32; user |= ftUser.dwLowDateTime; total = user + kernel; tp->tv_sec = (time_t)(total / 10000000); tp->tv_nsec = (long)((total % 10000000) * 100); break; } else { clock_t n = clock();; /* if GetThreadTimes fails, we're probably running Windows 95 */ tp->tv_sec = (time_t)(n / CLOCKS_PER_SEC); tp->tv_nsec = (long)((n % CLOCKS_PER_SEC) * (1000000000 / CLOCKS_PER_SEC)); break; } } case time_duration: case time_monotonic: { LARGE_INTEGER count; if (hires_cps == 0 && QueryPerformanceFrequency(&count)) hires_cps = count.QuadPart; if (hires_cps && QueryPerformanceCounter(&count)) { tp->tv_sec = (time_t)(count.QuadPart / hires_cps); tp->tv_nsec = (long)((count.QuadPart % hires_cps) * (1000000000 / hires_cps)); break; } else { DWORD count = GetTickCount(); tp->tv_sec = (time_t)(count / 1000); tp->tv_nsec = (long)((count % 1000) * 1000000); break; } } case time_utc: { FILETIME ft; __int64 total; GetSystemTimeAsFileTime(&ft); total = ft.dwHighDateTime; total <<= 32; total |= ft.dwLowDateTime; /* measurement interval is 100 nanoseconds = 1/10 microseconds */ /* adjust by number of seconds between Windows (1601) and Unix (1970) epochs */ tp->tv_sec = (time_t)(total / 10000000 - 11644473600L); tp->tv_nsec = (long)((total % 10000000) * 100); break; } default: S_error1("s_gettime", "unexpected typeno ~s", Sinteger(typeno)); break; } }