diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/lazyload.h | 43 | ||||
-rw-r--r-- | win32/mingw.c | 18 | ||||
-rw-r--r-- | win32/process.c | 47 |
3 files changed, 106 insertions, 2 deletions
diff --git a/win32/lazyload.h b/win32/lazyload.h new file mode 100644 index 000000000..9d1a05550 --- /dev/null +++ b/win32/lazyload.h | |||
@@ -0,0 +1,43 @@ | |||
1 | #ifndef LAZYLOAD_H | ||
2 | #define LAZYLOAD_H | ||
3 | |||
4 | /* simplify loading of DLL functions */ | ||
5 | |||
6 | struct proc_addr { | ||
7 | const char *const dll; | ||
8 | const char *const function; | ||
9 | FARPROC pfunction; | ||
10 | unsigned initialized : 1; | ||
11 | }; | ||
12 | |||
13 | /* Declares a function to be loaded dynamically from a DLL. */ | ||
14 | #define DECLARE_PROC_ADDR(dll, rettype, function, ...) \ | ||
15 | static struct proc_addr proc_addr_##function = \ | ||
16 | { #dll, #function, NULL, 0 }; \ | ||
17 | static rettype (WINAPI *function)(__VA_ARGS__) | ||
18 | |||
19 | /* | ||
20 | * Loads a function from a DLL (once-only). | ||
21 | * Returns non-NULL function pointer on success. | ||
22 | * Returns NULL + errno == ENOSYS on failure. | ||
23 | */ | ||
24 | #define INIT_PROC_ADDR(function) (function = get_proc_addr(&proc_addr_##function)) | ||
25 | |||
26 | static inline void *get_proc_addr(struct proc_addr *proc) | ||
27 | { | ||
28 | /* only do this once */ | ||
29 | if (!proc->initialized) { | ||
30 | HANDLE hnd; | ||
31 | proc->initialized = 1; | ||
32 | hnd = LoadLibraryExA(proc->dll, NULL, | ||
33 | LOAD_LIBRARY_SEARCH_SYSTEM32); | ||
34 | if (hnd) | ||
35 | proc->pfunction = GetProcAddress(hnd, proc->function); | ||
36 | } | ||
37 | /* set ENOSYS if DLL or function was not found */ | ||
38 | if (!proc->pfunction) | ||
39 | errno = ENOSYS; | ||
40 | return proc->pfunction; | ||
41 | } | ||
42 | |||
43 | #endif | ||
diff --git a/win32/mingw.c b/win32/mingw.c index 7f37eadda..afcb6c6d2 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -707,7 +707,7 @@ int getlogin_r(char *buf, size_t len) | |||
707 | long sysconf(int name) | 707 | long sysconf(int name) |
708 | { | 708 | { |
709 | if ( name == _SC_CLK_TCK ) { | 709 | if ( name == _SC_CLK_TCK ) { |
710 | return 100; | 710 | return TICKS_PER_SECOND; |
711 | } | 711 | } |
712 | errno = EINVAL; | 712 | errno = EINVAL; |
713 | return -1; | 713 | return -1; |
@@ -1064,3 +1064,19 @@ off_t mingw_lseek(int fd, off_t offset, int whence) | |||
1064 | } | 1064 | } |
1065 | return _lseeki64(fd, offset, whence); | 1065 | return _lseeki64(fd, offset, whence); |
1066 | } | 1066 | } |
1067 | |||
1068 | #if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG | ||
1069 | #undef GetTickCount64 | ||
1070 | #include "lazyload.h" | ||
1071 | |||
1072 | ULONGLONG CompatGetTickCount64(void) | ||
1073 | { | ||
1074 | DECLARE_PROC_ADDR(kernel32.dll, ULONGLONG, GetTickCount64, void); | ||
1075 | |||
1076 | if (!INIT_PROC_ADDR(GetTickCount64)) { | ||
1077 | return (ULONGLONG)GetTickCount(); | ||
1078 | } | ||
1079 | |||
1080 | return GetTickCount64(); | ||
1081 | } | ||
1082 | #endif | ||
diff --git a/win32/process.c b/win32/process.c index c0ff78105..f88a4898c 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -334,8 +334,18 @@ mingw_execv(const char *cmd, char *const *argv) | |||
334 | return mingw_execve(cmd, argv, environ); | 334 | return mingw_execve(cmd, argv, environ); |
335 | } | 335 | } |
336 | 336 | ||
337 | static inline long long filetime_to_ticks(const FILETIME *ft) | ||
338 | { | ||
339 | return (((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime)/ | ||
340 | HNSEC_PER_TICK; | ||
341 | } | ||
342 | |||
337 | /* POSIX version in libbb/procps.c */ | 343 | /* POSIX version in libbb/procps.c */ |
338 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags UNUSED_PARAM) | 344 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags |
345 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG | ||
346 | UNUSED_PARAM | ||
347 | #endif | ||
348 | ) | ||
339 | { | 349 | { |
340 | PROCESSENTRY32 pe; | 350 | PROCESSENTRY32 pe; |
341 | 351 | ||
@@ -361,6 +371,41 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags UNUSED_PAR | |||
361 | } | 371 | } |
362 | } | 372 | } |
363 | 373 | ||
374 | #if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG | ||
375 | if (flags & (PSSCAN_STIME|PSSCAN_UTIME|PSSCAN_START_TIME)) { | ||
376 | HANDLE proc; | ||
377 | FILETIME crTime, exTime, keTime, usTime; | ||
378 | |||
379 | if ((proc=OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, | ||
380 | FALSE, pe.th32ProcessID))) { | ||
381 | if (GetProcessTimes(proc, &crTime, &exTime, &keTime, &usTime)) { | ||
382 | /* times in ticks since 1 January 1601 */ | ||
383 | static long long boot_time = 0; | ||
384 | long long start_time; | ||
385 | |||
386 | if (boot_time == 0) { | ||
387 | long long ticks_since_boot; | ||
388 | FILETIME now; | ||
389 | |||
390 | ticks_since_boot = GetTickCount64()/MS_PER_TICK; | ||
391 | GetSystemTimeAsFileTime(&now); | ||
392 | boot_time = filetime_to_ticks(&now) - ticks_since_boot; | ||
393 | } | ||
394 | |||
395 | start_time = filetime_to_ticks(&crTime); | ||
396 | sp->start_time = (unsigned long)(start_time - boot_time); | ||
397 | |||
398 | sp->stime = (unsigned long)filetime_to_ticks(&keTime); | ||
399 | sp->utime = (unsigned long)filetime_to_ticks(&usTime); | ||
400 | } | ||
401 | else { | ||
402 | sp->start_time = sp->stime = sp->utime = 0; | ||
403 | } | ||
404 | CloseHandle(proc); | ||
405 | } | ||
406 | } | ||
407 | #endif | ||
408 | |||
364 | sp->pid = pe.th32ProcessID; | 409 | sp->pid = pe.th32ProcessID; |
365 | sp->ppid = pe.th32ParentProcessID; | 410 | sp->ppid = pe.th32ParentProcessID; |
366 | safe_strncpy(sp->comm, pe.szExeFile, COMM_LEN); | 411 | safe_strncpy(sp->comm, pe.szExeFile, COMM_LEN); |