Re: printf can't handle the '+' char in front of an integer

2018-10-30 Thread Denys Vlasenko
On Fri, Oct 19, 2018 at 3:43 PM Bernhard Reutner-Fischer
 wrote:
> On Fri, 19 Oct 2018 at 15:30, Bernhard Reutner-Fischer
>  wrote:
> > On Fri, 19 Oct 2018 at 11:03, Cristian Ionescu-Idbohrn
> >  wrote:
>
> Oh, an I should mention that on a 64bit box we diverge from coreutils printf:
>
> $ printf "%f\n" '  +18446744073709551614'
> 18446744073709551614.00
> $ ./busybox printf "%f\n" '  +18446744073709551614'
> 18446744073709551616.00

It's far worse than that:

$ ./busybox printf "%f\n" 18446744073709550592 18446744073709553665
18446744073709551616.00
18446744073709551616.00

64-bit double's mantissa is only 53 bits...

With "long double" shenanigans, I managed to "improve" this to:

$ ./busybox printf "%f\n" 18446744073709550592 18446744073709553665
18446744073709550591.50
18446744073709553663.50

at this cost:

function old new   delta
printf_main  909 976 +67
strtold-  19 +19
print_direc  457 475 +18
conv_strtod   54  61  +7
--
(add/remove: 3/0 grow/shrink: 3/0 up/down: 130/0) Total: 111 bytes

See attached. Do you think it's worth it?
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 67d3b2eda..215f4fef9 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -120,12 +120,18 @@ static void FAST_FUNC conv_strtoll(const char *arg, void *result)
 static void FAST_FUNC conv_strtod(const char *arg, void *result)
 {
 	char *end;
-	/* Well, this one allows leading whitespace... so what? */
-	/* What I like much less is that "-" accepted too! :( */
-	*(double*)result = strtod(arg, );
+
+	/* If long double is no different than double, avoid using strtold() */
+	if (sizeof(double) == sizeof(long double))
+		/* Well, this one allows leading whitespace... so what? */
+		/* What I like much less is that "-" accepted too! :( */
+		*(long double*)result = strtod(arg, );
+	else
+		*(long double*)result = strtold(arg, );
+
 	if (end[0]) {
 		errno = ERANGE;
-		*(double*)result = 0;
+		*(long double*)result = 0;
 	}
 }
 
@@ -144,9 +150,9 @@ static long long my_xstrtoll(const char *arg)
 		result = 0;
 	return result;
 }
-static double my_xstrtod(const char *arg)
+static long double my_xstrtod(const char *arg)
 {
-	double result;
+	long double result;
 	multiconvert(arg, , conv_strtod);
 	return result;
 }
@@ -187,7 +193,6 @@ static void print_direc(char *format, unsigned fmt_length,
 		const char *argument)
 {
 	long long llv;
-	double dv;
 	char saved;
 	char *have_prec, *have_width;
 
@@ -255,17 +260,35 @@ static void print_direc(char *format, unsigned fmt_length,
 	case 'E':
 	case 'g':
 	case 'G':
-		dv = my_xstrtod(argument);
-		if (!have_width) {
-			if (!have_prec)
-printf(format, dv);
-			else
-printf(format, precision, dv);
+		if (sizeof(double) == sizeof(long double)) {
+			double dv;
+			dv = my_xstrtod(argument);
+			if (!have_width) {
+if (!have_prec)
+	printf(format, dv);
+else
+	printf(format, precision, dv);
+			} else {
+if (!have_prec)
+	printf(format, field_width, dv);
+else
+	printf(format, field_width, precision, dv);
+			}
 		} else {
-			if (!have_prec)
-printf(format, field_width, dv);
-			else
-printf(format, field_width, precision, dv);
+			/* Parsing code added "L" prefix (a-la "%Lf") */
+			long double dv;
+			dv = my_xstrtod(argument);
+			if (!have_width) {
+if (!have_prec)
+	printf(format, dv);
+else
+	printf(format, precision, dv);
+			} else {
+if (!have_prec)
+	printf(format, field_width, dv);
+else
+	printf(format, field_width, precision, dv);
+			}
 		}
 		break;
 	} /* switch */
@@ -371,6 +394,18 @@ static char **print_formatted(char *f, char **argv, int *conv_err)
 	//bb_error_msg("<%s>", p);
 	direc_length += 2;
 	direc_start = p;
+} else
+if (sizeof(double) < sizeof(long double)
+ && p - format_chars <= 10
+) {
+	/* it is one of "feEgG" */
+	p = xmalloc(direc_length + 2);
+	memcpy(p, direc_start, direc_length);
+	p[direc_length] = p[direc_length - 1];
+	p[direc_length - 1] = 'L';
+	//bb_error_msg("<%s>", p);
+	direc_length += 1;
+	direc_start = p;
 } else {
 	p = NULL;
 }
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] dd: add 'oflag=seek_bytes'

2018-10-30 Thread Denys Vlasenko
Applied, thanks!
On Mon, Oct 15, 2018 at 12:35 PM Rostislav Skudnov  wrote:
>
> Allow specifying position in the output file in bytes instead of
> obs-sized blocks, improve compatibility with GNU dd.
>
> function old new   delta
> dd_main 14481518 +70
> .rodata26143   26167 +24
> static.oflag_words -  12 +12
> --
> (add/remove: 1/0 grow/shrink: 2/0 up/down: 106/0) Total: 106 bytes
>
> Signed-off-by: Rostislav Skudnov 
> ---
>  coreutils/dd.c | 33 -
>  docs/posix_conformance.txt |  1 +
>  2 files changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/coreutils/dd.c b/coreutils/dd.c
> index 0f130bc..129637e 100644
> --- a/coreutils/dd.c
> +++ b/coreutils/dd.c
> @@ -37,7 +37,7 @@
>  //config:  elapsed time and speed.
>  //config:
>  //config:config FEATURE_DD_IBS_OBS
> -//config:  bool "Enable ibs, obs, iflag and conv options"
> +//config:  bool "Enable ibs, obs, iflag, oflag and conv options"
>  //config:  default y
>  //config:  depends on DD
>  //config:  help
> @@ -57,7 +57,7 @@
>
>  //usage:#define dd_trivial_usage
>  //usage:   "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] 
> ") "[bs=N] [count=N] [skip=N]\n"
> -//usage:   "   [seek=N]" IF_FEATURE_DD_IBS_OBS(" 
> [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes|fullblock]")
> +//usage:   "   [seek=N]" IF_FEATURE_DD_IBS_OBS(" 
> [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes|fullblock] 
> [oflag=seek_bytes]")
>  //usage:#define dd_full_usage "\n\n"
>  //usage:   "Copy a file with converting and formatting\n"
>  //usage: "\n   if=FILE Read from FILE instead of stdin"
> @@ -80,6 +80,7 @@
>  //usage: "\n   conv=swab   Swap every pair of bytes"
>  //usage: "\n   iflag=skip_bytesskip=N is in bytes"
>  //usage: "\n   iflag=fullblock Read full blocks"
> +//usage: "\n   oflag=seek_bytesseek=N is in bytes"
>  //usage:   )
>  //usage:   IF_FEATURE_DD_STATUS(
>  //usage: "\n   status=noxfer   Suppress rate output"
> @@ -133,10 +134,14 @@ enum {
> FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS,
> FLAG_FULLBLOCK = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS,
> /* end of input flags */
> -   FLAG_TWOBUFS = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
> -   FLAG_COUNT   = 1 << 8,
> -   FLAG_STATUS_NONE = 1 << 9,
> -   FLAG_STATUS_NOXFER = 1 << 10,
> +   /* start of output flags */
> +   FLAG_OFLAG_SHIFT = 7,
> +   FLAG_SEEK_BYTES = (1 << 7) * ENABLE_FEATURE_DD_IBS_OBS,
> +   /* end of output flags */
> +   FLAG_TWOBUFS = (1 << 8) * ENABLE_FEATURE_DD_IBS_OBS,
> +   FLAG_COUNT   = 1 << 9,
> +   FLAG_STATUS_NONE = 1 << 10,
> +   FLAG_STATUS_NOXFER = 1 << 11,
>  };
>
>  static void dd_output_status(int UNUSED_PARAM cur_signal)
> @@ -250,7 +255,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
> static const char keywords[] ALIGN1 =
> 
> "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0")
>  #if ENABLE_FEATURE_DD_IBS_OBS
> -   "ibs\0""obs\0""conv\0""iflag\0"
> +   "ibs\0""obs\0""conv\0""iflag\0""oflag\0"
>  #endif
> ;
>  #if ENABLE_FEATURE_DD_IBS_OBS
> @@ -258,6 +263,8 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
> "notrunc\0""sync\0""noerror\0""fsync\0""swab\0";
> static const char iflag_words[] ALIGN1 =
> "skip_bytes\0""fullblock\0";
> +   static const char oflag_words[] ALIGN1 =
> +   "seek_bytes\0";
>  #endif
>  #if ENABLE_FEATURE_DD_STATUS
> static const char status_words[] ALIGN1 =
> @@ -276,6 +283,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
> OP_obs,
> OP_conv,
> OP_iflag,
> +   OP_oflag,
> /* Must be in the same order as FLAG_XXX! */
> OP_conv_notrunc = 0,
> OP_conv_sync,
> @@ -297,6 +305,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
> //swab  swap every pair of input bytes: will abort on 
> non-even reads
> OP_iflag_skip_bytes,
> OP_iflag_fullblock,
> +   OP_oflag_seek_bytes,
>  #endif
> };
> smallint exitcode = EXIT_FAILURE;
> @@ -368,6 +377,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
> G.flags |= parse_comma_flags(val, iflag_words, 
> "iflag") << FLAG_IFLAG_SHIFT;
> /*continue;*/
> }
> +   if (what == OP_oflag) {
> +   G.flags |= parse_comma_flags(val, oflag_words, 

Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Gavin Howard
On Tue, Oct 30, 2018 at 3:32 AM Denys Vlasenko  wrote:
>
> On Tue, Oct 30, 2018 at 12:30 AM Gavin Howard  
> wrote:
> > On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  
> > wrote:
> > > > Because my patch is so large, I cannot get it through the mailing list
> > > > filter. Therefore, I have pasted it on pastebin, instead.
> > > >
> > > > The link is https://pastebin.com/PJa2vaUR and the raw version can be
> > > > found at https://pastebin.com/raw/PJa2vaUR
> > >
> > > Probably could send it bzipped.
> >
> > I tried, unfortunately. Even though it was under the limit, the
> > mailing list software rejected.
>
> Ok, pastebin would work for the time being.
>
>
> > > +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> > > BC_STATUS_ALLOC_ERR;
> > >
> > > (1) Please do not nest assignments:
> > >
> > > v->v = malloc(esize * BC_VEC_START_CAP);
> > > if (!v->v)
> > > return BC_STATUS_ALLOC_ERR;
> >
> > Oh boy. I was afraid of this.
> >
> > The problem is that I am also trying to get this bc into toybox (might
> > as well reduce duplication of effort), and as I am sure you know,
> > Landley is very particular about the line count of commands. To be
> > honest, I would prefer your style (except for putting if statements
> > that on one line if possible), but this reduces line count.
> >
> > I don't really know what to do here.
>
> I can rewrite these constructs after patch is merged.
>
>
> > > +BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
> > > +return bc_vec_push(v, );
> > > +}
> > >
> > > The entire bbox code base uses this formatting of function body:
> > >
> > > BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
> > > {
> > > return bc_vec_push(v, );
> > > }
> >
> > This one might be a little harder.
>
> I can rewrite these constructs after patch is merged.
>
>
> > > +if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;
> > >
> > > len is not boolean or a pointer. !foo is usually used with those.
> > > len is an integer. You are testing whether it's zero. Why obfuscate?
> > > For readability, should be:
> > >if (v->len == 0) {
> > >s = bc_vec_pushByte(v, '\0');
> > >if (s)
> > >return s;
> > > }
>
> One-line "if (s) return s;" is okay too, when both if-expression and
> statement are simple.
>
>
> > > +static void bc_vm_sig(int sig) {
> > > +if (sig == SIGINT) {
> > > +size_t len = strlen(bcg.sig_msg);
> > > +if (write(2, bcg.sig_msg, len) == (ssize_t) len)
> > > +bcg.sig += (bcg.signe = bcg.sig == bcg.sigc);
> > > +}
> > > +else bcg.sig_other = 1;
> > > +}
> > >
> > > +sa.sa_handler = bc_vm_sig;
> > > +sa.sa_flags = 0;
> > > +
> > > +if (sigaction(SIGINT, , NULL) < 0 || sigaction(SIGPIPE, ,
> > > NULL) < 0 ||
> > > +sigaction(SIGHUP, , NULL) < 0 || sigaction(SIGTERM, , 
> > > NULL) < 0)
> > > +{
> > > +return BC_STATUS_EXEC_SIGACTION_FAIL;
> > > +}
> > >
> > > Calculator has signal handling?!
> > > siganction() never fails - no need to check result.
> >
> > GNU bc has signal handling. It is so users can stop long-running
> > calculations. This bc is meant to be compatible.
>
> Well, without signal handling ^C will stop long-running calculations
> too. :)
> I can imagine some users who use interactive bc *a lot* (scientist?),
> and who would want "^C abort calc but stays in bc" behavior,
> but they are likely a minority. Can you make signal handling optional?
>
>
> > Okay, as it stands, I see one big showstopper for getting this into
> > busybox: code style. I don't know how to fix code style with a script,
> > so if it is a showstopper for you
>
> It is not.

Thank you for being willing. I can work with this. It may take me a
few days to generate a new patch.

Gavin Howard
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] free: Add 'available' memory if provided by the kernel

2018-10-30 Thread Denys Vlasenko
On Tue, Oct 30, 2018 at 2:46 PM Guillermo Rodriguez Garcia
 wrote:
>
> Thank you.
>
> One minor thing; in the code that has been commited, the seen_cached
> and seen_available vars have been combined into one
> (seen_cached_and_available). However the code now parses all lines in
> /proc/meminfo twice until both Cached and MemAvailable have been
> found:
>
>seen_cached_and_available = 2;
> while (fgets(buf, sizeof(buf), fp)) {
> if (sscanf(buf, "Cached: %lu %*s\n", cached_kb) == 1)
> if (--seen_cached_and_available == 0)
> break;
> if (sscanf(buf, "MemAvailable: %lu %*s\n", available_kb) == 1)
> if (--seen_cached_and_available == 0)
> break;
> }
>
> However the original code only checks for things it has not seen yet;
> for example if it finds "Cached" then it will only check for
> MemAvailable in the remaining lines:
>
>while (fgets(buf, sizeof(buf), f) != NULL && !(seen_cached &&
> seen_available)) {
>if (!seen_cached && sscanf(buf, "Cached: %lu %*s\n",
> cached_kb) == 1) {
>seen_cached = 1;
>}
>else if (!seen_available && sscanf(buf, "MemAvailable:
> %lu %*s\n", available_kb) == 1) {
>seen_available = 1;
>}
>}
>
> I think it would be convenient to revert this change and keep the two
> separate variables in order to avoid doing unnecessary work.


That's larger code. I don't think users of "free" are that
performance-sensitive.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] free: Add 'available' memory if provided by the kernel

2018-10-30 Thread Guillermo Rodriguez Garcia
Thank you.

One minor thing; in the code that has been commited, the seen_cached
and seen_available vars have been combined into one
(seen_cached_and_available). However the code now parses all lines in
/proc/meminfo twice until both Cached and MemAvailable have been
found:

   seen_cached_and_available = 2;
while (fgets(buf, sizeof(buf), fp)) {
if (sscanf(buf, "Cached: %lu %*s\n", cached_kb) == 1)
if (--seen_cached_and_available == 0)
break;
if (sscanf(buf, "MemAvailable: %lu %*s\n", available_kb) == 1)
if (--seen_cached_and_available == 0)
break;
}

However the original code only checks for things it has not seen yet;
for example if it finds "Cached" then it will only check for
MemAvailable in the remaining lines:

   while (fgets(buf, sizeof(buf), f) != NULL && !(seen_cached &&
seen_available)) {
   if (!seen_cached && sscanf(buf, "Cached: %lu %*s\n",
cached_kb) == 1) {
   seen_cached = 1;
   }
   else if (!seen_available && sscanf(buf, "MemAvailable:
%lu %*s\n", available_kb) == 1) {
   seen_available = 1;
   }
   }

I think it would be convenient to revert this change and keep the two
separate variables in order to avoid doing unnecessary work.

Best,

Guillermo

El mar., 30 oct. 2018 a las 14:15, Denys Vlasenko
() escribió:
>
> Applied, thanks
> On Thu, Oct 4, 2018 at 4:27 PM Guillermo Rodríguez
>  wrote:
> >
> > Show estimated available memory if this is provided by the
> > kernel. See [1] for the full story.
> >
> >  [1]: 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
> >
> > Signed-off-by: Guillermo Rodriguez 
> > ---
> >  procps/free.c | 54 ++
> >  1 file changed, 34 insertions(+), 20 deletions(-)
> >
> > diff --git a/procps/free.c b/procps/free.c
> > index 0991713..e7ba974 100644
> > --- a/procps/free.c
> > +++ b/procps/free.c
> > @@ -44,27 +44,36 @@ static unsigned long long scale(unsigned long d)
> > return ((unsigned long long)d * G.mem_unit) >> G_unit_steps;
> >  }
> >
> > -static unsigned long parse_cached_kb(void)
> > +static unsigned int parse_meminfo(unsigned long *cached_kb, unsigned long 
> > *available_kb)
> >  {
> > char buf[60]; /* actual lines we expect are ~30 chars or less */
> > FILE *f;
> > -   unsigned long cached = 0;
> > +   int seen_cached = 0;
> > +   int seen_available = 0;
> > +
> > +   *cached_kb = *available_kb = 0;
> >
> > f = xfopen_for_read("/proc/meminfo");
> > -   while (fgets(buf, sizeof(buf), f) != NULL) {
> > -   if (sscanf(buf, "Cached: %lu %*s\n", ) == 1)
> > -   break;
> > +   while (fgets(buf, sizeof(buf), f) != NULL && !(seen_cached && 
> > seen_available)) {
> > +   if (!seen_cached && sscanf(buf, "Cached: %lu %*s\n", 
> > cached_kb) == 1) {
> > +   seen_cached = 1;
> > +   }
> > +   else if (!seen_available && sscanf(buf, "MemAvailable: %lu 
> > %*s\n", available_kb) == 1) {
> > +   seen_available = 1;
> > +   }
> > }
> > fclose(f);
> >
> > -   return cached;
> > +   return seen_available;
> >  }
> >
> >  int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
> >  int free_main(int argc UNUSED_PARAM, char **argv 
> > IF_NOT_DESKTOP(UNUSED_PARAM))
> >  {
> > struct sysinfo info;
> > -   unsigned long long cached;
> > +   unsigned long long cached, available;
> > +   unsigned long cached_kb, available_kb;
> > +   int seen_available;
> >
> > INIT_G();
> >
> > @@ -95,17 +104,19 @@ int free_main(int argc UNUSED_PARAM, char **argv 
> > IF_NOT_DESKTOP(UNUSED_PARAM))
> > /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... 
> > */
> > G.mem_unit = (info.mem_unit ? info.mem_unit : 1);
> >
> > -   /* Extract cached from /proc/meminfo and convert to mem_units */
> > -   cached = ((unsigned long long) parse_cached_kb() * 1024) / 
> > G.mem_unit;
> > +   /* Extract cached and memavailable from /proc/meminfo and convert 
> > to mem_units */
> > +   seen_available = parse_meminfo(_kb, _kb);
> > +   cached = ((unsigned long long) cached_kb * 1024) / G.mem_unit;
> > +   available = ((unsigned long long) available_kb * 1024) / G.mem_unit;
> >
> > -   printf("   %11s%11s%11s%11s%11s%11s\n",
> > +   printf("   %12s%12s%12s%12s%12s%12s\n",
> > "total",
> > "used",
> > "free",
> > -   "shared", "buffers", "cached" /* swap and total don't have 
> > these columns */
> > +   "shared", "buff/cache", "available" /* swap and 

Re: [PATCH] free: Add 'available' memory if provided by the kernel

2018-10-30 Thread Denys Vlasenko
Applied, thanks
On Thu, Oct 4, 2018 at 4:27 PM Guillermo Rodríguez
 wrote:
>
> Show estimated available memory if this is provided by the
> kernel. See [1] for the full story.
>
>  [1]: 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
>
> Signed-off-by: Guillermo Rodriguez 
> ---
>  procps/free.c | 54 ++
>  1 file changed, 34 insertions(+), 20 deletions(-)
>
> diff --git a/procps/free.c b/procps/free.c
> index 0991713..e7ba974 100644
> --- a/procps/free.c
> +++ b/procps/free.c
> @@ -44,27 +44,36 @@ static unsigned long long scale(unsigned long d)
> return ((unsigned long long)d * G.mem_unit) >> G_unit_steps;
>  }
>
> -static unsigned long parse_cached_kb(void)
> +static unsigned int parse_meminfo(unsigned long *cached_kb, unsigned long 
> *available_kb)
>  {
> char buf[60]; /* actual lines we expect are ~30 chars or less */
> FILE *f;
> -   unsigned long cached = 0;
> +   int seen_cached = 0;
> +   int seen_available = 0;
> +
> +   *cached_kb = *available_kb = 0;
>
> f = xfopen_for_read("/proc/meminfo");
> -   while (fgets(buf, sizeof(buf), f) != NULL) {
> -   if (sscanf(buf, "Cached: %lu %*s\n", ) == 1)
> -   break;
> +   while (fgets(buf, sizeof(buf), f) != NULL && !(seen_cached && 
> seen_available)) {
> +   if (!seen_cached && sscanf(buf, "Cached: %lu %*s\n", 
> cached_kb) == 1) {
> +   seen_cached = 1;
> +   }
> +   else if (!seen_available && sscanf(buf, "MemAvailable: %lu 
> %*s\n", available_kb) == 1) {
> +   seen_available = 1;
> +   }
> }
> fclose(f);
>
> -   return cached;
> +   return seen_available;
>  }
>
>  int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
>  int free_main(int argc UNUSED_PARAM, char **argv 
> IF_NOT_DESKTOP(UNUSED_PARAM))
>  {
> struct sysinfo info;
> -   unsigned long long cached;
> +   unsigned long long cached, available;
> +   unsigned long cached_kb, available_kb;
> +   int seen_available;
>
> INIT_G();
>
> @@ -95,17 +104,19 @@ int free_main(int argc UNUSED_PARAM, char **argv 
> IF_NOT_DESKTOP(UNUSED_PARAM))
> /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
> G.mem_unit = (info.mem_unit ? info.mem_unit : 1);
>
> -   /* Extract cached from /proc/meminfo and convert to mem_units */
> -   cached = ((unsigned long long) parse_cached_kb() * 1024) / G.mem_unit;
> +   /* Extract cached and memavailable from /proc/meminfo and convert to 
> mem_units */
> +   seen_available = parse_meminfo(_kb, _kb);
> +   cached = ((unsigned long long) cached_kb * 1024) / G.mem_unit;
> +   available = ((unsigned long long) available_kb * 1024) / G.mem_unit;
>
> -   printf("   %11s%11s%11s%11s%11s%11s\n",
> +   printf("   %12s%12s%12s%12s%12s%12s\n",
> "total",
> "used",
> "free",
> -   "shared", "buffers", "cached" /* swap and total don't have 
> these columns */
> +   "shared", "buff/cache", "available" /* swap and total don't 
> have these columns */
> );
>
> -#define FIELDS_6 "%11llu%11llu%11llu%11llu%11llu%11llu\n"
> +#define FIELDS_6 "%12llu%12llu%12llu%12llu%12llu%12llu\n"
>  #define FIELDS_3 (FIELDS_6 + 3*6)
>  #define FIELDS_2 (FIELDS_6 + 4*6)
>
> @@ -115,16 +126,19 @@ int free_main(int argc UNUSED_PARAM, char **argv 
> IF_NOT_DESKTOP(UNUSED_PARAM))
> scale(info.totalram - info.freeram),
> scale(info.freeram),
> scale(info.sharedram),
> -   scale(info.bufferram),
> -   scale(cached)
> +   scale(info.bufferram) + scale(cached),
> +   scale(available)
> );
> -   /* Show alternate, more meaningful busy/free numbers by counting
> +   /* On kernels < 3.14, MemAvailable is not provided.
> +* Show alternate, more meaningful busy/free numbers by counting
>  * buffer cache as free memory. */
> -   printf("-/+ buffers/cache:");
> -   printf(FIELDS_2,
> -   scale(info.totalram - info.freeram - info.bufferram - cached),
> -   scale(info.freeram + info.bufferram + cached)
> -   );
> +   if (!seen_available) {
> +   printf("-/+ buffers/cache:");
> +   printf(FIELDS_2,
> +   scale(info.totalram - info.freeram - info.bufferram - 
> cached),
> +   scale(info.freeram + info.bufferram + cached)
> +   );
> +   }
>  #if BB_MMU
> printf("Swap:  ");
> printf(FIELDS_3,
> --
> 1.9.1
>
> ___
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox

Re: [resend PATCH] add possibility to use modern "ip"

2018-10-30 Thread Denys Vlasenko
Applied, thanks!
On Thu, Oct 4, 2018 at 9:02 AM Jiří Prchal  wrote:
>
> Script uses "ifconfig" only, not up-to-date so much. This patch adds "ip" in 
> condition if exists.
>
> Signed-off-by: Jiri Prchal 
> ---
>   examples/udhcp/simple.script | 18 +++---
>   1 file changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/examples/udhcp/simple.script b/examples/udhcp/simple.script
> index e4c1f2d76..d043d39de 100755
> --- a/examples/udhcp/simple.script
> +++ b/examples/udhcp/simple.script
> @@ -6,19 +6,31 @@ RESOLV_CONF="/etc/resolv.conf"
>   [ -n "$1" ] || { echo "Error: should be called from udhcpc"; exit 1; }
>
>   NETMASK=""
> -[ -n "$subnet" ] && NETMASK="netmask $subnet"
> +if [ -x /sbin/ip ]; then
> +   [ -n "$subnet" ] && NETMASK="/$subnet"
> +else
> +   [ -n "$subnet" ] && NETMASK="netmask $subnet"
> +fi
>   BROADCAST="broadcast +"
>   [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
>
>   case "$1" in
> deconfig)
> echo "Setting IP address 0.0.0.0 on $interface"
> -   ifconfig $interface 0.0.0.0
> +   if [ -x /sbin/ip ]; then
> +   ip addr flush dev $interface
> +   else
> +   ifconfig $interface 0.0.0.0
> +   fi
> ;;
>
> renew|bound)
> echo "Setting IP address $ip on $interface"
> -   ifconfig $interface $ip $NETMASK $BROADCAST
> +   if [ -x /sbin/ip ]; then
> +   ip addr add $ip$NETMASK $BROADCAST dev $interface
> +   else
> +   ifconfig $interface $ip $NETMASK $BROADCAST
> +   fi
>
> if [ -n "$router" ] ; then
> echo "Deleting routers"
> --
> 2.17.1
>
> ___
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH 1/2] allow honouring libc provided SIGRTMIN/SIGRTMAX

2018-10-30 Thread Rasmus Villemoes
On 2018-10-05 09:08, Rasmus Villemoes wrote:
> On 2018-09-12 16:06, Rasmus Villemoes wrote:
>> When an application documents that it responds such and such to
>> SIGRTMIN+n, that almost always means with respect to the libc-provided
>> SIGRTMIN. Hence I disagree with the "more correct" in commit
>> 7b276fc17594. In any case, this is rather unfortunate:
>>
>> # kill -l RTMIN+2
>> 36
>> # busybox kill -l RTMIN+2
>> 34
>>
>> (the first shell is bash). We probably can't change default behaviour
>> after 7 years, but at least we can provide a config option.
> 
> ping

ping2
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: udhcpc: udhcpc skips RENEWING state when lease time is short

2018-10-30 Thread Denys Vlasenko
Should be fixed by:

commit c05aa6a776ab2420a42c041a3b5d45db587fd9ef
Date:   Tue Oct 30 11:56:18 2018 +0100

udhcpc: ensure at least one unicast renew attempt

Signed-off-by: Denys Vlasenko 

diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 66e4b6c6a..e2f8a6a9c 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -1738,8 +1738,9 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
/* note: "int timeout" will not
overflow even with 0x inputs here: */
timeout = (prefix_timeout <
address_timeout ? prefix_timeout : address_timeout) / 2;
/* paranoia: must not be too small */
-   if (timeout < 0x10)
-   timeout = 0x10;
+   /* timeout > 60 - ensures at least one
unicast renew attempt */
+   if (timeout < 61)
+   timeout = 61;
/* enter bound state */
d6_run_script(packet.d6_options, packet_end,
(state == REQUESTING ? "bound"
: "renew"));
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index ab3e5a463..d2f165904 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1725,8 +1725,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)

move_from_unaligned32(lease_seconds, temp);
lease_seconds = ntohl(lease_seconds);
/* paranoia: must not be too
small and not prone to overflows */
-   if (lease_seconds < 0x10)
-   lease_seconds = 0x10;
+   /* timeout > 60 - ensures at
least one unicast renew attempt */
+   if (lease_seconds < 2 * 61)
+   lease_seconds = 2 * 61;
//if (lease_seconds > 0x7fff)
//  lease_seconds = 0x7fff;
//^^^not necessary since
"timeout = lease_seconds / 2"
On Wed, Oct 3, 2018 at 10:06 PM Tomas Tonhauser  wrote:
>
> Hello all,
>
>
>
> busybox 1.28.3-4 (OpenWrt 18.06.1) running on a WiFi router, requesting IP 
> address from 4G router (Huawei B2338-168) running in IPv4 passtrough mode. In 
> this mode, 4G router is assigning the the same IP address it got from ISP 
> (mobile network operator), lease time is 120 seconds. Because first renew 
> request is sent after 60 seconds, it is broadcasted (= REBINDING state); 
> RENEWING state is skipped:
>
>
>
> ...
>
> case RENEWING:
> if (timeout > 60) {
> /* send an unicast renew request */
>
> ...
>
>
>
> 4G router drops broadcasted renew request and after lease is expired, WiFi 
> router releases the IP address and enters init state:
>
>
>
> Wed Oct  3 19:02:39 2018 user.notice firewall: Reloading firewall due to ifup 
> of wan (eth1)
> Wed Oct  3 19:03:37 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:07 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:22 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:29 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:32 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:33 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> renew to 0.0.0.0
> Wed Oct  3 19:04:33 2018 daemon.notice netifd: wan (1166): udhcpc: lease 
> lost, entering init state
> Wed Oct  3 19:04:34 2018 daemon.notice netifd: Interface 'wan' has lost the 
> connection
> Wed Oct  3 19:04:34 2018 daemon.notice netifd: wan (1166): udhcpc: sending 
> select for 10.98.21.140
> Wed Oct  3 19:04:34 2018 daemon.notice netifd: wan (1166): udhcpc: lease of 
> 10.98.21.140 obtained, lease time 120
> Wed Oct  3 19:04:34 2018 daemon.err openvpn(**)[1539]: write UDP: Network 
> unreachable (code=128)
> Wed Oct  3 19:04:34 2018 daemon.warn dnsmasq[1511]: no servers found in 
> /tmp/resolv.conf.auto, will retry
> Wed Oct  3 19:04:35 2018 daemon.notice netifd: Interface 'wan' is now up
> Wed Oct  3 19:04:35 2018 daemon.info dnsmasq[1511]: reading 
> /tmp/resolv.conf.auto
> Wed Oct  3 19:04:35 2018 daemon.info dnsmasq[1511]: using local addresses 
> only for domain test
> Wed Oct  3 19:04:35 2018 daemon.info dnsmasq[1511]: using local addresses 
> only for domain onion
> Wed Oct  3 19:04:35 2018 daemon.info dnsmasq[1511]: using local addresses 
> only for domain localhost
> Wed Oct  3 19:04:35 2018 daemon.info dnsmasq[1511]: using local 

Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Denys Vlasenko
On Tue, Oct 30, 2018 at 12:30 AM Gavin Howard  wrote:
> On Mon, Oct 29, 2018 at 4:46 PM Denys Vlasenko  
> wrote:
> > > Because my patch is so large, I cannot get it through the mailing list
> > > filter. Therefore, I have pasted it on pastebin, instead.
> > >
> > > The link is https://pastebin.com/PJa2vaUR and the raw version can be
> > > found at https://pastebin.com/raw/PJa2vaUR
> >
> > Probably could send it bzipped.
>
> I tried, unfortunately. Even though it was under the limit, the
> mailing list software rejected.

Ok, pastebin would work for the time being.


> > +if (!(v->v = malloc(esize * BC_VEC_START_CAP))) return 
> > BC_STATUS_ALLOC_ERR;
> >
> > (1) Please do not nest assignments:
> >
> > v->v = malloc(esize * BC_VEC_START_CAP);
> > if (!v->v)
> > return BC_STATUS_ALLOC_ERR;
>
> Oh boy. I was afraid of this.
>
> The problem is that I am also trying to get this bc into toybox (might
> as well reduce duplication of effort), and as I am sure you know,
> Landley is very particular about the line count of commands. To be
> honest, I would prefer your style (except for putting if statements
> that on one line if possible), but this reduces line count.
>
> I don't really know what to do here.

I can rewrite these constructs after patch is merged.


> > +BcStatus bc_vec_pushByte(BcVec *v, uint8_t data) {
> > +return bc_vec_push(v, );
> > +}
> >
> > The entire bbox code base uses this formatting of function body:
> >
> > BcStatus bc_vec_pushByte(BcVec *v, uint8_t data)
> > {
> > return bc_vec_push(v, );
> > }
>
> This one might be a little harder.

I can rewrite these constructs after patch is merged.


> > +if (!v->len && (s = bc_vec_pushByte(v, '\0'))) return s;
> >
> > len is not boolean or a pointer. !foo is usually used with those.
> > len is an integer. You are testing whether it's zero. Why obfuscate?
> > For readability, should be:
> >if (v->len == 0) {
> >s = bc_vec_pushByte(v, '\0');
> >if (s)
> >return s;
> > }

One-line "if (s) return s;" is okay too, when both if-expression and
statement are simple.


> > +static void bc_vm_sig(int sig) {
> > +if (sig == SIGINT) {
> > +size_t len = strlen(bcg.sig_msg);
> > +if (write(2, bcg.sig_msg, len) == (ssize_t) len)
> > +bcg.sig += (bcg.signe = bcg.sig == bcg.sigc);
> > +}
> > +else bcg.sig_other = 1;
> > +}
> >
> > +sa.sa_handler = bc_vm_sig;
> > +sa.sa_flags = 0;
> > +
> > +if (sigaction(SIGINT, , NULL) < 0 || sigaction(SIGPIPE, ,
> > NULL) < 0 ||
> > +sigaction(SIGHUP, , NULL) < 0 || sigaction(SIGTERM, , NULL) 
> > < 0)
> > +{
> > +return BC_STATUS_EXEC_SIGACTION_FAIL;
> > +}
> >
> > Calculator has signal handling?!
> > siganction() never fails - no need to check result.
>
> GNU bc has signal handling. It is so users can stop long-running
> calculations. This bc is meant to be compatible.

Well, without signal handling ^C will stop long-running calculations
too. :)
I can imagine some users who use interactive bc *a lot* (scientist?),
and who would want "^C abort calc but stays in bc" behavior,
but they are likely a minority. Can you make signal handling optional?


> Okay, as it stands, I see one big showstopper for getting this into
> busybox: code style. I don't know how to fix code style with a script,
> so if it is a showstopper for you

It is not.
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox


Re: [PATCH] Add bc (Last patch)

2018-10-30 Thread Lauri Kasanen
On Mon, 29 Oct 2018 17:30:09 -0600
Gavin Howard  wrote:

> Okay, as it stands, I see one big showstopper for getting this into
> busybox: code style. I don't know how to fix code style with a script,
> so if it is a showstopper for you (and if it is, I don't blame you), I
> guess I have to respectfully withdraw my patch and apologize for
> wasting your time.
> 
> If, however, it is not, we can talk about what to do about it. And I
> will get started on changing the other things.

Install GNU indent. It has an option for where to put the braces.

- Lauri
___
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox