diff options
author | Ron Yorston <rmy@pobox.com> | 2020-04-06 09:03:52 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-04-06 09:03:52 +0100 |
commit | 9181e1363f09f80ba822175886450b751e408f14 (patch) | |
tree | 000415bab289dd387e9217db9c1da7b0c2bf8549 | |
parent | 4ecfc9fc115221ec66769915bf02ac37c40ffcd5 (diff) | |
download | busybox-w32-9181e1363f09f80ba822175886450b751e408f14.tar.gz busybox-w32-9181e1363f09f80ba822175886450b751e408f14.tar.bz2 busybox-w32-9181e1363f09f80ba822175886450b751e408f14.zip |
time: WIN32 port
Port the time applet to WIN32. This requires the implemntation of
a replacement for wait3(2).
Only elapsed, user and system times are supported, not the memory
and i/o statistics reported by GNU time.
-rw-r--r-- | configs/mingw32_defconfig | 4 | ||||
-rw-r--r-- | configs/mingw64_defconfig | 4 | ||||
-rw-r--r-- | include/mingw.h | 3 | ||||
-rw-r--r-- | miscutils/time.c | 55 | ||||
-rw-r--r-- | win32/process.c | 41 | ||||
-rw-r--r-- | win32/sys/resource.h | 11 |
6 files changed, 106 insertions, 12 deletions
diff --git a/configs/mingw32_defconfig b/configs/mingw32_defconfig index 5616851f6..a86be37ea 100644 --- a/configs/mingw32_defconfig +++ b/configs/mingw32_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.32.0.git | 3 | # Busybox version: 1.32.0.git |
4 | # Sun Apr 5 09:22:18 2020 | 4 | # Mon Apr 6 08:34:52 2020 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -832,7 +832,7 @@ CONFIG_MAN=y | |||
832 | # CONFIG_SETFATTR is not set | 832 | # CONFIG_SETFATTR is not set |
833 | # CONFIG_SETSERIAL is not set | 833 | # CONFIG_SETSERIAL is not set |
834 | CONFIG_STRINGS=y | 834 | CONFIG_STRINGS=y |
835 | # CONFIG_TIME is not set | 835 | CONFIG_TIME=y |
836 | CONFIG_TS=y | 836 | CONFIG_TS=y |
837 | CONFIG_TTYSIZE=y | 837 | CONFIG_TTYSIZE=y |
838 | # CONFIG_UBIRENAME is not set | 838 | # CONFIG_UBIRENAME is not set |
diff --git a/configs/mingw64_defconfig b/configs/mingw64_defconfig index 92daa7839..2c60d22ac 100644 --- a/configs/mingw64_defconfig +++ b/configs/mingw64_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.32.0.git | 3 | # Busybox version: 1.32.0.git |
4 | # Sun Apr 5 09:22:18 2020 | 4 | # Mon Apr 6 08:34:52 2020 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | # CONFIG_PLATFORM_POSIX is not set | 7 | # CONFIG_PLATFORM_POSIX is not set |
@@ -832,7 +832,7 @@ CONFIG_MAN=y | |||
832 | # CONFIG_SETFATTR is not set | 832 | # CONFIG_SETFATTR is not set |
833 | # CONFIG_SETSERIAL is not set | 833 | # CONFIG_SETSERIAL is not set |
834 | CONFIG_STRINGS=y | 834 | CONFIG_STRINGS=y |
835 | # CONFIG_TIME is not set | 835 | CONFIG_TIME=y |
836 | CONFIG_TS=y | 836 | CONFIG_TS=y |
837 | CONFIG_TTYSIZE=y | 837 | CONFIG_TTYSIZE=y |
838 | # CONFIG_UBIRENAME is not set | 838 | # CONFIG_UBIRENAME is not set |
diff --git a/include/mingw.h b/include/mingw.h index 3d0daee38..3516cd31c 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -347,7 +347,8 @@ int mingw_fstat(int fd, struct mingw_stat *buf); | |||
347 | */ | 347 | */ |
348 | #define WNOHANG 1 | 348 | #define WNOHANG 1 |
349 | #define WUNTRACED 2 | 349 | #define WUNTRACED 2 |
350 | int waitpid(pid_t pid, int *status, int options); | 350 | pid_t waitpid(pid_t pid, int *status, int options); |
351 | pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage); | ||
351 | 352 | ||
352 | /* | 353 | /* |
353 | * time.h | 354 | * time.h |
diff --git a/miscutils/time.c b/miscutils/time.c index d15d363f3..eace390e6 100644 --- a/miscutils/time.c +++ b/miscutils/time.c | |||
@@ -22,12 +22,21 @@ | |||
22 | //kbuild:lib-$(CONFIG_TIME) += time.o | 22 | //kbuild:lib-$(CONFIG_TIME) += time.o |
23 | 23 | ||
24 | //usage:#define time_trivial_usage | 24 | //usage:#define time_trivial_usage |
25 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
25 | //usage: "[-vpa] [-o FILE] PROG ARGS" | 26 | //usage: "[-vpa] [-o FILE] PROG ARGS" |
27 | //usage: ) | ||
28 | //usage: IF_PLATFORM_MINGW32( | ||
29 | //usage: "[-pa] [-o FILE] PROG ARGS" | ||
30 | //usage: ) | ||
26 | //usage:#define time_full_usage "\n\n" | 31 | //usage:#define time_full_usage "\n\n" |
27 | //usage: "Run PROG, display resource usage when it exits\n" | 32 | //usage: "Run PROG, display resource usage when it exits\n" |
33 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
28 | //usage: "\n -v Verbose" | 34 | //usage: "\n -v Verbose" |
35 | //usage: ) | ||
29 | //usage: "\n -p POSIX output format" | 36 | //usage: "\n -p POSIX output format" |
37 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
30 | //usage: "\n -f FMT Custom format" | 38 | //usage: "\n -f FMT Custom format" |
39 | //usage: ) | ||
31 | //usage: "\n -o FILE Write result to FILE" | 40 | //usage: "\n -o FILE Write result to FILE" |
32 | //usage: "\n -a Append (else overwrite)" | 41 | //usage: "\n -a Append (else overwrite)" |
33 | 42 | ||
@@ -50,6 +59,7 @@ static const char default_format[] ALIGN1 = "real\t%E\nuser\t%u\nsys\t%T"; | |||
50 | /* The output format for the -p option .*/ | 59 | /* The output format for the -p option .*/ |
51 | static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S"; | 60 | static const char posix_format[] ALIGN1 = "real %e\nuser %U\nsys %S"; |
52 | 61 | ||
62 | #if !ENABLE_PLATFORM_MINGW32 | ||
53 | /* Format string for printing all statistics verbosely. | 63 | /* Format string for printing all statistics verbosely. |
54 | Keep this output to 24 lines so users on terminals can see it all.*/ | 64 | Keep this output to 24 lines so users on terminals can see it all.*/ |
55 | static const char long_format[] ALIGN1 = | 65 | static const char long_format[] ALIGN1 = |
@@ -76,6 +86,7 @@ static const char long_format[] ALIGN1 = | |||
76 | "\tSignals delivered: %k\n" | 86 | "\tSignals delivered: %k\n" |
77 | "\tPage size (bytes): %Z\n" | 87 | "\tPage size (bytes): %Z\n" |
78 | "\tExit status: %x"; | 88 | "\tExit status: %x"; |
89 | #endif | ||
79 | 90 | ||
80 | /* Wait for and fill in data on child process PID. | 91 | /* Wait for and fill in data on child process PID. |
81 | Return 0 on error, 1 if ok. */ | 92 | Return 0 on error, 1 if ok. */ |
@@ -86,7 +97,11 @@ static void resuse_end(pid_t pid, resource_t *resp) | |||
86 | 97 | ||
87 | /* Ignore signals, but don't ignore the children. When wait3 | 98 | /* Ignore signals, but don't ignore the children. When wait3 |
88 | * returns the child process, set the time the command finished. */ | 99 | * returns the child process, set the time the command finished. */ |
100 | #if !ENABLE_PLATFORM_MINGW32 | ||
89 | while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) { | 101 | while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) { |
102 | #else | ||
103 | while ((caught=mingw_wait3(pid, &resp->waitstatus, 0, &resp->ru)) != pid) { | ||
104 | #endif | ||
90 | if (caught == -1 && errno != EINTR) { | 105 | if (caught == -1 && errno != EINTR) { |
91 | bb_simple_perror_msg("wait"); | 106 | bb_simple_perror_msg("wait"); |
92 | return; | 107 | return; |
@@ -95,6 +110,7 @@ static void resuse_end(pid_t pid, resource_t *resp) | |||
95 | resp->elapsed_ms = monotonic_ms() - resp->elapsed_ms; | 110 | resp->elapsed_ms = monotonic_ms() - resp->elapsed_ms; |
96 | } | 111 | } |
97 | 112 | ||
113 | #if !ENABLE_PLATFORM_MINGW32 | ||
98 | static void printargv(char *const *argv) | 114 | static void printargv(char *const *argv) |
99 | { | 115 | { |
100 | const char *fmt = " %s" + 1; | 116 | const char *fmt = " %s" + 1; |
@@ -124,6 +140,7 @@ static unsigned long ptok(const unsigned pagesize, const unsigned long pages) | |||
124 | tmp = pages * pagesize; /* Larger first, */ | 140 | tmp = pages * pagesize; /* Larger first, */ |
125 | return tmp / 1024; /* then smaller. */ | 141 | return tmp / 1024; /* then smaller. */ |
126 | } | 142 | } |
143 | #endif | ||
127 | 144 | ||
128 | /* summarize: Report on the system use of a command. | 145 | /* summarize: Report on the system use of a command. |
129 | 146 | ||
@@ -173,11 +190,17 @@ static unsigned long ptok(const unsigned pagesize, const unsigned long pages) | |||
173 | #define TICKS_PER_SEC 100 | 190 | #define TICKS_PER_SEC 100 |
174 | #endif | 191 | #endif |
175 | 192 | ||
193 | #if ENABLE_PLATFORM_MINGW32 | ||
194 | #define summarize(f, c, r) summarize(f, r) | ||
195 | #endif | ||
196 | |||
176 | static void summarize(const char *fmt, char **command, resource_t *resp) | 197 | static void summarize(const char *fmt, char **command, resource_t *resp) |
177 | { | 198 | { |
199 | #if !ENABLE_PLATFORM_MINGW32 | ||
178 | unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */ | 200 | unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */ |
179 | unsigned cpu_ticks; /* Same, in "CPU ticks" */ | 201 | unsigned cpu_ticks; /* Same, in "CPU ticks" */ |
180 | unsigned pagesize = getpagesize(); | 202 | unsigned pagesize = getpagesize(); |
203 | #endif | ||
181 | 204 | ||
182 | /* Impossible: we do not use WUNTRACED flag in wait()... | 205 | /* Impossible: we do not use WUNTRACED flag in wait()... |
183 | if (WIFSTOPPED(resp->waitstatus)) | 206 | if (WIFSTOPPED(resp->waitstatus)) |
@@ -191,6 +214,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
191 | printf("Command exited with non-zero status %u\n", | 214 | printf("Command exited with non-zero status %u\n", |
192 | WEXITSTATUS(resp->waitstatus)); | 215 | WEXITSTATUS(resp->waitstatus)); |
193 | 216 | ||
217 | #if !ENABLE_PLATFORM_MINGW32 | ||
194 | vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000 | 218 | vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000 |
195 | + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000; | 219 | + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000; |
196 | 220 | ||
@@ -201,6 +225,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
201 | cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000; | 225 | cpu_ticks = vv_ms * (unsigned long long)TICKS_PER_SEC / 1000; |
202 | #endif | 226 | #endif |
203 | if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */ | 227 | if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */ |
228 | #endif | ||
204 | 229 | ||
205 | while (*fmt) { | 230 | while (*fmt) { |
206 | /* Handle leading literal part */ | 231 | /* Handle leading literal part */ |
@@ -234,6 +259,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
234 | bb_putchar(*fmt); | 259 | bb_putchar(*fmt); |
235 | break; | 260 | break; |
236 | #endif | 261 | #endif |
262 | #if !ENABLE_PLATFORM_MINGW32 | ||
237 | case 'C': /* The command that got timed. */ | 263 | case 'C': /* The command that got timed. */ |
238 | printargv(command); | 264 | printargv(command); |
239 | break; | 265 | break; |
@@ -242,6 +268,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
242 | (ptok(pagesize, (UL) resp->ru.ru_idrss) + | 268 | (ptok(pagesize, (UL) resp->ru.ru_idrss) + |
243 | ptok(pagesize, (UL) resp->ru.ru_isrss)) / cpu_ticks); | 269 | ptok(pagesize, (UL) resp->ru.ru_isrss)) / cpu_ticks); |
244 | break; | 270 | break; |
271 | #endif | ||
245 | case 'E': { /* Elapsed real (wall clock) time. */ | 272 | case 'E': { /* Elapsed real (wall clock) time. */ |
246 | unsigned seconds = resp->elapsed_ms / 1000; | 273 | unsigned seconds = resp->elapsed_ms / 1000; |
247 | if (seconds >= 3600) /* One hour -> h:m:s. */ | 274 | if (seconds >= 3600) /* One hour -> h:m:s. */ |
@@ -256,6 +283,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
256 | (unsigned)(resp->elapsed_ms / 10) % 100); | 283 | (unsigned)(resp->elapsed_ms / 10) % 100); |
257 | break; | 284 | break; |
258 | } | 285 | } |
286 | #if !ENABLE_PLATFORM_MINGW32 | ||
259 | case 'F': /* Major page faults. */ | 287 | case 'F': /* Major page faults. */ |
260 | printf("%lu", resp->ru.ru_majflt); | 288 | printf("%lu", resp->ru.ru_majflt); |
261 | break; | 289 | break; |
@@ -284,6 +312,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
284 | case 'R': /* Minor page faults (reclaims). */ | 312 | case 'R': /* Minor page faults (reclaims). */ |
285 | printf("%lu", resp->ru.ru_minflt); | 313 | printf("%lu", resp->ru.ru_minflt); |
286 | break; | 314 | break; |
315 | #endif | ||
287 | case 'S': /* System time. */ | 316 | case 'S': /* System time. */ |
288 | printf("%u.%02u", | 317 | printf("%u.%02u", |
289 | (unsigned)resp->ru.ru_stime.tv_sec, | 318 | (unsigned)resp->ru.ru_stime.tv_sec, |
@@ -318,6 +347,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
318 | (unsigned)(resp->ru.ru_utime.tv_sec % 60), | 347 | (unsigned)(resp->ru.ru_utime.tv_sec % 60), |
319 | (unsigned)(resp->ru.ru_utime.tv_usec / 10000)); | 348 | (unsigned)(resp->ru.ru_utime.tv_usec / 10000)); |
320 | break; | 349 | break; |
350 | #if !ENABLE_PLATFORM_MINGW32 | ||
321 | case 'W': /* Times swapped out. */ | 351 | case 'W': /* Times swapped out. */ |
322 | printf("%lu", resp->ru.ru_nswap); | 352 | printf("%lu", resp->ru.ru_nswap); |
323 | break; | 353 | break; |
@@ -330,11 +360,13 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
330 | case 'c': /* Involuntary context switches. */ | 360 | case 'c': /* Involuntary context switches. */ |
331 | printf("%lu", resp->ru.ru_nivcsw); | 361 | printf("%lu", resp->ru.ru_nivcsw); |
332 | break; | 362 | break; |
363 | #endif | ||
333 | case 'e': /* Elapsed real time in seconds. */ | 364 | case 'e': /* Elapsed real time in seconds. */ |
334 | printf("%u.%02u", | 365 | printf("%u.%02u", |
335 | (unsigned)resp->elapsed_ms / 1000, | 366 | (unsigned)resp->elapsed_ms / 1000, |
336 | (unsigned)(resp->elapsed_ms / 10) % 100); | 367 | (unsigned)(resp->elapsed_ms / 10) % 100); |
337 | break; | 368 | break; |
369 | #if !ENABLE_PLATFORM_MINGW32 | ||
338 | case 'k': /* Signals delivered. */ | 370 | case 'k': /* Signals delivered. */ |
339 | printf("%lu", resp->ru.ru_nsignals); | 371 | printf("%lu", resp->ru.ru_nsignals); |
340 | break; | 372 | break; |
@@ -356,6 +388,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
356 | case 'x': /* Exit status. */ | 388 | case 'x': /* Exit status. */ |
357 | printf("%u", WEXITSTATUS(resp->waitstatus)); | 389 | printf("%u", WEXITSTATUS(resp->waitstatus)); |
358 | break; | 390 | break; |
391 | #endif | ||
359 | } | 392 | } |
360 | break; | 393 | break; |
361 | 394 | ||
@@ -390,6 +423,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp) | |||
390 | static void run_command(char *const *cmd, resource_t *resp) | 423 | static void run_command(char *const *cmd, resource_t *resp) |
391 | { | 424 | { |
392 | pid_t pid; | 425 | pid_t pid; |
426 | #if !ENABLE_PLATFORM_MINGW32 | ||
393 | void (*interrupt_signal)(int); | 427 | void (*interrupt_signal)(int); |
394 | void (*quit_signal)(int); | 428 | void (*quit_signal)(int); |
395 | 429 | ||
@@ -410,6 +444,13 @@ static void run_command(char *const *cmd, resource_t *resp) | |||
410 | /* Re-enable signals. */ | 444 | /* Re-enable signals. */ |
411 | signal(SIGINT, interrupt_signal); | 445 | signal(SIGINT, interrupt_signal); |
412 | signal(SIGQUIT, quit_signal); | 446 | signal(SIGQUIT, quit_signal); |
447 | #else | ||
448 | resp->elapsed_ms = monotonic_ms(); | ||
449 | if ((pid=spawn((char **)cmd)) == -1) | ||
450 | bb_perror_msg_and_die("can't execute %s", cmd[0]); | ||
451 | |||
452 | resuse_end(pid, resp); | ||
453 | #endif | ||
413 | } | 454 | } |
414 | 455 | ||
415 | int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 456 | int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -423,20 +464,34 @@ int time_main(int argc UNUSED_PARAM, char **argv) | |||
423 | int opt; | 464 | int opt; |
424 | int ex; | 465 | int ex; |
425 | enum { | 466 | enum { |
467 | #if ENABLE_PLATFORM_MINGW32 | ||
426 | OPT_v = (1 << 0), | 468 | OPT_v = (1 << 0), |
427 | OPT_p = (1 << 1), | 469 | OPT_p = (1 << 1), |
428 | OPT_a = (1 << 2), | 470 | OPT_a = (1 << 2), |
429 | OPT_o = (1 << 3), | 471 | OPT_o = (1 << 3), |
430 | OPT_f = (1 << 4), | 472 | OPT_f = (1 << 4), |
473 | #else | ||
474 | OPT_p = (1 << 0), | ||
475 | OPT_a = (1 << 1), | ||
476 | OPT_o = (1 << 2), | ||
477 | #endif | ||
431 | }; | 478 | }; |
432 | 479 | ||
433 | /* "+": stop on first non-option */ | 480 | /* "+": stop on first non-option */ |
481 | #if !ENABLE_PLATFORM_MINGW32 | ||
434 | opt = getopt32(argv, "^+" "vpao:f:" "\0" "-1"/*at least one arg*/, | 482 | opt = getopt32(argv, "^+" "vpao:f:" "\0" "-1"/*at least one arg*/, |
435 | &output_filename, &output_format | 483 | &output_filename, &output_format |
436 | ); | 484 | ); |
485 | #else | ||
486 | opt = getopt32(argv, "^+" "pao:" "\0" "-1"/*at least one arg*/, | ||
487 | &output_filename | ||
488 | ); | ||
489 | #endif | ||
437 | argv += optind; | 490 | argv += optind; |
491 | #if !ENABLE_PLATFORM_MINGW32 | ||
438 | if (opt & OPT_v) | 492 | if (opt & OPT_v) |
439 | output_format = long_format; | 493 | output_format = long_format; |
494 | #endif | ||
440 | if (opt & OPT_p) | 495 | if (opt & OPT_p) |
441 | output_format = posix_format; | 496 | output_format = posix_format; |
442 | output_fd = STDERR_FILENO; | 497 | output_fd = STDERR_FILENO; |
diff --git a/win32/process.c b/win32/process.c index 67ce3c100..28df33c23 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -3,21 +3,48 @@ | |||
3 | #include <psapi.h> | 3 | #include <psapi.h> |
4 | #include "lazyload.h" | 4 | #include "lazyload.h" |
5 | 5 | ||
6 | int waitpid(pid_t pid, int *status, int options) | 6 | pid_t waitpid(pid_t pid, int *status, int options) |
7 | #if ENABLE_TIME | ||
8 | { | ||
9 | return mingw_wait3(pid, status, options, NULL); | ||
10 | } | ||
11 | #endif | ||
12 | |||
13 | #if ENABLE_TIME | ||
14 | pid_t mingw_wait3(pid_t pid, int *status, int options, struct rusage *rusage) | ||
15 | #endif | ||
7 | { | 16 | { |
8 | HANDLE proc; | 17 | HANDLE proc; |
9 | intptr_t ret; | 18 | DWORD code; |
10 | 19 | ||
11 | /* Windows does not understand parent-child */ | 20 | /* Windows does not understand parent-child */ |
12 | if (pid > 0 && options == 0) { | 21 | if (pid > 0 && options == 0) { |
13 | if ( (proc=OpenProcess(SYNCHRONIZE|PROCESS_QUERY_INFORMATION, | 22 | if ( (proc=OpenProcess(SYNCHRONIZE|PROCESS_QUERY_INFORMATION, |
14 | FALSE, pid)) != NULL ) { | 23 | FALSE, pid)) != NULL ) { |
15 | ret = _cwait(status, (intptr_t)proc, 0); | 24 | WaitForSingleObject(proc, INFINITE); |
16 | CloseHandle(proc); | 25 | GetExitCodeProcess(proc, &code); |
17 | if (ret == -1) { | 26 | #if ENABLE_TIME |
18 | return -1; | 27 | if (rusage != NULL) { |
28 | FILETIME crTime, exTime, keTime, usTime; | ||
29 | |||
30 | memset(rusage, 0, sizeof(*rusage)); | ||
31 | if (GetProcessTimes(proc, &crTime, &exTime, &keTime, &usTime)) { | ||
32 | uint64_t kernel_usec = | ||
33 | (((uint64_t)keTime.dwHighDateTime << 32) | ||
34 | | (uint64_t)keTime.dwLowDateTime)/10; | ||
35 | uint64_t user_usec = | ||
36 | (((uint64_t)usTime.dwHighDateTime << 32) | ||
37 | | (uint64_t)usTime.dwLowDateTime)/10; | ||
38 | |||
39 | rusage->ru_utime.tv_sec = user_usec / 1000000U; | ||
40 | rusage->ru_utime.tv_usec = user_usec % 1000000U; | ||
41 | rusage->ru_stime.tv_sec = kernel_usec / 1000000U; | ||
42 | rusage->ru_stime.tv_usec = kernel_usec % 1000000U; | ||
43 | } | ||
19 | } | 44 | } |
20 | *status <<= 8; | 45 | #endif |
46 | CloseHandle(proc); | ||
47 | *status = code << 8; | ||
21 | return pid; | 48 | return pid; |
22 | } | 49 | } |
23 | } | 50 | } |
diff --git a/win32/sys/resource.h b/win32/sys/resource.h index e69de29bb..3220d8112 100644 --- a/win32/sys/resource.h +++ b/win32/sys/resource.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef _SYS_RESOURCE_H | ||
2 | #define _SYS_RESOURCE_H 1 | ||
3 | |||
4 | #include <time.h> | ||
5 | |||
6 | struct rusage { | ||
7 | struct timeval ru_utime; | ||
8 | struct timeval ru_stime; | ||
9 | }; | ||
10 | |||
11 | #endif | ||