/****************************************************************************** * * Copyright (c) 2017-2019 by Löwenware Ltd * Please, refer LICENSE file for legal information * ******************************************************************************/ /** * @file file.c * @author Ilja Kartašov * @brief * * @see https://lowenware.com/ */ #include #include #include #include #include #include #include #include #include "file.h" bool cstuff_file_exists(const char *file) { return ( access( file, F_OK ) != -1 ) ? true : false; } CStuffRetcode cstuff_file_copy(const char *src, const char *dest) { CStuffRetcode rc = CSTUFF_SYSCALL_ERROR; int fd_src = open(src, O_RDWR), fd_dest, len; struct stat src_stat; if (!(fd_src < 0)) { if (lockf(fd_src, F_LOCK, 0) != -1) { if (!stat(src, &src_stat)) { fd_dest = open(dest, O_CREAT | O_WRONLY | O_TRUNC); if (!(fd_dest < 0)) { len = sendfile(fd_dest, fd_src, NULL, src_stat.st_size); if (len == src_stat.st_size) { rc = CSTUFF_SUCCESS; } else { fprintf(stderr, "sendfile error (%d != %d): %s\n", len, (int)src_stat.st_size, strerror(errno)); } close(fd_dest); } else { fprintf(stderr, "dest open() error\n"); } } else { fprintf(stderr, "src stat() error\n"); } if (lockf(fd_src, F_TEST, 0) == 0){ lockf(fd_src, F_ULOCK, 0); } } else { fprintf(stderr, "src lockf() error\n"); } close(fd_src); } else { fprintf(stderr, "src open() error\n"); } return rc; } CStuffRetcode cstuff_file_move(const char *src, const char *dest) { CStuffRetcode rc; if (!(rc = cstuff_file_copy(src, dest))) { if (unlink(src) != 0) return CSTUFF_SYSCALL_ERROR; } return rc; } CStuffRetcode cstuff_file_get_lines(const char *src, CStuffFileGetLine get_line, void *ctx) { FILE *f = NULL; size_t sz = 256; char *line; ssize_t rs; CStuffRetcode result = CSTUFF_SUCCESS; if (!(line = malloc(sz))) goto e_malloc; if (!(f = fopen(src, "r"))) goto e_syscall; while ((rs = getdelim(&line, &sz, '\n', f)) != -1) { if (!get_line(line, rs, ctx)) { continue; } else { goto e_input; } } switch(errno) { case 0: break; case ENOMEM: goto e_malloc; default: goto e_syscall; } goto finally; e_input: result = CSTUFF_INPUT_ERROR; goto finally; e_malloc: result = CSTUFF_MALLOC_ERROR; goto finally; e_syscall: result = CSTUFF_SYSCALL_ERROR; goto finally; finally: if (line) free(line); if (f) fclose(f); return result; }