diff options
-rw-r--r-- | Doxyfile | 2 | ||||
-rw-r--r-- | configure.ac | 18 | ||||
-rw-r--r-- | packaging/libsystem.spec | 4 | ||||
-rw-r--r-- | src/Makefile.am | 22 | ||||
-rw-r--r-- | src/libsystem/config-parser.c | 10 | ||||
-rw-r--r-- | src/libsystem/glib-util.h | 45 | ||||
-rw-r--r-- | src/libsystem/libsystem.c | 424 | ||||
-rw-r--r-- | src/libsystem/libsystem.h | 368 | ||||
-rw-r--r-- | src/libsystem/proc.c | 18 | ||||
-rw-r--r-- | src/test/test-foreach-glist.c | 138 | ||||
-rw-r--r-- | src/test/test-read-write.c | 110 |
11 files changed, 1007 insertions, 152 deletions
@@ -38,7 +38,7 @@ PROJECT_NAME = libsystem # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 4.0 +PROJECT_NUMBER = 4.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/configure.ac b/configure.ac index df18d8e..d0e5c51 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT([libsystem], [4.0], [walyong.cho@samsung.com]) +AC_INIT([libsystem], [4.1], [walyong.cho@samsung.com]) dnl AC_CONFIG_MACRO_DIRS([m4]) AC_CONFIG_MACRO_DIR([m4]) @@ -17,17 +17,21 @@ LT_PREREQ(2.2) LT_INIT([disable-static]) # Checks for programs. -AC_PROG_CC AC_PROG_CXX +AC_PROG_AWK +AC_PROG_CC +AC_PROG_CPP AC_PROG_INSTALL +AC_PROG_LN_S AC_PROG_MAKE_SET +AC_PROG_RANLIB # Checks for libraries. # FIXME: Replace `main' with a function in `-lrt': AC_CHECK_LIB([rt], [main]) # Checks for header files. -AC_CHECK_HEADERS([fcntl.h limits.h mntent.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h]) +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h mntent.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL @@ -68,6 +72,9 @@ our_ldflags=" \ -Wl,-z,now \ -pie" +our_cflags=$(echo $our_cflags |sed 's/\t/ /g' | sed 's/ / /g') +our_ldflags=$(echo $our_ldflags | sed 's/\t/ /g' | sed 's/ / /g') + AC_SUBST([OUR_CFLAGS], "$our_cflags") AC_SUBST([OUR_LDFLAGS], "$our_ldflags") @@ -111,5 +118,8 @@ AC_MSG_RESULT([ lib dir: ${libdir} rootlib dir: ${with_rootlibdir} - OUR CFLAGS: ${OUR_CFLAGS} ${CFLAGS} + OUR CFLAGS: ${OUR_CFLAGS} + CFLAGS: ${CFLAGS} + OUR LDFLAGS: ${OUR_LDFLAGS} + LDFLAGS: ${LDFLAGS} ]) diff --git a/packaging/libsystem.spec b/packaging/libsystem.spec index e2a32d4..073ebb7 100644 --- a/packaging/libsystem.spec +++ b/packaging/libsystem.spec @@ -1,7 +1,7 @@ Name: libsystem Summary: System Libraries -Version: 4.0 -Release: 4%{?release_flags} +Version: 4.1 +Release: 0%{?release_flags} License: Apache-2.0 Group: System/Libraries Source: %{name}-%{version}.tar.gz diff --git a/src/Makefile.am b/src/Makefile.am index 48ad051..0b63ea5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,6 +113,28 @@ test_cp_LDADD = \ tests += test-cp # ------------------------------------------------------------------------------ +test_read_write_SOURCES = \ + test/test-read-write.c + +test_read_write_LDADD = \ + libsystem.la + +tests += test-read-write + +# ------------------------------------------------------------------------------ +test_foreach_glist_SOURCES = \ + test/test-foreach-glist.c + +test_foreach_glist_CFLAGS = \ + $(GIO_CFLAGS) + +test_foreach_glist_LDADD = \ + $(GIO_LIBS) \ + libsystem.la + +tests += test-foreach-glist + +# ------------------------------------------------------------------------------ pkgconfiglib_DATA += \ libsystem-sd/libsystem-sd.pc diff --git a/src/libsystem/config-parser.c b/src/libsystem/config-parser.c index e6ade0e..2799f0a 100644 --- a/src/libsystem/config-parser.c +++ b/src/libsystem/config-parser.c @@ -103,9 +103,7 @@ static int config_parse_table( return 0; } -int config_parse( - const char *filename, - void *table) { +int config_parse(const char *filename, void *table) { _cleanup_fclose_ FILE *f = NULL; char *sections[MAX_SECTION] = { 0 }; @@ -140,12 +138,12 @@ int config_parse( if (*l == '[') { len = strlen(l); - if (l[len-1] != ']') { + if (l[len - 1] != ']') { r = -EBADMSG; goto finish; } - n = strndup(l+1, len-2); + n = strndup(l + 1, len - 2); if (!n) { r = -ENOMEM; goto finish; @@ -203,7 +201,7 @@ int config_parse( r = 0; finish: - for (i=0; i<num_section; i++) + for (i = 0; i < num_section; i++) if (sections[i]) free(sections[i]); diff --git a/src/libsystem/glib-util.h b/src/libsystem/glib-util.h index 7d3c7ad..560acc4 100644 --- a/src/libsystem/glib-util.h +++ b/src/libsystem/glib-util.h @@ -30,9 +30,6 @@ #pragma once #include <glib.h> -#include <gio/gio.h> - -#include "libsystem.h" #ifdef __cplusplus extern "C" { @@ -41,11 +38,47 @@ extern "C" { /** * @brief Iterate for each list nodes. * - * @param n each list nodes + * @param c current node + * @param l list to iterate + */ +#define FOREACH_G_LIST(c, l) \ + for (c = g_list_first(l); c; c = g_list_next(c)) + +/** + * @brief Reverse iterate for each list nodes. + * + * @param c current node + * @param l list to iterate + */ +#define FOREACH_G_LIST_REVERSE(c, l) \ + for (c = g_list_last(l); c; c = g_list_previous(c)) + +/** + * @brief Iterate for each list nodes. #FOREACH_G_LIST_SAFE is similar + * with #FOREACH_G_LIST but safe for list remove. When you are + * iterating a list to remove some of list nodes, you have to use + * #FOREACH_G_LIST_SAFE for safe iteration. + * + * @param c current node + * @param n next node of current iteration, this is used for safe iteration + * @param l list to iterate + */ +#define FOREACH_G_LIST_SAFE(c, n, l) \ + for (c = g_list_first(l), n = g_list_next(c); c; c = n, n = g_list_next(c)) + +/** + * @brief Reverse iterate for each list + * nodes. #FOREACH_G_LIST_SAFE_REVERSE is similar with + * #FOREACH_G_LIST_REVERSE but safe for list remove. When you are + * iterating a list to remove some of list nodes, you have to use + * #FOREACH_G_LIST_SAFE_REVERSE for safe iteration. + * + * @param c current node + * @param p previous node of current iteration, this is used for safe iteration * @param l list to iterate */ -#define FOREACH_G_LIST(n, l) \ - for (n = g_list_first(l); n; n = g_list_next(n)) +#define FOREACH_G_LIST_SAFE_REVERSE(c, p, l) \ + for (c = g_list_last(l), p = g_list_previous(c); c; c = p, p = g_list_previous(c)) /** * @brief Convert GError to errno. diff --git a/src/libsystem/libsystem.c b/src/libsystem/libsystem.c index 2a8aced..c8b7c58 100644 --- a/src/libsystem/libsystem.c +++ b/src/libsystem/libsystem.c @@ -28,17 +28,19 @@ #include <sys/stat.h> #include <fcntl.h> #include <mntent.h> +#include <stdint.h> +#include <inttypes.h> #include "libsystem.h" static int _errno_old; -#define STORE_RESET_ERRNO do { \ +#define STORE_RESET_ERRNO do { \ _errno_old = errno; \ errno = 0; \ } while (0) -#define RESTORE_ERRNO do { \ +#define RESTORE_ERRNO do { \ errno = _errno_old; \ _errno_old = 0; \ } while (0) @@ -81,16 +83,16 @@ char *strnappend(const char *s, const char *suffix, size_t b) { assert(suffix); a = strlen(s); - if (b > ((size_t) -1) - a) + if (b > ((size_t) - 1) - a) return NULL; - r = new(char, a+b+1); + r = new(char, a + b + 1); if (!r) return NULL; memcpy(r, s, a); - memcpy(r+a, suffix, b); - r[a+b] = 0; + memcpy(r + a, suffix, b); + r[a + b] = 0; return r; } @@ -107,7 +109,7 @@ char *strstrip(char *s) { s += strspn(s, WHITESPACE); - for (e = strchr(s, 0); e > s; e --) + for (e = strchr(s, 0); e > s; e--) if (!strchr(WHITESPACE, e[-1])) break; @@ -166,7 +168,7 @@ int strndup_strip(const char *str, size_t len, char **ret) { return 0; } -bool nulstr_contains(const char*nulstr, const char *needle) { +bool nulstr_contains(const char *nulstr, const char *needle) { const char *i; if (!nulstr) @@ -221,7 +223,7 @@ char *path_kill_slashes(char *path) { return path; } -char* endswith(const char *s, const char *postfix) { +char *endswith(const char *s, const char *postfix) { size_t sl, pl; assert(s); @@ -231,7 +233,7 @@ char* endswith(const char *s, const char *postfix) { pl = strlen(postfix); if (pl == 0) - return (char*) s + sl; + return (char *) s + sl; if (sl < pl) return NULL; @@ -239,7 +241,7 @@ char* endswith(const char *s, const char *postfix) { if (memcmp(s + sl - pl, postfix, pl) != 0) return NULL; - return (char*) s + sl - pl; + return (char *) s + sl - pl; } int parse_boolean(const char *v) { @@ -265,7 +267,7 @@ int parse_bytes(const char *b, size_t *s) { return 0; num_l = strspn(b, "0123456789"); - if (num_l < len-1) + if (num_l < len - 1) return -EINVAL; unit_l = strcspn(b, "BKMG"); @@ -306,11 +308,11 @@ int parse_percent(const char *string, size_t *percent) { if (!len) return 0; - if (string[len-1] != '%') + if (string[len - 1] != '%') return -EINVAL; num_len = strspn(string, "0123456789"); - if (num_len < len-1) + if (num_len < len - 1) return -EINVAL; num = strndup(string, num_len); @@ -376,7 +378,7 @@ char *split(const char *c, size_t *l, const char *separator, char **state) { assert(separator); assert(state); - current = *state ? *state : (char*) c; + current = *state ? *state : (char *) c; if (!*current || *c == 0) return NULL; @@ -384,7 +386,7 @@ char *split(const char *c, size_t *l, const char *separator, char **state) { separator_include_quotes = !!strspn(separator, QUOTES); current += strspn(current, separator); - while((s = strcspn(current + *l, separator))) { + while ((s = strcspn(current + *l, separator))) { *l += s; if (separator_include_quotes || quote_complete(current, *l)) @@ -394,7 +396,7 @@ char *split(const char *c, size_t *l, const char *separator, char **state) { *state = current + *l; - return (char *)current; + return (char *) current; } bool is_number(const char *s, int l) { @@ -543,9 +545,8 @@ char *strdup_unquote(const char *str, const char *quotes) { if (l < 2) return strdup(str); - if (strchr(quotes, str[0]) && - str[0] == str[l-1]) - return strndup(str+1, l-2); + if (strchr(quotes, str[0]) && str[0] == str[l - 1]) + return strndup(str + 1, l - 2); return strdup(str); } @@ -559,8 +560,7 @@ int write_str_to_file(FILE *f, const char *str, enum file_write_flags flags) { STORE_RESET_ERRNO; (void) fputs(str, f); - if ((flags & FILE_WRITE_NEWLINE_IF_NOT) && - !endswith(str, "\n")) + if ((flags & FILE_WRITE_NEWLINE_IF_NOT) && !endswith(str, "\n")) (void) fputc('\n', f); if (flags & FILE_WRITE_WITH_FFLUSH) @@ -590,183 +590,365 @@ int write_str_to_path(const char *path, const char *str, enum file_write_flags f return write_str_to_file(f, str, flags); } -int write_int32_to_file(FILE *f, int32_t i, enum file_write_flags flags) { - int r = 0; +int read_one_line_from_file(FILE *f, char **line) { + char t[LINE_MAX], *c; assert(f); + assert(line); STORE_RESET_ERRNO; - (void) fprintf(f, "%d", i); - if (flags & FILE_WRITE_NEWLINE_IF_NOT) - (void) fputc('\n', f); + if (!fgets(t, sizeof(t), f)) { - if (flags & FILE_WRITE_WITH_FFLUSH) - (void) fflush(f); + if (ferror(f)) { + int r; - if (ferror(f)) - r = errno ? -errno : -EIO; + r = errno ? -errno : -EIO; + RESTORE_ERRNO; + return r; + } + + t[0] = 0; + } RESTORE_ERRNO; - return r; + c = strdup(t); + if (!c) + return -ENOMEM; + + *line = truncate_nl(c); + + return 0; } -int write_int32_to_path(const char *path, int32_t i, enum file_write_flags flags) { +int read_one_line_from_path(const char *path, char **line) { _cleanup_fclose_ FILE *f = NULL; assert(path); + assert(line); - if (flags & FILE_WRITE_APPEND) - f = fopen(path, "ae"); - else - f = fopen(path, "we"); + f = fopen(path, "re"); if (!f) return -errno; - return write_int32_to_file(f, i, flags); + return read_one_line_from_file(f, line); } -int write_uint32_to_file(FILE *f, uint32_t u, enum file_write_flags flags) { - int r = 0; +#define DEFINE_WRITE_NUM_TO_FILE(type, format) \ + int write_##type##_to_file(FILE *f, \ + type##_t u, \ + enum file_write_flags flags) { \ + int r = 0; \ + \ + assert(f); \ + \ + STORE_RESET_ERRNO; \ + \ + (void) fprintf(f, format, u); \ + if (flags & FILE_WRITE_NEWLINE_IF_NOT) \ + (void) fputc('\n', f); \ + \ + if (flags & FILE_WRITE_WITH_FFLUSH) \ + (void) fflush(f); \ + \ + if (ferror(f)) \ + r = errno ? -errno : -EIO; \ + \ + RESTORE_ERRNO; \ + \ + return r; \ + } - assert(f); +#define DEFINE_WRITE_NUM_TO_PATH(type) \ + int write_##type##_to_path(const char *path, \ + type##_t u, \ + enum file_write_flags flags) { \ + _cleanup_fclose_ FILE *f = NULL; \ + \ + assert(path); \ + \ + if (flags & FILE_WRITE_APPEND) \ + f = fopen(path, "ae"); \ + else \ + f = fopen(path, "we"); \ + if (!f) \ + return -errno; \ + \ + return write_##type##_to_file(f, u, flags); \ + } - STORE_RESET_ERRNO; +#define DEFINE_WRITE_NUM_DUAL(type, format) \ + DEFINE_WRITE_NUM_TO_FILE(type, format); \ + DEFINE_WRITE_NUM_TO_PATH(type) + +#define DEFINE_READ_NUM_FROM_FILE(type, format) \ + int read_##type##_from_file(FILE *f, type##_t *num) { \ + int r = 0; \ + \ + assert(f); \ + assert(num); \ + \ + STORE_RESET_ERRNO; \ + \ + r = fscanf(f, format, num); \ + if (r == EOF && ferror(f)) \ + r = errno ? -errno : -EOF; \ + \ + RESTORE_ERRNO; \ + \ + return r; \ + } - (void) fprintf(f, "%u", u); - if (flags & FILE_WRITE_NEWLINE_IF_NOT) - (void) fputc('\n', f); +#define DEFINE_READ_NUM_FROM_PATH(type) \ + int read_##type##_from_path(const char *path, type##_t *num) { \ + _cleanup_fclose_ FILE *f = NULL; \ + \ + assert(path); \ + assert(num); \ + \ + f = fopen(path, "re"); \ + if (!f) \ + return -errno; \ + \ + return read_##type##_from_file(f, num); \ + } - if (flags & FILE_WRITE_WITH_FFLUSH) - (void) fflush(f); +#define DEFINE_READ_NUM_DUAL(type, format) \ + DEFINE_READ_NUM_FROM_FILE(type, format); \ + DEFINE_READ_NUM_FROM_PATH(type) - if (ferror(f)) - r = errno ? -errno : -EIO; +#define DEFINE_READ_WRITE_NUM_DUAL(type, r_format, w_format) \ + DEFINE_READ_NUM_DUAL(type, r_format); \ + DEFINE_WRITE_NUM_DUAL(type, w_format) - RESTORE_ERRNO; +DEFINE_READ_WRITE_NUM_DUAL(int32, "%d", "%d"); +DEFINE_READ_WRITE_NUM_DUAL(uint32, "%u", "%u"); +DEFINE_READ_WRITE_NUM_DUAL(int64, "%" SCNd64, "%" PRId64); +DEFINE_READ_WRITE_NUM_DUAL(uint64, "%" SCNu64, "%" PRIu64); - return r; +int write_int_to_file(FILE *f, int num, enum file_write_flags flags) { + + assert(f); + assert(num); + + return write_int32_to_file(f, (int32_t) num, flags); } -int write_uint32_to_path(const char *path, uint32_t u, enum file_write_flags flags) { - _cleanup_fclose_ FILE *f = NULL; +int write_int_to_path(const char *path, int num, enum file_write_flags flags) { assert(path); + assert(num); - if (flags & FILE_WRITE_APPEND) - f = fopen(path, "ae"); - else - f = fopen(path, "we"); - if (!f) - return -errno; + return write_int32_to_path(path, (int32_t) num, flags); +} - return write_uint32_to_file(f, u, flags); +int write_unsigned_int_to_file(FILE *f, unsigned int num, enum file_write_flags flags) { + + assert(f); + assert(num); + + return write_uint32_to_file(f, (uint32_t) num, flags); } -int read_one_line_from_file(FILE *f, char **line) { - char t[LINE_MAX], *c; +int write_unsigned_int_to_path(const char *path, unsigned int num, enum file_write_flags flags) { + + assert(path); + assert(num); + + return write_uint32_to_path(path, (uint32_t) num, flags); +} + +int write_long_int_to_file(FILE *f, long int num, enum file_write_flags flags) { assert(f); - assert(line); + assert(num); - STORE_RESET_ERRNO; +#if __WORDSIZE == 64 + return write_int64_to_file(f, (int64_t) num, flags); +#else + return write_int32_to_file(f, (int32_t) num, flags); +#endif +} - if (!fgets(t, sizeof(t), f)) { +int write_long_int_to_path(const char *path, long int num, enum file_write_flags flags) { - if (ferror(f)) { - int r; + assert(path); + assert(num); - r = errno ? -errno : -EIO; - RESTORE_ERRNO; - return r; - } +#if __WORDSIZE == 64 + return write_int64_to_path(path, (int64_t) num, flags); +#else + return write_int32_to_path(path, (int32_t) num, flags); +#endif +} - t[0] = 0; - } +int write_unsigned_long_int_to_file(FILE *f, unsigned long int num, enum file_write_flags flags) { - RESTORE_ERRNO; + assert(f); + assert(num); - c = strdup(t); - if (!c) - return -ENOMEM; +#if __WORDSIZE == 64 + return write_uint64_to_file(f, (uint64_t) num, flags); +#else + return write_uint32_to_file(f, (uint32_t) num, flags); +#endif +} - *line = truncate_nl(c); +int write_unsigned_long_int_to_path(const char *path, unsigned long int num, enum file_write_flags flags) { - return 0; + assert(path); + assert(num); + +#if __WORDSIZE == 64 + return write_uint64_to_path(path, (uint64_t) num, flags); +#else + return write_uint32_to_path(path, (uint32_t) num, flags); +#endif } -int read_one_line_from_path(const char *path, char **line) { - _cleanup_fclose_ FILE *f = NULL; +int write_long_long_int_to_file(FILE *f, long long int num, enum file_write_flags flags) { + + assert(f); + assert(num); + + return write_int64_to_file(f, (int64_t) num, flags); +} + +int write_long_long_int_to_path(const char *path, long long int num, enum file_write_flags flags) { assert(path); - assert(line); + assert(num); - f = fopen(path, "re"); - if (!f) - return -errno; + return write_int64_to_path(path, (int64_t) num, flags); +} - return read_one_line_from_file(f, line); +int write_unsigned_long_long_int_to_file(FILE *f, unsigned long long int num, enum file_write_flags flags) { + + assert(f); + assert(num); + + return write_uint64_to_file(f, (uint64_t) num, flags); } -int read_int32_from_file(FILE *f, int32_t *i) { - int r = 0; +int write_unsigned_long_long_int_to_path(const char *path, unsigned long long int num, enum file_write_flags flags) { + + assert(path); + assert(num); + + return write_uint64_to_path(path, (uint64_t) num, flags); +} + +int read_int_from_file(FILE *f, int *num) { assert(f); - assert(i); + assert(num); - STORE_RESET_ERRNO; + return read_int32_from_file(f, (int32_t *) num); +} - r = fscanf(f, "%d", i); - if (r == EOF && ferror(f)) - r = errno ? -errno : -EOF; +int read_int_from_path(const char *path, int *num) { - RESTORE_ERRNO; + assert(path); + assert(num); - return r; + return read_int32_from_path(path, (int32_t *) num); } -int read_int32_from_path(const char *path, int32_t *i) { - _cleanup_fclose_ FILE *f = NULL; +int read_unsigned_int_from_file(FILE *f, unsigned int *num) { + + assert(f); + assert(num); + + return read_uint32_from_file(f, (uint32_t *) num); +} + +int read_unsigned_int_from_path(const char *path, unsigned int *num) { assert(path); - assert(i); + assert(num); - f = fopen(path, "re"); - if (!f) - return -errno; + return read_uint32_from_path(path, (uint32_t *) num); +} + +int read_long_int_from_file(FILE *f, long int *num) { + + assert(f); + assert(num); - return read_int32_from_file(f, i); +#if __WORDSIZE == 64 + return read_int64_from_file(f, (int64_t *) num); +#else + return read_int32_from_file(f, (int32_t *) num); +#endif } -int read_uint32_from_file(FILE *f, uint32_t *u) { - int r = 0; +int read_long_int_from_path(const char *path, long int *num) { + + assert(path); + assert(num); + +#if __WORDSIZE == 64 + return read_int64_from_path(path, (int64_t *) num); +#else + return read_int32_from_path(path, (int32_t *) num); +#endif +} + +int read_unsigned_long_int_from_file(FILE *f, unsigned long int *num) { assert(f); - assert(u); + assert(num); - STORE_RESET_ERRNO; +#if __WORDSIZE == 64 + return read_uint64_from_file(f, (uint64_t *) num); +#else + return read_uint32_from_file(f, (uint32_t *) num); +#endif +} - r = fscanf(f, "%u", u); - if (r == EOF && ferror(f)) - r = errno ? -errno : -EOF; +int read_unsigned_long_int_from_path(const char *path, unsigned long int *num) { - RESTORE_ERRNO; + assert(path); + assert(num); - return r; +#if __WORDSIZE == 64 + return read_uint64_from_path(path, (uint64_t *) num); +#else + return read_uint32_from_path(path, (uint32_t *) num); +#endif } -int read_uint32_from_path(const char *path, uint32_t *u) { - _cleanup_fclose_ FILE *f = NULL; +int read_long_long_int_from_file(FILE *f, long long *num) { + + assert(f); + assert(num); + + return read_int64_from_file(f, (int64_t *) num); +} + +int read_long_long_int_from_path(const char *path, long long *num) { assert(path); - assert(u); + assert(num); - f = fopen(path, "re"); - if (!f) - return -errno; + return read_int64_from_path(path, (int64_t *) num); +} + +int read_unsigned_long_long_int_from_file(FILE *f, unsigned long long *num) { + + assert(f); + assert(num); + + return read_uint64_from_file(f, (uint64_t *) num); +} + +int read_unsigned_long_long_int_from_path(const char *path, unsigned long long *num) { + + assert(path); + assert(num); - return read_uint32_from_file(f, u); + return read_uint64_from_path(path, (uint64_t *) num); } int str_to_strv(const char *str, char ***strv, const char *separator) { @@ -782,7 +964,7 @@ int str_to_strv(const char *str, char ***strv, const char *separator) { return -ENOMEM; } - new = (char **)realloc(v, sizeof(char *) * (i + 2)); + new = (char **) realloc(v, sizeof(char *) * (i + 2)); if (!new) { free(p); free(v); @@ -793,7 +975,7 @@ int str_to_strv(const char *str, char ***strv, const char *separator) { v = new; v[i] = p; - v[i+1] = NULL; + v[i + 1] = NULL; i++; } @@ -826,7 +1008,7 @@ int strv_attach(char **first, char **second, char ***strv, bool free_second) { if (second) { n2 = sizeof_strv(second); - new = (char **)realloc(first, sizeof(char *) * (n1 + n2 + 1)); + new = (char **) realloc(first, sizeof(char *) * (n1 + n2 + 1)); if (!new) return -ENOMEM; diff --git a/src/libsystem/libsystem.h b/src/libsystem/libsystem.h index 5f6df97..4452179 100644 --- a/src/libsystem/libsystem.h +++ b/src/libsystem/libsystem.h @@ -428,6 +428,214 @@ int write_uint32_to_file(FILE *f, uint32_t u, enum file_write_flags flags); int write_uint32_to_path(const char *path, uint32_t u, enum file_write_flags flags); /** + * @brief Write 64 bit signed decimal integer to FILE. + * + * @param f File pointer. + * @param i 64 bit signed integer to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_int64_to_file(FILE *f, int64_t i, enum file_write_flags flags); + +/** + * @brief Write 64 bit signed decimal integer to path. + * + * @param path File path. + * @param i 64 bit signed integer to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_int64_to_path(const char *path, int64_t i, enum file_write_flags flags); + +/** + * @brief Write 64 bit unsigned decimal integer to FILE. + * + * @param f File pointer + * @param u 64 bit Unsigned integer to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_uint64_to_file(FILE *f, uint64_t u, enum file_write_flags flags); + +/** + * @brief Write 64 bit unsigned decimal integer to path. + * + * @param path File path. + * @param u 64 bit Unsigned integer to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_uint64_to_path(const char *path, uint64_t u, enum file_write_flags flags); + +/** + * @brief Write int to FILE. + * + * @param f File pointer + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_int_to_file(FILE *f, int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_int_to_path(const char *path, int num, enum file_write_flags flags); + +/** + * @brief Write type unsigned int to FILE. + * + * @param f File pointer + * @param num unsigned int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_int_to_file(FILE *f, unsigned int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_int_to_path(const char *path, unsigned int num, enum file_write_flags flags); + +/** + * @brief Write long int to FILE. + * + * @param f File pointer + * @param num long int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_long_int_to_file(FILE *f, long int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_long_int_to_path(const char *path, long int num, enum file_write_flags flags); + +/** + * @brief Write unsigned long int to FILE. + * + * @param f File pointer + * @param num unsigned long int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_long_int_to_file(FILE *f, unsigned long int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_long_int_to_path(const char *path, unsigned long int num, enum file_write_flags flags); + +/** + * @brief Write long long int to FILE. + * + * @param f File pointer + * @param num long long int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_long_long_int_to_file(FILE *f, long long int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_long_long_int_to_path(const char *path, long long int num, enum file_write_flags flags); + +/** + * @brief Write unsigned long long int to FILE. + * + * @param f File pointer + * @param num unsigned long long int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_long_long_int_to_file(FILE *f, unsigned long long int num, enum file_write_flags flags); + +/** + * @brief Write int to path. + * + * @param path File path. + * @param num int to write. + * @param flags Optional flags to write file. if + * ::FILE_WRITE_NEWLINE_IF_NOT is set, line-end added. For detail, see + * ::file_write_flags. + * + * @return 0 on success, -errno on failure. + */ +int write_unsigned_long_long_int_to_path(const char *path, unsigned long long int num, enum file_write_flags flags); + +/** * @brief Read the first line from FILE * * @param f File pointer. @@ -488,6 +696,166 @@ int read_uint32_from_file(FILE *f, uint32_t *u); * @return 0 on success, -errno on failure. */ int read_uint32_from_path(const char *path, uint32_t *u); + +/** + * @brief Read 64 bit signed decimal integer from FILE. + * + * @param f File pointer. + * @param i 64 bit signed int value pointer. + * + * @return 0 on success, -errno on failure. + */ +int read_int64_from_file(FILE *f, int64_t *i); + +/** + * @brief Read 64 bit signed decimal integer from path. + * + * @param path File path. + * @param i 64 bit signed int value pointer. + * + * @return 0 on success, -errno on failure. + */ +int read_int64_from_path(const char *path, int64_t *i); + +/** + * @brief Read 64 bit unsigned decimal integer from FILE. + * + * @param f File pointer. + * @param u 64 bit unsigned int value pointer. + * + * @return 0 on success, -errno on failure. + */ +int read_uint64_from_file(FILE *f, uint64_t *u); + +/** + * @brief Read 64 bit unsigned decimal integer from path + * + * @param path File path. + * @param u 64 bit unsigned int value pointer. + * + * @return 0 on success, -errno on failure. + */ +int read_uint64_from_path(const char *path, uint64_t *u); + +/** + * @brief Read type int from FILE + * + * @param f File pointer. + * @param num type int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_int_from_file(FILE *f, int *num); + +/** + * @brief Read type int from path + * + * @param path File path. + * @param num type int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_int_from_path(const char *path, int *num); + +/** + * @brief Read type unsigned int from FILE + * + * @param f File pointer. + * @param num type unsigned int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_int_from_file(FILE *f, unsigned int *num); + +/** + * @brief Read type unsigned int from path + * + * @param path File path. + * @param num type unsigned int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_int_from_path(const char *path, unsigned int *num); + +/** + * @brief Read type long int from FILE + * + * @param f File pointer. + * @param num type long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_long_int_from_file(FILE *f, long int *num); + +/** + * @brief Read type long int from path + * + * @param path File path. + * @param num type long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_long_int_from_path(const char *path, long int *num); + +/** + * @brief Read type unsigned long int from FILE + * + * @param f File pointer. + * @param num type unsigned long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_long_int_from_file(FILE *f, unsigned long int *num); + +/** + * @brief Read type unsigned long int from path + * + * @param path File path. + * @param num type unsigned long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_long_int_from_path(const char *path, unsigned long int *num); + +/** + * @brief Read type long long int from FILE + * + * @param f File pointer. + * @param num type long long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_long_long_int_from_file(FILE *f, long long *num); + +/** + * @brief Read type long long int from path + * + * @param path File path. + * @param num type long long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_long_long_int_from_path(const char *path, long long *num); + +/** + * @brief Read type unsigned long long int from FILE + * + * @param f File pointer. + * @param num type unsigned long long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_long_long_int_from_file(FILE *f, unsigned long long *num); + +/** + * @brief Read type unsigned long long int from path + * + * @param path File path. + * @param num type unsigned long long int pointer + * + * @return 0 on success, -errno on failure. + */ +int read_unsigned_long_long_int_from_path(const char *path, unsigned long long *num); /** * @} */ diff --git a/src/libsystem/proc.c b/src/libsystem/proc.c index 6a3d3df..49ddfde 100644 --- a/src/libsystem/proc.c +++ b/src/libsystem/proc.c @@ -89,7 +89,7 @@ int proc_pid_of(const char *pname) { if (r < 0) continue; - if (strneq(pname, comm, TASK_COMM_LEN-1)) + if (strneq(pname, comm, TASK_COMM_LEN - 1)) return atoi(de->d_name); } @@ -130,9 +130,7 @@ static int add_smap_to_smaps(struct smaps *maps, struct smap *map) { maps->n_map++; - maps->maps = (struct smap **)realloc( - maps->maps, - sizeof(struct smap *) * maps->n_map); + maps->maps = (struct smap **) realloc(maps->maps, sizeof(struct smap *) * maps->n_map); if (!maps->maps) return -ENOMEM; @@ -189,8 +187,7 @@ int proc_pid_get_smaps(pid_t pid, struct smaps **maps, enum smap_mask mask) { goto on_error; } - n = sscanf(buf, "%x-%x %ms %*s %*s %*s %ms", - &map->start, &map->end, &map->mode, &map->name); + n = sscanf(buf, "%x-%x %ms %*s %*s %*s %ms", &map->start, &map->end, &map->mode, &map->name); if (n == 3 && !map->name) map->name = strdup("[anon]"); @@ -214,8 +211,7 @@ int proc_pid_get_smaps(pid_t pid, struct smaps **maps, enum smap_mask mask) { break; } - if ((*buf >= '0' && *buf <= '9') || - (*buf >= 'a' && *buf <= 'f')) { + if ((*buf >= '0' && *buf <= '9') || (*buf >= 'a' && *buf <= 'f')) { get_line = false; break; } @@ -314,8 +310,7 @@ int proc_get_meminfo(struct meminfo *mi, enum meminfo_mask mask) { return -errno; if (remain_mask & MEMINFO_MASK_MEM_AVAILABLE) - remain_mask |= (MEMINFO_MASK_MEM_FREE | - MEMINFO_MASK_CACHED); + remain_mask |= (MEMINFO_MASK_MEM_FREE | MEMINFO_MASK_CACHED); while (remain_mask) { unsigned int v = 0; @@ -350,8 +345,7 @@ int proc_get_meminfo(struct meminfo *mi, enum meminfo_mask mask) { } if (remain_mask & MEMINFO_MASK_MEM_AVAILABLE) { - mi->value[MEMINFO_ID_MEM_AVAILABLE] = - mi->value[MEMINFO_ID_MEM_FREE] + mi->value[MEMINFO_ID_MEM_AVAILABLE] = mi->value[MEMINFO_ID_MEM_FREE] + mi->value[MEMINFO_ID_CACHED]; } diff --git a/src/test/test-foreach-glist.c b/src/test/test-foreach-glist.c new file mode 100644 index 0000000..ba952e0 --- /dev/null +++ b/src/test/test-foreach-glist.c @@ -0,0 +1,138 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * libsystem + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <limits.h> +#include <glib.h> + +#include "libsystem/libsystem.h" +#include "libsystem/glib-util.h" + +static void gen_test_list(GList **list) { + GList *l = NULL; + int i; + + assert(list); + assert(!*list); + + for (i = 1; i <= 10; i++) + l = g_list_append(l, GINT_TO_POINTER(i)); + + *list = l; +} + +static void test_foreach_g_list(void) { + GList *list = NULL, *node; + char buf[LINE_MAX]; + int n = 0; + + gen_test_list(&list); + + FOREACH_G_LIST(node, list) { + int i = GPOINTER_TO_INT(node->data); + + n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i); + } + + assert(streq(buf, "1 2 3 4 5 6 7 8 9 10 ")); + + g_list_free(list); +} + +static void test_foreach_g_list_reverse(void) { + GList *list = NULL, *node; + char buf[LINE_MAX]; + int n = 0; + + gen_test_list(&list); + + FOREACH_G_LIST_REVERSE(node, list) { + int i = GPOINTER_TO_INT(node->data); + + n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i); + } + + assert(streq(buf, "10 9 8 7 6 5 4 3 2 1 ")); + + g_list_free(list); +} + +static void test_foreach_g_list_safe(void) { + GList *list = NULL, *node, *next; + char buf[LINE_MAX]; + int n = 0; + + gen_test_list(&list); + + FOREACH_G_LIST_SAFE(node, next, list) { + int i = GPOINTER_TO_INT(node->data); + + if (i % 2) + list = g_list_remove_link(list, node); + } + + FOREACH_G_LIST(node, list) { + int i = GPOINTER_TO_INT(node->data); + + n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i); + } + + assert(streq(buf, "2 4 6 8 10 ")); + + g_list_free(list); +} + +static void test_foreach_g_list_safe_reverse(void) { + GList *list = NULL, *node, *prev; + char buf[LINE_MAX]; + int n = 0; + + gen_test_list(&list); + + FOREACH_G_LIST_SAFE_REVERSE(node, prev, list) { + int i = GPOINTER_TO_INT(node->data); + + if (i % 2) + list = g_list_remove_link(list, node); + } + + FOREACH_G_LIST_REVERSE(node, list) { + int i = GPOINTER_TO_INT(node->data); + + n += snprintf(buf + n, LINE_MAX - n - 1, "%d ", i); + } + + assert(streq(buf, "10 8 6 4 2 ")); + + g_list_free(list); +} + +int main(int argc, char *argv[]) { + + test_foreach_g_list(); + test_foreach_g_list_reverse(); + + test_foreach_g_list_safe(); + test_foreach_g_list_safe_reverse(); + + return 0; +} diff --git a/src/test/test-read-write.c b/src/test/test-read-write.c new file mode 100644 index 0000000..5661ac9 --- /dev/null +++ b/src/test/test-read-write.c @@ -0,0 +1,110 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * libsystem + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#include <errno.h> +#include <stdint.h> + +#include "libsystem/libsystem.h" + +#define TEST_READ_WRITE_FILE "/tmp/test-read-write" +#define TEST_STRING "L!i@b#s$y%s^t&e*m(T)e-s=tS`t_r+i|n~g" +#define TEST_INT32 0x7fabcdef +#define TEST_UINT32 0xffabcdef +#define TEST_INT64 0x7fabcdef00abcdef +#define TEST_UINT64 0xffabcdef00abcdef + +static void test_string_read_write(void) { + _cleanup_free_ char *str = NULL; + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); + + assert(write_str_to_path(TEST_READ_WRITE_FILE, TEST_STRING, 0) >= 0); + assert(read_one_line_from_path(TEST_READ_WRITE_FILE, &str) >= 0); + + assert(streq(str, TEST_STRING)); + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); +} + +static void test_int32_read_write(void) { + int32_t i; + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); + + assert(write_int32_to_path(TEST_READ_WRITE_FILE, TEST_INT32, 0) >= 0); + assert(read_int32_from_path(TEST_READ_WRITE_FILE, &i) >= 0); + + assert(i == TEST_INT32); + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); +} + +static void test_uint32_read_write(void) { + uint32_t u; + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); + + assert(write_uint32_to_path(TEST_READ_WRITE_FILE, TEST_UINT32, 0) >= 0); + assert(read_uint32_from_path(TEST_READ_WRITE_FILE, &u) >= 0); + + assert(u == TEST_UINT32); + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); +} + +static void test_int64_read_write(void) { + int64_t i; + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); + + assert(write_int64_to_path(TEST_READ_WRITE_FILE, TEST_INT64, 0) >= 0); + assert(read_int64_from_path(TEST_READ_WRITE_FILE, &i) >= 0); + + assert(i == TEST_INT64); + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); +} + +static void test_uint64_read_write(void) { + uint64_t u; + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); + + assert(write_uint64_to_path(TEST_READ_WRITE_FILE, TEST_UINT64, 0) >= 0); + assert(read_uint64_from_path(TEST_READ_WRITE_FILE, &u) >= 0); + + assert(u == TEST_UINT64); + + assert(unlink(TEST_READ_WRITE_FILE) == 0 || errno == ENOENT); +} + +int main(int argc, char *argv[]) { + test_string_read_write(); + test_int32_read_write(); + test_uint32_read_write(); + test_int64_read_write(); + test_uint64_read_write(); + + return 0; +} |