Table of Contents
ex_file_copy.c
n_file_copy_verified(), n_file_same_content() and n_file_free_space() Copies a file larger than one block, checks the copy is there and equal, that no ".part" is left, that an existing destination is refused and left as it was, that a missing source fails without leaving anything, and that n_file_same_content() tells equal files from different ones of the same size. Last, n_file_free_space() reads some room where the file was written, the same through the file and its folder, and fails on a path that is not there. ```c
#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>
#include "nilorea/n_common.h" #include "nilorea/n_files.h" #include "nilorea/n_log.h"
static int failures = 0;
static void expect_true(const char* what, int ok) { if (!ok) { n_log(LOG_ERR, "FAIL: %s", what); failures++; } }
static int there(const char* path) { FILE* f = fopen(path, "rb");
if (!f) return 0;
fclose(f);
return 1;
}
int main(void) { const char* tmp = getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp"; char src[512], dst[512], part[520], other[512]; size_t copied = 0, i = 0; FILE* f = NULL;
set_log_level(LOG_NOTICE);
snprintf(src, sizeof(src), "%s/ex_file_copy_%d.src", tmp, (int)getpid());
snprintf(dst, sizeof(dst), "%s/ex_file_copy_%d.dst", tmp, (int)getpid());
snprintf(part, sizeof(part), "%s.part", dst);
snprintf(other, sizeof(other), "%s/ex_file_copy_%d.other", tmp, (int)getpid());
/* A little over three blocks, so the loop turns and the tail is short. */
f = fopen(src, "wb");
if (!f) return 1;
for (i = 0; i < 800000; i++) fputc((int)((i * 7 + i / 13) & 0xff), f);
fclose(f);
expect_true("a file is copied", n_file_copy_verified(src, dst, &copied) == TRUE);
expect_true("every byte of it", copied == 800000);
expect_true("the copy is equal", n_file_same_content(src, dst) == TRUE);
expect_true("no part file is left", !there(part));
expect_true("an existing copy is not replaced", n_file_copy_verified(src, dst, NULL) == FALSE);
expect_true("and is still equal after the refusal", n_file_same_content(src, dst) == TRUE);
/* Same size, one byte different. */
f = fopen(other, "wb");
if (f) {
for (i = 0; i < 800000; i++) fputc(i == 500000 ? 0 : (int)((i * 7 + i / 13) & 0xff), f); /* 29 there in the original */
fclose(f);
}
expect_true("one byte different is different", n_file_same_content(src, other) == FALSE);
remove(other);
remove(dst);
expect_true("a missing source fails", n_file_copy_verified(other, dst, NULL) == FALSE);
expect_true("and leaves nothing", !there(dst) && !there(part));
expect_true("a NULL is refused", n_file_copy_verified(NULL, dst, NULL) == FALSE);
{
/* Room where the file was written, read through the file and
* through its folder: one filesystem, so the same within what other
* processes write between the two calls. */
uint64_t by_file = 0, by_folder = 0, gone = 1;
char missing[600];
expect_true("free space through a file", n_file_free_space(src, &by_file) == TRUE && by_file > 0);
expect_true("free space through its folder", n_file_free_space(tmp, &by_folder) == TRUE && by_folder > 0);
expect_true("the same filesystem, the same room",
(by_file > by_folder ? by_file - by_folder : by_folder - by_file) < ((uint64_t)64 << 20));
snprintf(missing, sizeof(missing), "%s/ex_file_copy_%d.none/below", tmp, (int)getpid());
expect_true("a path that is not there fails", n_file_free_space(missing, &gone) == FALSE && gone == 0);
expect_true("a NULL is refused", n_file_free_space(NULL, &gone) == FALSE);
n_log(LOG_NOTICE, "free space in %s: %llu MB", tmp, (unsigned long long)(by_folder >> 20));
}
remove(src);
remove(dst);
n_log(LOG_NOTICE, "ex_file_copy: %s", failures ? "FAILED" : "ok");
return failures ? 1 : 0;
}
_Filename: ex_file_copy.c_
Modules
- AABB3D
- ACCEPT_POOL
- ALLEGRO4
- ALLEGRO5
- ANIM_LIB
- ASTAR
- ATLAS_LIB
- AVRO
- CLOCK_SYNC
- COMMONS
- CONFIGFILE
- CYPHER_BASE64
- CYPHER_VIGENERE
- DEAD_RECKONING
- ENUMS
- EXCEPTIONS
- GAME_ENV
- GIT
- GUI
- HASH_TABLE
- ISOMETRIC_ENGINE
- LIST
- LOG
- LOGNODUP
- LZ4
- NETWORKING
- NETWORK_MSG
- N_COOKIES
- N_DIFF
- N_DIGEST
- N_DISK_CACHE
- N_DNS
- N_ECC
- N_ENTROPY
- N_FILES
- N_FLUIDS
- N_GUI_COLOR
- N_GUI_COLORWHEEL
- N_GUI_CURVE
- N_GUI_GRID
- N_GUI_POPUP
- N_HEX
- N_HTTP3
- N_HTTP_COOKIE
- N_HTTP_FORM
- N_HTTP_MIME
- N_HTTP_REQ
- N_HTTP_RESP
- N_HTTP_ROUTER
- N_HTTP_SERVER
- N_ICC
- N_JSON
- N_KAFKA
- N_LINALG
- N_MODULE
- N_OPENSSL_COMPAT
- N_PRETTY
- N_PTH
- N_QUERY
- N_RANDOM
- N_SHA256
- N_STR
- N_TIFF
- N_TIME
- N_USER
- N_X509
- N_ZIP
- PARTICLES
- PCRE
- PHYSICS
- SIGNALS
- STACK
- THREADS
- TRAJECTORY
- TREE
- ZLIB