diff options
-rw-r--r-- | configs/mingw32_defconfig | 2 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 2 | ||||
-rw-r--r-- | include/mingw.h | 7 | ||||
-rw-r--r-- | procps/ps.c | 7 | ||||
-rw-r--r-- | win32/lazyload.h | 43 | ||||
-rw-r--r-- | win32/mingw.c | 18 | ||||
-rw-r--r-- | win32/process.c | 47 |
7 files changed, 119 insertions, 7 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index abe56f619..3a30cf366 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -991,7 +991,7 @@ CONFIG_FEATURE_PIDOF_OMIT=y | |||
991 | CONFIG_PS=y | 991 | CONFIG_PS=y |
992 | # CONFIG_FEATURE_PS_WIDE is not set | 992 | # CONFIG_FEATURE_PS_WIDE is not set |
993 | # CONFIG_FEATURE_PS_LONG is not set | 993 | # CONFIG_FEATURE_PS_LONG is not set |
994 | # CONFIG_FEATURE_PS_TIME is not set | 994 | CONFIG_FEATURE_PS_TIME=y |
995 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | 995 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set |
996 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set | 996 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set |
997 | # CONFIG_PSTREE is not set | 997 | # CONFIG_PSTREE is not set |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index 286846f95..c474c13ee 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -991,7 +991,7 @@ CONFIG_FEATURE_PIDOF_OMIT=y | |||
991 | CONFIG_PS=y | 991 | CONFIG_PS=y |
992 | # CONFIG_FEATURE_PS_WIDE is not set | 992 | # CONFIG_FEATURE_PS_WIDE is not set |
993 | # CONFIG_FEATURE_PS_LONG is not set | 993 | # CONFIG_FEATURE_PS_LONG is not set |
994 | # CONFIG_FEATURE_PS_TIME is not set | 994 | CONFIG_FEATURE_PS_TIME=y |
995 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | 995 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set |
996 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set | 996 | # CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set |
997 | # CONFIG_PSTREE is not set | 997 | # CONFIG_PSTREE is not set |
diff --git a/include/mingw.h b/include/mingw.h index dd676bf2c..87abd077b 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -374,6 +374,10 @@ clock_t times(struct tms *buf); | |||
374 | 374 | ||
375 | #define _SC_CLK_TCK 2 | 375 | #define _SC_CLK_TCK 2 |
376 | 376 | ||
377 | #define TICKS_PER_SECOND 100 | ||
378 | #define MS_PER_TICK 10 | ||
379 | #define HNSEC_PER_TICK 100000 | ||
380 | |||
377 | IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM); | 381 | IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM); |
378 | IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM); | 382 | IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM); |
379 | NOIMPL(chroot,const char *root UNUSED_PARAM); | 383 | NOIMPL(chroot,const char *root UNUSED_PARAM); |
@@ -475,3 +479,6 @@ int has_exe_suffix(const char *p); | |||
475 | char *file_is_win32_executable(const char *p); | 479 | char *file_is_win32_executable(const char *p); |
476 | 480 | ||
477 | int err_win_to_posix(DWORD winerr); | 481 | int err_win_to_posix(DWORD winerr); |
482 | |||
483 | ULONGLONG CompatGetTickCount64(void); | ||
484 | #define GetTickCount64 CompatGetTickCount64 | ||
diff --git a/procps/ps.c b/procps/ps.c index a8541e6cf..de062fe8b 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -35,7 +35,6 @@ | |||
35 | //config: bool "Enable -o time and -o etime specifiers" | 35 | //config: bool "Enable -o time and -o etime specifiers" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on (PS || MINIPS) && DESKTOP | 37 | //config: depends on (PS || MINIPS) && DESKTOP |
38 | //config: select PLATFORM_LINUX | ||
39 | //config: | 38 | //config: |
40 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS | 39 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS |
41 | //config: bool "Support Linux prior to 2.4.0 and non-ELF systems" | 40 | //config: bool "Support Linux prior to 2.4.0 and non-ELF systems" |
@@ -126,7 +125,7 @@ static unsigned long get_uptime(void) | |||
126 | if (sysinfo(&info) < 0) | 125 | if (sysinfo(&info) < 0) |
127 | return 0; | 126 | return 0; |
128 | return info.uptime; | 127 | return info.uptime; |
129 | #elif 1 | 128 | #elif !ENABLE_PLATFORM_MINGW32 |
130 | unsigned long uptime; | 129 | unsigned long uptime; |
131 | char buf[sizeof(uptime)*3 + 2]; | 130 | char buf[sizeof(uptime)*3 + 2]; |
132 | /* /proc/uptime is "UPTIME_SEC.NN IDLE_SEC.NN\n" | 131 | /* /proc/uptime is "UPTIME_SEC.NN IDLE_SEC.NN\n" |
@@ -137,6 +136,8 @@ static unsigned long get_uptime(void) | |||
137 | buf[sizeof(buf)-1] = '\0'; | 136 | buf[sizeof(buf)-1] = '\0'; |
138 | sscanf(buf, "%lu", &uptime); | 137 | sscanf(buf, "%lu", &uptime); |
139 | return uptime; | 138 | return uptime; |
139 | #elif ENABLE_PLATFORM_MINGW32 | ||
140 | return GetTickCount64()/1000; | ||
140 | #else | 141 | #else |
141 | struct timespec ts; | 142 | struct timespec ts; |
142 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) | 143 | if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) |
@@ -556,7 +557,7 @@ static void format_process(const procps_status_t *ps) | |||
556 | # define SELINUX_O_PREFIX "label," | 557 | # define SELINUX_O_PREFIX "label," |
557 | # define DEFAULT_O_STR (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args") | 558 | # define DEFAULT_O_STR (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args") |
558 | #elif ENABLE_PLATFORM_MINGW32 | 559 | #elif ENABLE_PLATFORM_MINGW32 |
559 | # define DEFAULT_O_STR ("pid,ppid,comm") | 560 | # define DEFAULT_O_STR ("pid,ppid" IF_FEATURE_PS_TIME(",time,etime") ",comm") |
560 | #else | 561 | #else |
561 | # define DEFAULT_O_STR ("pid,user" IF_FEATURE_PS_TIME(",time") ",args") | 562 | # define DEFAULT_O_STR ("pid,user" IF_FEATURE_PS_TIME(",time") ",args") |
562 | #endif | 563 | #endif |
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); |