aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 13:36:48 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 13:36:48 +1000
commit6e55663080e33d1856d949d60e45b135f2613087 (patch)
tree7318387028176038ca96344831febb30a582d661
parentc6933c626b97c3f6bc446586ee2e6c7d9930c938 (diff)
parentdcaed97e0f44d0cd285fb590ec6ec80d0d73e738 (diff)
downloadbusybox-w32-6e55663080e33d1856d949d60e45b135f2613087.tar.gz
busybox-w32-6e55663080e33d1856d949d60e45b135f2613087.tar.bz2
busybox-w32-6e55663080e33d1856d949d60e45b135f2613087.zip
Merge branch 'origin/master' (early part)
-rw-r--r--README2
-rw-r--r--TEST_config_rh91
-rw-r--r--coreutils/cut.c4
-rw-r--r--coreutils/date.c2
-rw-r--r--debianutils/start_stop_daemon.c2
-rw-r--r--docs/new-applet-HOWTO.txt11
-rw-r--r--e2fsprogs/fsck.c4
-rw-r--r--e2fsprogs/old_e2fsprogs/mke2fs.c6
-rw-r--r--findutils/find.c2
-rw-r--r--include/libbb.h11
-rw-r--r--include/usage.src.h30
-rw-r--r--libbb/getopt32.c6
-rw-r--r--libbb/progress.c55
-rw-r--r--libbb/rtc.c7
-rw-r--r--libbb/xatonum.c2
-rw-r--r--miscutils/fbsplash.c2
-rw-r--r--miscutils/hdparm.c4
-rw-r--r--miscutils/ionice.c2
-rw-r--r--miscutils/makedevs.c8
-rw-r--r--miscutils/mt.c2
-rw-r--r--miscutils/rfkill.c2
-rw-r--r--modutils/modutils-24.c21
-rw-r--r--networking/Config.src12
-rw-r--r--networking/brctl.c2
-rw-r--r--networking/ftpd.c2
-rw-r--r--networking/udhcp/Config.src2
-rw-r--r--networking/wget.c123
-rw-r--r--printutils/lpd.c2
-rw-r--r--procps/free.c28
-rw-r--r--procps/iostat.c618
-rw-r--r--procps/mpstat.c6
-rw-r--r--procps/nmeter.c2
-rw-r--r--runit/svlogd.c6
-rw-r--r--shell/ash.c108
-rw-r--r--shell/ash_test/ash-vars/var_bash4.right25
-rwxr-xr-xshell/ash_test/ash-vars/var_bash4.tests51
-rw-r--r--shell/hush.c2
-rwxr-xr-xtestsuite/cpio.tests2
-rw-r--r--testsuite/date/date-works-13
-rw-r--r--testsuite/du/du-k-works4
-rw-r--r--testsuite/du/du-l-works3
-rw-r--r--testsuite/hostname/hostname-d-works4
-rwxr-xr-xtestsuite/makedevs.tests4
-rwxr-xr-xtestsuite/tar.tests6
-rwxr-xr-xtestsuite/uuencode.tests3
-rw-r--r--util-linux/Config.src2
-rw-r--r--util-linux/fdisk_osf.c3
-rw-r--r--util-linux/flock.c2
-rw-r--r--util-linux/hexdump.c2
-rw-r--r--util-linux/mount.c2
50 files changed, 990 insertions, 225 deletions
diff --git a/README b/README
index 3a9d849a6..a3a725a5d 100644
--- a/README
+++ b/README
@@ -80,7 +80,7 @@ Downloading the current source code:
80 The developers also have a bug and patch tracking system 80 The developers also have a bug and patch tracking system
81 (https://bugs.busybox.net) although posting a bug/patch to the mailing list 81 (https://bugs.busybox.net) although posting a bug/patch to the mailing list
82 is generally a faster way of getting it fixed, and the complete archive of 82 is generally a faster way of getting it fixed, and the complete archive of
83 what happened is the subversion changelog. 83 what happened is the git changelog.
84 84
85 Note: if you want to compile busybox in a busybox environment you must 85 Note: if you want to compile busybox in a busybox environment you must
86 select CONFIG_DESKTOP. 86 select CONFIG_DESKTOP.
diff --git a/TEST_config_rh9 b/TEST_config_rh9
index f376cd439..3ffb1c6f3 100644
--- a/TEST_config_rh9
+++ b/TEST_config_rh9
@@ -803,6 +803,7 @@ CONFIG_WGET=y
803CONFIG_FEATURE_WGET_STATUSBAR=y 803CONFIG_FEATURE_WGET_STATUSBAR=y
804CONFIG_FEATURE_WGET_AUTHENTICATION=y 804CONFIG_FEATURE_WGET_AUTHENTICATION=y
805CONFIG_FEATURE_WGET_LONG_OPTIONS=y 805CONFIG_FEATURE_WGET_LONG_OPTIONS=y
806CONFIG_FEATURE_WGET_TIMEOUT=y
806CONFIG_ZCIP=y 807CONFIG_ZCIP=y
807 808
808# 809#
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 696478bb2..b7a3cfabb 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -224,7 +224,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
224 if (!ntok[0]) { 224 if (!ntok[0]) {
225 s = BOL; 225 s = BOL;
226 } else { 226 } else {
227 s = xatoi_u(ntok); 227 s = xatoi_positive(ntok);
228 /* account for the fact that arrays are zero based, while 228 /* account for the fact that arrays are zero based, while
229 * the user expects the first char on the line to be char #1 */ 229 * the user expects the first char on the line to be char #1 */
230 if (s != 0) 230 if (s != 0)
@@ -237,7 +237,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
237 } else if (!ltok[0]) { 237 } else if (!ltok[0]) {
238 e = EOL; 238 e = EOL;
239 } else { 239 } else {
240 e = xatoi_u(ltok); 240 e = xatoi_positive(ltok);
241 /* if the user specified and end position of 0, 241 /* if the user specified and end position of 0,
242 * that means "til the end of the line" */ 242 * that means "til the end of the line" */
243 if (e == 0) 243 if (e == 0)
diff --git a/coreutils/date.c b/coreutils/date.c
index cb41724af..3ce352c8d 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -300,7 +300,7 @@ int date_main(int argc UNUSED_PARAM, char **argv)
300 scale = 1; 300 scale = 1;
301 pres = 9; 301 pres = 9;
302 if (n) { 302 if (n) {
303 pres = xatoi_u(p); 303 pres = xatoi_positive(p);
304 if (pres == 0) 304 if (pres == 0)
305 pres = 9; 305 pres = 9;
306 m = 9 - pres; 306 m = 9 - pres;
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 665f38fbd..568f32eec 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -373,7 +373,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
373 373
374// IF_FEATURE_START_STOP_DAEMON_FANCY( 374// IF_FEATURE_START_STOP_DAEMON_FANCY(
375// if (retry_arg) 375// if (retry_arg)
376// retries = xatoi_u(retry_arg); 376// retries = xatoi_positive(retry_arg);
377// ) 377// )
378 //argc -= optind; 378 //argc -= optind;
379 argv += optind; 379 argv += optind;
diff --git a/docs/new-applet-HOWTO.txt b/docs/new-applet-HOWTO.txt
index 0646e728e..7fbd62ed1 100644
--- a/docs/new-applet-HOWTO.txt
+++ b/docs/new-applet-HOWTO.txt
@@ -8,7 +8,7 @@ Matt Kraai - initial writeup
8Mark Whitley - the remix 8Mark Whitley - the remix
9Thomas Lundquist - Trying to keep it updated. 9Thomas Lundquist - Trying to keep it updated.
10 10
11When doing this you should consider using the latest svn trunk. 11When doing this you should consider using the latest git HEAD.
12This is a good thing if you plan to getting it committed into mainline. 12This is a good thing if you plan to getting it committed into mainline.
13 13
14Initial Write 14Initial Write
@@ -169,12 +169,13 @@ Be sure to read the top of applets.h before adding your applet.
169The Grand Announcement 169The Grand Announcement
170---------------------- 170----------------------
171 171
172Then create a diff by adding the new files with svn (remember your libbb files) 172Then create a diff by adding the new files to git (remember your libbb files)
173 svn add <where you put it>/mu.c 173 git add <where you put it>/mu.c
174eventually also: 174eventually also:
175 svn add libbb/function.c 175 git add libbb/function.c
176then 176then
177 svn diff 177 git commit
178 git format-patch HEAD^
178and send it to the mailing list: 179and send it to the mailing list:
179 busybox@busybox.net 180 busybox@busybox.net
180 http://busybox.net/mailman/listinfo/busybox 181 http://busybox.net/mailman/listinfo/busybox
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c
index 7c449e3e7..d694bb110 100644
--- a/e2fsprogs/fsck.c
+++ b/e2fsprogs/fsck.c
@@ -972,13 +972,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv)
972 case 'C': 972 case 'C':
973 progress = 1; 973 progress = 1;
974 if (arg[++j]) { /* -Cn */ 974 if (arg[++j]) { /* -Cn */
975 progress_fd = xatoi_u(&arg[j]); 975 progress_fd = xatoi_positive(&arg[j]);
976 goto next_arg; 976 goto next_arg;
977 } 977 }
978 /* -C n */ 978 /* -C n */
979 if (!*++argv) 979 if (!*++argv)
980 bb_show_usage(); 980 bb_show_usage();
981 progress_fd = xatoi_u(*argv); 981 progress_fd = xatoi_positive(*argv);
982 goto next_arg; 982 goto next_arg;
983#endif 983#endif
984 case 'V': 984 case 'V':
diff --git a/e2fsprogs/old_e2fsprogs/mke2fs.c b/e2fsprogs/old_e2fsprogs/mke2fs.c
index 520364550..f1e97b96a 100644
--- a/e2fsprogs/old_e2fsprogs/mke2fs.c
+++ b/e2fsprogs/old_e2fsprogs/mke2fs.c
@@ -895,7 +895,7 @@ static int PRS(int argc, char **argv)
895 creator_os = optarg; 895 creator_os = optarg;
896 break; 896 break;
897 case 'r': 897 case 'r':
898 param.s_rev_level = xatoi_u(optarg); 898 param.s_rev_level = xatoi_positive(optarg);
899 if (param.s_rev_level == EXT2_GOOD_OLD_REV) { 899 if (param.s_rev_level == EXT2_GOOD_OLD_REV) {
900 param.s_feature_incompat = 0; 900 param.s_feature_incompat = 0;
901 param.s_feature_compat = 0; 901 param.s_feature_compat = 0;
@@ -912,11 +912,11 @@ static int PRS(int argc, char **argv)
912 break; 912 break;
913#ifdef EXT2_DYNAMIC_REV 913#ifdef EXT2_DYNAMIC_REV
914 case 'I': 914 case 'I':
915 inode_size = xatoi_u(optarg); 915 inode_size = xatoi_positive(optarg);
916 break; 916 break;
917#endif 917#endif
918 case 'N': 918 case 'N':
919 num_inodes = xatoi_u(optarg); 919 num_inodes = xatoi_positive(optarg);
920 break; 920 break;
921 case 'v': 921 case 'v':
922 quiet = 0; 922 quiet = 0;
diff --git a/findutils/find.c b/findutils/find.c
index 297081489..d4bcd6545 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -1210,7 +1210,7 @@ IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,)
1210 if (opt == OPT_MINDEPTH || opt == OPT_MINDEPTH + 1) { 1210 if (opt == OPT_MINDEPTH || opt == OPT_MINDEPTH + 1) {
1211 if (!argp[1]) 1211 if (!argp[1])
1212 bb_show_usage(); 1212 bb_show_usage();
1213 minmaxdepth[opt - OPT_MINDEPTH] = xatoi_u(argp[1]); 1213 minmaxdepth[opt - OPT_MINDEPTH] = xatoi_positive(argp[1]);
1214 argp[0] = (char*)"-a"; 1214 argp[0] = (char*)"-a";
1215 argp[1] = (char*)"-a"; 1215 argp[1] = (char*)"-a";
1216 argp++; 1216 argp++;
diff --git a/include/libbb.h b/include/libbb.h
index a7814b75f..3a7a8f33f 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -201,7 +201,7 @@ typedef unsigned long long uoff_t;
201/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway. 201/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
202 * gcc will throw warnings on printf("%d", off_t). Crap... */ 202 * gcc will throw warnings on printf("%d", off_t). Crap... */
203typedef unsigned long uoff_t; 203typedef unsigned long uoff_t;
204# define XATOOFF(a) xatoi_u(a) 204# define XATOOFF(a) xatoi_positive(a)
205# define BB_STRTOOFF bb_strtou 205# define BB_STRTOOFF bb_strtou
206# define STRTOOFF strtol 206# define STRTOOFF strtol
207# define OFF_FMT "l" 207# define OFF_FMT "l"
@@ -781,11 +781,16 @@ struct suffix_mult {
781}; 781};
782#include "xatonum.h" 782#include "xatonum.h"
783/* Specialized: */ 783/* Specialized: */
784
784/* Using xatoi() instead of naive atoi() is not always convenient - 785/* Using xatoi() instead of naive atoi() is not always convenient -
785 * in many places people want *non-negative* values, but store them 786 * in many places people want *non-negative* values, but store them
786 * in signed int. Therefore we need this one: 787 * in signed int. Therefore we need this one:
787 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc */ 788 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc.
788int xatoi_u(const char *numstr) FAST_FUNC; 789 * It should really be named xatoi_nonnegative (since it allows 0),
790 * but that would be too long.
791 */
792int xatoi_positive(const char *numstr) FAST_FUNC;
793
789/* Useful for reading port numbers */ 794/* Useful for reading port numbers */
790uint16_t xatou16(const char *numstr) FAST_FUNC; 795uint16_t xatou16(const char *numstr) FAST_FUNC;
791 796
diff --git a/include/usage.src.h b/include/usage.src.h
index 0053a7c4b..0eff1b129 100644
--- a/include/usage.src.h
+++ b/include/usage.src.h
@@ -2989,9 +2989,7 @@ INSERT
2989 "\n -d Verbose" \ 2989 "\n -d Verbose" \
2990 "\n -n Do not daemonize" \ 2990 "\n -n Do not daemonize" \
2991 "\n -q Quit after clock is set" \ 2991 "\n -q Quit after clock is set" \
2992/* -N exists for mostly compat reasons, thus not essential to inform */ \ 2992 "\n -N Run at high priority" \
2993/* the user that it exists: user may use nice as well */ \
2994/* "\n -N Run at high priority" */ \
2995 "\n -w Do not set time (only query peers), implies -n" \ 2993 "\n -w Do not set time (only query peers), implies -n" \
2996 "\n -l Run as server on port 123" \ 2994 "\n -l Run as server on port 123" \
2997 "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" \ 2995 "\n -S PROG Run PROG after stepping time, stratum change, and every 11 mins" \
@@ -4467,8 +4465,13 @@ INSERT
4467#define tune2fs_full_usage "\n\n" \ 4465#define tune2fs_full_usage "\n\n" \
4468 "Adjust filesystem options on ext[23] filesystems" 4466 "Adjust filesystem options on ext[23] filesystems"
4469 4467
4468#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
4469# define IF_UDHCP_VERBOSE(...) __VA_ARGS__
4470#else
4471# define IF_UDHCP_VERBOSE(...)
4472#endif
4470#define udhcpc_trivial_usage \ 4473#define udhcpc_trivial_usage \
4471 "[-fbnqvoCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" \ 4474 "[-fbnq"IF_UDHCP_VERBOSE("v")"oCR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" \
4472 " [-H HOSTNAME] [-c CID] [-V VENDOR] [-O DHCP_OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") 4475 " [-H HOSTNAME] [-c CID] [-V VENDOR] [-O DHCP_OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]")
4473#define udhcpc_full_usage "\n" \ 4476#define udhcpc_full_usage "\n" \
4474 IF_LONG_OPTS( \ 4477 IF_LONG_OPTS( \
@@ -4501,6 +4504,9 @@ INSERT
4501 "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" \ 4504 "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" \
4502 "\n -c,--clientid CLIENTID Client identifier (default own MAC)" \ 4505 "\n -c,--clientid CLIENTID Client identifier (default own MAC)" \
4503 "\n -C,--clientid-none Don't send client identifier" \ 4506 "\n -C,--clientid-none Don't send client identifier" \
4507 IF_UDHCP_VERBOSE( \
4508 "\n -v Verbose" \
4509 ) \
4504 ) \ 4510 ) \
4505 IF_NOT_LONG_OPTS( \ 4511 IF_NOT_LONG_OPTS( \
4506 "\n -i IFACE Interface to use (default eth0)" \ 4512 "\n -i IFACE Interface to use (default eth0)" \
@@ -4532,7 +4538,10 @@ INSERT
4532 "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" \ 4538 "\n -V VENDOR Vendor identifier (default 'udhcp VERSION')" \
4533 "\n -c CLIENTID Client identifier (default own MAC)" \ 4539 "\n -c CLIENTID Client identifier (default own MAC)" \
4534 "\n -C Don't send client identifier" \ 4540 "\n -C Don't send client identifier" \
4535 ) 4541 IF_UDHCP_VERBOSE( \
4542 "\n -v Verbose" \
4543 ) \
4544 ) \
4536 4545
4537#define udhcpd_trivial_usage \ 4546#define udhcpd_trivial_usage \
4538 "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [configfile]" \ 4547 "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [configfile]" \
@@ -4768,10 +4777,12 @@ INSERT
4768 IF_FEATURE_WGET_LONG_OPTIONS( \ 4777 IF_FEATURE_WGET_LONG_OPTIONS( \
4769 "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" \ 4778 "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" \
4770 " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" \ 4779 " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" \
4771 " [--no-check-certificate] [-U|--user-agent AGENT] URL" \ 4780 " [--no-check-certificate] [-U|--user-agent AGENT]" \
4781 IF_FEATURE_WGET_TIMEOUT("[-T SEC] ") " URL" \
4772 ) \ 4782 ) \
4773 IF_NOT_FEATURE_WGET_LONG_OPTIONS( \ 4783 IF_NOT_FEATURE_WGET_LONG_OPTIONS( \
4774 "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT] URL" \ 4784 "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" \
4785 IF_FEATURE_WGET_TIMEOUT("[-T SEC] ") " URL" \
4775 ) 4786 )
4776#define wget_full_usage "\n\n" \ 4787#define wget_full_usage "\n\n" \
4777 "Retrieve files via HTTP or FTP\n" \ 4788 "Retrieve files via HTTP or FTP\n" \
@@ -4779,7 +4790,10 @@ INSERT
4779 "\n -s Spider mode - only check file existence" \ 4790 "\n -s Spider mode - only check file existence" \
4780 "\n -c Continue retrieval of aborted transfer" \ 4791 "\n -c Continue retrieval of aborted transfer" \
4781 "\n -q Quiet" \ 4792 "\n -q Quiet" \
4782 "\n -P Set directory prefix to DIR" \ 4793 "\n -P DIR Save to DIR (default .)" \
4794 IF_FEATURE_WGET_TIMEOUT( \
4795 "\n -T SEC Network read timeout is SEC seconds" \
4796 ) \
4783 "\n -O FILE Save to FILE ('-' for stdout)" \ 4797 "\n -O FILE Save to FILE ('-' for stdout)" \
4784 "\n -U STR Use STR for User-Agent header" \ 4798 "\n -U STR Use STR for User-Agent header" \
4785 "\n -Y Use proxy ('on' or 'off')" \ 4799 "\n -Y Use proxy ('on' or 'off')" \
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 20e1b8a8b..bcb2db645 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -233,7 +233,7 @@ Special characters:
233 233
234 "a+" A plus after a char in opt_complementary means that the parameter 234 "a+" A plus after a char in opt_complementary means that the parameter
235 for this option is a nonnegative integer. It will be processed 235 for this option is a nonnegative integer. It will be processed
236 with xatoi_u() - allowed range is 0..INT_MAX. 236 with xatoi_positive() - allowed range is 0..INT_MAX.
237 237
238 int param; // "unsigned param;" will also work 238 int param; // "unsigned param;" will also work
239 opt_complementary = "p+"; 239 opt_complementary = "p+";
@@ -579,8 +579,8 @@ getopt32(char **argv, const char *applet_opts, ...)
579 llist_add_to_end((llist_t **)(on_off->optarg), optarg); 579 llist_add_to_end((llist_t **)(on_off->optarg), optarg);
580 } else if (on_off->param_type == PARAM_INT) { 580 } else if (on_off->param_type == PARAM_INT) {
581 if (optarg) 581 if (optarg)
582//TODO: xatoi_u indirectly pulls in printf machinery 582//TODO: xatoi_positive indirectly pulls in printf machinery
583 *(unsigned*)(on_off->optarg) = xatoi_u(optarg); 583 *(unsigned*)(on_off->optarg) = xatoi_positive(optarg);
584 } else if (on_off->optarg) { 584 } else if (on_off->optarg) {
585 if (optarg) 585 if (optarg)
586 *(char **)(on_off->optarg) = optarg; 586 *(char **)(on_off->optarg) = optarg;
diff --git a/libbb/progress.c b/libbb/progress.c
index e96039042..f53271398 100644
--- a/libbb/progress.c
+++ b/libbb/progress.c
@@ -66,16 +66,29 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
66 off_t transferred, 66 off_t transferred,
67 off_t totalsize) 67 off_t totalsize)
68{ 68{
69 off_t abbrevsize; 69 uoff_t beg_and_transferred;
70 unsigned since_last_update, elapsed; 70 unsigned since_last_update, elapsed;
71 unsigned ratio; 71 unsigned ratio;
72 int barlength, i; 72 int barlength, i;
73 73
74 /* totalsize == 0 if it is unknown */
75
76 elapsed = monotonic_sec();
77 since_last_update = elapsed - p->lastupdate_sec;
78 /* Do not update on every call
79 * (we can be called on every network read!) */
80 if (since_last_update == 0 && !totalsize)
81 return;
82
83 beg_and_transferred = beg_range + transferred;
74 ratio = 100; 84 ratio = 100;
75 if (totalsize) { 85 if (beg_and_transferred < totalsize) {
86 /* Do not update on every call
87 * (we can be called on every network read!) */
88 if (since_last_update == 0)
89 return;
76 /* long long helps to have it working even if !LFS */ 90 /* long long helps to have it working even if !LFS */
77 ratio = (unsigned) (100ULL * (transferred+beg_range) / totalsize); 91 ratio = 100ULL * beg_and_transferred / (uoff_t)totalsize;
78 if (ratio > 100) ratio = 100;
79 } 92 }
80 93
81#if ENABLE_UNICODE_SUPPORT 94#if ENABLE_UNICODE_SUPPORT
@@ -95,35 +108,33 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
95 /* back to multibyte; cant overflow */ 108 /* back to multibyte; cant overflow */
96 wcstombs(buf, wbuf21, INT_MAX); 109 wcstombs(buf, wbuf21, INT_MAX);
97 len = (len > 20) ? 0 : 20 - len; 110 len = (len > 20) ? 0 : 20 - len;
98 fprintf(stderr, "\r%s%*s%4d%% ", buf, len, "", ratio); 111 fprintf(stderr, "\r%s%*s%4u%% ", buf, len, "", ratio);
99 free(buf); 112 free(buf);
100 } 113 }
101#else 114#else
102 fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio); 115 fprintf(stderr, "\r%-20.20s%4u%% ", curfile, ratio);
103#endif 116#endif
104 117
105 barlength = get_tty2_width() - 49; 118 barlength = get_tty2_width() - 49;
106 if (barlength > 0) { 119 if (barlength > 0) {
107 /* god bless gcc for variable arrays :) */ 120 /* god bless gcc for variable arrays :) */
108 i = barlength * ratio / 100; 121 char buf[barlength + 1];
109 { 122 unsigned stars = (unsigned)barlength * ratio / (unsigned)100;
110 char buf[i+1]; 123 memset(buf, ' ', barlength);
111 memset(buf, '*', i); 124 buf[barlength] = '\0';
112 buf[i] = '\0'; 125 memset(buf, '*', stars);
113 fprintf(stderr, "|%s%*s|", buf, barlength - i, ""); 126 fprintf(stderr, "|%s|", buf);
114 }
115 } 127 }
128
116 i = 0; 129 i = 0;
117 abbrevsize = transferred + beg_range; 130 while (beg_and_transferred >= 100000) {
118 while (abbrevsize >= 100000) {
119 i++; 131 i++;
120 abbrevsize >>= 10; 132 beg_and_transferred >>= 10;
121 } 133 }
122 /* see http://en.wikipedia.org/wiki/Tera */ 134 /* see http://en.wikipedia.org/wiki/Tera */
123 fprintf(stderr, "%6d%c ", (int)abbrevsize, " kMGTPEZY"[i]); 135 fprintf(stderr, "%6u%c ", (unsigned)beg_and_transferred, " kMGTPEZY"[i]);
136#define beg_and_transferred dont_use_beg_and_transferred_below
124 137
125 elapsed = monotonic_sec();
126 since_last_update = elapsed - p->lastupdate_sec;
127 if (transferred > p->lastsize) { 138 if (transferred > p->lastsize) {
128 p->lastupdate_sec = elapsed; 139 p->lastupdate_sec = elapsed;
129 p->lastsize = transferred; 140 p->lastsize = transferred;
@@ -144,10 +155,10 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p,
144 fprintf(stderr, "--:--:-- ETA"); 155 fprintf(stderr, "--:--:-- ETA");
145 } else { 156 } else {
146 /* to_download / (transferred/elapsed) - elapsed: */ 157 /* to_download / (transferred/elapsed) - elapsed: */
147 int eta = (int) ((unsigned long long)to_download*elapsed/transferred - elapsed);
148 /* (long long helps to have working ETA even if !LFS) */ 158 /* (long long helps to have working ETA even if !LFS) */
149 i = eta % 3600; 159 unsigned eta = (unsigned long long)to_download*elapsed/(uoff_t)transferred - elapsed;
150 fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60); 160 unsigned secs = eta % 3600;
161 fprintf(stderr, "%02u:%02u:%02u ETA", eta / 3600, secs / 60, secs % 60);
151 } 162 }
152 } 163 }
153} 164}
diff --git a/libbb/rtc.c b/libbb/rtc.c
index fcd6c64d7..97d18ed53 100644
--- a/libbb/rtc.c
+++ b/libbb/rtc.c
@@ -22,13 +22,6 @@ int FAST_FUNC rtc_adjtime_is_utc(void)
22 char buffer[128]; 22 char buffer[128];
23 23
24 while (fgets(buffer, sizeof(buffer), f)) { 24 while (fgets(buffer, sizeof(buffer), f)) {
25 int len = strlen(buffer);
26
27 while (len && isspace(buffer[len - 1]))
28 len--;
29
30 buffer[len] = 0;
31
32 if (strncmp(buffer, "UTC", 3) == 0) { 25 if (strncmp(buffer, "UTC", 3) == 0) {
33 utc = 1; 26 utc = 1;
34 break; 27 break;
diff --git a/libbb/xatonum.c b/libbb/xatonum.c
index 3cdf63425..60b65f525 100644
--- a/libbb/xatonum.c
+++ b/libbb/xatonum.c
@@ -59,7 +59,7 @@ unsigned bb_strtoui(const char *str, char **end, int b)
59 59
60/* A few special cases */ 60/* A few special cases */
61 61
62int FAST_FUNC xatoi_u(const char *numstr) 62int FAST_FUNC xatoi_positive(const char *numstr)
63{ 63{
64 return xatou_range(numstr, 0, INT_MAX); 64 return xatou_range(numstr, 0, INT_MAX);
65} 65}
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c
index e370d207b..a031cbd3a 100644
--- a/miscutils/fbsplash.c
+++ b/miscutils/fbsplash.c
@@ -311,7 +311,7 @@ static void init(const char *cfg_filename)
311 parser_t *parser = config_open2(cfg_filename, xfopen_stdin); 311 parser_t *parser = config_open2(cfg_filename, xfopen_stdin);
312 while (config_read(parser, token, 2, 2, "#=", 312 while (config_read(parser, token, 2, 2, "#=",
313 (PARSE_NORMAL | PARSE_MIN_DIE) & ~(PARSE_TRIM | PARSE_COLLAPSE))) { 313 (PARSE_NORMAL | PARSE_MIN_DIE) & ~(PARSE_TRIM | PARSE_COLLAPSE))) {
314 unsigned val = xatoi_u(token[1]); 314 unsigned val = xatoi_positive(token[1]);
315 int i = index_in_strings(param_names, token[0]); 315 int i = index_in_strings(param_names, token[0]);
316 if (i < 0) 316 if (i < 0)
317 bb_error_msg_and_die("syntax error: %s", token[0]); 317 bb_error_msg_and_die("syntax error: %s", token[0]);
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index 236b1749c..c6ca3af80 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -2055,8 +2055,8 @@ int hdparm_main(int argc, char **argv)
2055#if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF 2055#if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF
2056 if (c == 'R') { 2056 if (c == 'R') {
2057 scan_hwif = parse_opts_0_INTMAX(&hwif_data); 2057 scan_hwif = parse_opts_0_INTMAX(&hwif_data);
2058 hwif_ctrl = xatoi_u((argv[optind]) ? argv[optind] : ""); 2058 hwif_ctrl = xatoi_positive((argv[optind]) ? argv[optind] : "");
2059 hwif_irq = xatoi_u((argv[optind+1]) ? argv[optind+1] : ""); 2059 hwif_irq = xatoi_positive((argv[optind+1]) ? argv[optind+1] : "");
2060 /* Move past the 2 additional arguments */ 2060 /* Move past the 2 additional arguments */
2061 argv += 2; 2061 argv += 2;
2062 argc -= 2; 2062 argc -= 2;
diff --git a/miscutils/ionice.c b/miscutils/ionice.c
index 52e51b908..6b791c491 100644
--- a/miscutils/ionice.c
+++ b/miscutils/ionice.c
@@ -73,7 +73,7 @@ int ionice_main(int argc UNUSED_PARAM, char **argv)
73 73
74 if (!(opt & (OPT_n|OPT_c))) { 74 if (!(opt & (OPT_n|OPT_c))) {
75 if (!(opt & OPT_p) && *argv) 75 if (!(opt & OPT_p) && *argv)
76 pid = xatoi_u(*argv); 76 pid = xatoi_positive(*argv);
77 77
78 pri = ioprio_get(IOPRIO_WHO_PROCESS, pid); 78 pri = ioprio_get(IOPRIO_WHO_PROCESS, pid);
79 if (pri == -1) 79 if (pri == -1)
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index abf505770..0578d9251 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -36,10 +36,10 @@ int makedevs_main(int argc, char **argv)
36 basedev = argv[1]; 36 basedev = argv[1];
37 buf = xasprintf("%s%u", argv[1], (unsigned)-1); 37 buf = xasprintf("%s%u", argv[1], (unsigned)-1);
38 type = argv[2]; 38 type = argv[2];
39 Smajor = xatoi_u(argv[3]); 39 Smajor = xatoi_positive(argv[3]);
40 Sminor = xatoi_u(argv[4]); 40 Sminor = xatoi_positive(argv[4]);
41 S = xatoi_u(argv[5]); 41 S = xatoi_positive(argv[5]);
42 E = xatoi_u(argv[6]); 42 E = xatoi_positive(argv[6]);
43 nodname = argv[7] ? basedev : buf; 43 nodname = argv[7] ? basedev : buf;
44 44
45 mode = 0660; 45 mode = 0660;
diff --git a/miscutils/mt.c b/miscutils/mt.c
index 586373d13..8df2b75f7 100644
--- a/miscutils/mt.c
+++ b/miscutils/mt.c
@@ -106,7 +106,7 @@ int mt_main(int argc UNUSED_PARAM, char **argv)
106 106
107 op.mt_op = opcode_value[idx]; 107 op.mt_op = opcode_value[idx];
108 if (argv[2]) 108 if (argv[2])
109 op.mt_count = xatoi_u(argv[2]); 109 op.mt_count = xatoi_positive(argv[2]);
110 else 110 else
111 op.mt_count = 1; /* One, not zero, right? */ 111 op.mt_count = 1; /* One, not zero, right? */
112 112
diff --git a/miscutils/rfkill.c b/miscutils/rfkill.c
index 0f5817b76..7d8ad1cfc 100644
--- a/miscutils/rfkill.c
+++ b/miscutils/rfkill.c
@@ -53,7 +53,7 @@ int rfkill_main(int argc UNUSED_PARAM, char **argv)
53 rf_name = "uwb"; 53 rf_name = "uwb";
54 rf_type = index_in_strings(rfkill_types, rf_name); 54 rf_type = index_in_strings(rfkill_types, rf_name);
55 if (rf_type < 0) { 55 if (rf_type < 0) {
56 rf_idx = xatoi_u(rf_name); 56 rf_idx = xatoi_positive(rf_name);
57 } 57 }
58 } 58 }
59 59
diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c
index 7f39e253d..c42d3c0bb 100644
--- a/modutils/modutils-24.c
+++ b/modutils/modutils-24.c
@@ -90,6 +90,27 @@
90#define USE_SINGLE 90#define USE_SINGLE
91#endif 91#endif
92 92
93/* NDS32 support */
94#if defined(__nds32__) || defined(__NDS32__)
95#define CONFIG_USE_GOT_ENTRIES
96#define CONFIG_GOT_ENTRY_SIZE 4
97#define CONFIG_USE_SINGLE
98
99#if defined(__NDS32_EB__)
100#define MATCH_MACHINE(x) (x == EM_NDS32)
101#define SHT_RELM SHT_RELA
102#define Elf32_RelM Elf32_Rela
103#define ELFCLASSM ELFCLASS32
104#endif
105
106#if defined(__NDS32_EL__)
107#define MATCH_MACHINE(x) (x == EM_NDS32)
108#define SHT_RELM SHT_RELA
109#define Elf32_RelM Elf32_Rela
110#define ELFCLASSM ELFCLASS32
111#endif
112#endif
113
93/* blackfin */ 114/* blackfin */
94#if defined(BFIN) 115#if defined(BFIN)
95#define MATCH_MACHINE(x) (x == EM_BLACKFIN) 116#define MATCH_MACHINE(x) (x == EM_BLACKFIN)
diff --git a/networking/Config.src b/networking/Config.src
index 8604c53e9..9fc122bf3 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -1012,6 +1012,18 @@ config FEATURE_WGET_LONG_OPTIONS
1012 help 1012 help
1013 Support long options for the wget applet. 1013 Support long options for the wget applet.
1014 1014
1015config FEATURE_WGET_TIMEOUT
1016 bool "Enable read timeout option -T SEC"
1017 default y
1018 depends on WGET
1019 help
1020 Supports network read timeout for wget, so that wget will give
1021 up and timeout when reading network data, through the -T command
1022 line option. Currently only network data read timeout is
1023 supported (i.e., timeout is not applied to the DNS nor TCP
1024 connection initialization). When FEATURE_WGET_LONG_OPTIONS is
1025 also enabled, the --timeout option will work in addition to -T.
1026
1015config ZCIP 1027config ZCIP
1016 bool "zcip" 1028 bool "zcip"
1017 default y 1029 default y
diff --git a/networking/brctl.c b/networking/brctl.c
index a36ab45c3..0f56412ce 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -271,7 +271,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
271 } 271 }
272 } 272 }
273 arg1 = port; 273 arg1 = port;
274 arg2 = xatoi_u(*argv); 274 arg2 = xatoi_positive(*argv);
275 if (key == ARG_setbridgeprio) { 275 if (key == ARG_setbridgeprio) {
276 arg1 = arg2; 276 arg1 = arg2;
277 arg2 = 0; 277 arg2 = 0;
diff --git a/networking/ftpd.c b/networking/ftpd.c
index e8cae0a36..0daf9f7a3 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -534,7 +534,7 @@ static void
534handle_rest(void) 534handle_rest(void)
535{ 535{
536 /* When ftp_arg == NULL simply restart from beginning */ 536 /* When ftp_arg == NULL simply restart from beginning */
537 G.restart_pos = G.ftp_arg ? xatoi_u(G.ftp_arg) : 0; 537 G.restart_pos = G.ftp_arg ? xatoi_positive(G.ftp_arg) : 0;
538 WRITE_OK(FTP_RESTOK); 538 WRITE_OK(FTP_RESTOK);
539} 539}
540 540
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 331dffc2e..dcd493f13 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -85,7 +85,7 @@ config UDHCP_DEBUG
85 depends on UDHCPD || UDHCPC || DHCPRELAY 85 depends on UDHCPD || UDHCPC || DHCPRELAY
86 help 86 help
87 Verbosity can be increased with multiple -v options. 87 Verbosity can be increased with multiple -v options.
88 This options controls how high it can be cranked up. 88 This option controls how high it can be cranked up.
89 89
90 Bigger values result in bigger code. Levels above 1 90 Bigger values result in bigger code. Levels above 1
91 are very verbose and useful for debugging only. 91 are very verbose and useful for debugging only.
diff --git a/networking/wget.c b/networking/wget.c
index 1f35f8b03..784e405da 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -3,8 +3,10 @@
3 * wget - retrieve a file using HTTP or FTP 3 * wget - retrieve a file using HTTP or FTP
4 * 4 *
5 * Chip Rosenthal Covad Communications <chip@laserlink.net> 5 * Chip Rosenthal Covad Communications <chip@laserlink.net>
6 *
7 * Licensed under GPLv2, see file LICENSE in this tarball for details. 6 * Licensed under GPLv2, see file LICENSE in this tarball for details.
7 *
8 * Copyright (C) 2010 Bradley M. Kuhn <bkuhn@ebb.org>
9 * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2.
8 */ 10 */
9#include "libbb.h" 11#include "libbb.h"
10 12
@@ -19,7 +21,7 @@ struct host_info {
19}; 21};
20 22
21 23
22/* Globals (can be accessed from signal handlers) */ 24/* Globals */
23struct globals { 25struct globals {
24 off_t content_len; /* Content-length of the file */ 26 off_t content_len; /* Content-length of the file */
25 off_t beg_range; /* Range at which continue begins */ 27 off_t beg_range; /* Range at which continue begins */
@@ -28,6 +30,9 @@ struct globals {
28 const char *curfile; /* Name of current file being transferred */ 30 const char *curfile; /* Name of current file being transferred */
29 bb_progress_t pmt; 31 bb_progress_t pmt;
30#endif 32#endif
33#if ENABLE_FEATURE_WGET_TIMEOUT
34 unsigned timeout_seconds;
35#endif
31 smallint chunked; /* chunked transfer encoding */ 36 smallint chunked; /* chunked transfer encoding */
32 smallint got_clen; /* got content-length: from server */ 37 smallint got_clen; /* got content-length: from server */
33} FIX_ALIASING; 38} FIX_ALIASING;
@@ -35,42 +40,51 @@ struct globals {
35struct BUG_G_too_big { 40struct BUG_G_too_big {
36 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 41 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
37}; 42};
38#define INIT_G() do { } while (0) 43#define INIT_G() do { \
44 IF_FEATURE_WGET_TIMEOUT(G.timeout_seconds = 900;) \
45} while (0)
39 46
40 47
41#if ENABLE_FEATURE_WGET_STATUSBAR 48/* Must match option string! */
49enum {
50 WGET_OPT_CONTINUE = (1 << 0),
51 WGET_OPT_SPIDER = (1 << 1),
52 WGET_OPT_QUIET = (1 << 2),
53 WGET_OPT_OUTNAME = (1 << 3),
54 WGET_OPT_PREFIX = (1 << 4),
55 WGET_OPT_PROXY = (1 << 5),
56 WGET_OPT_USER_AGENT = (1 << 6),
57 WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 7),
58 WGET_OPT_RETRIES = (1 << 8),
59 WGET_OPT_PASSIVE = (1 << 9),
60 WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
61 WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
62};
42 63
64enum {
65 PROGRESS_START = -1,
66 PROGRESS_END = 0,
67 PROGRESS_BUMP = 1,
68};
69#if ENABLE_FEATURE_WGET_STATUSBAR
43static void progress_meter(int flag) 70static void progress_meter(int flag)
44{ 71{
45 /* We can be called from signal handler */ 72 if (option_mask32 & WGET_OPT_QUIET)
46 int save_errno = errno; 73 return;
47 74
48 if (flag == -1) { /* first call to progress_meter */ 75 if (flag == PROGRESS_START)
49 bb_progress_init(&G.pmt); 76 bb_progress_init(&G.pmt);
50 }
51 77
52 bb_progress_update(&G.pmt, G.curfile, G.beg_range, G.transferred, 78 bb_progress_update(&G.pmt, G.curfile, G.beg_range, G.transferred,
53 G.chunked ? 0 : G.beg_range + G.transferred + G.content_len); 79 G.chunked ? 0 : G.beg_range + G.transferred + G.content_len);
54 80
55 if (flag == 0) { 81 if (flag == PROGRESS_END) {
56 /* last call to progress_meter */
57 alarm(0);
58 bb_putchar_stderr('\n'); 82 bb_putchar_stderr('\n');
59 G.transferred = 0; 83 G.transferred = 0;
60 } else {
61 if (flag == -1) { /* first call to progress_meter */
62 signal_SA_RESTART_empty_mask(SIGALRM, progress_meter);
63 }
64 alarm(1);
65 } 84 }
66
67 errno = save_errno;
68} 85}
69 86#else
70#else /* FEATURE_WGET_STATUSBAR */
71
72static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) { } 87static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) { }
73
74#endif 88#endif
75 89
76 90
@@ -199,7 +213,7 @@ static int ftpcmd(const char *s1, const char *s2, FILE *fp, char *buf)
199 } while (!isdigit(buf[0]) || buf[3] != ' '); 213 } while (!isdigit(buf[0]) || buf[3] != ' ');
200 214
201 buf[3] = '\0'; 215 buf[3] = '\0';
202 result = xatoi_u(buf); 216 result = xatoi_positive(buf);
203 buf[3] = ' '; 217 buf[3] = ' ';
204 return result; 218 return result;
205} 219}
@@ -430,28 +444,20 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
430 return sfp; 444 return sfp;
431} 445}
432 446
433/* Must match option string! */
434enum {
435 WGET_OPT_CONTINUE = (1 << 0),
436 WGET_OPT_SPIDER = (1 << 1),
437 WGET_OPT_QUIET = (1 << 2),
438 WGET_OPT_OUTNAME = (1 << 3),
439 WGET_OPT_PREFIX = (1 << 4),
440 WGET_OPT_PROXY = (1 << 5),
441 WGET_OPT_USER_AGENT = (1 << 6),
442 WGET_OPT_RETRIES = (1 << 7),
443 WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 8),
444 WGET_OPT_PASSIVE = (1 << 9),
445 WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
446 WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
447};
448
449static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) 447static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
450{ 448{
451 char buf[512]; 449 char buf[512];
452 450#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
453 if (!(option_mask32 & WGET_OPT_QUIET)) 451# if ENABLE_FEATURE_WGET_TIMEOUT
454 progress_meter(-1); 452 unsigned second_cnt;
453# endif
454 struct pollfd polldata;
455
456 polldata.fd = fileno(dfp);
457 polldata.events = POLLIN | POLLPRI;
458 ndelay_on(polldata.fd);
459#endif
460 progress_meter(PROGRESS_START);
455 461
456 if (G.chunked) 462 if (G.chunked)
457 goto get_clen; 463 goto get_clen;
@@ -470,6 +476,23 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
470 rdsz = (unsigned)G.content_len; 476 rdsz = (unsigned)G.content_len;
471 } 477 }
472 } 478 }
479#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT
480# if ENABLE_FEATURE_WGET_TIMEOUT
481 second_cnt = G.timeout_seconds;
482# endif
483 while (1) {
484 if (safe_poll(&polldata, 1, 1000) != 0)
485 break; /* error, EOF, or data is available */
486# if ENABLE_FEATURE_WGET_TIMEOUT
487 if (second_cnt != 0 && --second_cnt == 0) {
488 progress_meter(PROGRESS_END);
489 bb_perror_msg_and_die("download timed out");
490 }
491# endif
492 /* Needed for "stalled" indicator */
493 progress_meter(PROGRESS_BUMP);
494 }
495#endif
473 n = safe_fread(buf, rdsz, dfp); 496 n = safe_fread(buf, rdsz, dfp);
474 if (n <= 0) { 497 if (n <= 0) {
475 if (ferror(dfp)) { 498 if (ferror(dfp)) {
@@ -481,6 +504,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
481 xwrite(output_fd, buf, n); 504 xwrite(output_fd, buf, n);
482#if ENABLE_FEATURE_WGET_STATUSBAR 505#if ENABLE_FEATURE_WGET_STATUSBAR
483 G.transferred += n; 506 G.transferred += n;
507 progress_meter(PROGRESS_BUMP);
484#endif 508#endif
485 if (G.got_clen) 509 if (G.got_clen)
486 G.content_len -= n; 510 G.content_len -= n;
@@ -499,8 +523,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd)
499 G.got_clen = 1; 523 G.got_clen = 1;
500 } 524 }
501 525
502 if (!(option_mask32 & WGET_OPT_QUIET)) 526 progress_meter(PROGRESS_END);
503 progress_meter(0);
504} 527}
505 528
506int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 529int wget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -541,9 +564,11 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
541 "directory-prefix\0" Required_argument "P" 564 "directory-prefix\0" Required_argument "P"
542 "proxy\0" Required_argument "Y" 565 "proxy\0" Required_argument "Y"
543 "user-agent\0" Required_argument "U" 566 "user-agent\0" Required_argument "U"
567#if ENABLE_FEATURE_WGET_TIMEOUT
568 "timeout\0" Required_argument "T"
569#endif
544 /* Ignored: */ 570 /* Ignored: */
545 // "tries\0" Required_argument "t" 571 // "tries\0" Required_argument "t"
546 // "timeout\0" Required_argument "T"
547 /* Ignored (we always use PASV): */ 572 /* Ignored (we always use PASV): */
548 "passive-ftp\0" No_argument "\xff" 573 "passive-ftp\0" No_argument "\xff"
549 "header\0" Required_argument "\xfe" 574 "header\0" Required_argument "\xfe"
@@ -559,12 +584,12 @@ int wget_main(int argc UNUSED_PARAM, char **argv)
559 applet_long_options = wget_longopts; 584 applet_long_options = wget_longopts;
560#endif 585#endif
561 /* server.allocated = target.allocated = NULL; */ 586 /* server.allocated = target.allocated = NULL; */
562 opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); 587 opt_complementary = "-1" IF_FEATURE_WGET_TIMEOUT(":T+") IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::");
563 opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:", 588 opt = getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:",
564 &fname_out, &dir_prefix, 589 &fname_out, &dir_prefix,
565 &proxy_flag, &user_agent, 590 &proxy_flag, &user_agent,
566 NULL, /* -t RETRIES */ 591 IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL),
567 NULL /* -T NETWORK_READ_TIMEOUT */ 592 NULL /* -t RETRIES */
568 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) 593 IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist)
569 IF_FEATURE_WGET_LONG_OPTIONS(, &post_data) 594 IF_FEATURE_WGET_LONG_OPTIONS(, &post_data)
570 ); 595 );
diff --git a/printutils/lpd.c b/printutils/lpd.c
index d91491f1b..54ff2227e 100644
--- a/printutils/lpd.c
+++ b/printutils/lpd.c
@@ -135,7 +135,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[])
135 while (1) { 135 while (1) {
136 char *fname; 136 char *fname;
137 int fd; 137 int fd;
138 // int is easier than ssize_t: can use xatoi_u, 138 // int is easier than ssize_t: can use xatoi_positive,
139 // and can correctly display error returns (-1) 139 // and can correctly display error returns (-1)
140 int expected_len, real_len; 140 int expected_len, real_len;
141 141
diff --git a/procps/free.c b/procps/free.c
index 473d70be8..db70712cf 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -53,29 +53,41 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
53 info.bufferram *= mem_unit; 53 info.bufferram *= mem_unit;
54 } 54 }
55 55
56 printf(" %13s%13s%13s%13s%13s\n", 56 printf(" %13s%13s%13s%13s%13s\n",
57 "total", 57 "total",
58 "used", 58 "used",
59 "free", 59 "free",
60 "shared", "buffers" /* swap and total don't have these columns */ 60 "shared", "buffers" /* swap and total don't have these columns */
61 /* procps version 3.2.8 also shows "cached" column, but
62 * sysinfo() does not provide this value, need to parse
63 * /proc/meminfo instead and get "Cached: NNN kB" from there.
64 */
61 ); 65 );
62 printf("%6s%13lu%13lu%13lu%13lu%13lu\n", "Mem:", 66#define FIELDS_5 "%13lu%13lu%13lu%13lu%13lu\n"
67#define FIELDS_3 (FIELDS_5 + 2*5)
68#define FIELDS_2 (FIELDS_5 + 3*5)
69 printf("Mem: ");
70 printf(FIELDS_5,
63 info.totalram, 71 info.totalram,
64 info.totalram - info.freeram, 72 info.totalram - info.freeram,
65 info.freeram, 73 info.freeram,
66 info.sharedram, info.bufferram 74 info.sharedram, info.bufferram
67 ); 75 );
76 /* Show alternate, more meaningful busy/free numbers by counting
77 * buffer cache as free memory (make it "-/+ buffers/cache"
78 * if/when we add support for "cached" column): */
79 printf("-/+ buffers: ");
80 printf(FIELDS_2,
81 info.totalram - info.freeram - info.bufferram,
82 info.freeram + info.bufferram
83 );
68#if BB_MMU 84#if BB_MMU
69 printf("%6s%13lu%13lu%13lu\n", "Swap:", 85 printf("Swap:");
86 printf(FIELDS_3,
70 info.totalswap, 87 info.totalswap,
71 info.totalswap - info.freeswap, 88 info.totalswap - info.freeswap,
72 info.freeswap 89 info.freeswap
73 ); 90 );
74 printf("%6s%13lu%13lu%13lu\n", "Total:",
75 info.totalram + info.totalswap,
76 (info.totalram - info.freeram) + (info.totalswap - info.freeswap),
77 info.freeram + info.freeswap
78 );
79#endif 91#endif
80 return EXIT_SUCCESS; 92 return EXIT_SUCCESS;
81} 93}
diff --git a/procps/iostat.c b/procps/iostat.c
new file mode 100644
index 000000000..76c5353cc
--- /dev/null
+++ b/procps/iostat.c
@@ -0,0 +1,618 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Report CPU and I/O stats, based on sysstat version 9.1.2 by Sebastien Godard
4 *
5 * Copyright (C) 2010 Marek Polacek <mmpolacek@gmail.com>
6 *
7 * Licensed under GPLv2, see file License in this tarball for details.
8 */
9
10//applet:IF_IOSTAT(APPLET(iostat, _BB_DIR_BIN, _BB_SUID_DROP))
11
12//kbuild:lib-$(CONFIG_IOSTAT) += iostat.o
13
14//config:config IOSTAT
15//config: bool "iostat"
16//config: default y
17//config: help
18//config: Report CPU and I/O statistics
19
20#include "libbb.h"
21#include <sys/utsname.h> /* Need struct utsname */
22
23//#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
24#define debug(fmt, ...) ((void)0)
25
26#define MAX_DEVICE_NAME 12
27#define CURRENT 0
28#define LAST 1
29
30#if 1
31typedef unsigned long long cputime_t;
32typedef long long icputime_t;
33# define FMT_DATA "ll"
34# define CPUTIME_MAX (~0ULL)
35#else
36typedef unsigned long cputime_t;
37typedef long icputime_t;
38# define FMT_DATA "l"
39# define CPUTIME_MAX (~0UL)
40#endif
41
42struct stats_cpu {
43 cputime_t cpu_user;
44 cputime_t cpu_nice;
45 cputime_t cpu_system;
46 cputime_t cpu_idle;
47 cputime_t cpu_iowait;
48 cputime_t cpu_steal;
49 cputime_t cpu_irq;
50 cputime_t cpu_softirq;
51 cputime_t cpu_guest;
52};
53
54struct stats_dev {
55 char dname[MAX_DEVICE_NAME];
56 unsigned long long rd_sectors;
57 unsigned long long wr_sectors;
58 unsigned long rd_ops;
59 unsigned long wr_ops;
60};
61
62/* List of devices entered on the command line */
63struct device_list {
64 char dname[MAX_DEVICE_NAME];
65};
66
67/* Globals. Sort by size and access frequency. */
68struct globals {
69 smallint show_all;
70 unsigned devlist_i; /* Index to the list of devices */
71 unsigned total_cpus; /* Number of CPUs */
72 unsigned clk_tck; /* Number of clock ticks per second */
73 struct device_list *dlist;
74 struct stats_dev *saved_stats_dev;
75 struct tm tmtime;
76};
77#define G (*ptr_to_globals)
78#define INIT_G() do { \
79 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
80} while (0)
81
82/* Must match option string! */
83enum {
84 OPT_c = 1 << 0,
85 OPT_d = 1 << 1,
86 OPT_t = 1 << 2,
87 OPT_z = 1 << 3,
88 OPT_k = 1 << 4,
89 OPT_m = 1 << 5,
90};
91
92static ALWAYS_INLINE unsigned get_user_hz(void)
93{
94 return sysconf(_SC_CLK_TCK);
95}
96
97static ALWAYS_INLINE int this_is_smp(void)
98{
99 return (G.total_cpus > 1);
100}
101
102static void print_header(void)
103{
104 char buf[16];
105 struct utsname uts;
106
107 if (uname(&uts) < 0)
108 bb_perror_msg_and_die("uname");
109
110 strftime(buf, sizeof(buf), "%x", &G.tmtime);
111
112 printf("%s %s (%s) \t%s \t_%s_\t(%d CPU)\n\n",
113 uts.sysname, uts.release, uts.nodename,
114 buf, uts.machine, G.total_cpus);
115}
116
117static int get_number_of_cpus(void)
118{
119#ifdef _SC_NPROCESSORS_CONF
120 return sysconf(_SC_NPROCESSORS_CONF);
121#else
122 char buf[128];
123 int n = 0;
124 FILE *fp;
125
126 fp = xfopen_for_read("/proc/cpuinfo");
127
128 while (fgets(buf, sizeof(buf), fp))
129 if (strncmp(buf, "processor\t:", 11) == 0)
130 n++;
131
132 fclose(fp);
133 return n;
134#endif
135}
136
137static void get_localtime(struct tm *ptm)
138{
139 time_t timer;
140 time(&timer);
141 localtime_r(&timer, ptm);
142}
143
144static void print_timestamp(void)
145{
146 char buf[20];
147 strftime(buf, sizeof(buf), "%x %X", &G.tmtime);
148 printf("%s\n", buf);
149}
150
151/* Does str start with "cpu"? */
152static int starts_with_cpu(const char *str)
153{
154 return ((str[0] - 'c') | (str[1] - 'p') | (str[2] - 'u')) == 0;
155}
156
157/* Fetch CPU statistics from /proc/stat */
158static void get_cpu_statistics(struct stats_cpu *sc)
159{
160 FILE *fp;
161 char buf[1024];
162
163 fp = xfopen_for_read("/proc/stat");
164
165 memset(sc, 0, sizeof(*sc));
166
167 while (fgets(buf, sizeof(buf), fp)) {
168 /* Does the line starts with "cpu "? */
169 if (starts_with_cpu(buf) && buf[3] == ' ') {
170 sscanf(buf + 4 + 1,
171 "%"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"
172 FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u",
173 &sc->cpu_user, &sc->cpu_nice, &sc->cpu_system,
174 &sc->cpu_idle, &sc->cpu_iowait, &sc->cpu_irq,
175 &sc->cpu_softirq, &sc->cpu_steal, &sc->cpu_guest);
176 }
177 }
178
179 fclose(fp);
180}
181
182static cputime_t get_smp_uptime(void)
183{
184 FILE *fp;
185 char buf[sizeof(long)*3 * 2 + 4];
186 unsigned long sec, dec;
187
188 fp = xfopen_for_read("/proc/uptime");
189
190 if (fgets(buf, sizeof(buf), fp))
191 if (sscanf(buf, "%lu.%lu", &sec, &dec) != 2)
192 bb_error_msg_and_die("can't read /proc/uptime");
193
194 fclose(fp);
195
196 return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100;
197}
198
199/*
200 * Obtain current uptime in jiffies.
201 * Uptime is sum of individual CPUs' uptimes.
202 */
203static cputime_t get_uptime(const struct stats_cpu *sc)
204{
205 /* NB: Don't include cpu_guest, it is already in cpu_user */
206 return sc->cpu_user + sc->cpu_nice + sc->cpu_system + sc->cpu_idle +
207 + sc->cpu_iowait + sc->cpu_irq + sc->cpu_steal + sc->cpu_softirq;
208}
209
210static ALWAYS_INLINE cputime_t get_interval(cputime_t old, cputime_t new)
211{
212 cputime_t itv = new - old;
213
214 return (itv == 0) ? 1 : itv;
215}
216
217#if CPUTIME_MAX > 0xffffffff
218/*
219 * Handle overflow conditions properly for counters which can have
220 * less bits than cputime_t, depending on the kernel version.
221 */
222/* Surprisingly, on 32bit inlining is a size win */
223static ALWAYS_INLINE cputime_t overflow_safe_sub(cputime_t prev, cputime_t curr)
224{
225 cputime_t v = curr - prev;
226
227 if ((icputime_t)v < 0 /* curr < prev - counter overflow? */
228 && prev <= 0xffffffff /* kernel uses 32bit value for the counter? */
229 ) {
230 /* Add 33th bit set to 1 to curr, compensating for the overflow */
231 /* double shift defeats "warning: left shift count >= width of type" */
232 v += ((cputime_t)1 << 16) << 16;
233 }
234 return v;
235}
236#else
237static ALWAYS_INLINE cputime_t overflow_safe_sub(cputime_t prev, cputime_t curr)
238{
239 return curr - prev;
240}
241#endif
242
243static double percent_value(cputime_t prev, cputime_t curr, cputime_t itv)
244{
245 return ((double)overflow_safe_sub(prev, curr)) / itv * 100;
246}
247
248static void print_stats_cpu_struct(const struct stats_cpu *p,
249 const struct stats_cpu *c, cputime_t itv)
250{
251 printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n",
252 percent_value(p->cpu_user , c->cpu_user , itv),
253 percent_value(p->cpu_nice , c->cpu_nice , itv),
254 percent_value(p->cpu_system + p->cpu_softirq + p->cpu_irq,
255 c->cpu_system + c->cpu_softirq + c->cpu_irq, itv),
256 percent_value(p->cpu_iowait , c->cpu_iowait , itv),
257 percent_value(p->cpu_steal , c->cpu_steal , itv),
258 percent_value(p->cpu_idle , c->cpu_idle , itv)
259 );
260}
261
262static void print_stats_dev_struct(const struct stats_dev *p,
263 const struct stats_dev *c, cputime_t itv)
264{
265 int unit = 1;
266
267 if (option_mask32 & OPT_k)
268 unit = 2;
269 else if (option_mask32 & OPT_m)
270 unit = 2048;
271
272 if (option_mask32 & OPT_z)
273 if (p->rd_ops == c->rd_ops && p->wr_ops == c->wr_ops)
274 return;
275
276 printf("%-13s", c->dname);
277 printf(" %8.2f %12.2f %12.2f %10llu %10llu \n",
278 percent_value(p->rd_ops + p->wr_ops ,
279 /**/ c->rd_ops + c->wr_ops , itv),
280 percent_value(p->rd_sectors, c->rd_sectors, itv) / unit,
281 percent_value(p->wr_sectors, c->wr_sectors, itv) / unit,
282 (c->rd_sectors - p->rd_sectors) / unit,
283 (c->wr_sectors - p->wr_sectors) / unit);
284}
285
286static void cpu_report(const struct stats_cpu *last,
287 const struct stats_cpu *cur,
288 cputime_t itv)
289{
290 /* Always print a header */
291 puts("avg-cpu: %user %nice %system %iowait %steal %idle");
292
293 /* Print current statistics */
294 print_stats_cpu_struct(last, cur, itv);
295}
296
297static void print_devstat_header(void)
298{
299 printf("Device: tps");
300
301 if (option_mask32 & OPT_m)
302 puts(" MB_read/s MB_wrtn/s MB_read MB_wrtn");
303 else if (option_mask32 & OPT_k)
304 puts(" kB_read/s kB_wrtn/s kB_read kB_wrtn");
305 else
306 puts(" Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn");
307}
308
309/*
310 * Is input partition of format [sdaN]?
311 */
312static int is_partition(const char *dev)
313{
314 /* Ok, this is naive... */
315 return ((dev[0] - 's') | (dev[1] - 'd') | (dev[2] - 'a')) == 0 && isdigit(dev[3]);
316}
317
318/*
319 * Return number of numbers on cmdline.
320 * Reasonable values are only 0 (no interval/count specified),
321 * 1 (interval specified) and 2 (both interval and count specified)
322 */
323static int numbers_on_cmdline(int argc, char *argv[])
324{
325 int sum = 0;
326
327 if (isdigit(argv[argc-1][0]))
328 sum++;
329 if (argc > 2 && isdigit(argv[argc-2][0]))
330 sum++;
331
332 return sum;
333}
334
335static int is_dev_in_dlist(const char *dev)
336{
337 int i;
338
339 /* Go through the device list */
340 for (i = 0; i < G.devlist_i; i++)
341 if (strcmp(G.dlist[i].dname, dev) == 0)
342 /* Found a match */
343 return 1;
344
345 /* No match found */
346 return 0;
347}
348
349static void do_disk_statistics(cputime_t itv)
350{
351 FILE *fp;
352 int rc;
353 int i = 0;
354 char buf[128];
355 unsigned major, minor;
356 unsigned long wr_ops, dummy; /* %*lu for suppres the conversion wouldn't work */
357 unsigned long long rd_sec_or_wr_ops;
358 unsigned long long rd_sec_or_dummy, wr_sec_or_dummy, wr_sec;
359 struct stats_dev sd;
360
361 fp = xfopen_for_read("/proc/diskstats");
362
363 /* Read and possibly print stats from /proc/diskstats */
364 while (fgets(buf, sizeof(buf), fp)) {
365 rc = sscanf(buf, "%u %u %s %lu %llu %llu %llu %lu %lu %llu %lu %lu %lu %lu",
366 &major, &minor, sd.dname, &sd.rd_ops,
367 &rd_sec_or_dummy, &rd_sec_or_wr_ops, &wr_sec_or_dummy,
368 &wr_ops, &dummy, &wr_sec, &dummy, &dummy, &dummy, &dummy);
369
370 switch (rc) {
371 case 14:
372 sd.wr_ops = wr_ops;
373 sd.rd_sectors = rd_sec_or_wr_ops;
374 sd.wr_sectors = wr_sec;
375 break;
376 case 7:
377 sd.rd_sectors = rd_sec_or_dummy;
378 sd.wr_ops = (unsigned long)rd_sec_or_wr_ops;
379 sd.wr_sectors = wr_sec_or_dummy;
380 break;
381 default:
382 break;
383 }
384
385 if (!G.devlist_i && !is_partition(sd.dname)) {
386 /* User didn't specify device */
387 if (!G.show_all && !sd.rd_ops && !sd.wr_ops) {
388 /* Don't print unused device */
389 continue;
390 }
391 print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv);
392 G.saved_stats_dev[i] = sd;
393 i++;
394 } else {
395 /* Is device in device list? */
396 if (is_dev_in_dlist(sd.dname)) {
397 /* Print current statistics */
398 print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv);
399 G.saved_stats_dev[i] = sd;
400 i++;
401 } else
402 continue;
403 }
404 }
405
406 fclose(fp);
407}
408
409static void dev_report(cputime_t itv)
410{
411 /* Always print a header */
412 print_devstat_header();
413
414 /* Fetch current disk statistics */
415 do_disk_statistics(itv);
416}
417
418static void save_to_devlist(const char *dname)
419{
420 int i;
421 struct device_list *tmp = G.dlist;
422
423 if (strncmp(dname, "/dev/", 5) == 0)
424 /* We'll ignore prefix '/dev/' */
425 dname += 5;
426
427 /* Go through the list */
428 for (i = 0; i < G.devlist_i; i++, tmp++)
429 if (strcmp(tmp->dname, dname) == 0)
430 /* Already in the list */
431 return;
432
433 /* Add device name to the list */
434 strncpy(tmp->dname, dname, MAX_DEVICE_NAME - 1);
435
436 /* Update device list index */
437 G.devlist_i++;
438}
439
440static unsigned get_number_of_devices(void)
441{
442 FILE *fp;
443 char buf[128];
444 int rv;
445 unsigned n = 0;
446 unsigned long rd_ops, wr_ops;
447 char dname[MAX_DEVICE_NAME];
448
449 fp = xfopen_for_read("/proc/diskstats");
450
451 while (fgets(buf, sizeof(buf), fp)) {
452 rv = sscanf(buf, "%*d %*d %s %lu %*u %*u %*u %lu",
453 dname, &rd_ops, &wr_ops);
454 if (rv == 2 || is_partition(dname))
455 /* A partition */
456 continue;
457 if (!rd_ops && !wr_ops) {
458 /* Unused device */
459 if (!G.show_all)
460 continue;
461 }
462 n++;
463 }
464
465 fclose(fp);
466 return n;
467}
468
469static int number_of_ALL_on_cmdline(char **argv)
470{
471 int alls = 0;
472
473 /* Iterate over cmd line arguments, count "ALL" */
474 while (*argv)
475 if (strcmp(*argv++, "ALL") == 0)
476 alls++;
477
478 return alls;
479}
480
481//usage:#define iostat_trivial_usage
482//usage: "[-c] [-d] [-t] [-z] [-k|-m] [ALL|BLOCKDEV...] [INTERVAL [COUNT]]"
483//usage:#define iostat_full_usage "\n\n"
484//usage: "Report CPU and I/O statistics\n"
485//usage: "\nOptions:"
486//usage: "\n -c Show CPU utilization"
487//usage: "\n -d Show device utilization"
488//usage: "\n -t Print current time"
489//usage: "\n -z Omit devices with no activity"
490//usage: "\n -k Use kb/s"
491//usage: "\n -m Use Mb/s"
492
493int iostat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
494int iostat_main(int argc, char **argv)
495{
496 int opt, dev_num;
497 unsigned interval = 0;
498 int count;
499 cputime_t global_uptime[2] = { 0 };
500 cputime_t smp_uptime[2] = { 0 };
501 cputime_t itv;
502 struct stats_cpu stats_cur, stats_last;
503
504 INIT_G();
505
506 memset(&stats_last, 0, sizeof(stats_last));
507
508 /* Get number of clock ticks per sec */
509 G.clk_tck = get_user_hz();
510
511 /* Determine number of CPUs */
512 G.total_cpus = get_number_of_cpus();
513
514 /* Parse and process arguments */
515 /* -k and -m are mutually exclusive */
516 opt_complementary = "k--m:m--k";
517 opt = getopt32(argv, "cdtzkm");
518 if (!(opt & (OPT_c + OPT_d)))
519 /* Default is -cd */
520 opt |= OPT_c + OPT_d;
521
522 argv += optind;
523 argc -= optind;
524
525 dev_num = argc - numbers_on_cmdline(argc, argv);
526 /* We don't want to allocate space for 'ALL' */
527 dev_num -= number_of_ALL_on_cmdline(argv);
528 if (dev_num > 0)
529 /* Make space for device list */
530 G.dlist = xzalloc(sizeof(G.dlist[0]) * dev_num);
531
532 /* Store device names into device list */
533 while (*argv && !isdigit(*argv[0])) {
534 if (strcmp(*argv, "ALL") != 0)
535 /* If not ALL, save device name */
536 save_to_devlist(*argv);
537 else
538 G.show_all = 1;
539 argv++;
540 }
541
542 count = 1;
543 if (*argv) {
544 /* Get interval */
545 interval = xatoi_positive(*argv);
546 count = (interval != 0 ? -1 : 1);
547 argv++;
548 if (*argv)
549 /* Get count value */
550 count = xatoi_positive(*argv);
551 }
552
553 /* Allocate space for device stats */
554 if (opt & OPT_d) {
555 G.saved_stats_dev = xzalloc(sizeof(G.saved_stats_dev[0]) *
556 (dev_num ? dev_num : get_number_of_devices())
557 );
558 }
559
560 /* Display header */
561 print_header();
562
563 /* Main loop */
564 for (;;) {
565 /* Fill the time structure */
566 get_localtime(&G.tmtime);
567
568 /* Fetch current CPU statistics */
569 get_cpu_statistics(&stats_cur);
570
571 /* Fetch current uptime */
572 global_uptime[CURRENT] = get_uptime(&stats_cur);
573
574 /* Get interval */
575 itv = get_interval(global_uptime[LAST], global_uptime[CURRENT]);
576
577 if (opt & OPT_t)
578 print_timestamp();
579
580 if (opt & OPT_c) {
581 cpu_report(&stats_last, &stats_cur, itv);
582 if (opt & OPT_d)
583 /* Separate outputs by a newline */
584 bb_putchar('\n');
585 }
586
587 if (opt & OPT_d) {
588 if (this_is_smp()) {
589 smp_uptime[CURRENT] = get_smp_uptime();
590 itv = get_interval(smp_uptime[LAST], smp_uptime[CURRENT]);
591 smp_uptime[LAST] = smp_uptime[CURRENT];
592 }
593 dev_report(itv);
594 }
595
596 if (count > 0) {
597 if (--count == 0)
598 break;
599 }
600
601 /* Backup current stats */
602 global_uptime[LAST] = global_uptime[CURRENT];
603 stats_last = stats_cur;
604
605 bb_putchar('\n');
606 sleep(interval);
607 }
608
609 bb_putchar('\n');
610
611 if (ENABLE_FEATURE_CLEAN_UP) {
612 free(&G);
613 free(G.dlist);
614 free(G.saved_stats_dev);
615 }
616
617 return EXIT_SUCCESS;
618}
diff --git a/procps/mpstat.c b/procps/mpstat.c
index 7610a68fb..85cbb45db 100644
--- a/procps/mpstat.c
+++ b/procps/mpstat.c
@@ -930,14 +930,14 @@ int mpstat_main(int UNUSED_PARAM argc, char **argv)
930 930
931 if (*argv) { 931 if (*argv) {
932 /* Get interval */ 932 /* Get interval */
933 G.interval = xatoi_u(*argv); 933 G.interval = xatoi_positive(*argv);
934 G.count = -1; 934 G.count = -1;
935 argv++; 935 argv++;
936 if (*argv) { 936 if (*argv) {
937 /* Get count value */ 937 /* Get count value */
938 if (G.interval == 0) 938 if (G.interval == 0)
939 bb_show_usage(); 939 bb_show_usage();
940 G.count = xatoi_u(*argv); 940 G.count = xatoi_positive(*argv);
941 //if (*++argv) 941 //if (*++argv)
942 // bb_show_usage(); 942 // bb_show_usage();
943 } 943 }
@@ -979,7 +979,7 @@ int mpstat_main(int UNUSED_PARAM argc, char **argv)
979 memset(G.cpu_bitmap, 0xff, G.cpu_bitmap_len); 979 memset(G.cpu_bitmap, 0xff, G.cpu_bitmap_len);
980 } else { 980 } else {
981 /* Get CPU number */ 981 /* Get CPU number */
982 unsigned n = xatoi_u(t); 982 unsigned n = xatoi_positive(t);
983 if (n >= G.cpu_nr) 983 if (n >= G.cpu_nr)
984 bb_error_msg_and_die("not that many processors"); 984 bb_error_msg_and_die("not that many processors");
985 n++; 985 n++;
diff --git a/procps/nmeter.c b/procps/nmeter.c
index bb1e819a6..930585695 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -422,7 +422,7 @@ static s_stat* init_int(const char *param)
422 if (param[0] == '\0') { 422 if (param[0] == '\0') {
423 s->no = 1; 423 s->no = 1;
424 } else { 424 } else {
425 int n = xatoi_u(param); 425 int n = xatoi_positive(param);
426 s->no = n + 2; 426 s->no = n + 2;
427 } 427 }
428 return (s_stat*)s; 428 return (s_stat*)s;
diff --git a/runit/svlogd.c b/runit/svlogd.c
index 9fe81b900..1f0a77cc2 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -688,10 +688,10 @@ static NOINLINE unsigned logdir_open(struct logdir *ld, const char *fn)
688 break; 688 break;
689 } 689 }
690 case 'n': 690 case 'n':
691 ld->nmax = xatoi_u(&s[1]); 691 ld->nmax = xatoi_positive(&s[1]);
692 break; 692 break;
693 case 'N': 693 case 'N':
694 ld->nmin = xatoi_u(&s[1]); 694 ld->nmin = xatoi_positive(&s[1]);
695 break; 695 break;
696 case 't': { 696 case 't': {
697 static const struct suffix_mult mh_suffixes[] = { 697 static const struct suffix_mult mh_suffixes[] = {
@@ -981,7 +981,7 @@ int svlogd_main(int argc, char **argv)
981 linemax = 256; 981 linemax = 256;
982 } 982 }
983 ////if (opt & 8) { // -b 983 ////if (opt & 8) { // -b
984 //// buflen = xatoi_u(b); 984 //// buflen = xatoi_positive(b);
985 //// if (buflen == 0) buflen = 1024; 985 //// if (buflen == 0) buflen = 1024;
986 ////} 986 ////}
987 //if (opt & 0x10) timestamp++; // -t 987 //if (opt & 0x10) timestamp++; // -t
diff --git a/shell/ash.c b/shell/ash.c
index 308cc0273..f7fad88cd 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5977,7 +5977,7 @@ removerecordregions(int endoff)
5977 return; 5977 return;
5978 5978
5979 if (ifsfirst.endoff > endoff) { 5979 if (ifsfirst.endoff > endoff) {
5980 while (ifsfirst.next != NULL) { 5980 while (ifsfirst.next) {
5981 struct ifsregion *ifsp; 5981 struct ifsregion *ifsp;
5982 INT_OFF; 5982 INT_OFF;
5983 ifsp = ifsfirst.next->next; 5983 ifsp = ifsfirst.next->next;
@@ -5985,9 +5985,9 @@ removerecordregions(int endoff)
5985 ifsfirst.next = ifsp; 5985 ifsfirst.next = ifsp;
5986 INT_ON; 5986 INT_ON;
5987 } 5987 }
5988 if (ifsfirst.begoff > endoff) 5988 if (ifsfirst.begoff > endoff) {
5989 ifslastp = NULL; 5989 ifslastp = NULL;
5990 else { 5990 } else {
5991 ifslastp = &ifsfirst; 5991 ifslastp = &ifsfirst;
5992 ifsfirst.endoff = endoff; 5992 ifsfirst.endoff = endoff;
5993 } 5993 }
@@ -5996,8 +5996,8 @@ removerecordregions(int endoff)
5996 5996
5997 ifslastp = &ifsfirst; 5997 ifslastp = &ifsfirst;
5998 while (ifslastp->next && ifslastp->next->begoff < endoff) 5998 while (ifslastp->next && ifslastp->next->begoff < endoff)
5999 ifslastp=ifslastp->next; 5999 ifslastp = ifslastp->next;
6000 while (ifslastp->next != NULL) { 6000 while (ifslastp->next) {
6001 struct ifsregion *ifsp; 6001 struct ifsregion *ifsp;
6002 INT_OFF; 6002 INT_OFF;
6003 ifsp = ifslastp->next->next; 6003 ifsp = ifslastp->next->next;
@@ -6205,9 +6205,9 @@ expbackq(union node *cmd, int quoted, int quotes)
6205 6205
6206 if (quoted == 0) 6206 if (quoted == 0)
6207 recordregion(startloc, dest - (char *)stackblock(), 0); 6207 recordregion(startloc, dest - (char *)stackblock(), 0);
6208 TRACE(("evalbackq: size=%d: \"%.*s\"\n", 6208 TRACE(("evalbackq: size:%d:'%.*s'\n",
6209 (dest - (char *)stackblock()) - startloc, 6209 (int)((dest - (char *)stackblock()) - startloc),
6210 (dest - (char *)stackblock()) - startloc, 6210 (int)((dest - (char *)stackblock()) - startloc),
6211 stackblock() + startloc)); 6211 stackblock() + startloc));
6212} 6212}
6213 6213
@@ -6426,42 +6426,16 @@ argstr(char *p, int flags, struct strlist *var_str_list)
6426} 6426}
6427 6427
6428static char * 6428static char *
6429scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM, char *str, int quotes, 6429scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
6430 int zero) 6430 char *pattern, int quotes, int zero)
6431{ 6431{
6432// This commented out code was added by James Simmons <jsimmons@infradead.org> 6432 char *loc, *loc2;
6433// as part of a larger change when he added support for ${var/a/b}.
6434// However, it broke # and % operators:
6435//
6436//var=ababcdcd
6437// ok bad
6438//echo ${var#ab} abcdcd abcdcd
6439//echo ${var##ab} abcdcd abcdcd
6440//echo ${var#a*b} abcdcd ababcdcd (!)
6441//echo ${var##a*b} cdcd cdcd
6442//echo ${var#?} babcdcd ababcdcd (!)
6443//echo ${var##?} babcdcd babcdcd
6444//echo ${var#*} ababcdcd babcdcd (!)
6445//echo ${var##*}
6446//echo ${var%cd} ababcd ababcd
6447//echo ${var%%cd} ababcd abab (!)
6448//echo ${var%c*d} ababcd ababcd
6449//echo ${var%%c*d} abab ababcdcd (!)
6450//echo ${var%?} ababcdc ababcdc
6451//echo ${var%%?} ababcdc ababcdcd (!)
6452//echo ${var%*} ababcdcd ababcdcd
6453//echo ${var%%*}
6454//
6455// Commenting it back out helped. Remove it completely if it really
6456// is not needed.
6457
6458 char *loc, *loc2; //, *full;
6459 char c; 6433 char c;
6460 6434
6461 loc = startp; 6435 loc = startp;
6462 loc2 = rmesc; 6436 loc2 = rmesc;
6463 do { 6437 do {
6464 int match; // = strlen(str); 6438 int match;
6465 const char *s = loc2; 6439 const char *s = loc2;
6466 6440
6467 c = *loc2; 6441 c = *loc2;
@@ -6469,35 +6443,22 @@ scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM, char *str, int
6469 *loc2 = '\0'; 6443 *loc2 = '\0';
6470 s = rmesc; 6444 s = rmesc;
6471 } 6445 }
6472 match = pmatch(str, s); // this line was deleted 6446 match = pmatch(pattern, s);
6473 6447
6474// // chop off end if its '*'
6475// full = strrchr(str, '*');
6476// if (full && full != str)
6477// match--;
6478//
6479// // If str starts with '*' replace with s.
6480// if ((*str == '*') && strlen(s) >= match) {
6481// full = xstrdup(s);
6482// strncpy(full+strlen(s)-match+1, str+1, match-1);
6483// } else
6484// full = xstrndup(str, match);
6485// match = strncmp(s, full, strlen(full));
6486// free(full);
6487//
6488 *loc2 = c; 6448 *loc2 = c;
6489 if (match) // if (!match) 6449 if (match)
6490 return loc; 6450 return loc;
6491 if (quotes && (unsigned char)*loc == CTLESC) 6451 if (quotes && (unsigned char)*loc == CTLESC)
6492 loc++; 6452 loc++;
6493 loc++; 6453 loc++;
6494 loc2++; 6454 loc2++;
6495 } while (c); 6455 } while (c);
6496 return 0; 6456 return NULL;
6497} 6457}
6498 6458
6499static char * 6459static char *
6500scanright(char *startp, char *rmesc, char *rmescend, char *pattern, int quotes, int match_at_start) 6460scanright(char *startp, char *rmesc, char *rmescend,
6461 char *pattern, int quotes, int match_at_start)
6501{ 6462{
6502#if !ENABLE_ASH_OPTIMIZE_FOR_SIZE 6463#if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6503 int try2optimize = match_at_start; 6464 int try2optimize = match_at_start;
@@ -6563,7 +6524,7 @@ scanright(char *startp, char *rmesc, char *rmescend, char *pattern, int quotes,
6563 } 6524 }
6564 } 6525 }
6565 } 6526 }
6566 return 0; 6527 return NULL;
6567} 6528}
6568 6529
6569static void varunset(const char *, const char *, const char *, int) NORETURN; 6530static void varunset(const char *, const char *, const char *, int) NORETURN;
@@ -6583,16 +6544,18 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
6583 msg = umsg; 6544 msg = umsg;
6584 } 6545 }
6585 } 6546 }
6586 ash_msg_and_raise_error("%.*s: %s%s", end - var - 1, var, msg, tail); 6547 ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6587} 6548}
6588 6549
6589#if ENABLE_ASH_BASH_COMPAT 6550#if ENABLE_ASH_BASH_COMPAT
6590static char * 6551static char *
6591parse_sub_pattern(char *arg, int inquotes) 6552parse_sub_pattern(char *arg, int varflags)
6592{ 6553{
6593 char *idx, *repl = NULL; 6554 char *idx, *repl = NULL;
6594 unsigned char c; 6555 unsigned char c;
6595 6556
6557 //char *org_arg = arg;
6558 //bb_error_msg("arg:'%s' varflags:%x", arg, varflags);
6596 idx = arg; 6559 idx = arg;
6597 while (1) { 6560 while (1) {
6598 c = *arg; 6561 c = *arg;
@@ -6606,11 +6569,23 @@ parse_sub_pattern(char *arg, int inquotes)
6606 } 6569 }
6607 } 6570 }
6608 *idx++ = c; 6571 *idx++ = c;
6609 if (!inquotes && c == '\\' && arg[1] == '\\')
6610 arg++; /* skip both \\, not just first one */
6611 arg++; 6572 arg++;
6573 /*
6574 * Example: v='ab\c'; echo ${v/\\b/_\\_\z_}
6575 * The result is a_\_z_c (not a\_\_z_c)!
6576 *
6577 * Enable debug prints in this function and you'll see:
6578 * ash: arg:'\\b/_\\_z_' varflags:d
6579 * ash: pattern:'\\b' repl:'_\_z_'
6580 * That is, \\b is interpreted as \\b, but \\_ as \_!
6581 * IOW: search pattern and replace string treat backslashes
6582 * differently! That is the reason why we check repl below:
6583 */
6584 if (c == '\\' && *arg == '\\' && repl && !(varflags & VSQUOTE))
6585 arg++; /* skip both '\', not just first one */
6612 } 6586 }
6613 *idx = c; /* NUL */ 6587 *idx = c; /* NUL */
6588 //bb_error_msg("pattern:'%s' repl:'%s'", org_arg, repl);
6614 6589
6615 return repl; 6590 return repl;
6616} 6591}
@@ -6748,7 +6723,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
6748 char *idx, *end; 6723 char *idx, *end;
6749 6724
6750 if (!repl) { 6725 if (!repl) {
6751 repl = parse_sub_pattern(str, varflags & VSQUOTE); 6726 repl = parse_sub_pattern(str, varflags);
6752 //bb_error_msg("repl:'%s'", repl); 6727 //bb_error_msg("repl:'%s'", repl);
6753 if (!repl) 6728 if (!repl)
6754 repl = nullstr; 6729 repl = nullstr;
@@ -6817,12 +6792,9 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
6817 } 6792 }
6818 6793
6819 if (subtype == VSREPLACE) { 6794 if (subtype == VSREPLACE) {
6795 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
6820 while (*idx) { 6796 while (*idx) {
6821 char *restart_detect = stackblock(); 6797 char *restart_detect = stackblock();
6822 if (quotes && *idx == '\\') {
6823 STPUTC(CTLESC, expdest);
6824 len++;
6825 }
6826 STPUTC(*idx, expdest); 6798 STPUTC(*idx, expdest);
6827 if (stackblock() != restart_detect) 6799 if (stackblock() != restart_detect)
6828 goto restart; 6800 goto restart;
diff --git a/shell/ash_test/ash-vars/var_bash4.right b/shell/ash_test/ash-vars/var_bash4.right
index fc3a9e41c..600e8532f 100644
--- a/shell/ash_test/ash-vars/var_bash4.right
+++ b/shell/ash_test/ash-vars/var_bash4.right
@@ -1,4 +1,23 @@
1In assignment: a*b-backslashstar- 1Source: a*b\*c
2Unquoted: a*b-backslashstar- 2Replace str: _\\_\z_
3Quoted: a*b-backslashstar- 3Pattern: single backslash and star: "replace literal star"
4In assignment: a_\_z_b\*c
5Unquoted: a_\_z_b\*c
6Quoted: a_\_\z_b\*c
7Pattern: double backslash and star: "replace backslash and everything after it"
8In assignment: a*b_\_z_
9Unquoted: a*b_\_z_
10Quoted: a*b_\_\z_
11
12Source: a\bc
13Replace str: _\\_\z_
14Pattern: single backslash and b: "replace b"
15In assignment: a\_\_z_c
16Unquoted: a\_\_z_c
17Quoted: a\_\_\z_c
18Pattern: double backslash and b: "replace backslash and b"
19In assignment: a_\_z_c
20Unquoted: a_\_z_c
21Quoted: a_\_\z_c
22
4Done: 0 23Done: 0
diff --git a/shell/ash_test/ash-vars/var_bash4.tests b/shell/ash_test/ash-vars/var_bash4.tests
index 3b323c576..d5470614b 100755
--- a/shell/ash_test/ash-vars/var_bash4.tests
+++ b/shell/ash_test/ash-vars/var_bash4.tests
@@ -1,6 +1,47 @@
1FOO='a*b\*c' 1# This testcase demonstrates that backslashes are treated differently
2BAR=${FOO//\\*/-backslashstar-} 2# in 1st and 2nd parts of ${var/search/repl}:
3echo In assignment: "$BAR" 3# if quoted ("${var/search/repl}"), and repl contains \a (a non-special char),
4echo Unquoted: ${FOO//\\*/-backslashstar-} 4# the backslash in repl stays; if unquoted, backslash is removed.
5echo Quoted: "${FOO//\\*/-backslashstar-}" 5# But search part does not act like that: \a is always converted to just a,
6# even in quotes.
7#
8# bash4 (and probably bash3 too): "Quoted:" results are different from
9# unquoted and assignment expansions - they have a backslash before z.
10
11v='a*b\*c'
12echo 'Source: ' "$v"
13echo 'Replace str: ' '_\\_\z_'
14
15echo 'Pattern: ' 'single backslash and star: "replace literal star"'
16r=${v/\*/_\\_\z_}
17echo 'In assignment:' "$r"
18echo 'Unquoted: ' ${v/\*/_\\_\z_}
19echo 'Quoted: ' "${v/\*/_\\_\z_}"
20
21echo 'Pattern: ' 'double backslash and star: "replace backslash and everything after it"'
22r=${v/\\*/_\\_\z_}
23echo 'In assignment:' "$r"
24echo 'Unquoted: ' ${v/\\*/_\\_\z_}
25echo 'Quoted: ' "${v/\\*/_\\_\z_}"
26
27echo
28
29v='a\bc'
30echo 'Source: ' "$v"
31echo 'Replace str: ' '_\\_\z_'
32
33echo 'Pattern: ' 'single backslash and b: "replace b"'
34r=${v/\b/_\\_\z_}
35echo 'In assignment:' "$r"
36echo 'Unquoted: ' ${v/\b/_\\_\z_}
37echo 'Quoted: ' "${v/\b/_\\_\z_}"
38
39echo 'Pattern: ' 'double backslash and b: "replace backslash and b"'
40r=${v/\\b/_\\_\z_}
41echo 'In assignment:' "$r"
42echo 'Unquoted: ' ${v/\\b/_\\_\z_}
43echo 'Quoted: ' "${v/\\b/_\\_\z_}"
44
45echo
46
6echo Done: $? 47echo Done: $?
diff --git a/shell/hush.c b/shell/hush.c
index 0a420f685..df4058998 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2788,7 +2788,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
2788 /* lookup the variable in question */ 2788 /* lookup the variable in question */
2789 if (isdigit(var[0])) { 2789 if (isdigit(var[0])) {
2790 /* parse_dollar() should have vetted var for us */ 2790 /* parse_dollar() should have vetted var for us */
2791 i = xatoi_u(var); 2791 i = xatoi_positive(var);
2792 if (i < G.global_argc) 2792 if (i < G.global_argc)
2793 val = G.global_argv[i]; 2793 val = G.global_argv[i];
2794 /* else val remains NULL: $N with too big N */ 2794 /* else val remains NULL: $N with too big N */
diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests
index 7aee774a1..44c17e693 100755
--- a/testsuite/cpio.tests
+++ b/testsuite/cpio.tests
@@ -4,6 +4,8 @@
4 4
5. ./testing.sh 5. ./testing.sh
6 6
7umask 022
8
7# ls -ln shows date. Need to remove that, it's variable. 9# ls -ln shows date. Need to remove that, it's variable.
8# sed: coalesce spaces 10# sed: coalesce spaces
9# cut: remove date 11# cut: remove date
diff --git a/testsuite/date/date-works-1 b/testsuite/date/date-works-1
index e745d3841..cb5cea2c5 100644
--- a/testsuite/date/date-works-1
+++ b/testsuite/date/date-works-1
@@ -1,4 +1,7 @@
1unset LANG 1unset LANG
2unset LANGUAGE
3unset LC_TIME
4unset LC_ALL
2 5
3dt=`busybox date -d 1:2 +%T` 6dt=`busybox date -d 1:2 +%T`
4test x"$dt" = x"01:02:00" 7test x"$dt" = x"01:02:00"
diff --git a/testsuite/du/du-k-works b/testsuite/du/du-k-works
index a52264945..229a948ee 100644
--- a/testsuite/du/du-k-works
+++ b/testsuite/du/du-k-works
@@ -1,4 +1,6 @@
1mkdir du.testdir
2cd du.testdir
1dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null 3dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null
2dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null 4dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null
3test x"`busybox du -k .`" = x"80 ." \ 5test x"`busybox du -k .`" = x"80 ." \
4 -o x"`busybox du -k .`" = x"88 ." \ 6 -o x"`busybox du -k .`" = x"88 ."
diff --git a/testsuite/du/du-l-works b/testsuite/du/du-l-works
index 6b150e0dd..426ee891b 100644
--- a/testsuite/du/du-l-works
+++ b/testsuite/du/du-l-works
@@ -1,8 +1,11 @@
1# FEATURE: CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 1# FEATURE: CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
2 2
3mkdir du.testdir
4cd du.testdir
3dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null 5dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null
4ln file1 file1.1 6ln file1 file1.1
5dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null 7dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null
6test x"`busybox du -l .`" = x"144 ." \ 8test x"`busybox du -l .`" = x"144 ." \
7 -o x"`busybox du -l .`" = x"148 ." \ 9 -o x"`busybox du -l .`" = x"148 ." \
8 -o x"`busybox du -l .`" = x"152 ." \ 10 -o x"`busybox du -l .`" = x"152 ." \
11 -o x"`busybox du -l .`" = x"156 ."
diff --git a/testsuite/hostname/hostname-d-works b/testsuite/hostname/hostname-d-works
index e062242bb..54c0aac0c 100644
--- a/testsuite/hostname/hostname-d-works
+++ b/testsuite/hostname/hostname-d-works
@@ -1,3 +1,3 @@
1f=$(busybox hostname -f) 1f=$(busybox hostname -f).
2d=$(busybox hostname -d) 2d=$(busybox hostname -d)
3test x"${f#*.}" = x"$d" 3test x"${f#*.}" = x"$d${d:+.}"
diff --git a/testsuite/makedevs.tests b/testsuite/makedevs.tests
index f69b4a6b1..f19af8a52 100755
--- a/testsuite/makedevs.tests
+++ b/testsuite/makedevs.tests
@@ -4,6 +4,10 @@
4 4
5. ./testing.sh 5. ./testing.sh
6 6
7unset LANG
8unset LC_COLLATE
9unset LC_ALL
10
7# ls -ln is showing date. Need to remove that, it's variable 11# ls -ln is showing date. Need to remove that, it's variable
8# sed: (1) "maj, min" -> "maj,min" (2) coalesce spaces 12# sed: (1) "maj, min" -> "maj,min" (2) coalesce spaces
9# cut: remove date 13# cut: remove date
diff --git a/testsuite/tar.tests b/testsuite/tar.tests
index f40079037..6604b4d22 100755
--- a/testsuite/tar.tests
+++ b/testsuite/tar.tests
@@ -4,6 +4,12 @@
4 4
5. ./testing.sh 5. ./testing.sh
6 6
7unset LANG
8unset LANGUAGE
9unset LC_COLLATE
10unset LC_ALL
11umask 022
12
7rm -rf tar.tempdir 2>/dev/null 13rm -rf tar.tempdir 2>/dev/null
8mkdir tar.tempdir && cd tar.tempdir || exit 1 14mkdir tar.tempdir && cd tar.tempdir || exit 1
9 15
diff --git a/testsuite/uuencode.tests b/testsuite/uuencode.tests
index 6556e60d1..adb2d3390 100755
--- a/testsuite/uuencode.tests
+++ b/testsuite/uuencode.tests
@@ -13,11 +13,10 @@
13# test can create a file "actual" instead of writing to stdout 13# test can create a file "actual" instead of writing to stdout
14 14
15# Test setup of standard input 15# Test setup of standard input
16saved_umask=$(umask)
17umask 0 16umask 0
18testing "uuencode sets standard input mode correctly" \ 17testing "uuencode sets standard input mode correctly" \
19 "uuencode foo </dev/null | head -n 1 | grep -q 666 && echo yes" "yes\n" "" "" 18 "uuencode foo </dev/null | head -n 1 | grep -q 666 && echo yes" "yes\n" "" ""
20umask $saved_umask 19umask 022
21 20
22testing "uuencode correct encoding" "uuencode bb_uuenc_test.out" \ 21testing "uuencode correct encoding" "uuencode bb_uuenc_test.out" \
23"begin 644 bb_uuenc_test.out\nM5&AE(&9A<W0@9W)E>2!F;W@@:G5M<&5D(&]V97(@=&AE(&QA>GD@8G)O=VX@\n%9&]G+@H\`\n\`\nend\n" \ 22"begin 644 bb_uuenc_test.out\nM5&AE(&9A<W0@9W)E>2!F;W@@:G5M<&5D(&]V97(@=&AE(&QA>GD@8G)O=VX@\n%9&]G+@H\`\n\`\nend\n" \
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 98953c17b..afa30923b 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -333,7 +333,7 @@ config FEATURE_HWCLOCK_LONG_OPTIONS
333 333
334config FEATURE_HWCLOCK_ADJTIME_FHS 334config FEATURE_HWCLOCK_ADJTIME_FHS
335 bool "Use FHS /var/lib/hwclock/adjtime" 335 bool "Use FHS /var/lib/hwclock/adjtime"
336 default y 336 default n # util-linux-ng in Fedora 13 still uses /etc/adjtime
337 depends on HWCLOCK 337 depends on HWCLOCK
338 help 338 help
339 Starting with FHS 2.3, the adjtime state file is supposed to exist 339 Starting with FHS 2.3, the adjtime state file is supposed to exist
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index b89a2b2af..79be0cd0f 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -46,7 +46,8 @@
46#if defined(i386) || defined(__sparc__) || defined(__arm__) \ 46#if defined(i386) || defined(__sparc__) || defined(__arm__) \
47 || defined(__m68k__) || defined(__mips__) || defined(__s390__) \ 47 || defined(__m68k__) || defined(__mips__) || defined(__s390__) \
48 || defined(__s390__) || defined(__s390x__) \ 48 || defined(__s390__) || defined(__s390x__) \
49 || defined(__sh__) || defined(__x86_64__) || defined(__avr32__) 49 || defined(__sh__) || defined(__x86_64__) || defined(__avr32__) \
50 || defined(__nds32__)
50# define BSD_LABELSECTOR 1 51# define BSD_LABELSECTOR 1
51# define BSD_LABELOFFSET 0 52# define BSD_LABELOFFSET 0
52#elif defined(__alpha__) || defined(__powerpc__) || defined(__ia64__) \ 53#elif defined(__alpha__) || defined(__powerpc__) || defined(__ia64__) \
diff --git a/util-linux/flock.c b/util-linux/flock.c
index 78b1e4ba3..be3d552fa 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -40,7 +40,7 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
40 bb_perror_msg_and_die("can't open '%s'", argv[0]); 40 bb_perror_msg_and_die("can't open '%s'", argv[0]);
41 //TODO? close_on_exec_on(fd); 41 //TODO? close_on_exec_on(fd);
42 } else { 42 } else {
43 fd = xatoi_u(argv[0]); 43 fd = xatoi_positive(argv[0]);
44 } 44 }
45 argv++; 45 argv++;
46 46
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index 2eb5e57ae..7b89e6fdc 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -90,7 +90,7 @@ int hexdump_main(int argc, char **argv)
90 bb_dump_addfile(dumper, optarg); 90 bb_dump_addfile(dumper, optarg);
91 } /* else */ 91 } /* else */
92 if (ch == 'n') { 92 if (ch == 'n') {
93 dumper->dump_length = xatoi_u(optarg); 93 dumper->dump_length = xatoi_positive(optarg);
94 } /* else */ 94 } /* else */
95 if (ch == 's') { /* compat: -s accepts hex numbers too */ 95 if (ch == 's') { /* compat: -s accepts hex numbers too */
96 dumper->dump_skip = xstrtoul_range_sfx(optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ LONG_MAX, suffixes); 96 dumper->dump_skip = xstrtoul_range_sfx(optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ LONG_MAX, suffixes);
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 9107e4308..aa17872da 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -1147,7 +1147,7 @@ static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
1147 continue; 1147 continue;
1148 } 1148 }
1149 1149
1150 val = xatoi_u(opteq); 1150 val = xatoi_positive(opteq);
1151 switch (idx) { 1151 switch (idx) {
1152 case 0: // "rsize" 1152 case 0: // "rsize"
1153 data.rsize = val; 1153 data.rsize = val;