aboutsummaryrefslogtreecommitdiff
path: root/uxd.c
diff options
context:
space:
mode:
Diffstat (limited to 'uxd.c')
-rw-r--r--uxd.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/uxd.c b/uxd.c
index 9e402dc..80bf910 100644
--- a/uxd.c
+++ b/uxd.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <limits.h>
/* UTF-8 spec summary, taken from Wikipedia and elsewhere, kept here
for locality of reference.
@@ -237,9 +238,9 @@ void number_err(int opt) {
long parse_number(int opt, const char *s) {
char *e;
- long result;
+ double result;
- result = strtol(s, &e, 0);
+ result = strtod(s, &e);
/* require at least one digit (otherwise -sk would be allowed) */
if(e == s)
@@ -251,14 +252,14 @@ long parse_number(int opt, const char *s) {
case 'B':
if(e[1]) number_err(opt);
break; /* allow & ignore b/B for "bytes" */
- case 'k': result *= 1024L; break;
- case 'm': result *= 1048576L; break;
- case 'g': result *= 1073741824L; break;
- case 't': result *= 1099511627776L; break;
- case 'K': result *= 1000L; break;
- case 'M': result *= 1000000L; break;
- case 'G': result *= 1000000000L; break;
- case 'T': result *= 1000000000000L; break;
+ case 'k': result *= 1024.0L; break;
+ case 'm': result *= 1048576.0L; break;
+ case 'g': result *= 1073741824.0L; break;
+ case 't': result *= 1099511627776.0L; break;
+ case 'K': result *= 1000.0L; break;
+ case 'M': result *= 1000000.0L; break;
+ case 'G': result *= 1000000000.0L; break;
+ case 'T': result *= 1000000000000.0L; break;
default:
number_err(opt);
}
@@ -267,7 +268,10 @@ long parse_number(int opt, const char *s) {
if(e[0] && e[1] && e[1] != 'b' && e[1] != 'B')
number_err(opt);
- return result;
+ if(result < LONG_MIN || result > LONG_MAX)
+ number_err(opt);
+
+ return (long)result;
}
void parse_args(int argc, char **argv) {