aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configs/mingw32_defconfig2
-rw-r--r--configs/mingw64_defconfig2
-rw-r--r--include/mingw.h7
-rw-r--r--procps/ps.c7
-rw-r--r--win32/lazyload.h43
-rw-r--r--win32/mingw.c18
-rw-r--r--win32/process.c47
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
991CONFIG_PS=y 991CONFIG_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 994CONFIG_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
991CONFIG_PS=y 991CONFIG_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 994CONFIG_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
377IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM); 381IMPL(alarm,unsigned int,0,unsigned int seconds UNUSED_PARAM);
378IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM); 382IMPL(chown,int,0,const char *path UNUSED_PARAM, uid_t uid UNUSED_PARAM, gid_t gid UNUSED_PARAM);
379NOIMPL(chroot,const char *root UNUSED_PARAM); 383NOIMPL(chroot,const char *root UNUSED_PARAM);
@@ -475,3 +479,6 @@ int has_exe_suffix(const char *p);
475char *file_is_win32_executable(const char *p); 479char *file_is_win32_executable(const char *p);
476 480
477int err_win_to_posix(DWORD winerr); 481int err_win_to_posix(DWORD winerr);
482
483ULONGLONG 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
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);