В Fri, 16 Sep 2011 18:06:15 +0300 Roman Yeryomin <leroi.li...@gmail.com> пишет:
> On 16 September 2011 17:51, Alexander Gordeev <lasa...@lvk.cs.msu.su> wrote: > > В Fri, 16 Sep 2011 17:41:37 +0300 > > Roman Yeryomin <leroi.li...@gmail.com> пишет: > > > >> On 16 September 2011 01:40, Alexander Gordeev <lasa...@lvk.cs.msu.su> > >> wrote: > >> > В Fri, 26 Aug 2011 04:30:43 +0300 > >> > Roman Yeryomin <leroi.li...@gmail.com> пишет: > >> > > >> >> This method is much more stable than reading dd's output via stdin. > >> > > >> > What kind of problems do you have with piping dd's output to stdin? > >> > > >> > >> It outputs garbage very frequently and maccalc fails to convert the > >> mac (and as a consequence uci-default script fails to set the real mac > >> address). Try dd without piping to maccalc and you'll see. > >> I've noticed this bug on ramips platform and can't say anything about > >> other boards. > > > > Well, then this is probably a bug in dd? Or uClibc? Or kernel? > > Ok, I'll try to reproduce it. Can you please tell me what exactly is > > happening? > > > > Two different reads: > root@OpenWrt:/# dd bs=1 skip=262148 count=6 if=/dev/mtd0 > "u�������6+0 records in > 6+0 records out > root@OpenWrt:/# dd bs=1 skip=262148 count=6 if=/dev/mtd0 > "u���6+0 records in > 6+0 records out > > I don't think this is the bug in dd/kernel/uclibc - it would probably > expose when writing to a file too. > Maybe it's something with busybox. I'm not sure of cause. The bug is in maccalc. It does a single read() and expects to get everything in one shot which doesn't happen sometimes. The patch is attached. It fixes the problem according to my tests. I don't know whether Roman's change is necessary anymore. What do you think, Roman? -- Alexander
From ae35ee0ce9fc9b6cb5d8bea0a5a059df71602eab Mon Sep 17 00:00:00 2001 From: Alexander Gordeev <lasa...@lvk.cs.msu.su> Date: Sun, 18 Sep 2011 21:43:12 +0400 Subject: [PATCH] maccalc: don't expect to get all data in one read Signed-off-by: Alexander Gordeev <lasa...@lvk.cs.msu.su> --- package/maccalc/src/main.c | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletions(-) diff --git a/package/maccalc/src/main.c b/package/maccalc/src/main.c index e1e12cd..dcb5f55 100644 --- a/package/maccalc/src/main.c +++ b/package/maccalc/src/main.c @@ -9,6 +9,7 @@ * */ +#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <stdint.h> @@ -124,6 +125,34 @@ static int maccalc_do_mac2bin(int argc, const char *argv[]) return 0; } +static ssize_t read_safe(int fd, void *buf, size_t count) +{ + ssize_t total = 0; + ssize_t r; + + while(count > 0) { + r = read(fd, buf, count); + if (r == 0) + /* EOF */ + break; + if (r < 0) { + if (errno == EINTR) + /* interrupted by a signal, restart */ + continue; + /* error */ + total = -1; + break; + } + + /* ok */ + total += r; + count -= r; + buf += r; + } + + return total; +} + static int maccalc_do_bin2mac(int argc, const char *argv[]) { unsigned char mac[MAC_ADDRESS_LEN]; @@ -134,7 +163,7 @@ static int maccalc_do_bin2mac(int argc, const char *argv[]) return ERR_INVALID; } - c = read(STDIN_FILENO, mac, sizeof(mac)); + c = read_safe(STDIN_FILENO, mac, sizeof(mac)); if (c != sizeof(mac)) { fprintf(stderr, "failed to read from stdin\n"); return ERR_IO; -- 1.7.5.4
signature.asc
Description: PGP signature
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel