aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/lazyload.h43
-rw-r--r--win32/mingw.c18
-rw-r--r--win32/process.c47
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
6struct 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
26static 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)
707long sysconf(int name) 707long 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
1072ULONGLONG 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
337static 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 */
338procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags UNUSED_PARAM) 344procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags
345#if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG
346UNUSED_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);