From: WaLyong Cho Date: Tue, 15 Nov 2016 04:49:53 +0000 (+0900) Subject: libsystem: introduce do_cp() and do_cp_mode() X-Git-Tag: accepted/tizen/unified/20180326.075213~2^2~2^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f949f53e9e76545325d69e8f4445c6cc61c44949;p=platform%2Fcore%2Fsystem%2Flibsystem.git libsystem: introduce do_cp() and do_cp_mode() (This is the first step to remove do_copy() which is invoking "/bin/cp" directly.) Add new two file copy api. - do_cp_mode(): copy src file to dst file with given mode. - do_cp(): same with do_cp_mode(), but mode is 0644. Change-Id: I6a1bada8de677b64886ed0c6b0b16cf80d57459c Signed-off-by: WaLyong Cho --- diff --git a/src/Makefile.am b/src/Makefile.am index 9378c18..48ad051 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -104,6 +104,15 @@ test_exec_LDADD = \ tests += test-exec # ------------------------------------------------------------------------------ +test_cp_SOURCES = \ + test/test-cp.c + +test_cp_LDADD = \ + libsystem.la + +tests += test-cp + +# ------------------------------------------------------------------------------ pkgconfiglib_DATA += \ libsystem-sd/libsystem-sd.pc diff --git a/src/libsystem/libsystem.c b/src/libsystem/libsystem.c index f87dfa0..fc704f9 100644 --- a/src/libsystem/libsystem.c +++ b/src/libsystem/libsystem.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "libsystem.h" @@ -423,6 +424,40 @@ int do_copy(const char *src, const char *dst, const char *option, int64_t timeou return do_fork_exec(argv, NULL, timeout_msec); } +int do_cp_mode(const char *src, const char *dst, mode_t mode) { + _cleanup_close_ int rfd = -1, wfd = -1; + ssize_t red; + char buf[1024]; + + assert(src); + assert(dst); + + rfd = open(src, O_RDONLY); + if (rfd < 0) + return -errno; + + wfd = open(dst, O_CREAT | O_WRONLY | O_TRUNC, mode); + if (wfd < 0) + return -errno; + + while ((red = read(rfd, buf, 1024)) > 0) + if (write(wfd, buf, red) != red) + return -errno; + + if (red < 0) + return -errno; + + return 0; +} + +int do_cp(const char *src, const char *dst) { + + assert(src); + assert(dst); + + return do_cp_mode(src, dst, 0644); +} + int do_mkdir(const char *path, mode_t mode) { char d[PATH_MAX]; size_t s, l; diff --git a/src/libsystem/libsystem.h b/src/libsystem/libsystem.h index 631a216..9b0bd1e 100644 --- a/src/libsystem/libsystem.h +++ b/src/libsystem/libsystem.h @@ -274,6 +274,27 @@ bool is_number(const char *s, int l); int do_copy(const char *src, const char *dst, const char *option, int64_t timeout_msec); /** + * @brief copy a file with mode + * + * @param src source file path + * @param dst destination file path + * @param mode destination file mode + * + * @return 0 on success, -errno on failure. + */ +int do_cp_mode(const char *src, const char *dst, mode_t mode); + +/** + * @brief copy a file, destination file mode is 0644 + * + * @param src source file path + * @param dst destination file path + * + * @return 0 on success, -errno on failure. + */ +int do_cp(const char *src, const char *dst); + +/** * @brief Make a directory. If parent directories are also absent, * make them also. Corresponding with "mkdir -p". * diff --git a/src/test/test-cp.c b/src/test/test-cp.c new file mode 100644 index 0000000..c875cca --- /dev/null +++ b/src/test/test-cp.c @@ -0,0 +1,130 @@ +/*-*- 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 +#include + +#include "libsystem/libsystem.h" + +#define TEST_SRC_FILE "/tmp/test-cp-src" +#define TEST_DST_FILE "/tmp/test-cp-dst" + +static int random_char(char **buf, size_t len) { + static int rand_init = 0; + char *b; + int rnd; + size_t s; + + if (!rand_init) { + srand(time(NULL)); + rand_init = 1; + } + + b = new0(char, len); + if (!b) + return -ENOMEM; + + for (s = 0; s < len; s++) { + + /* 98 = number_of_chars((sp) ~ (DEL) + \t + \n + \r) */ + rnd = rand() % 98; + + assert(rnd < 98); + + switch (rnd) { + case 95: + b[s] = '\t'; + break; + case 96: + b[s] = '\n'; + break; + case 97: + b[s] = '\r'; + break; + default: + b[s] = ' ' + rnd; + break; + } + } + + *buf = b; + + return 0; +} + +static int write_src_file(unsigned int n_byte) { + _cleanup_free_ char *buf = NULL; + _cleanup_close_ int fd = -1; + + assert(random_char(&buf, n_byte) == 0); + + fd = open(TEST_SRC_FILE, O_CREAT | O_WRONLY | O_TRUNC, 0644); + assert(fd >= 0); + assert(write(fd, buf, n_byte) == n_byte); + + return 0; +} + +static void compare_file(void) { + _cleanup_close_ int src_fd = -1, dst_fd = -1; + char src_buf[1024], dst_buf[1024]; + ssize_t src_red, dst_red; + + src_fd = open(TEST_SRC_FILE, O_RDONLY); + assert(src_fd >= 0); + + dst_fd = open(TEST_DST_FILE, O_RDONLY); + assert(dst_fd >= 0); + + while(src_red = read(src_fd, src_buf, 1024) > 0, + dst_red = read(dst_fd, dst_buf, 1024) > 0) { + assert(src_red == dst_red); + assert(memcmp(src_buf, dst_buf, src_red) == 0); + } +} + +static void test_n_byte_cp(unsigned int n) { + assert(unlink(TEST_SRC_FILE) == 0 || errno == ENOENT); + + assert(unlink(TEST_SRC_FILE) == 0 || errno == ENOENT); + + assert(write_src_file(n) == 0); + assert(do_cp(TEST_SRC_FILE, TEST_DST_FILE) == 0); + compare_file(); +} + +int main(int argc, char *argv[]) { + + unsigned int b; + + for (b = 8; b < (1 << 30); b = b << 1) + test_n_byte_cp(b); + + unlink(TEST_SRC_FILE); + unlink(TEST_DST_FILE); + + return 0; +}