diff options
author | Pino Toscano <toscano.pino@tiscali.it> | 2012-09-07 18:21:00 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-09-30 19:42:24 +0200 |
commit | 0cf1f48d64813fa46d83442ade4c94958ad4300b (patch) | |
tree | fd2dcf6d4b35564410e3c6292fdafac9780c7009 | |
parent | b6768b326c2e80f5c2326ab46459644d417c6e98 (diff) |
tmpfs: extract size string parsing in an own function
* tmpfs/tmpfs.c (parse_opt_size): New function, broken out of ...
(parse_opt): ... here. Call it.
-rw-r--r-- | tmpfs/tmpfs.c | 115 |
1 files changed, 64 insertions, 51 deletions
diff --git a/tmpfs/tmpfs.c b/tmpfs/tmpfs.c index b72459fe..2a98178a 100644 --- a/tmpfs/tmpfs.c +++ b/tmpfs/tmpfs.c @@ -112,6 +112,66 @@ struct option_values mode_t mode; }; +/* Parse the size string ARG, and set *NEWSIZE with the resulting size. */ +static error_t +parse_opt_size (const char *arg, struct argp_state *state, off_t *newsize) +{ + char *end = NULL; + intmax_t size = strtoimax (arg, &end, 0); + if (end == NULL || end == arg) + { + argp_error (state, "argument must be a number"); + return EINVAL; + } + if (size < 0) + { + argp_error (state, "negative size not meaningful"); + return EINVAL; + } + switch (*end) + { + case 'g': + case 'G': + size <<= 10; + case 'm': + case 'M': + size <<= 10; + case 'k': + case 'K': + size <<= 10; + break; + case '%': + { + /* Set as a percentage of the machine's physical memory. */ + struct vm_statistics vmstats; + error_t err = vm_statistics (mach_task_self (), &vmstats); + if (err) + { + argp_error (state, "cannot find total physical memory: %s", + strerror (err)); + return err; + } + size = round_page ((((vmstats.free_count + + vmstats.active_count + + vmstats.inactive_count + + vmstats.wire_count) + * vm_page_size) + * size + 99) / 100); + break; + } + } + size = (off_t) size; + if (size < 0) + { + argp_error (state, "size too large"); + return EINVAL; + } + + *newsize = size; + + return 0; +} + /* Parse a command line option. */ static error_t parse_opt (int key, char *arg, struct argp_state *state) @@ -166,57 +226,10 @@ parse_opt (int key, char *arg, struct argp_state *state) } else { - char *end = NULL; - intmax_t size = strtoimax (state->argv[state->next], &end, 0); - if (end == NULL || end == arg) - { - argp_error (state, "argument must be a number"); - return EINVAL; - } - if (size < 0) - { - argp_error (state, "negative size not meaningful"); - return EINVAL; - } - switch (*end) - { - case 'g': - case 'G': - size <<= 10; - case 'm': - case 'M': - size <<= 10; - case 'k': - case 'K': - size <<= 10; - break; - case '%': - { - /* Set as a percentage of the machine's physical memory. */ - struct vm_statistics vmstats; - error_t err = vm_statistics (mach_task_self (), &vmstats); - if (err) - { - argp_error (state, "cannot find total physical memory: %s", - strerror (err)); - return err; - } - size = round_page ((((vmstats.free_count - + vmstats.active_count - + vmstats.inactive_count - + vmstats.wire_count) - * vm_page_size) - * size + 99) / 100); - break; - } - } - size = (off_t) size; - if (size < 0) - { - argp_error (state, "size too large"); - return EINVAL; - } - values->size = size; + error_t err = parse_opt_size (state->argv[state->next], state, + &values->size); + if (err) + return err; } break; |