From f1e973d34066d3e071c774182ae4530b0af7d5d3 Mon Sep 17 00:00:00 2001 From: WaLyong Cho Date: Tue, 13 Dec 2016 11:45:20 +0900 Subject: [PATCH] libsystem: add 64 bit signed/unsigned read-write api Change-Id: Ia2bc5ce5e606154b179ea9e39109e6765a4cdea2 Signed-off-by: WaLyong Cho --- src/Makefile.am | 9 +++ src/libsystem/libsystem.c | 136 +++++++++++++++++++++++++++++++++++++ src/libsystem/libsystem.h | 92 +++++++++++++++++++++++++ src/test/test-read-write.c | 110 ++++++++++++++++++++++++++++++ 4 files changed, 347 insertions(+) create mode 100644 src/test/test-read-write.c diff --git a/src/Makefile.am b/src/Makefile.am index 48ad051..f6cbb81 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -112,6 +112,15 @@ 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 + # ------------------------------------------------------------------------------ pkgconfiglib_DATA += \ libsystem-sd/libsystem-sd.pc diff --git a/src/libsystem/libsystem.c b/src/libsystem/libsystem.c index 2a8aced..f8cfdc4 100644 --- a/src/libsystem/libsystem.c +++ b/src/libsystem/libsystem.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "libsystem.h" @@ -664,6 +666,80 @@ int write_uint32_to_path(const char *path, uint32_t u, enum file_write_flags fla return write_uint32_to_file(f, u, flags); } +int write_int64_to_file(FILE *f, int64_t i, enum file_write_flags flags) { + int r = 0; + + assert(f); + + STORE_RESET_ERRNO; + + (void) fprintf(f, "%" PRId64, i); + 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; +} + +int write_int64_to_path(const char *path, int64_t i, 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_int64_to_file(f, i, flags); +} + +int write_uint64_to_file(FILE *f, uint64_t u, enum file_write_flags flags) { + int r = 0; + + assert(f); + + STORE_RESET_ERRNO; + + (void) fprintf(f, "%" PRIu64, 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; +} + +int write_uint64_to_path(const char *path, uint64_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_uint64_to_file(f, u, flags); +} + int read_one_line_from_file(FILE *f, char **line) { char t[LINE_MAX], *c; @@ -769,6 +845,66 @@ int read_uint32_from_path(const char *path, uint32_t *u) { return read_uint32_from_file(f, u); } +int read_int64_from_file(FILE *f, int64_t *i) { + int r = 0; + + assert(f); + assert(i); + + STORE_RESET_ERRNO; + + r = fscanf(f, "%" SCNd64, i); + if (r == EOF && ferror(f)) + r = errno ? -errno : -EOF; + + RESTORE_ERRNO; + + return r; +} + +int read_int64_from_path(const char *path, int64_t *i) { + _cleanup_fclose_ FILE *f = NULL; + + assert(path); + assert(i); + + f = fopen(path, "re"); + if (!f) + return -errno; + + return read_int64_from_file(f, i); +} + +int read_uint64_from_file(FILE *f, uint64_t *u) { + int r = 0; + + assert(f); + assert(u); + + STORE_RESET_ERRNO; + + r = fscanf(f, "%" SCNu64, u); + if (r == EOF && ferror(f)) + r = errno ? -errno : -EOF; + + RESTORE_ERRNO; + + return r; +} + +int read_uint64_from_path(const char *path, uint64_t *u) { + _cleanup_fclose_ FILE *f = NULL; + + assert(path); + assert(u); + + f = fopen(path, "re"); + if (!f) + return -errno; + + return read_uint64_from_file(f, u); +} + int str_to_strv(const char *str, char ***strv, const char *separator) { char *w, *state, *p; char **v = NULL, **new = NULL; diff --git a/src/libsystem/libsystem.h b/src/libsystem/libsystem.h index 5f6df97..acd50dc 100644 --- a/src/libsystem/libsystem.h +++ b/src/libsystem/libsystem.h @@ -427,6 +427,58 @@ 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 Read the first line from FILE * @@ -488,6 +540,46 @@ 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); /** * @} */ 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 +#include +#include +#include +#include +#include + +#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; +} -- 2.34.1