libsystem: add 64 bit signed/unsigned read-write api
authorWaLyong Cho <walyong.cho@samsung.com>
Tue, 13 Dec 2016 02:45:20 +0000 (11:45 +0900)
committerWaLyong Cho <walyong.cho@samsung.com>
Tue, 13 Dec 2016 05:23:36 +0000 (14:23 +0900)
Change-Id: Ia2bc5ce5e606154b179ea9e39109e6765a4cdea2
Signed-off-by: WaLyong Cho <walyong.cho@samsung.com>
src/Makefile.am
src/libsystem/libsystem.c
src/libsystem/libsystem.h
src/test/test-read-write.c [new file with mode: 0644]

index 48ad051..f6cbb81 100644 (file)
@@ -113,6 +113,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
 
index 2a8aced..f8cfdc4 100644 (file)
@@ -28,6 +28,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <mntent.h>
+#include <stdint.h>
+#include <inttypes.h>
 
 #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;
index 5f6df97..acd50dc 100644 (file)
@@ -428,6 +428,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
  *
  * @param f File pointer.
@@ -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 (file)
index 0000000..5661ac9
--- /dev/null
@@ -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;
+}