aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-06-12 15:51:29 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-06-12 15:51:29 +0200
commitd0db975a9f399140ddb7dacdfffaf098df3e249b (patch)
tree4b9cbdad519a80e410dea6c2a917d77bd3209ad5
parent58cdca3984beb4e1019ef5ccf1dd7361f032a9a6 (diff)
downloadbusybox-w32-d0db975a9f399140ddb7dacdfffaf098df3e249b.tar.gz
busybox-w32-d0db975a9f399140ddb7dacdfffaf098df3e249b.tar.bz2
busybox-w32-d0db975a9f399140ddb7dacdfffaf098df3e249b.zip
post-1.16.1 fixes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--archival/cpio.c2
-rw-r--r--editors/sed.c24
-rw-r--r--include/platform.h2
-rw-r--r--networking/dnsd.c14
-rw-r--r--networking/httpd_indexcgi.c2
-rw-r--r--networking/udhcp/leases.c2
-rw-r--r--shell/ash.c6
-rw-r--r--shell/hush.c2
-rwxr-xr-xtestsuite/cpio.tests8
-rwxr-xr-xtestsuite/sed.tests24
-rw-r--r--util-linux/hwclock.c112
11 files changed, 149 insertions, 49 deletions
diff --git a/archival/cpio.c b/archival/cpio.c
index 858e59b30..2698f0791 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -424,7 +424,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv)
424 if (archive_handle->cpio__blocks != (off_t)-1 424 if (archive_handle->cpio__blocks != (off_t)-1
425 && !(opt & CPIO_OPT_QUIET) 425 && !(opt & CPIO_OPT_QUIET)
426 ) { 426 ) {
427 printf("%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks); 427 fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks);
428 } 428 }
429 429
430 return EXIT_SUCCESS; 430 return EXIT_SUCCESS;
diff --git a/editors/sed.c b/editors/sed.c
index fd9dd1be6..4289aa646 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -487,7 +487,7 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr)
487static void add_cmd(const char *cmdstr) 487static void add_cmd(const char *cmdstr)
488{ 488{
489 sed_cmd_t *sed_cmd; 489 sed_cmd_t *sed_cmd;
490 int temp; 490 unsigned len, n;
491 491
492 /* Append this line to any unfinished line from last time. */ 492 /* Append this line to any unfinished line from last time. */
493 if (G.add_cmd_line) { 493 if (G.add_cmd_line) {
@@ -496,12 +496,14 @@ static void add_cmd(const char *cmdstr)
496 cmdstr = G.add_cmd_line = tp; 496 cmdstr = G.add_cmd_line = tp;
497 } 497 }
498 498
499 /* If this line ends with backslash, request next line. */ 499 /* If this line ends with unescaped backslash, request next line. */
500 temp = strlen(cmdstr); 500 n = len = strlen(cmdstr);
501 if (temp && cmdstr[--temp] == '\\') { 501 while (n && cmdstr[n-1] == '\\')
502 n--;
503 if ((len - n) & 1) { /* if odd number of trailing backslashes */
502 if (!G.add_cmd_line) 504 if (!G.add_cmd_line)
503 G.add_cmd_line = xstrdup(cmdstr); 505 G.add_cmd_line = xstrdup(cmdstr);
504 G.add_cmd_line[temp] = '\0'; 506 G.add_cmd_line[len-1] = '\0';
505 return; 507 return;
506 } 508 }
507 509
@@ -936,7 +938,15 @@ static void process_files(void)
936 /* Skip blocks of commands we didn't match */ 938 /* Skip blocks of commands we didn't match */
937 if (sed_cmd->cmd == '{') { 939 if (sed_cmd->cmd == '{') {
938 if (sed_cmd->invert ? matched : !matched) { 940 if (sed_cmd->invert ? matched : !matched) {
939 while (sed_cmd->cmd != '}') { 941 unsigned nest_cnt = 0;
942 while (1) {
943 if (sed_cmd->cmd == '{')
944 nest_cnt++;
945 if (sed_cmd->cmd == '}') {
946 nest_cnt--;
947 if (nest_cnt == 0)
948 break;
949 }
940 sed_cmd = sed_cmd->next; 950 sed_cmd = sed_cmd->next;
941 if (!sed_cmd) 951 if (!sed_cmd)
942 bb_error_msg_and_die("unterminated {"); 952 bb_error_msg_and_die("unterminated {");
@@ -1031,7 +1041,7 @@ static void process_files(void)
1031 case 'c': 1041 case 'c':
1032 /* Only triggers on last line of a matching range. */ 1042 /* Only triggers on last line of a matching range. */
1033 if (!sed_cmd->in_match) 1043 if (!sed_cmd->in_match)
1034 sed_puts(sed_cmd->string, NO_EOL_CHAR); 1044 sed_puts(sed_cmd->string, '\n');
1035 goto discard_line; 1045 goto discard_line;
1036 1046
1037 /* Read file, append contents to output */ 1047 /* Read file, append contents to output */
diff --git a/include/platform.h b/include/platform.h
index a41daa08c..804fab4e1 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -291,10 +291,12 @@ typedef unsigned smalluint;
291#if 1 /* if needed: !defined(arch1) && !defined(arch2) */ 291#if 1 /* if needed: !defined(arch1) && !defined(arch2) */
292# define ALIGN1 __attribute__((aligned(1))) 292# define ALIGN1 __attribute__((aligned(1)))
293# define ALIGN2 __attribute__((aligned(2))) 293# define ALIGN2 __attribute__((aligned(2)))
294# define ALIGN4 __attribute__((aligned(4)))
294#else 295#else
295/* Arches which MUST have 2 or 4 byte alignment for everything are here */ 296/* Arches which MUST have 2 or 4 byte alignment for everything are here */
296# define ALIGN1 297# define ALIGN1
297# define ALIGN2 298# define ALIGN2
299# define ALIGN4
298#endif 300#endif
299 301
300 302
diff --git a/networking/dnsd.c b/networking/dnsd.c
index 56ede3fca..1a4ccb911 100644
--- a/networking/dnsd.c
+++ b/networking/dnsd.c
@@ -44,10 +44,15 @@ struct dns_head {
44 uint16_t nauth; 44 uint16_t nauth;
45 uint16_t nadd; 45 uint16_t nadd;
46}; 46};
47/* Structure used to access type and class fields.
48 * They are totally unaligned, but gcc 4.3.4 thinks that pointer of type uint16_t*
49 * is 16-bit aligned and replaces 16-bit memcpy (in move_from_unaligned16 macro)
50 * with aligned halfword access on arm920t!
51 * Oh well. Slapping PACKED everywhere seems to help: */
47struct dns_prop { 52struct dns_prop {
48 uint16_t type; 53 uint16_t type PACKED;
49 uint16_t class; 54 uint16_t class PACKED;
50}; 55} PACKED;
51/* element of known name, ip address and reversed ip address */ 56/* element of known name, ip address and reversed ip address */
52struct dns_entry { 57struct dns_entry {
53 struct dns_entry *next; 58 struct dns_entry *next;
@@ -459,7 +464,8 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv)
459 unsigned lsa_size; 464 unsigned lsa_size;
460 int udps, opts; 465 int udps, opts;
461 uint16_t port = 53; 466 uint16_t port = 53;
462 uint8_t buf[MAX_PACK_LEN + 1]; 467 /* Ensure buf is 32bit aligned (we need 16bit, but 32bit can't hurt) */
468 uint8_t buf[MAX_PACK_LEN + 1] ALIGN4;
463 469
464 opts = getopt32(argv, "vi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport); 470 opts = getopt32(argv, "vi:c:t:p:d", &listen_interface, &fileconf, &sttl, &sport);
465 //if (opts & 0x1) // -v 471 //if (opts & 0x1) // -v
diff --git a/networking/httpd_indexcgi.c b/networking/httpd_indexcgi.c
index 9fa7c7481..af4338006 100644
--- a/networking/httpd_indexcgi.c
+++ b/networking/httpd_indexcgi.c
@@ -315,7 +315,7 @@ int main(int argc, char *argv[])
315 if (S_ISREG(cdir->dl_mode)) 315 if (S_ISREG(cdir->dl_mode))
316 fmt_ull(cdir->dl_size); 316 fmt_ull(cdir->dl_size);
317 fmt_str("<td class=dt>"); 317 fmt_str("<td class=dt>");
318 tm = gmtime(&cdir->dl_mtime); 318 ptm = gmtime(&cdir->dl_mtime);
319 fmt_04u(1900 + ptm->tm_year); *dst++ = '-'; 319 fmt_04u(1900 + ptm->tm_year); *dst++ = '-';
320 fmt_02u(ptm->tm_mon + 1); *dst++ = '-'; 320 fmt_02u(ptm->tm_mon + 1); *dst++ = '-';
321 fmt_02u(ptm->tm_mday); *dst++ = ' '; 321 fmt_02u(ptm->tm_mday); *dst++ = ' ';
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 78b0d0ade..7b6bb2066 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -64,6 +64,8 @@ struct dyn_lease* FAST_FUNC add_lease(
64 oldest->hostname[0] = '\0'; 64 oldest->hostname[0] = '\0';
65 if (hostname) { 65 if (hostname) {
66 char *p; 66 char *p;
67
68 hostname_len++; /* include NUL */
67 if (hostname_len > sizeof(oldest->hostname)) 69 if (hostname_len > sizeof(oldest->hostname))
68 hostname_len = sizeof(oldest->hostname); 70 hostname_len = sizeof(oldest->hostname);
69 p = safe_strncpy(oldest->hostname, hostname, hostname_len); 71 p = safe_strncpy(oldest->hostname, hostname, hostname_len);
diff --git a/shell/ash.c b/shell/ash.c
index 34f70ecfc..e018e877b 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5059,7 +5059,7 @@ static int is_hidden_fd(struct redirtab *rp, int fd)
5059 return 0; 5059 return 0;
5060 pf = g_parsefile; 5060 pf = g_parsefile;
5061 while (pf) { 5061 while (pf) {
5062 if (fd == pf->fd) { 5062 if (pf->fd > 0 && fd == pf->fd) {
5063 return 1; 5063 return 1;
5064 } 5064 }
5065 pf = pf->prev; 5065 pf = pf->prev;
@@ -5424,7 +5424,11 @@ rmescapes(char *str, int flag)
5424 size_t fulllen = len + strlen(p) + 1; 5424 size_t fulllen = len + strlen(p) + 1;
5425 5425
5426 if (flag & RMESCAPE_GROW) { 5426 if (flag & RMESCAPE_GROW) {
5427 int strloc = str - (char *)stackblock();
5427 r = makestrspace(fulllen, expdest); 5428 r = makestrspace(fulllen, expdest);
5429 /* p and str may be invalidated by makestrspace */
5430 str = (char *)stackblock() + strloc;
5431 p = str + len;
5428 } else if (flag & RMESCAPE_HEAP) { 5432 } else if (flag & RMESCAPE_HEAP) {
5429 r = ckmalloc(fulllen); 5433 r = ckmalloc(fulllen);
5430 } else { 5434 } else {
diff --git a/shell/hush.c b/shell/hush.c
index 2aeb8e440..78f0f7940 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -6944,7 +6944,7 @@ int hush_main(int argc, char **argv)
6944 /* -c 'script' (no params): prevent empty $0 */ 6944 /* -c 'script' (no params): prevent empty $0 */
6945 G.global_argv--; /* points to argv[i] of 'script' */ 6945 G.global_argv--; /* points to argv[i] of 'script' */
6946 G.global_argv[0] = argv[0]; 6946 G.global_argv[0] = argv[0];
6947 G.global_argc--; 6947 G.global_argc++;
6948 } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */ 6948 } /* else -c 'script' ARG0 [ARG1...]: $0 is ARG0 */
6949 init_sigmasks(); 6949 init_sigmasks();
6950 parse_and_run_string(optarg); 6950 parse_and_run_string(optarg);
diff --git a/testsuite/cpio.tests b/testsuite/cpio.tests
index e53ade925..325664d71 100755
--- a/testsuite/cpio.tests
+++ b/testsuite/cpio.tests
@@ -32,7 +32,7 @@ rm -rf cpio.testdir cpio.testdir2 2>/dev/null
32# testing "test name" "command" "expected result" "file input" "stdin" 32# testing "test name" "command" "expected result" "file input" "stdin"
33 33
34testing "cpio extracts zero-sized hardlinks" \ 34testing "cpio extracts zero-sized hardlinks" \
35"$ECHO -ne '$hexdump' | bzcat | cpio -i; echo \$?; 35"$ECHO -ne '$hexdump' | bzcat | cpio -i 2>&1; echo \$?;
36ls -ln cpio.testdir | $FILTER_LS" \ 36ls -ln cpio.testdir | $FILTER_LS" \
37"\ 37"\
381 blocks 381 blocks
@@ -45,7 +45,7 @@ ls -ln cpio.testdir | $FILTER_LS" \
45 45
46test x"$SKIP_KNOWN_BUGS" = x"" && { 46test x"$SKIP_KNOWN_BUGS" = x"" && {
47# Currently fails. Numerous buglets: "1 blocks" versus "1 block", 47# Currently fails. Numerous buglets: "1 blocks" versus "1 block",
48# "1 block" must go to stderr, does not list cpio.testdir/x and cpio.testdir/y 48# does not list cpio.testdir/x and cpio.testdir/y
49testing "cpio lists hardlinks" \ 49testing "cpio lists hardlinks" \
50"$ECHO -ne '$hexdump' | bzcat | cpio -t 2>&1; echo \$?" \ 50"$ECHO -ne '$hexdump' | bzcat | cpio -t 2>&1; echo \$?" \
51"\ 51"\
@@ -70,7 +70,7 @@ ln cpio.testdir/nonempty cpio.testdir/nonempty1
70mkdir cpio.testdir2 70mkdir cpio.testdir2
71 71
72testing "cpio extracts zero-sized hardlinks 2" \ 72testing "cpio extracts zero-sized hardlinks 2" \
73"find cpio.testdir | cpio -H newc --create | (cd cpio.testdir2 && cpio -i); echo \$?; 73"find cpio.testdir | cpio -H newc --create | (cd cpio.testdir2 && cpio -i 2>&1); echo \$?;
74ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \ 74ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \
75"\ 75"\
762 blocks 762 blocks
@@ -87,7 +87,7 @@ ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \
87# Was trying to create "/usr/bin", correct is "usr/bin". 87# Was trying to create "/usr/bin", correct is "usr/bin".
88rm -rf cpio.testdir 88rm -rf cpio.testdir
89testing "cpio -p with absolute paths" \ 89testing "cpio -p with absolute paths" \
90"echo /usr/bin | cpio -dp cpio.testdir; echo \$?; 90"echo /usr/bin | cpio -dp cpio.testdir 2>&1; echo \$?;
91ls cpio.testdir" \ 91ls cpio.testdir" \
92"\ 92"\
931 blocks 931 blocks
diff --git a/testsuite/sed.tests b/testsuite/sed.tests
index 875c946be..5b0750cac 100755
--- a/testsuite/sed.tests
+++ b/testsuite/sed.tests
@@ -248,4 +248,28 @@ testing "sed beginning (^) matches only once" \
248 ">/usr</>lib<\n" "" \ 248 ">/usr</>lib<\n" "" \
249 "/usr/lib\n" 249 "/usr/lib\n"
250 250
251testing "sed c" \
252 "sed 'crepl'" \
253 "repl\nrepl\n" "" \
254 "first\nsecond\n"
255
256testing "sed nested {}s" \
257 "sed '/asd/ { p; /s/ { s/s/c/ }; p; q }'" \
258 "qwe\nasd\nacd\nacd\n" "" \
259 "qwe\nasd\nzxc\n"
260
261testing "sed a cmd ended by double backslash" \
262 "sed -e '/| one /a \\
263 | three \\\\' -e '/| one-/a \\
264 | three-* \\\\'" \
265' | one \\
266 | three \\
267 | two \\
268' '' \
269' | one \\
270 | two \\
271'
272
273# testing "description" "arguments" "result" "infile" "stdin"
274
251exit $FAILCOUNT 275exit $FAILCOUNT
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index b8300570e..416271b31 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -109,10 +109,53 @@ static void to_sys_clock(const char **pp_rtcname, int utc)
109 109
110static void from_sys_clock(const char **pp_rtcname, int utc) 110static void from_sys_clock(const char **pp_rtcname, int utc)
111{ 111{
112#define TWEAK_USEC 200 112#if 1
113 struct tm tm_time;
114 struct timeval tv; 113 struct timeval tv;
114 struct tm tm_time;
115 int rtc;
116
117 rtc = rtc_xopen(pp_rtcname, O_WRONLY);
118 gettimeofday(&tv, NULL);
119 /* Prepare tm_time */
120 if (sizeof(time_t) == sizeof(tv.tv_sec)) {
121 if (utc)
122 gmtime_r((time_t*)&tv.tv_sec, &tm_time);
123 else
124 localtime_r((time_t*)&tv.tv_sec, &tm_time);
125 } else {
126 time_t t = tv.tv_sec;
127 if (utc)
128 gmtime_r(&t, &tm_time);
129 else
130 localtime_r(&t, &tm_time);
131 }
132#else
133/* Bloated code which tries to set hw clock with better precision.
134 * On x86, even though code does set hw clock within <1ms of exact
135 * whole seconds, apparently hw clock (at least on some machines)
136 * doesn't reset internal fractional seconds to 0,
137 * making all this a pointless excercise.
138 */
139 /* If we see that we are N usec away from whole second,
140 * we'll sleep for N-ADJ usecs. ADJ corrects for the fact
141 * that CPU is not infinitely fast.
142 * On infinitely fast CPU, next wakeup would be
143 * on (exactly_next_whole_second - ADJ). On real CPUs,
144 * this difference between current time and whole second
145 * is less than ADJ (assuming system isn't heavily loaded).
146 */
147 /* Small value of 256us gives very precise sync for 2+ GHz CPUs.
148 * Slower CPUs will fail to sync and will go to bigger
149 * ADJ values. qemu-emulated armv4tl with ~100 MHz
150 * performance ends up using ADJ ~= 4*1024 and it takes
151 * 2+ secs (2 tries with successively larger ADJ)
152 * to sync. Even straced one on the same qemu (very slow)
153 * takes only 4 tries.
154 */
155#define TWEAK_USEC 256
115 unsigned adj = TWEAK_USEC; 156 unsigned adj = TWEAK_USEC;
157 struct tm tm_time;
158 struct timeval tv;
116 int rtc = rtc_xopen(pp_rtcname, O_WRONLY); 159 int rtc = rtc_xopen(pp_rtcname, O_WRONLY);
117 160
118 /* Try to catch the moment when whole second is close */ 161 /* Try to catch the moment when whole second is close */
@@ -124,55 +167,64 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
124 167
125 t = tv.tv_sec; 168 t = tv.tv_sec;
126 rem_usec = 1000000 - tv.tv_usec; 169 rem_usec = 1000000 - tv.tv_usec;
127 if (rem_usec < 1024) { 170 if (rem_usec < adj) {
128 /* Less than 1ms to next second. Good enough */ 171 /* Close enough */
129 small_rem: 172 small_rem:
130 t++; 173 t++;
131 } 174 }
132 175
133 /* Prepare tm */ 176 /* Prepare tm_time from t */
134 if (utc) 177 if (utc)
135 gmtime_r(&t, &tm_time); /* may read /etc/xxx (it takes time) */ 178 gmtime_r(&t, &tm_time); /* may read /etc/xxx (it takes time) */
136 else 179 else
137 localtime_r(&t, &tm_time); /* same */ 180 localtime_r(&t, &tm_time); /* same */
138 tm_time.tm_isdst = 0; 181
182 if (adj >= 32*1024) {
183 break; /* 32 ms diff and still no luck?? give up trying to sync */
184 }
139 185
140 /* gmtime/localtime took some time, re-get cur time */ 186 /* gmtime/localtime took some time, re-get cur time */
141 gettimeofday(&tv, NULL); 187 gettimeofday(&tv, NULL);
142 188
143 if (tv.tv_sec < t /* may happen if rem_usec was < 1024 */ 189 if (tv.tv_sec < t /* we are still in old second */
144 || (tv.tv_sec == t && tv.tv_usec < 1024) 190 || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */
145 ) { 191 ) {
146 /* We are not too far into next second. Good. */ 192 break; /* good, we are in sync! */
147 break;
148 }
149 adj += 32; /* 2^(10-5) = 2^5 = 32 iterations max */
150 if (adj >= 1024) {
151 /* Give up trying to sync */
152 break;
153 } 193 }
154 194
155 /* Try to sync up by sleeping */
156 rem_usec = 1000000 - tv.tv_usec; 195 rem_usec = 1000000 - tv.tv_usec;
157 if (rem_usec < 1024) { 196 if (rem_usec < adj) {
158 goto small_rem; /* already close, don't sleep */ 197 t = tv.tv_sec;
198 goto small_rem; /* already close to next sec, don't sleep */
159 } 199 }
160 /* Need to sleep.
161 * Note that small adj on slow processors can make us
162 * to always overshoot tv.tv_usec < 1024 check on next
163 * iteration. That's why adj is increased on each iteration.
164 * This also allows it to be reused as a loop limiter.
165 */
166 usleep(rem_usec - adj);
167 }
168 200
169 xioctl(rtc, RTC_SET_TIME, &tm_time); 201 /* Try to sync up by sleeping */
202 usleep(rem_usec - adj);
170 203
171 /* Debug aid to find "good" TWEAK_USEC. 204 /* Jump to 1ms diff, then increase fast (x2): EVERY loop
205 * takes ~1 sec, people won't like slowly converging code here!
206 */
207 //bb_error_msg("adj:%d tv.tv_usec:%d", adj, (int)tv.tv_usec);
208 if (adj < 512)
209 adj = 512;
210 /* ... and if last "overshoot" does not look insanely big,
211 * just use it as adj increment. This makes convergence faster.
212 */
213 if (tv.tv_usec < adj * 8) {
214 adj += tv.tv_usec;
215 continue;
216 }
217 adj *= 2;
218 }
219 /* Debug aid to find "optimal" TWEAK_USEC with nearly exact sync.
172 * Look for a value which makes tv_usec close to 999999 or 0. 220 * Look for a value which makes tv_usec close to 999999 or 0.
173 * for 2.20GHz Intel Core 2: TWEAK_USEC ~= 200 221 * For 2.20GHz Intel Core 2: optimal TWEAK_USEC ~= 200
174 */ 222 */
175 //bb_error_msg("tv.tv_usec:%d adj:%d", (int)tv.tv_usec, adj); 223 //bb_error_msg("tv.tv_usec:%d", (int)tv.tv_usec);
224#endif
225
226 tm_time.tm_isdst = 0;
227 xioctl(rtc, RTC_SET_TIME, &tm_time);
176 228
177 if (ENABLE_FEATURE_CLEAN_UP) 229 if (ENABLE_FEATURE_CLEAN_UP)
178 close(rtc); 230 close(rtc);