diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 19:09:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 19:09:05 +0000 |
commit | 459be35234cc24b69309eb0ee22600024c73713e (patch) | |
tree | 15ac4122d9c42ec75ba68d342827e37fcb1306ed | |
parent | e79dd06782175d50f639180cde5b2c56933aa2ee (diff) | |
download | busybox-w32-459be35234cc24b69309eb0ee22600024c73713e.tar.gz busybox-w32-459be35234cc24b69309eb0ee22600024c73713e.tar.bz2 busybox-w32-459be35234cc24b69309eb0ee22600024c73713e.zip |
hwclock: size optimizations
libbb/time.c: new file, introducing monotonic_us()
pscan, traceroute, arping: use it instead of gettimeofday
ping, zcip: TODO
function old new delta
monotonic_us - 89 +89
find_pair 164 180 +16
.rodata 129747 129763 +16
refresh 1144 1152 +8
............
timeout 8 4 -4
static.start 8 4 -4
last 8 4 -4
parse_conf 1303 1284 -19
time_main 1149 1124 -25
gettimeofday_us 39 - -39
arping_main 2042 1969 -73
hwclock_main 594 501 -93
catcher 485 380 -105
traceroute_main 4300 4117 -183
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 8/11 up/down: 157/-562) Total: -405 bytes
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/Config.in | 10 | ||||
-rw-r--r-- | libbb/Kbuild | 1 | ||||
-rw-r--r-- | libbb/time.c | 32 | ||||
-rw-r--r-- | miscutils/time.c | 180 | ||||
-rw-r--r-- | networking/arping.c | 125 | ||||
-rw-r--r-- | networking/pscan.c | 28 | ||||
-rw-r--r-- | networking/traceroute.c | 53 | ||||
-rw-r--r-- | networking/wget.c | 2 | ||||
-rw-r--r-- | util-linux/hwclock.c | 60 |
10 files changed, 230 insertions, 262 deletions
diff --git a/include/libbb.h b/include/libbb.h index c0c417c95..2a50bce66 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -200,6 +200,7 @@ struct sysinfo { | |||
200 | }; | 200 | }; |
201 | int sysinfo(struct sysinfo* info); | 201 | int sysinfo(struct sysinfo* info); |
202 | 202 | ||
203 | unsigned long long monotonic_us(void); | ||
203 | 204 | ||
204 | extern void chomp(char *s); | 205 | extern void chomp(char *s); |
205 | extern void trim(char *s); | 206 | extern void trim(char *s); |
diff --git a/libbb/Config.in b/libbb/Config.in index a1ff7c056..0a3769df2 100644 --- a/libbb/Config.in +++ b/libbb/Config.in | |||
@@ -95,4 +95,14 @@ config FEATURE_EDITING_FANCY_PROMPT | |||
95 | Setting this option allows for prompts to use things like \w and | 95 | Setting this option allows for prompts to use things like \w and |
96 | \$ and escape codes. | 96 | \$ and escape codes. |
97 | 97 | ||
98 | config MONOTONIC_SYSCALL | ||
99 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" | ||
100 | default y | ||
101 | help | ||
102 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring | ||
103 | time intervals (time, ping, traceroute etc need this). | ||
104 | Probably requires Linux 2.6+. If not selected, gettimeofday | ||
105 | will be used instead (which gives wrong results if date/time | ||
106 | is reset). | ||
107 | |||
98 | endmenu | 108 | endmenu |
diff --git a/libbb/Kbuild b/libbb/Kbuild index e562f3222..693f6092c 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -78,6 +78,7 @@ lib-y += simplify_path.o | |||
78 | lib-y += skip_whitespace.o | 78 | lib-y += skip_whitespace.o |
79 | lib-y += speed_table.o | 79 | lib-y += speed_table.o |
80 | lib-y += str_tolower.o | 80 | lib-y += str_tolower.o |
81 | lib-y += time.o | ||
81 | lib-y += trim.o | 82 | lib-y += trim.o |
82 | lib-y += u_signal_names.o | 83 | lib-y += u_signal_names.o |
83 | lib-y += udp_io.o | 84 | lib-y += udp_io.o |
diff --git a/libbb/time.c b/libbb/time.c new file mode 100644 index 000000000..f2a741521 --- /dev/null +++ b/libbb/time.c | |||
@@ -0,0 +1,32 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) 2007 Denis Vlasenko | ||
6 | * | ||
7 | * Licensed under GPL version 2, see file LICENSE in this tarball for details. | ||
8 | */ | ||
9 | |||
10 | #include "libbb.h" | ||
11 | |||
12 | #if ENABLE_MONOTONIC_SYSCALL | ||
13 | #include <sys/syscall.h> | ||
14 | |||
15 | /* libc has incredibly messy way of doing this, | ||
16 | * typically requiring -lrt. We just skip all this mess */ | ||
17 | unsigned long long monotonic_us(void) | ||
18 | { | ||
19 | struct timespec ts; | ||
20 | if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &ts)) | ||
21 | bb_error_msg_and_die("clock_gettime(MONOTONIC) failed"); | ||
22 | return ts.tv_sec * 1000000ULL + ts.tv_nsec/1000; | ||
23 | } | ||
24 | #else | ||
25 | unsigned long long monotonic_us(void) | ||
26 | { | ||
27 | struct timeval tv; | ||
28 | if (gettimeofday(&tv, NULL)) | ||
29 | bb_error_msg_and_die("gettimeofday failed"); | ||
30 | return tv.tv_sec * 1000000ULL + tv_usec; | ||
31 | } | ||
32 | #endif | ||
diff --git a/miscutils/time.c b/miscutils/time.c index 705123c9e..578cb35ff 100644 --- a/miscutils/time.c +++ b/miscutils/time.c | |||
@@ -11,28 +11,16 @@ | |||
11 | 11 | ||
12 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | 13 | ||
14 | #define TV_MSEC tv_usec / 1000 | ||
15 | |||
16 | /* Information on the resources used by a child process. */ | 14 | /* Information on the resources used by a child process. */ |
17 | typedef struct { | 15 | typedef struct { |
18 | int waitstatus; | 16 | int waitstatus; |
19 | struct rusage ru; | 17 | struct rusage ru; |
20 | struct timeval start, elapsed; /* Wallclock time of process. */ | 18 | unsigned elapsed_ms; /* Wallclock time of process. */ |
21 | } resource_t; | 19 | } resource_t; |
22 | 20 | ||
23 | /* msec = milliseconds = 1/1,000 (1*10e-3) second. | 21 | /* msec = milliseconds = 1/1,000 (1*10e-3) second. |
24 | usec = microseconds = 1/1,000,000 (1*10e-6) second. */ | 22 | usec = microseconds = 1/1,000,000 (1*10e-6) second. */ |
25 | 23 | ||
26 | #ifndef TICKS_PER_SEC | ||
27 | #define TICKS_PER_SEC 100 | ||
28 | #endif | ||
29 | |||
30 | /* The number of milliseconds in one `tick' used by the `rusage' structure. */ | ||
31 | #define MSEC_PER_TICK (1000 / TICKS_PER_SEC) | ||
32 | |||
33 | /* Return the number of clock ticks that occur in M milliseconds. */ | ||
34 | #define MSEC_TO_TICKS(m) ((m) / MSEC_PER_TICK) | ||
35 | |||
36 | #define UL unsigned long | 24 | #define UL unsigned long |
37 | 25 | ||
38 | static const char default_format[] = "real\t%E\nuser\t%u\nsys\t%T"; | 26 | static const char default_format[] = "real\t%E\nuser\t%u\nsys\t%T"; |
@@ -76,7 +64,6 @@ static const char long_format[] = | |||
76 | static int resuse_end(pid_t pid, resource_t * resp) | 64 | static int resuse_end(pid_t pid, resource_t * resp) |
77 | { | 65 | { |
78 | int status; | 66 | int status; |
79 | |||
80 | pid_t caught; | 67 | pid_t caught; |
81 | 68 | ||
82 | /* Ignore signals, but don't ignore the children. When wait3 | 69 | /* Ignore signals, but don't ignore the children. When wait3 |
@@ -85,18 +72,8 @@ static int resuse_end(pid_t pid, resource_t * resp) | |||
85 | if (caught == -1) | 72 | if (caught == -1) |
86 | return 0; | 73 | return 0; |
87 | } | 74 | } |
88 | 75 | resp->elapsed_ms = (monotonic_us() / 1000) - resp->elapsed_ms; | |
89 | gettimeofday(&resp->elapsed, (struct timezone *) 0); | ||
90 | resp->elapsed.tv_sec -= resp->start.tv_sec; | ||
91 | if (resp->elapsed.tv_usec < resp->start.tv_usec) { | ||
92 | /* Manually carry a one from the seconds field. */ | ||
93 | resp->elapsed.tv_usec += 1000000; | ||
94 | --resp->elapsed.tv_sec; | ||
95 | } | ||
96 | resp->elapsed.tv_usec -= resp->start.tv_usec; | ||
97 | |||
98 | resp->waitstatus = status; | 76 | resp->waitstatus = status; |
99 | |||
100 | return 1; | 77 | return 1; |
101 | } | 78 | } |
102 | 79 | ||
@@ -181,30 +158,30 @@ static unsigned long ptok(unsigned long pages) | |||
181 | COMMAND is the command and args that are being summarized. | 158 | COMMAND is the command and args that are being summarized. |
182 | RESP is resource information on the command. */ | 159 | RESP is resource information on the command. */ |
183 | 160 | ||
161 | #ifndef TICKS_PER_SEC | ||
162 | #define TICKS_PER_SEC 100 | ||
163 | #endif | ||
164 | |||
184 | static void summarize(const char *fmt, char **command, resource_t * resp) | 165 | static void summarize(const char *fmt, char **command, resource_t * resp) |
185 | { | 166 | { |
186 | unsigned long r; /* Elapsed real milliseconds. */ | 167 | unsigned vv_ms; /* Elapsed virtual (CPU) milliseconds */ |
187 | unsigned long v; /* Elapsed virtual (CPU) milliseconds. */ | 168 | unsigned cpu_ticks; /* Same, in "CPU ticks" */ |
188 | 169 | ||
189 | if (WIFSTOPPED(resp->waitstatus)) | 170 | if (WIFSTOPPED(resp->waitstatus)) |
190 | printf("Command stopped by signal %d\n", | 171 | printf("Command stopped by signal %u\n", |
191 | WSTOPSIG(resp->waitstatus)); | 172 | WSTOPSIG(resp->waitstatus)); |
192 | else if (WIFSIGNALED(resp->waitstatus)) | 173 | else if (WIFSIGNALED(resp->waitstatus)) |
193 | printf("Command terminated by signal %d\n", | 174 | printf("Command terminated by signal %u\n", |
194 | WTERMSIG(resp->waitstatus)); | 175 | WTERMSIG(resp->waitstatus)); |
195 | else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) | 176 | else if (WIFEXITED(resp->waitstatus) && WEXITSTATUS(resp->waitstatus)) |
196 | printf("Command exited with non-zero status %d\n", | 177 | printf("Command exited with non-zero status %u\n", |
197 | WEXITSTATUS(resp->waitstatus)); | 178 | WEXITSTATUS(resp->waitstatus)); |
198 | 179 | ||
199 | /* Convert all times to milliseconds. Occasionally, one of these values | 180 | vv_ms = (resp->ru.ru_utime.tv_sec + resp->ru.ru_stime.tv_sec) * 1000 |
200 | comes out as zero. Dividing by zero causes problems, so we first | 181 | + (resp->ru.ru_utime.tv_usec + resp->ru.ru_stime.tv_usec) / 1000; |
201 | check the time value. If it is zero, then we take `evasive action' | ||
202 | instead of calculating a value. */ | ||
203 | 182 | ||
204 | r = resp->elapsed.tv_sec * 1000 + resp->elapsed.tv_usec / 1000; | 183 | cpu_ticks = vv_ms * TICKS_PER_SEC / 1000; |
205 | 184 | if (!cpu_ticks) cpu_ticks = 1; /* we divide by it, must be nonzero */ | |
206 | v = resp->ru.ru_utime.tv_sec * 1000 + resp->ru.ru_utime.TV_MSEC + | ||
207 | resp->ru.ru_stime.tv_sec * 1000 + resp->ru.ru_stime.TV_MSEC; | ||
208 | 185 | ||
209 | /* putchar() != putc(stdout) in glibc! */ | 186 | /* putchar() != putc(stdout) in glibc! */ |
210 | 187 | ||
@@ -245,127 +222,122 @@ static void summarize(const char *fmt, char **command, resource_t * resp) | |||
245 | break; | 222 | break; |
246 | case 'D': /* Average unshared data size. */ | 223 | case 'D': /* Average unshared data size. */ |
247 | printf("%lu", | 224 | printf("%lu", |
248 | MSEC_TO_TICKS(v) == 0 ? 0 : | 225 | ptok((UL) resp->ru.ru_idrss) / cpu_ticks + |
249 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + | 226 | ptok((UL) resp->ru.ru_isrss) / cpu_ticks); |
250 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); | 227 | break; |
251 | break; | 228 | case 'E': { /* Elapsed real (wall clock) time. */ |
252 | case 'E': /* Elapsed real (wall clock) time. */ | 229 | unsigned seconds = resp->elapsed_ms / 1000; |
253 | if (resp->elapsed.tv_sec >= 3600) /* One hour -> h:m:s. */ | 230 | if (seconds >= 3600) /* One hour -> h:m:s. */ |
254 | printf("%ldh %ldm %02lds", | 231 | printf("%uh %um %02us", |
255 | resp->elapsed.tv_sec / 3600, | 232 | seconds / 3600, |
256 | (resp->elapsed.tv_sec % 3600) / 60, | 233 | (seconds % 3600) / 60, |
257 | resp->elapsed.tv_sec % 60); | 234 | seconds % 60); |
258 | else | 235 | else |
259 | printf("%ldm %ld.%02lds", /* -> m:s. */ | 236 | printf("%um %u.%02us", /* -> m:s. */ |
260 | resp->elapsed.tv_sec / 60, | 237 | seconds / 60, |
261 | resp->elapsed.tv_sec % 60, | 238 | seconds % 60, |
262 | resp->elapsed.tv_usec / 10000); | 239 | (unsigned)(resp->elapsed_ms / 10) % 100); |
263 | break; | 240 | break; |
241 | } | ||
264 | case 'F': /* Major page faults. */ | 242 | case 'F': /* Major page faults. */ |
265 | printf("%ld", resp->ru.ru_majflt); | 243 | printf("%lu", resp->ru.ru_majflt); |
266 | break; | 244 | break; |
267 | case 'I': /* Inputs. */ | 245 | case 'I': /* Inputs. */ |
268 | printf("%ld", resp->ru.ru_inblock); | 246 | printf("%lu", resp->ru.ru_inblock); |
269 | break; | 247 | break; |
270 | case 'K': /* Average mem usage == data+stack+text. */ | 248 | case 'K': /* Average mem usage == data+stack+text. */ |
271 | printf("%lu", | 249 | printf("%lu", |
272 | MSEC_TO_TICKS(v) == 0 ? 0 : | 250 | ptok((UL) resp->ru.ru_idrss) / cpu_ticks + |
273 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v) + | 251 | ptok((UL) resp->ru.ru_isrss) / cpu_ticks + |
274 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v) + | 252 | ptok((UL) resp->ru.ru_ixrss) / cpu_ticks); |
275 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); | ||
276 | break; | 253 | break; |
277 | case 'M': /* Maximum resident set size. */ | 254 | case 'M': /* Maximum resident set size. */ |
278 | printf("%lu", ptok((UL) resp->ru.ru_maxrss)); | 255 | printf("%lu", ptok((UL) resp->ru.ru_maxrss)); |
279 | break; | 256 | break; |
280 | case 'O': /* Outputs. */ | 257 | case 'O': /* Outputs. */ |
281 | printf("%ld", resp->ru.ru_oublock); | 258 | printf("%lu", resp->ru.ru_oublock); |
282 | break; | 259 | break; |
283 | case 'P': /* Percent of CPU this job got. */ | 260 | case 'P': /* Percent of CPU this job got. */ |
284 | /* % cpu is (total cpu time)/(elapsed time). */ | 261 | /* % cpu is (total cpu time)/(elapsed time). */ |
285 | if (r > 0) | 262 | if (resp->elapsed_ms > 0) |
286 | printf("%lu%%", (v * 100 / r)); | 263 | printf("%u%%", (unsigned)(vv_ms * 100 / resp->elapsed_ms)); |
287 | else | 264 | else |
288 | printf("?%%"); | 265 | printf("?%%"); |
289 | break; | 266 | break; |
290 | case 'R': /* Minor page faults (reclaims). */ | 267 | case 'R': /* Minor page faults (reclaims). */ |
291 | printf("%ld", resp->ru.ru_minflt); | 268 | printf("%lu", resp->ru.ru_minflt); |
292 | break; | 269 | break; |
293 | case 'S': /* System time. */ | 270 | case 'S': /* System time. */ |
294 | printf("%ld.%02ld", | 271 | printf("%u.%02u", |
295 | resp->ru.ru_stime.tv_sec, | 272 | (unsigned)resp->ru.ru_stime.tv_sec, |
296 | resp->ru.ru_stime.TV_MSEC / 10); | 273 | (unsigned)(resp->ru.ru_stime.tv_usec / 10000)); |
297 | break; | 274 | break; |
298 | case 'T': /* System time. */ | 275 | case 'T': /* System time. */ |
299 | if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */ | 276 | if (resp->ru.ru_stime.tv_sec >= 3600) /* One hour -> h:m:s. */ |
300 | printf("%ldh %ldm %02lds", | 277 | printf("%uh %um %02us", |
301 | resp->ru.ru_stime.tv_sec / 3600, | 278 | (unsigned)(resp->ru.ru_stime.tv_sec / 3600), |
302 | (resp->ru.ru_stime.tv_sec % 3600) / 60, | 279 | (unsigned)(resp->ru.ru_stime.tv_sec % 3600) / 60, |
303 | resp->ru.ru_stime.tv_sec % 60); | 280 | (unsigned)(resp->ru.ru_stime.tv_sec % 60)); |
304 | else | 281 | else |
305 | printf("%ldm %ld.%02lds", /* -> m:s. */ | 282 | printf("%um %u.%02us", /* -> m:s. */ |
306 | resp->ru.ru_stime.tv_sec / 60, | 283 | (unsigned)(resp->ru.ru_stime.tv_sec / 60), |
307 | resp->ru.ru_stime.tv_sec % 60, | 284 | (unsigned)(resp->ru.ru_stime.tv_sec % 60), |
308 | resp->ru.ru_stime.tv_usec / 10000); | 285 | (unsigned)(resp->ru.ru_stime.tv_usec / 10000)); |
309 | break; | 286 | break; |
310 | case 'U': /* User time. */ | 287 | case 'U': /* User time. */ |
311 | printf("%ld.%02ld", | 288 | printf("%u.%02u", |
312 | resp->ru.ru_utime.tv_sec, | 289 | (unsigned)resp->ru.ru_utime.tv_sec, |
313 | resp->ru.ru_utime.TV_MSEC / 10); | 290 | (unsigned)(resp->ru.ru_utime.tv_usec / 10000)); |
314 | break; | 291 | break; |
315 | case 'u': /* User time. */ | 292 | case 'u': /* User time. */ |
316 | if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */ | 293 | if (resp->ru.ru_utime.tv_sec >= 3600) /* One hour -> h:m:s. */ |
317 | printf("%ldh %ldm %02lds", | 294 | printf("%uh %um %02us", |
318 | resp->ru.ru_utime.tv_sec / 3600, | 295 | (unsigned)(resp->ru.ru_utime.tv_sec / 3600), |
319 | (resp->ru.ru_utime.tv_sec % 3600) / 60, | 296 | (unsigned)(resp->ru.ru_utime.tv_sec % 3600) / 60, |
320 | resp->ru.ru_utime.tv_sec % 60); | 297 | (unsigned)(resp->ru.ru_utime.tv_sec % 60)); |
321 | else | 298 | else |
322 | printf("%ldm %ld.%02lds", /* -> m:s. */ | 299 | printf("%um %u.%02us", /* -> m:s. */ |
323 | resp->ru.ru_utime.tv_sec / 60, | 300 | (unsigned)(resp->ru.ru_utime.tv_sec / 60), |
324 | resp->ru.ru_utime.tv_sec % 60, | 301 | (unsigned)(resp->ru.ru_utime.tv_sec % 60), |
325 | resp->ru.ru_utime.tv_usec / 10000); | 302 | (unsigned)(resp->ru.ru_utime.tv_usec / 10000)); |
326 | break; | 303 | break; |
327 | case 'W': /* Times swapped out. */ | 304 | case 'W': /* Times swapped out. */ |
328 | printf("%ld", resp->ru.ru_nswap); | 305 | printf("%lu", resp->ru.ru_nswap); |
329 | break; | 306 | break; |
330 | case 'X': /* Average shared text size. */ | 307 | case 'X': /* Average shared text size. */ |
331 | printf("%lu", | 308 | printf("%lu", ptok((UL) resp->ru.ru_ixrss) / cpu_ticks); |
332 | MSEC_TO_TICKS(v) == 0 ? 0 : | ||
333 | ptok((UL) resp->ru.ru_ixrss) / MSEC_TO_TICKS(v)); | ||
334 | break; | 309 | break; |
335 | case 'Z': /* Page size. */ | 310 | case 'Z': /* Page size. */ |
336 | printf("%d", getpagesize()); | 311 | printf("%u", getpagesize()); |
337 | break; | 312 | break; |
338 | case 'c': /* Involuntary context switches. */ | 313 | case 'c': /* Involuntary context switches. */ |
339 | printf("%ld", resp->ru.ru_nivcsw); | 314 | printf("%lu", resp->ru.ru_nivcsw); |
340 | break; | 315 | break; |
341 | case 'e': /* Elapsed real time in seconds. */ | 316 | case 'e': /* Elapsed real time in seconds. */ |
342 | printf("%ld.%02ld", | 317 | printf("%u.%02u", |
343 | resp->elapsed.tv_sec, resp->elapsed.tv_usec / 10000); | 318 | (unsigned)resp->elapsed_ms / 1000, |
319 | (unsigned)(resp->elapsed_ms / 10) % 100); | ||
344 | break; | 320 | break; |
345 | case 'k': /* Signals delivered. */ | 321 | case 'k': /* Signals delivered. */ |
346 | printf("%ld", resp->ru.ru_nsignals); | 322 | printf("%lu", resp->ru.ru_nsignals); |
347 | break; | 323 | break; |
348 | case 'p': /* Average stack segment. */ | 324 | case 'p': /* Average stack segment. */ |
349 | printf("%lu", | 325 | printf("%lu", ptok((UL) resp->ru.ru_isrss) / cpu_ticks); |
350 | MSEC_TO_TICKS(v) == 0 ? 0 : | ||
351 | ptok((UL) resp->ru.ru_isrss) / MSEC_TO_TICKS(v)); | ||
352 | break; | 326 | break; |
353 | case 'r': /* Incoming socket messages received. */ | 327 | case 'r': /* Incoming socket messages received. */ |
354 | printf("%ld", resp->ru.ru_msgrcv); | 328 | printf("%lu", resp->ru.ru_msgrcv); |
355 | break; | 329 | break; |
356 | case 's': /* Outgoing socket messages sent. */ | 330 | case 's': /* Outgoing socket messages sent. */ |
357 | printf("%ld", resp->ru.ru_msgsnd); | 331 | printf("%lu", resp->ru.ru_msgsnd); |
358 | break; | 332 | break; |
359 | case 't': /* Average resident set size. */ | 333 | case 't': /* Average resident set size. */ |
360 | printf("%lu", | 334 | printf("%lu", ptok((UL) resp->ru.ru_idrss) / cpu_ticks); |
361 | MSEC_TO_TICKS(v) == 0 ? 0 : | ||
362 | ptok((UL) resp->ru.ru_idrss) / MSEC_TO_TICKS(v)); | ||
363 | break; | 335 | break; |
364 | case 'w': /* Voluntary context switches. */ | 336 | case 'w': /* Voluntary context switches. */ |
365 | printf("%ld", resp->ru.ru_nvcsw); | 337 | printf("%lu", resp->ru.ru_nvcsw); |
366 | break; | 338 | break; |
367 | case 'x': /* Exit status. */ | 339 | case 'x': /* Exit status. */ |
368 | printf("%d", WEXITSTATUS(resp->waitstatus)); | 340 | printf("%u", WEXITSTATUS(resp->waitstatus)); |
369 | break; | 341 | break; |
370 | } | 342 | } |
371 | break; | 343 | break; |
@@ -403,7 +375,7 @@ static void run_command(char *const *cmd, resource_t * resp) | |||
403 | pid_t pid; /* Pid of child. */ | 375 | pid_t pid; /* Pid of child. */ |
404 | __sighandler_t interrupt_signal, quit_signal; | 376 | __sighandler_t interrupt_signal, quit_signal; |
405 | 377 | ||
406 | gettimeofday(&resp->start, (struct timezone *) 0); | 378 | resp->elapsed_ms = monotonic_us() / 1000; |
407 | pid = vfork(); /* Run CMD as child process. */ | 379 | pid = vfork(); /* Run CMD as child process. */ |
408 | if (pid < 0) | 380 | if (pid < 0) |
409 | bb_error_msg_and_die("cannot fork"); | 381 | bb_error_msg_and_die("cannot fork"); |
diff --git a/networking/arping.c b/networking/arping.c index 1b2604902..a022e70ea 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -8,9 +8,6 @@ | |||
8 | * Busybox port: Nick Fedchik <nick@fedchik.org.ua> | 8 | * Busybox port: Nick Fedchik <nick@fedchik.org.ua> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | //#include <sys/ioctl.h> | ||
12 | //#include <signal.h> | ||
13 | |||
14 | #include <arpa/inet.h> | 11 | #include <arpa/inet.h> |
15 | #include <net/if.h> | 12 | #include <net/if.h> |
16 | #include <netinet/ether.h> | 13 | #include <netinet/ether.h> |
@@ -18,42 +15,42 @@ | |||
18 | 15 | ||
19 | #include "libbb.h" | 16 | #include "libbb.h" |
20 | 17 | ||
18 | /* We don't expect to see 1000+ seconds delay, unsigned is enough */ | ||
19 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | ||
20 | |||
21 | static struct in_addr src; | 21 | static struct in_addr src; |
22 | static struct in_addr dst; | 22 | static struct in_addr dst; |
23 | static struct sockaddr_ll me; | 23 | static struct sockaddr_ll me; |
24 | static struct sockaddr_ll he; | 24 | static struct sockaddr_ll he; |
25 | static struct timeval last; | 25 | static unsigned last; |
26 | 26 | ||
27 | enum cfg_e { | 27 | enum { |
28 | dad = 1, | 28 | DAD = 1, |
29 | unsolicited = 2, | 29 | UNSOLICITED = 2, |
30 | advert = 4, | 30 | ADVERT = 4, |
31 | quiet = 8, | 31 | QUIET = 8, |
32 | quit_on_reply = 16, | 32 | QUIT_ON_REPLY = 16, |
33 | broadcast_only = 32, | 33 | BCAST_ONLY = 32, |
34 | unicasting = 64 | 34 | UNICASTING = 64 |
35 | }; | 35 | }; |
36 | static int cfg; | 36 | static int cfg; |
37 | 37 | ||
38 | static int s; | 38 | static int s; |
39 | static unsigned count = UINT_MAX; | 39 | static unsigned count = UINT_MAX; |
40 | static unsigned timeout; | 40 | static unsigned timeout_us; |
41 | static int sent; | 41 | static int sent; |
42 | static int brd_sent; | 42 | static int brd_sent; |
43 | static int received; | 43 | static int received; |
44 | static int brd_recv; | 44 | static int brd_recv; |
45 | static int req_recv; | 45 | static int req_recv; |
46 | 46 | ||
47 | #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ | ||
48 | ((tv1).tv_usec-(tv2).tv_usec)/1000 ) | ||
49 | |||
50 | static int send_pack(int sock, struct in_addr *src_addr, | 47 | static int send_pack(int sock, struct in_addr *src_addr, |
51 | struct in_addr *dst_addr, struct sockaddr_ll *ME, | 48 | struct in_addr *dst_addr, struct sockaddr_ll *ME, |
52 | struct sockaddr_ll *HE) | 49 | struct sockaddr_ll *HE) |
53 | { | 50 | { |
54 | int err; | 51 | int err; |
55 | struct timeval now; | 52 | unsigned now; |
56 | RESERVE_CONFIG_UBUFFER(buf, 256); | 53 | unsigned char buf[256]; |
57 | struct arphdr *ah = (struct arphdr *) buf; | 54 | struct arphdr *ah = (struct arphdr *) buf; |
58 | unsigned char *p = (unsigned char *) (ah + 1); | 55 | unsigned char *p = (unsigned char *) (ah + 1); |
59 | 56 | ||
@@ -62,7 +59,7 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
62 | ah->ar_pro = htons(ETH_P_IP); | 59 | ah->ar_pro = htons(ETH_P_IP); |
63 | ah->ar_hln = ME->sll_halen; | 60 | ah->ar_hln = ME->sll_halen; |
64 | ah->ar_pln = 4; | 61 | ah->ar_pln = 4; |
65 | ah->ar_op = cfg & advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); | 62 | ah->ar_op = cfg & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); |
66 | 63 | ||
67 | memcpy(p, &ME->sll_addr, ah->ar_hln); | 64 | memcpy(p, &ME->sll_addr, ah->ar_hln); |
68 | p += ME->sll_halen; | 65 | p += ME->sll_halen; |
@@ -70,7 +67,7 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
70 | memcpy(p, src_addr, 4); | 67 | memcpy(p, src_addr, 4); |
71 | p += 4; | 68 | p += 4; |
72 | 69 | ||
73 | if (cfg & advert) | 70 | if (cfg & ADVERT) |
74 | memcpy(p, &ME->sll_addr, ah->ar_hln); | 71 | memcpy(p, &ME->sll_addr, ah->ar_hln); |
75 | else | 72 | else |
76 | memcpy(p, &HE->sll_addr, ah->ar_hln); | 73 | memcpy(p, &HE->sll_addr, ah->ar_hln); |
@@ -79,21 +76,21 @@ static int send_pack(int sock, struct in_addr *src_addr, | |||
79 | memcpy(p, dst_addr, 4); | 76 | memcpy(p, dst_addr, 4); |
80 | p += 4; | 77 | p += 4; |
81 | 78 | ||
82 | gettimeofday(&now, NULL); | 79 | now = MONOTONIC_US(); |
83 | err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE)); | 80 | err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE)); |
84 | if (err == p - buf) { | 81 | if (err == p - buf) { |
85 | last = now; | 82 | last = now; |
86 | sent++; | 83 | sent++; |
87 | if (!(cfg & unicasting)) | 84 | if (!(cfg & UNICASTING)) |
88 | brd_sent++; | 85 | brd_sent++; |
89 | } | 86 | } |
90 | RELEASE_CONFIG_BUFFER(buf); | ||
91 | return err; | 87 | return err; |
92 | } | 88 | } |
93 | 89 | ||
90 | static void finish(void) ATTRIBUTE_NORETURN; | ||
94 | static void finish(void) | 91 | static void finish(void) |
95 | { | 92 | { |
96 | if (!(cfg & quiet)) { | 93 | if (!(cfg & QUIET)) { |
97 | printf("Sent %d probe(s) (%d broadcast(s))\n" | 94 | printf("Sent %d probe(s) (%d broadcast(s))\n" |
98 | "Received %d repl%s" | 95 | "Received %d repl%s" |
99 | " (%d request(s), %d broadcast(s))\n", | 96 | " (%d request(s), %d broadcast(s))\n", |
@@ -101,30 +98,31 @@ static void finish(void) | |||
101 | received, (received == 1) ? "ies" : "y", | 98 | received, (received == 1) ? "ies" : "y", |
102 | req_recv, brd_recv); | 99 | req_recv, brd_recv); |
103 | } | 100 | } |
104 | if (cfg & dad) | 101 | if (cfg & DAD) |
105 | exit(!!received); | 102 | exit(!!received); |
106 | if (cfg & unsolicited) | 103 | if (cfg & UNSOLICITED) |
107 | exit(0); | 104 | exit(0); |
108 | exit(!received); | 105 | exit(!received); |
109 | } | 106 | } |
110 | 107 | ||
111 | static void catcher(void) | 108 | static void catcher(void) |
112 | { | 109 | { |
113 | struct timeval tv; | 110 | static unsigned start; |
114 | static struct timeval start; | ||
115 | 111 | ||
116 | gettimeofday(&tv, NULL); | 112 | unsigned now; |
117 | 113 | ||
118 | if (start.tv_sec == 0) | 114 | now = MONOTONIC_US(); |
119 | start = tv; | 115 | if (start == 0) |
116 | start = now; | ||
120 | 117 | ||
121 | if (count-- == 0 | 118 | if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000))) |
122 | || (timeout && MS_TDIFF(tv, start) > timeout * 1000 + 500)) | ||
123 | finish(); | 119 | finish(); |
124 | 120 | ||
125 | if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) { | 121 | count--; |
122 | |||
123 | if (last == 0 || (now - last) > 500000) { | ||
126 | send_pack(s, &src, &dst, &me, &he); | 124 | send_pack(s, &src, &dst, &me, &he); |
127 | if (count == 0 && (cfg & unsolicited)) | 125 | if (count == 0 && (cfg & UNSOLICITED)) |
128 | finish(); | 126 | finish(); |
129 | } | 127 | } |
130 | alarm(1); | 128 | alarm(1); |
@@ -162,7 +160,7 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
162 | return 0; | 160 | return 0; |
163 | memcpy(&src_ip, p + ah->ar_hln, 4); | 161 | memcpy(&src_ip, p + ah->ar_hln, 4); |
164 | memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); | 162 | memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); |
165 | if (!(cfg & dad)) { | 163 | if (!(cfg & DAD)) { |
166 | if (src_ip.s_addr != dst.s_addr) | 164 | if (src_ip.s_addr != dst.s_addr) |
167 | return 0; | 165 | return 0; |
168 | if (src.s_addr != dst_ip.s_addr) | 166 | if (src.s_addr != dst_ip.s_addr) |
@@ -190,11 +188,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
190 | if (src.s_addr && src.s_addr != dst_ip.s_addr) | 188 | if (src.s_addr && src.s_addr != dst_ip.s_addr) |
191 | return 0; | 189 | return 0; |
192 | } | 190 | } |
193 | if (!(cfg & quiet)) { | 191 | if (!(cfg & QUIET)) { |
194 | int s_printed = 0; | 192 | int s_printed = 0; |
195 | struct timeval tv; | ||
196 | |||
197 | gettimeofday(&tv, NULL); | ||
198 | 193 | ||
199 | printf("%scast re%s from %s [%s]", | 194 | printf("%scast re%s from %s [%s]", |
200 | FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", | 195 | FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", |
@@ -212,13 +207,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
212 | ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); | 207 | ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); |
213 | } | 208 | } |
214 | 209 | ||
215 | if (last.tv_sec) { | 210 | if (last) { |
216 | long usecs = (tv.tv_sec - last.tv_sec) * 1000000 + | 211 | printf(" %u.%03ums\n", last / 1000, last % 1000); |
217 | tv.tv_usec - last.tv_usec; | ||
218 | long msecs = (usecs + 500) / 1000; | ||
219 | |||
220 | usecs -= msecs * 1000 - 500; | ||
221 | printf(" %ld.%03ldms\n", msecs, usecs); | ||
222 | } else { | 212 | } else { |
223 | printf(" UNSOLICITED?\n"); | 213 | printf(" UNSOLICITED?\n"); |
224 | } | 214 | } |
@@ -229,11 +219,11 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) | |||
229 | brd_recv++; | 219 | brd_recv++; |
230 | if (ah->ar_op == htons(ARPOP_REQUEST)) | 220 | if (ah->ar_op == htons(ARPOP_REQUEST)) |
231 | req_recv++; | 221 | req_recv++; |
232 | if (cfg & quit_on_reply) | 222 | if (cfg & QUIT_ON_REPLY) |
233 | finish(); | 223 | finish(); |
234 | if (!(cfg & broadcast_only)) { | 224 | if (!(cfg & BCAST_ONLY)) { |
235 | memcpy(he.sll_addr, p, me.sll_halen); | 225 | memcpy(he.sll_addr, p, me.sll_halen); |
236 | cfg |= unicasting; | 226 | cfg |= UNICASTING; |
237 | } | 227 | } |
238 | return 1; | 228 | return 1; |
239 | } | 229 | } |
@@ -245,6 +235,7 @@ int arping_main(int argc, char **argv) | |||
245 | int ifindex; | 235 | int ifindex; |
246 | char *source = NULL; | 236 | char *source = NULL; |
247 | char *target; | 237 | char *target; |
238 | unsigned char *packet; | ||
248 | 239 | ||
249 | s = xsocket(PF_PACKET, SOCK_DGRAM, 0); | 240 | s = xsocket(PF_PACKET, SOCK_DGRAM, 0); |
250 | 241 | ||
@@ -258,28 +249,23 @@ int arping_main(int argc, char **argv) | |||
258 | /* Dad also sets quit_on_reply. | 249 | /* Dad also sets quit_on_reply. |
259 | * Advert also sets unsolicited. | 250 | * Advert also sets unsolicited. |
260 | */ | 251 | */ |
261 | opt_complementary = "Df:AU"; | 252 | opt_complementary = "=1:Df:AU"; |
262 | opt = getopt32(argc, argv, "DUAqfbc:w:I:s:", | 253 | opt = getopt32(argc, argv, "DUAqfbc:w:I:s:", |
263 | &_count, &_timeout, &device, &source); | 254 | &_count, &_timeout, &device, &source); |
264 | cfg |= opt & 0x3f; /* set respective flags */ | 255 | cfg |= opt & 0x3f; /* set respective flags */ |
265 | if (opt & 0x40) /* -c: count */ | 256 | if (opt & 0x40) /* -c: count */ |
266 | count = xatou(_count); | 257 | count = xatou(_count); |
267 | if (opt & 0x80) /* -w: timeout */ | 258 | if (opt & 0x80) /* -w: timeout */ |
268 | timeout = xatoul_range(_timeout, 0, INT_MAX/2000); | 259 | timeout_us = xatou_range(_timeout, 0, INT_MAX/2000000) * 1000000; |
269 | //if (opt & 0x100) /* -i: interface */ | 260 | //if (opt & 0x100) /* -I: interface */ |
270 | if (strlen(device) > IF_NAMESIZE) { | 261 | if (strlen(device) >= IF_NAMESIZE) { |
271 | bb_error_msg_and_die("interface name '%s' is too long", | 262 | bb_error_msg_and_die("interface name '%s' is too long", |
272 | device); | 263 | device); |
273 | } | 264 | } |
274 | //if (opt & 0x200) /* -s: source */ | 265 | //if (opt & 0x200) /* -s: source */ |
275 | } | 266 | } |
276 | argc -= optind; | ||
277 | argv += optind; | ||
278 | |||
279 | if (argc != 1) | ||
280 | bb_show_usage(); | ||
281 | 267 | ||
282 | target = *argv; | 268 | target = argv[optind]; |
283 | 269 | ||
284 | xfunc_error_retval = 2; | 270 | xfunc_error_retval = 2; |
285 | 271 | ||
@@ -301,7 +287,7 @@ int arping_main(int argc, char **argv) | |||
301 | } | 287 | } |
302 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { | 288 | if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { |
303 | bb_error_msg("interface %s is not ARPable", device); | 289 | bb_error_msg("interface %s is not ARPable", device); |
304 | return (cfg & dad ? 0 : 2); | 290 | return (cfg & DAD ? 0 : 2); |
305 | } | 291 | } |
306 | } | 292 | } |
307 | 293 | ||
@@ -317,10 +303,10 @@ int arping_main(int argc, char **argv) | |||
317 | bb_error_msg_and_die("invalid source address %s", source); | 303 | bb_error_msg_and_die("invalid source address %s", source); |
318 | } | 304 | } |
319 | 305 | ||
320 | if (!(cfg & dad) && (cfg & unsolicited) && src.s_addr == 0) | 306 | if (!(cfg & DAD) && (cfg & UNSOLICITED) && src.s_addr == 0) |
321 | src = dst; | 307 | src = dst; |
322 | 308 | ||
323 | if (!(cfg & dad) || src.s_addr) { | 309 | if (!(cfg & DAD) || src.s_addr) { |
324 | struct sockaddr_in saddr; | 310 | struct sockaddr_in saddr; |
325 | int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); | 311 | int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); |
326 | 312 | ||
@@ -333,7 +319,7 @@ int arping_main(int argc, char **argv) | |||
333 | if (src.s_addr) { | 319 | if (src.s_addr) { |
334 | saddr.sin_addr = src; | 320 | saddr.sin_addr = src; |
335 | xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); | 321 | xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); |
336 | } else if (!(cfg & dad)) { | 322 | } else if (!(cfg & DAD)) { |
337 | socklen_t alen = sizeof(saddr); | 323 | socklen_t alen = sizeof(saddr); |
338 | 324 | ||
339 | saddr.sin_port = htons(1025); | 325 | saddr.sin_port = htons(1025); |
@@ -364,18 +350,18 @@ int arping_main(int argc, char **argv) | |||
364 | } | 350 | } |
365 | if (me.sll_halen == 0) { | 351 | if (me.sll_halen == 0) { |
366 | bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); | 352 | bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); |
367 | return (cfg & dad ? 0 : 2); | 353 | return (cfg & DAD ? 0 : 2); |
368 | } | 354 | } |
369 | he = me; | 355 | he = me; |
370 | memset(he.sll_addr, -1, he.sll_halen); | 356 | memset(he.sll_addr, -1, he.sll_halen); |
371 | 357 | ||
372 | if (!(cfg & quiet)) { | 358 | if (!(cfg & QUIET)) { |
373 | printf("ARPING to %s from %s via %s\n", | 359 | printf("ARPING to %s from %s via %s\n", |
374 | inet_ntoa(dst), inet_ntoa(src), | 360 | inet_ntoa(dst), inet_ntoa(src), |
375 | device ? device : "unknown"); | 361 | device ? device : "unknown"); |
376 | } | 362 | } |
377 | 363 | ||
378 | if (!src.s_addr && !(cfg & dad)) { | 364 | if (!src.s_addr && !(cfg & DAD)) { |
379 | bb_error_msg_and_die("no src address in the non-DAD mode"); | 365 | bb_error_msg_and_die("no src address in the non-DAD mode"); |
380 | } | 366 | } |
381 | 367 | ||
@@ -394,9 +380,9 @@ int arping_main(int argc, char **argv) | |||
394 | 380 | ||
395 | catcher(); | 381 | catcher(); |
396 | 382 | ||
383 | packet = xmalloc(4096); | ||
397 | while (1) { | 384 | while (1) { |
398 | sigset_t sset, osset; | 385 | sigset_t sset, osset; |
399 | RESERVE_CONFIG_UBUFFER(packet, 4096); | ||
400 | struct sockaddr_ll from; | 386 | struct sockaddr_ll from; |
401 | socklen_t alen = sizeof(from); | 387 | socklen_t alen = sizeof(from); |
402 | int cc; | 388 | int cc; |
@@ -412,6 +398,5 @@ int arping_main(int argc, char **argv) | |||
412 | sigprocmask(SIG_BLOCK, &sset, &osset); | 398 | sigprocmask(SIG_BLOCK, &sset, &osset); |
413 | recv_pack(packet, cc, &from); | 399 | recv_pack(packet, cc, &from); |
414 | sigprocmask(SIG_SETMASK, &osset, NULL); | 400 | sigprocmask(SIG_SETMASK, &osset, NULL); |
415 | RELEASE_CONFIG_BUFFER(packet); | ||
416 | } | 401 | } |
417 | } | 402 | } |
diff --git a/networking/pscan.c b/networking/pscan.c index 10bf3b606..9fa6993e8 100644 --- a/networking/pscan.c +++ b/networking/pscan.c | |||
@@ -17,19 +17,6 @@ | |||
17 | #define DERR(...) ((void)0) | 17 | #define DERR(...) ((void)0) |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | /* return time in usec */ | ||
21 | // TODO: move to libbb and use in traceroute, zcip, arping etc | ||
22 | // (maybe also use absolute monotonic clock - no time warps | ||
23 | // due to admin resetting date/time?) | ||
24 | static unsigned gettimeofday_us(void) | ||
25 | { | ||
26 | struct timeval now; | ||
27 | |||
28 | if (gettimeofday(&now, NULL)) | ||
29 | return 0; | ||
30 | return (now.tv_sec * 1000000 + now.tv_usec); | ||
31 | } | ||
32 | |||
33 | static const char *port_name(unsigned port) | 20 | static const char *port_name(unsigned port) |
34 | { | 21 | { |
35 | struct servent *server; | 22 | struct servent *server; |
@@ -40,6 +27,9 @@ static const char *port_name(unsigned port) | |||
40 | return "unknown"; | 27 | return "unknown"; |
41 | } | 28 | } |
42 | 29 | ||
30 | /* We don't expect to see 1000+ seconds delay, unsigned is enough */ | ||
31 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | ||
32 | |||
43 | int pscan_main(int argc, char **argv); | 33 | int pscan_main(int argc, char **argv); |
44 | int pscan_main(int argc, char **argv) | 34 | int pscan_main(int argc, char **argv) |
45 | { | 35 | { |
@@ -91,7 +81,7 @@ int pscan_main(int argc, char **argv) | |||
91 | /* Nonblocking connect typically "fails" with errno == EINPROGRESS */ | 81 | /* Nonblocking connect typically "fails" with errno == EINPROGRESS */ |
92 | ndelay_on(s); | 82 | ndelay_on(s); |
93 | DMSG("connect to port %u", port); | 83 | DMSG("connect to port %u", port); |
94 | start = gettimeofday_us(); | 84 | start = MONOTONIC_US(); |
95 | if (connect(s, &lsap->sa, lsap->len) == 0) { | 85 | if (connect(s, &lsap->sa, lsap->len) == 0) { |
96 | /* Unlikely, for me even localhost fails :) */ | 86 | /* Unlikely, for me even localhost fails :) */ |
97 | DMSG("connect succeeded"); | 87 | DMSG("connect succeeded"); |
@@ -110,15 +100,15 @@ int pscan_main(int argc, char **argv) | |||
110 | closed_ports++; | 100 | closed_ports++; |
111 | break; | 101 | break; |
112 | } | 102 | } |
113 | DERR("port %u errno %d @%u", port, errno, gettimeofday_us() - start); | 103 | DERR("port %u errno %d @%u", port, errno, MONOTONIC_US() - start); |
114 | if ((gettimeofday_us() - start) > rtt_4) | 104 | if ((MONOTONIC_US() - start) > rtt_4) |
115 | break; | 105 | break; |
116 | /* Can sleep (much) longer than specified delay. | 106 | /* Can sleep (much) longer than specified delay. |
117 | * We check rtt BEFORE we usleep, otherwise | 107 | * We check rtt BEFORE we usleep, otherwise |
118 | * on localhost we'll do zero writes done (!) | 108 | * on localhost we'll do zero writes done (!) |
119 | * before we exceed (rather small) rtt */ | 109 | * before we exceed (rather small) rtt */ |
120 | usleep(rtt_4/8); | 110 | usleep(rtt_4/8); |
121 | DMSG("write to port %u @%u", port, gettimeofday_us() - start); | 111 | DMSG("write to port %u @%u", port, MONOTONIC_US() - start); |
122 | if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */ | 112 | if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */ |
123 | open: | 113 | open: |
124 | open_ports++; | 114 | open_ports++; |
@@ -126,13 +116,13 @@ int pscan_main(int argc, char **argv) | |||
126 | break; | 116 | break; |
127 | } | 117 | } |
128 | } | 118 | } |
129 | DMSG("out of loop @%u", gettimeofday_us() - start); | 119 | DMSG("out of loop @%u", MONOTONIC_US() - start); |
130 | 120 | ||
131 | /* Estimate new rtt - we don't want to wait entire timeout | 121 | /* Estimate new rtt - we don't want to wait entire timeout |
132 | * for each port. *4 allows for rise in net delay. | 122 | * for each port. *4 allows for rise in net delay. |
133 | * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2) | 123 | * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2) |
134 | * because we don't want to accidentally miss ports. */ | 124 | * because we don't want to accidentally miss ports. */ |
135 | rtt_4 = (gettimeofday_us() - start) * 4; | 125 | rtt_4 = (MONOTONIC_US() - start) * 4; |
136 | if (rtt_4 < min_rtt) | 126 | if (rtt_4 < min_rtt) |
137 | rtt_4 = min_rtt; | 127 | rtt_4 = min_rtt; |
138 | if (rtt_4 > timeout) | 128 | if (rtt_4 > timeout) |
diff --git a/networking/traceroute.c b/networking/traceroute.c index 40533a82d..9fc15d390 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -275,7 +275,8 @@ struct hostinfo { | |||
275 | struct outdata { | 275 | struct outdata { |
276 | unsigned char seq; /* sequence number of this packet */ | 276 | unsigned char seq; /* sequence number of this packet */ |
277 | unsigned char ttl; /* ttl packet left with */ | 277 | unsigned char ttl; /* ttl packet left with */ |
278 | struct timeval tv ATTRIBUTE_PACKED; /* time packet left */ | 278 | // UNUSED. Retaining to have the same packet size. |
279 | struct timeval tv_UNUSED ATTRIBUTE_PACKED; /* time packet left */ | ||
279 | }; | 280 | }; |
280 | 281 | ||
281 | struct IFADDRLIST { | 282 | struct IFADDRLIST { |
@@ -533,37 +534,19 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) | |||
533 | 534 | ||
534 | */ | 535 | */ |
535 | 536 | ||
536 | /* | ||
537 | * Subtract 2 timeval structs: out = out - in. | ||
538 | * Out is assumed to be >= in. | ||
539 | */ | ||
540 | static inline void | ||
541 | tvsub(struct timeval *out, struct timeval *in) | ||
542 | { | ||
543 | |||
544 | if ((out->tv_usec -= in->tv_usec) < 0) { | ||
545 | --out->tv_sec; | ||
546 | out->tv_usec += 1000000; | ||
547 | } | ||
548 | out->tv_sec -= in->tv_sec; | ||
549 | } | ||
550 | |||
551 | static int | 537 | static int |
552 | wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp) | 538 | wait_for_reply(int sock, struct sockaddr_in *fromp) |
553 | { | 539 | { |
554 | fd_set fds; | 540 | fd_set fds; |
555 | struct timeval now, tvwait; | 541 | struct timeval tvwait; |
556 | struct timezone tz; | ||
557 | int cc = 0; | 542 | int cc = 0; |
558 | socklen_t fromlen = sizeof(*fromp); | 543 | socklen_t fromlen = sizeof(*fromp); |
559 | 544 | ||
560 | FD_ZERO(&fds); | 545 | FD_ZERO(&fds); |
561 | FD_SET(sock, &fds); | 546 | FD_SET(sock, &fds); |
562 | 547 | ||
563 | tvwait.tv_sec = tp->tv_sec + waittime; | 548 | tvwait.tv_sec = waittime; |
564 | tvwait.tv_usec = tp->tv_usec; | 549 | tvwait.tv_usec = 0; |
565 | (void)gettimeofday(&now, &tz); | ||
566 | tvsub(&tvwait, &now); | ||
567 | 550 | ||
568 | if (select(sock + 1, &fds, NULL, NULL, &tvwait) > 0) | 551 | if (select(sock + 1, &fds, NULL, NULL, &tvwait) > 0) |
569 | cc = recvfrom(sock, (char *)packet, sizeof(packet), 0, | 552 | cc = recvfrom(sock, (char *)packet, sizeof(packet), 0, |
@@ -609,7 +592,7 @@ in_cksum(uint16_t *addr, int len) | |||
609 | 592 | ||
610 | 593 | ||
611 | static void | 594 | static void |
612 | send_probe(int seq, int ttl, struct timeval *tp) | 595 | send_probe(int seq, int ttl) |
613 | { | 596 | { |
614 | int cc; | 597 | int cc; |
615 | struct udpiphdr *ui, *oui; | 598 | struct udpiphdr *ui, *oui; |
@@ -633,7 +616,8 @@ send_probe(int seq, int ttl, struct timeval *tp) | |||
633 | /* Payload */ | 616 | /* Payload */ |
634 | outdata->seq = seq; | 617 | outdata->seq = seq; |
635 | outdata->ttl = ttl; | 618 | outdata->ttl = ttl; |
636 | memcpy(&outdata->tv, tp, sizeof(outdata->tv)); | 619 | // UNUSED: was storing gettimeofday's result there, but never ever checked it |
620 | /*memcpy(&outdata->tv, tp, sizeof(outdata->tv));*/ | ||
637 | 621 | ||
638 | #if ENABLE_FEATURE_TRACEROUTE_USE_ICMP | 622 | #if ENABLE_FEATURE_TRACEROUTE_USE_ICMP |
639 | if (useicmp) | 623 | if (useicmp) |
@@ -706,7 +690,6 @@ send_probe(int seq, int ttl, struct timeval *tp) | |||
706 | packlen, (struct sockaddr *)&whereto, sizeof(whereto)); | 690 | packlen, (struct sockaddr *)&whereto, sizeof(whereto)); |
707 | if (cc != packlen) { | 691 | if (cc != packlen) { |
708 | bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); | 692 | bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); |
709 | // (void)fflush(stdout); | ||
710 | } | 693 | } |
711 | } | 694 | } |
712 | 695 | ||
@@ -908,9 +891,9 @@ getaddr(uint32_t *ap, const char *host) | |||
908 | #endif | 891 | #endif |
909 | 892 | ||
910 | static void | 893 | static void |
911 | print_delta_ms(struct timeval *t1p, struct timeval *t2p) | 894 | print_delta_ms(unsigned t1p, unsigned t2p) |
912 | { | 895 | { |
913 | unsigned tt = (t2p->tv_sec - t1p->tv_sec) * 1000000 + (t2p->tv_usec - t1p->tv_usec); | 896 | unsigned tt = t2p - t1p; |
914 | printf(" %u.%03u ms", tt/1000, tt%1000); | 897 | printf(" %u.%03u ms", tt/1000, tt%1000); |
915 | } | 898 | } |
916 | 899 | ||
@@ -1230,17 +1213,17 @@ int traceroute_main(int argc, char **argv) | |||
1230 | printf("%2d ", ttl); | 1213 | printf("%2d ", ttl); |
1231 | for (probe = 0; probe < nprobes; ++probe) { | 1214 | for (probe = 0; probe < nprobes; ++probe) { |
1232 | int cc; | 1215 | int cc; |
1233 | struct timeval t1, t2; | 1216 | unsigned t1; |
1234 | struct timezone tz; | 1217 | unsigned t2; |
1235 | struct ip *ip; | 1218 | struct ip *ip; |
1236 | 1219 | ||
1237 | if (sentfirst && pausemsecs > 0) | 1220 | if (sentfirst && pausemsecs > 0) |
1238 | usleep(pausemsecs * 1000); | 1221 | usleep(pausemsecs * 1000); |
1239 | (void)gettimeofday(&t1, &tz); | 1222 | t1 = monotonic_us(); |
1240 | send_probe(++seq, ttl, &t1); | 1223 | send_probe(++seq, ttl); |
1241 | ++sentfirst; | 1224 | ++sentfirst; |
1242 | while ((cc = wait_for_reply(s, from, &t1)) != 0) { | 1225 | while ((cc = wait_for_reply(s, from)) != 0) { |
1243 | (void)gettimeofday(&t2, &tz); | 1226 | t2 = monotonic_us(); |
1244 | i = packet_ok(packet, cc, from, seq); | 1227 | i = packet_ok(packet, cc, from, seq); |
1245 | /* Skip short packet */ | 1228 | /* Skip short packet */ |
1246 | if (i == 0) | 1229 | if (i == 0) |
@@ -1251,7 +1234,7 @@ int traceroute_main(int argc, char **argv) | |||
1251 | lastaddr = from->sin_addr.s_addr; | 1234 | lastaddr = from->sin_addr.s_addr; |
1252 | ++gotlastaddr; | 1235 | ++gotlastaddr; |
1253 | } | 1236 | } |
1254 | print_delta_ms(&t1, &t2); | 1237 | print_delta_ms(t1, t2); |
1255 | ip = (struct ip *)packet; | 1238 | ip = (struct ip *)packet; |
1256 | if (op & OPT_TTL_FLAG) | 1239 | if (op & OPT_TTL_FLAG) |
1257 | printf(" (%d)", ip->ip_ttl); | 1240 | printf(" (%d)", ip->ip_ttl); |
diff --git a/networking/wget.c b/networking/wget.c index fe669bbdd..fc7f7c32c 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -705,7 +705,7 @@ progressmeter(int flag) | |||
705 | ratio = 100; | 705 | ratio = 100; |
706 | if (totalsize != 0 && !chunked) { | 706 | if (totalsize != 0 && !chunked) { |
707 | /* long long helps to have working ETA even if !LFS */ | 707 | /* long long helps to have working ETA even if !LFS */ |
708 | ratio = (int) (100 * (unsigned long long)(transferred+beg_range) / totalsize); | 708 | ratio = (int) (100ULL * (transferred+beg_range) / totalsize); |
709 | ratio = MIN(ratio, 100); | 709 | ratio = MIN(ratio, 100); |
710 | } | 710 | } |
711 | 711 | ||
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index c4b793ef8..204a103c3 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | //#include <sys/ioctl.h> | ||
11 | #include <sys/utsname.h> | 10 | #include <sys/utsname.h> |
12 | #include <getopt.h> | 11 | #include <getopt.h> |
13 | #include "libbb.h" | 12 | #include "libbb.h" |
@@ -98,49 +97,42 @@ static void write_rtc(time_t t, int utc) | |||
98 | close(rtc); | 97 | close(rtc); |
99 | } | 98 | } |
100 | 99 | ||
101 | static int show_clock(int utc) | 100 | static void show_clock(int utc) |
102 | { | 101 | { |
103 | struct tm *ptm; | 102 | //struct tm *ptm; |
104 | time_t t; | 103 | time_t t; |
105 | RESERVE_CONFIG_BUFFER(buffer, 64); | 104 | char *cp; |
106 | 105 | ||
107 | t = read_rtc(utc); | 106 | t = read_rtc(utc); |
108 | ptm = localtime(&t); /* Sets 'tzname[]' */ | 107 | //ptm = localtime(&t); /* Sets 'tzname[]' */ |
109 | 108 | ||
110 | safe_strncpy(buffer, ctime(&t), 64); | 109 | cp = ctime(&t); |
111 | if (buffer[0]) | 110 | if (cp[0]) |
112 | buffer[strlen(buffer) - 1] = 0; | 111 | cp[strlen(cp) - 1] = '\0'; |
113 | 112 | ||
114 | //printf("%s %.6f seconds %s\n", buffer, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); | 113 | //printf("%s %.6f seconds %s\n", cp, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); |
115 | printf( "%s %.6f seconds\n", buffer, 0.0); | 114 | printf("%s 0.000000 seconds\n", cp); |
116 | RELEASE_CONFIG_BUFFER(buffer); | ||
117 | |||
118 | return 0; | ||
119 | } | 115 | } |
120 | 116 | ||
121 | static int to_sys_clock(int utc) | 117 | static void to_sys_clock(int utc) |
122 | { | 118 | { |
123 | struct timeval tv = { 0, 0 }; | 119 | struct timeval tv; |
124 | const struct timezone tz = { timezone/60 - 60*daylight, 0 }; | 120 | const struct timezone tz = { timezone/60 - 60*daylight, 0 }; |
125 | 121 | ||
126 | tv.tv_sec = read_rtc(utc); | 122 | tv.tv_sec = read_rtc(utc); |
127 | 123 | tv.tv_usec = 0; | |
128 | if (settimeofday(&tv, &tz)) | 124 | if (settimeofday(&tv, &tz)) |
129 | bb_perror_msg_and_die("settimeofday() failed"); | 125 | bb_perror_msg_and_die("settimeofday() failed"); |
130 | |||
131 | return 0; | ||
132 | } | 126 | } |
133 | 127 | ||
134 | static int from_sys_clock(int utc) | 128 | static void from_sys_clock(int utc) |
135 | { | 129 | { |
136 | struct timeval tv = { 0, 0 }; | 130 | struct timeval tv; |
137 | struct timezone tz = { 0, 0 }; | ||
138 | |||
139 | if (gettimeofday(&tv, &tz)) | ||
140 | bb_perror_msg_and_die("gettimeofday() failed"); | ||
141 | 131 | ||
132 | gettimeofday(&tv, NULL); | ||
133 | //if (gettimeofday(&tv, NULL)) | ||
134 | // bb_perror_msg_and_die("gettimeofday() failed"); | ||
142 | write_rtc(tv.tv_sec, utc); | 135 | write_rtc(tv.tv_sec, utc); |
143 | return 0; | ||
144 | } | 136 | } |
145 | 137 | ||
146 | #ifdef CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS | 138 | #ifdef CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS |
@@ -182,8 +174,8 @@ static int check_utc(void) | |||
182 | #define HWCLOCK_OPT_SYSTOHC 0x10 | 174 | #define HWCLOCK_OPT_SYSTOHC 0x10 |
183 | #define HWCLOCK_OPT_RTCFILE 0x20 | 175 | #define HWCLOCK_OPT_RTCFILE 0x20 |
184 | 176 | ||
185 | int hwclock_main(int argc, char **argv ); | 177 | int hwclock_main(int argc, char **argv); |
186 | int hwclock_main(int argc, char **argv ) | 178 | int hwclock_main(int argc, char **argv) |
187 | { | 179 | { |
188 | unsigned opt; | 180 | unsigned opt; |
189 | int utc; | 181 | int utc; |
@@ -210,12 +202,14 @@ int hwclock_main(int argc, char **argv ) | |||
210 | utc = check_utc(); | 202 | utc = check_utc(); |
211 | 203 | ||
212 | if (opt & HWCLOCK_OPT_HCTOSYS) { | 204 | if (opt & HWCLOCK_OPT_HCTOSYS) { |
213 | return to_sys_clock(utc); | 205 | to_sys_clock(utc); |
206 | return 0; | ||
214 | } | 207 | } |
215 | else if (opt & HWCLOCK_OPT_SYSTOHC) { | 208 | if (opt & HWCLOCK_OPT_SYSTOHC) { |
216 | return from_sys_clock(utc); | 209 | from_sys_clock(utc); |
217 | } else { | 210 | return 0; |
218 | /* default HWCLOCK_OPT_SHOW */ | ||
219 | return show_clock(utc); | ||
220 | } | 211 | } |
212 | /* default HWCLOCK_OPT_SHOW */ | ||
213 | show_clock(utc); | ||
214 | return 0; | ||
221 | } | 215 | } |