cStuff/file.c

142 行
2.6 KiB
C

/******************************************************************************
*
* Copyright (c) 2017-2019 by Löwenware Ltd
* Please, refer LICENSE file for legal information
*
******************************************************************************/
/**
* @file file.c
* @author Ilja Kartašov <ik@lowenware.com>
* @brief
*
* @see https://lowenware.com/
*/
#include <stdio.h>
#include <sys/sendfile.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#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;
}