diff options
Diffstat (limited to 'usr/src/lib')
-rw-r--r-- | usr/src/lib/libcmdutils/Makefile.com | 3 | ||||
-rw-r--r-- | usr/src/lib/libcmdutils/common/custr.c | 135 | ||||
-rw-r--r-- | usr/src/lib/libcmdutils/common/mapfile-vers | 7 | ||||
-rw-r--r-- | usr/src/lib/libcmdutils/libcmdutils.h | 43 |
4 files changed, 187 insertions, 1 deletions
diff --git a/usr/src/lib/libcmdutils/Makefile.com b/usr/src/lib/libcmdutils/Makefile.com index 2f98fe5f25..ffe3c9cba5 100644 --- a/usr/src/lib/libcmdutils/Makefile.com +++ b/usr/src/lib/libcmdutils/Makefile.com @@ -25,7 +25,8 @@ LIBRARY= libcmdutils.a VERS= .1 -CMD_OBJS= avltree.o sysattrs.o writefile.o process_xattrs.o uid.o gid.o +CMD_OBJS= avltree.o sysattrs.o writefile.o process_xattrs.o uid.o gid.o \ + custr.o COM_OBJS= list.o OBJECTS= $(CMD_OBJS) $(COM_OBJS) diff --git a/usr/src/lib/libcmdutils/common/custr.c b/usr/src/lib/libcmdutils/common/custr.c new file mode 100644 index 0000000000..1ec72de9dd --- /dev/null +++ b/usr/src/lib/libcmdutils/common/custr.c @@ -0,0 +1,135 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * String utility functions with dynamic memory management. + */ + +/* + * Copyright 2014, Joyent, Inc. + */ + +#include <stdlib.h> +#include <err.h> +#include <string.h> + +#include "libcmdutils.h" + +struct custr { + size_t cus_strlen; + size_t cus_datalen; + char *cus_data; +}; + +#define STRING_CHUNK_SIZE 64 + +void +custr_reset(custr_t *cus) +{ + if (cus->cus_data == NULL) + return; + + cus->cus_strlen = 0; + cus->cus_data[0] = '\0'; +} + +size_t +custr_len(custr_t *cus) +{ + return (cus->cus_strlen); +} + +const char * +custr_cstr(custr_t *cus) +{ + return (cus->cus_data); +} + +int +custr_appendc(custr_t *cus, char newc) +{ + char news[2]; + + news[0] = newc; + news[1] = '\0'; + + return (custr_append(cus, news)); +} + +int +custr_append(custr_t *cus, const char *news) +{ + size_t len = strlen(news); + size_t chunksz = STRING_CHUNK_SIZE; + + while (chunksz < len) { + chunksz *= 2; + } + + if (len + cus->cus_strlen + 1 >= cus->cus_datalen) { + char *new_data; + size_t new_datalen = cus->cus_datalen + chunksz; + + /* + * Allocate replacement memory: + */ + if ((new_data = malloc(new_datalen)) == NULL) { + return (-1); + } + + /* + * Copy existing data into replacement memory and free + * the old memory. + */ + if (cus->cus_data != NULL) { + (void) memcpy(new_data, cus->cus_data, + cus->cus_strlen + 1); + free(cus->cus_data); + } + + /* + * Swap in the replacement buffer: + */ + cus->cus_data = new_data; + cus->cus_datalen = new_datalen; + } + /* + * Append new string to existing string: + */ + (void) memcpy(cus->cus_data + cus->cus_strlen, news, len + 1); + cus->cus_strlen += len; + + return (0); +} + +int +custr_alloc(custr_t **cus) +{ + custr_t *t; + + if ((t = calloc(1, sizeof (*t))) == NULL) { + *cus = NULL; + return (-1); + } + + *cus = t; + return (0); +} + +void +custr_free(custr_t *cus) +{ + if (cus == NULL) + return; + + free(cus->cus_data); + free(cus); +} diff --git a/usr/src/lib/libcmdutils/common/mapfile-vers b/usr/src/lib/libcmdutils/common/mapfile-vers index e4c5940c31..640959e4b5 100644 --- a/usr/src/lib/libcmdutils/common/mapfile-vers +++ b/usr/src/lib/libcmdutils/common/mapfile-vers @@ -42,6 +42,13 @@ $mapfile_version 2 SYMBOL_VERSION SUNWprivate_1.1 { global: add_tnode; + custr_alloc; + custr_append; + custr_appendc; + custr_cstr; + custr_free; + custr_len; + custr_reset; destroy_tree; findnextgid; findnextuid; diff --git a/usr/src/lib/libcmdutils/libcmdutils.h b/usr/src/lib/libcmdutils/libcmdutils.h index c315e0fbef..a280751c27 100644 --- a/usr/src/lib/libcmdutils/libcmdutils.h +++ b/usr/src/lib/libcmdutils/libcmdutils.h @@ -25,6 +25,9 @@ /* * Copyright (c) 2013 RackTop Systems. */ +/* + * Copyright 2014 Joyent, Inc. + */ /* * Declarations for the functions in libcmdutils. @@ -140,6 +143,46 @@ extern int findnextuid(uid_t, uid_t, uid_t *); */ extern int findnextgid(gid_t, gid_t, gid_t *); + + + /* dynamic string utilities */ + +typedef struct custr custr_t; + +/* + * Allocate and free a "custr_t" dynamic string object. Returns 0 on success + * and -1 otherwise. + */ +extern int custr_alloc(custr_t **); +extern void custr_free(custr_t *); + +/* + * Append a single character, or a NUL-terminated string of characters, to a + * dynamic string. Returns 0 on success and -1 otherwise. The dynamic string + * will be unmodified if the function returns -1. + */ +extern int custr_appendc(custr_t *, char); +extern int custr_append(custr_t *, const char *); + +/* + * Determine the length in bytes, not including the NUL terminator, of the + * dynamic string. + */ +extern size_t custr_len(custr_t *); + +/* + * Clear the contents of a dynamic string. Does not free the underlying + * memory. + */ +extern void custr_reset(custr_t *); + +/* + * Retrieve a const pointer to a NUL-terminated string version of the contents + * of the dynamic string. Storage for this string should not be freed, and + * the pointer will be invalidated by any mutations to the dynamic string. + */ +extern const char *custr_cstr(custr_t *str); + #ifdef __cplusplus } #endif |