On Fri, 2010-10-22 at 22:15 +0200, Karel Zak wrote: > On Fri, Oct 22, 2010 at 04:40:22PM -0300, Davidlohr Bueso wrote: > > On Fri, 2010-10-22 at 21:31 +0200, Karel Zak wrote: > > > On Fri, Oct 22, 2010 at 03:54:11PM -0300, Davidlohr Bueso wrote: > > > > [PATCH] strutils: general purpose string handling functions > > > > > > > > This patch replaces a few functions used throught the source: > > > > * Renames getnum (from schedutils) to strtol_on_err > > > > > > What about "strtol_or_err()" ? > > > > Don't quite follow, we had decided that that would be the name for the > > getnum() replacement. > > Yep, we have talked about "strtol ***or*** err", but I see "on" in > your patch ;-) Resending correction below. Thanks. Signed-off-by: Davidlohr Bueso <dave@xxxxxxx> --- include/Makefile.am | 4 +- lib/Makefile.am | 4 +- lib/strtosize.c | 148 ---------------------------------- lib/strutils.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++ misc-utils/Makefile.am | 4 +- mount/Makefile.am | 6 +- schedutils/Makefile.am | 2 +- schedutils/chrt.c | 6 +- schedutils/ionice.c | 12 ++-- schedutils/schedutils.c | 34 -------- schedutils/schedutils.h | 7 -- schedutils/taskset.c | 4 +- sys-utils/Makefile.am | 2 +- 13 files changed, 226 insertions(+), 211 deletions(-) delete mode 100644 lib/strtosize.c create mode 100644 lib/strutils.c delete mode 100644 schedutils/schedutils.c delete mode 100644 schedutils/schedutils.h diff --git a/include/Makefile.am b/include/Makefile.am index 3b93acd..ac7306c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -20,11 +20,11 @@ dist_noinst_HEADERS = \ nls.h \ pathnames.h \ setproctitle.h \ - strtosize.h \ swapheader.h \ tt.h \ usleep.h \ wholedisk.h \ widechar.h \ writeall.h \ - xstrncpy.h + xstrncpy.h \ + strutils.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 2a185f3..2f6291b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am AM_CPPFLAGS += -DTEST_PROGRAM noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \ - test_strtosize test_tt + test_tt test_strutils if LINUX if HAVE_CPU_SET_T noinst_PROGRAMS += test_cpuset @@ -14,7 +14,7 @@ test_blkdev_SOURCES = blkdev.c test_ismounted_SOURCES = ismounted.c test_wholedisk_SOURCES = wholedisk.c test_mangle_SOURCES = mangle.c -test_strtosize_SOURCES = strtosize.c +test_strutils_SOURCES = strutils.c if LINUX test_cpuset_SOURCES = cpuset.c endif diff --git a/lib/strtosize.c b/lib/strtosize.c deleted file mode 100644 index 068c542..0000000 --- a/lib/strtosize.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * strtosize() - convert string to size (uintmax_t). - * - * Supported suffixes: - * - * XiB or X for 2^N - * where X = {K,M,G,T,P,E,Y,Z} - * or X = {k,m,g,t,p,e} (undocumented for backward compatibility only) - * for example: - * 10KiB = 10240 - * 10K = 10240 - * - * XB for 10^N - * where X = {K,M,G,T,P,E,Y,Z} - * for example: - * 10KB = 10000 - * - * Note that the function does not accept numbers with '-' (negative sign) - * prefix. - * - * Returns 0 on success, -1 in case of error, -2 in case of overflow. - * - * Copyright (C) 2010 Karel Zak <kzak@xxxxxxxxxx> - */ -#include <stdio.h> -#include <inttypes.h> -#include <ctype.h> -#include <errno.h> - -static int do_scale_by_power (uintmax_t *x, int base, int power) -{ - while (power--) { - if (UINTMAX_MAX / base < *x) - return -2; - *x *= base; - } - return 0; -} - -int strtosize(const char *str, uintmax_t *res) -{ - char *p; - uintmax_t x; - int base = 1024, rc = 0; - - *res = 0; - - if (!str || !*str) - goto err; - - /* Only positive numbers are acceptable - * - * Note that this check is not perfect, it would be better to - * use lconv->negative_sign. But coreutils use the same solution, - * so it's probably good enough... - */ - p = (char *) str; - while (isspace((unsigned char) *p)) - p++; - if (*p == '-') - goto err; - p = NULL; - - errno = 0; - x = strtoumax(str, &p, 0); - - if (p == str || - (errno != 0 && (x == UINTMAX_MAX || x == 0))) - goto err; - - if (!p || !*p) - goto done; /* without suffix */ - - /* - * Check size suffixes - */ - if (*(p + 1) == 'i' && *(p + 2) == 'B' && !*(p + 3)) - base = 1024; /* XiB, 2^N */ - else if (*(p + 1) == 'B' && !*(p + 2)) - base = 1000; /* XB, 10^N */ - else if (*(p + 1)) - goto err; /* unexpected suffix */ - - switch(*p) { - case 'K': - case 'k': - rc = do_scale_by_power(&x, base, 1); - break; - case 'M': - case 'm': - rc = do_scale_by_power(&x, base, 2); - break; - case 'G': - case 'g': - rc = do_scale_by_power(&x, base, 3); - break; - case 'T': - case 't': - rc = do_scale_by_power(&x, base, 4); - break; - case 'P': - case 'p': - rc = do_scale_by_power(&x, base, 5); - break; - case 'E': - case 'e': - rc = do_scale_by_power(&x, base, 6); - break; - case 'Z': - rc = do_scale_by_power(&x, base, 7); - break; - case 'Y': - rc = do_scale_by_power(&x, base, 8); - break; - default: - goto err; - } - -done: - *res = x; - return rc; -err: - return -1; -} - -#ifdef TEST_PROGRAM - -#include <stdio.h> -#include <stdlib.h> -#include <err.h> - -int main(int argc, char *argv[]) -{ - uintmax_t size = 0; - - if (argc < 2) { - fprintf(stderr, "usage: %s <number>[suffix]\n", argv[0]); - exit(EXIT_FAILURE); - } - - if (strtosize(argv[1], &size)) - errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]); - - printf("%25s : %20ju\n", argv[1], size); - return EXIT_FAILURE; -} -#endif /* TEST_PROGRAM */ - diff --git a/lib/strutils.c b/lib/strutils.c new file mode 100644 index 0000000..9c8e32b --- /dev/null +++ b/lib/strutils.c @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2010 Davidlohr Bueso <dave@xxxxxxx> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * General purpose string related utilities. + */ + +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <err.h> +#include <inttypes.h> +#include <ctype.h> + +#include "nls.h" + +static int do_scale_by_power(uintmax_t *x, int base, int power) +{ + while (power--) { + if (UINTMAX_MAX / base < *x) + return -2; + *x *= base; + } + return 0; +} + +/* + * strtosize() - convert string to size (uintmax_t). + * + * Supported suffixes: + * + * XiB or X for 2^N + * where X = {K,M,G,T,P,E,Y,Z} + * or X = {k,m,g,t,p,e} (undocumented for backward compatibility only) + * for example: + * 10KiB = 10240 + * 10K = 10240 + * + * XB for 10^N + * where X = {K,M,G,T,P,E,Y,Z} + * for example: + * 10KB = 10000 + * + * Note that the function does not accept numbers with '-' (negative sign) + * prefix. + * + * Returns 0 on success, -1 in case of error, -2 in case of overflow. + */ +int strtosize(const char *str, uintmax_t *res) +{ + char *p; + uintmax_t x; + int base = 1024, rc = 0; + + *res = 0; + + if (!str || !*str) + goto err; + + /* Only positive numbers are acceptable + * + * Note that this check is not perfect, it would be better to + * use lconv->negative_sign. But coreutils use the same solution, + * so it's probably good enough... + */ + p = (char *) str; + while (isspace((unsigned char) *p)) + p++; + if (*p == '-') + goto err; + p = NULL; + + errno = 0; + x = strtoumax(str, &p, 0); + + if (p == str || + (errno != 0 && (x == UINTMAX_MAX || x == 0))) + goto err; + + if (!p || !*p) + goto done; /* without suffix */ + + /* + * Check size suffixes + */ + if (*(p + 1) == 'i' && *(p + 2) == 'B' && !*(p + 3)) + base = 1024; /* XiB, 2^N */ + else if (*(p + 1) == 'B' && !*(p + 2)) + base = 1000; /* XB, 10^N */ + else if (*(p + 1)) + goto err; /* unexpected suffix */ + + switch (*p) { + case 'K': + case 'k': + rc = do_scale_by_power(&x, base, 1); + break; + case 'M': + case 'm': + rc = do_scale_by_power(&x, base, 2); + break; + case 'G': + case 'g': + rc = do_scale_by_power(&x, base, 3); + break; + case 'T': + case 't': + rc = do_scale_by_power(&x, base, 4); + break; + case 'P': + case 'p': + rc = do_scale_by_power(&x, base, 5); + break; + case 'E': + case 'e': + rc = do_scale_by_power(&x, base, 6); + break; + case 'Z': + rc = do_scale_by_power(&x, base, 7); + break; + case 'Y': + rc = do_scale_by_power(&x, base, 8); + break; + default: + goto err; + } + +done: + *res = x; + return rc; +err: + return -1; +} + +#ifndef HAVE_STRNCHR +char *strnchr(const char *s, size_t maxlen, int c) +{ + for (; maxlen-- && *s != '\0'; ++s) + if (*s == (char)c) + return (char *)s; + return NULL; +} +#endif + +#ifndef HAVE_STRNDUP +char *strndup(const char *s, size_t n) +{ + size_t len = strnlen(s, n); + char *new = (char *) malloc((len + 1) * sizeof(char)); + if (!new) + return NULL; + new[len] = '\0'; + return (char *) memcpy(new, s, len); +} +#endif + +/* + * same as strtol(3) but exit on failure instead of returning crap + */ +long strtol_or_err(const char *str, const char *errmesg) +{ + long num; + char *end = NULL; + + if (str == NULL || *str == '\0') + goto err; + errno = 0; + num = strtol(str, &end, 10); + + if (errno || (end && *end)) + goto err; + + return num; +err: + if (errno) + err(EXIT_FAILURE, "%s: '%s'", errmesg, str); + else + errx(EXIT_FAILURE, "%s: '%s'", errmesg, str); + return 0; +} + +#ifdef TEST_PROGRAM + +#include <stdio.h> + +int main(int argc, char *argv[]) +{ + uintmax_t size = 0; + + if (argc < 2) { + fprintf(stderr, "usage %s <number>\n", argv[0]); + exit(EXIT_FAILURE); + } + printf("strtol_or_err: %l\n", strtol_or_err(argv[1], _("failed to parse number"))); + + if (strtosize(argv[1], &size)) + errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]); + + printf("%25s : %20ju\n", argv[1], size); + return EXIT_SUCCESS; +} +#endif /* TEST_PROGRAM */ diff --git a/misc-utils/Makefile.am b/misc-utils/Makefile.am index 6a16f99..6d58df8 100644 --- a/misc-utils/Makefile.am +++ b/misc-utils/Makefile.am @@ -37,12 +37,12 @@ if BUILD_LIBBLKID sbin_PROGRAMS += blkid findfs wipefs dist_man_MANS += blkid.8 findfs.8 wipefs.8 blkid_SOURCES = blkid.c $(top_srcdir)/lib/ismounted.c \ - $(top_srcdir)/lib/strtosize.c + $(top_srcdir)/lib/strutils.c blkid_LDADD = $(ul_libblkid_la) blkid_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir) findfs_LDADD = $(ul_libblkid_la) findfs_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir) -wipefs_SOURCES = wipefs.c $(top_srcdir)/lib/strtosize.c +wipefs_SOURCES = wipefs.c $(top_srcdir)/lib/strutils.c wipefs_LDADD = $(ul_libblkid_la) wipefs_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir) if HAVE_STATIC_BLKID diff --git a/mount/Makefile.am b/mount/Makefile.am index 235cceb..36b06e3 100644 --- a/mount/Makefile.am +++ b/mount/Makefile.am @@ -28,12 +28,12 @@ cflags_common = $(AM_CFLAGS) ldflags_static = -all-static mount_SOURCES = mount.c $(srcs_mount) $(top_srcdir)/lib/setproctitle.c \ - $(top_srcdir)/lib/strtosize.c + $(top_srcdir)/lib/strutils.c mount_CFLAGS = $(SUID_CFLAGS) $(cflags_common) mount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS) mount_LDADD = $(ldadd_common) -umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strtosize.c +umount_SOURCES = umount.c $(srcs_mount) $(top_srcdir)/lib/strutils.c umount_CFLAGS = $(SUID_CFLAGS) $(cflags_common) umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS) umount_LDADD = $(ldadd_common) @@ -45,7 +45,7 @@ swapon_CFLAGS = $(cflags_common) swapon_LDADD = $(ldadd_common) losetup_SOURCES = lomount.c $(srcs_common) loop.h lomount.h \ - $(top_srcdir)/lib/strtosize.c + $(top_srcdir)/lib/strutils.c losetup_CPPFLAGS = -DMAIN $(AM_CPPFLAGS) mount_static_LDADD = diff --git a/schedutils/Makefile.am b/schedutils/Makefile.am index c83e5ea..dc33175 100644 --- a/schedutils/Makefile.am +++ b/schedutils/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/config/include-Makefile.am if BUILD_SCHEDUTILS -srcs_common = schedutils.c schedutils.h +srcs_common = $(top_srcdir)/lib/strutils.c usrbin_exec_PROGRAMS = chrt dist_man_MANS = chrt.1 diff --git a/schedutils/chrt.c b/schedutils/chrt.c index 89b12c7..3cbf6d0 100644 --- a/schedutils/chrt.c +++ b/schedutils/chrt.c @@ -32,7 +32,7 @@ #include "c.h" #include "nls.h" -#include "schedutils.h" +#include "strutils.h" /* the SCHED_BATCH is supported since Linux 2.6.16 * -- temporary workaround for people with old glibc headers @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) break; case 'p': errno = 0; - pid = getnum(argv[argc - 1], _("failed to parse pid")); + pid = strtol_or_err(argv[argc - 1], _("failed to parse pid")); break; case 'r': policy = SCHED_RR; @@ -268,7 +268,7 @@ int main(int argc, char *argv[]) } errno = 0; - priority = getnum(argv[optind], _("failed to parse priority")); + priority = strtol_or_err(argv[optind], _("failed to parse priority")); #ifdef SCHED_RESET_ON_FORK /* sanity check */ diff --git a/schedutils/ionice.c b/schedutils/ionice.c index 34132f0..bb66e8e 100644 --- a/schedutils/ionice.c +++ b/schedutils/ionice.c @@ -18,7 +18,7 @@ #include "nls.h" -#include "schedutils.h" +#include "strutils.h" static int tolerant; @@ -105,15 +105,15 @@ int main(int argc, char *argv[]) while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) { switch (c) { case 'n': - ioprio = getnum(optarg, _("failed to parse class data")); + ioprio = strtol_or_err(optarg, _("failed to parse class data")); set |= 1; break; case 'c': - ioclass = getnum(optarg, _("failed to parse class")); + ioclass = strtol_or_err(optarg, _("failed to parse class")); set |= 2; break; case 'p': - pid = getnum(optarg, _("failed to parse pid")); + pid = strtol_or_err(optarg, _("failed to parse pid")); break; case 't': tolerant = 1; @@ -147,7 +147,7 @@ int main(int argc, char *argv[]) ioprio_print(pid); for(; argv[optind]; ++optind) { - pid = getnum(argv[optind], _("failed to parse pid")); + pid = strtol_or_err(argv[optind], _("failed to parse pid")); ioprio_print(pid); } } else { @@ -156,7 +156,7 @@ int main(int argc, char *argv[]) for(; argv[optind]; ++optind) { - pid = getnum(argv[optind], _("failed to parse pid")); + pid = strtol_or_err(argv[optind], _("failed to parse pid")); ioprio_setpid(pid, ioprio, ioclass); } } diff --git a/schedutils/schedutils.c b/schedutils/schedutils.c deleted file mode 100644 index 9d6051b..0000000 --- a/schedutils/schedutils.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010 Karel Zak <kzak@xxxxxxxxxx> - * - * Released under the terms of the GNU General Public License version 2 - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <err.h> - -#include "nls.h" - -long getnum(const char *str, const char *errmesg) -{ - long num; - char *end = NULL; - - if (str == NULL || *str == '\0') - goto err; - errno = 0; - num = strtol(str, &end, 10); - - if (errno || (end && *end)) - goto err; - - return num; -err: - if (errno) - err(EXIT_FAILURE, "%s: '%s'", errmesg, str); - else - errx(EXIT_FAILURE, "%s: '%s'", errmesg, str); - return 0; -} diff --git a/schedutils/schedutils.h b/schedutils/schedutils.h deleted file mode 100644 index 80e4f7b..0000000 --- a/schedutils/schedutils.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef UTIL_LINUX_SCHED_UTILS -#define UTIL_LINUX_SCHED_UTILS - -extern long getnum(const char *str, const char *errmesg); - -#endif - diff --git a/schedutils/taskset.c b/schedutils/taskset.c index 201fc15..0ba099d 100644 --- a/schedutils/taskset.c +++ b/schedutils/taskset.c @@ -32,7 +32,7 @@ #include "cpuset.h" #include "nls.h" -#include "schedutils.h" +#include "strutils.h" static void __attribute__((__noreturn__)) usage(FILE *out) { @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) while ((opt = getopt_long(argc, argv, "+pchV", longopts, NULL)) != -1) { switch (opt) { case 'p': - pid = getnum(argv[argc - 1], _("failed to parse pid")); + pid = strtol_or_err(argv[argc - 1], _("failed to parse pid")); break; case 'c': c_opt = 1; diff --git a/sys-utils/Makefile.am b/sys-utils/Makefile.am index 166d718..d3bedd4 100644 --- a/sys-utils/Makefile.am +++ b/sys-utils/Makefile.am @@ -33,7 +33,7 @@ info_TEXINFOS = ipc.texi if BUILD_FALLOCATE usrbin_exec_PROGRAMS += fallocate -fallocate_SOURCES = fallocate.c $(top_srcdir)/lib/strtosize.c +fallocate_SOURCES = fallocate.c $(top_srcdir)/lib/strutils.c dist_man_MANS += fallocate.1 endif -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html