diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-26 17:41:30 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-08-17 10:08:48 +0200 |
commit | 235be6bcea86304e7538d1ff720b14beca2914e8 (patch) | |
tree | 0945ef80029fcbbd871113a35aac7074603d53c6 /src/test/test-install-file.c | |
parent | 78c23b065f11e524c6730d5afcdba0c3c8129b76 (diff) | |
download | systemd-235be6bcea86304e7538d1ff720b14beca2914e8.tar.gz |
shared: add generic helper tools for installing files/dir trees
This adds a bit of generic helper tools for installing files/dir trees.
"installing" is supposed to mean the final step when preparing a disk
image or directory tree, where the result is renamed to its final name.
It has some bells and whistles, as it is able to replace existing files
sanely, can fsync() things carefully and can mark things read-only in a
nice way.
This is supposed to be generic, unified code that can be used eventually
for any of our tools that prepare disk images/directory trees, including
importd, nspawn's --template= mechanism, the discover-image.c logic,
and more.
Diffstat (limited to 'src/test/test-install-file.c')
-rw-r--r-- | src/test/test-install-file.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/test/test-install-file.c b/src/test/test-install-file.c new file mode 100644 index 0000000000..55d77ac236 --- /dev/null +++ b/src/test/test-install-file.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "fileio.h" +#include "install-file.h" +#include "path-util.h" +#include "rm-rf.h" +#include "tests.h" +#include "tmpfile-util.h" +#include "umask-util.h" + +static void test_install_file(void) { + _cleanup_(rm_rf_physical_and_freep) char *p = NULL; + _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL; + struct stat stat1, stat2; + + log_info("/* %s */", __func__); + + assert_se(mkdtemp_malloc(NULL, &p) >= 0); + assert_se(a = path_join(p, "foo")); + assert_se(b = path_join(p, "bar")); + + RUN_WITH_UMASK(0077) + assert_se(write_string_file(a, "wups", WRITE_STRING_FILE_CREATE) >= 0); + + assert_se(lstat(a, &stat1) >= 0); + assert_se(S_ISREG(stat1.st_mode)); + + assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, 0) >= 0); + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC) >= 0); + + assert_se(write_string_file(b, "ttss", WRITE_STRING_FILE_CREATE) >= 0); + assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, INSTALL_FSYNC_FULL) == -EEXIST); + assert_se(install_file(AT_FDCWD, a, AT_FDCWD, b, INSTALL_FSYNC_FULL|INSTALL_REPLACE) >= 0); + + assert_se(stat(b, &stat2) >= 0); + assert_se(stat1.st_dev == stat2.st_dev); + assert_se(stat1.st_ino == stat2.st_ino); + assert_se((stat2.st_mode & 0222) != 0); /* writable */ + + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE|INSTALL_READ_ONLY) >= 0); + + assert_se(stat(a, &stat2) >= 0); + assert_se(stat1.st_dev == stat2.st_dev); + assert_se(stat1.st_ino == stat2.st_ino); + assert_se((stat2.st_mode & 0222) == 0); /* read-only */ + + assert_se(mkdir(b, 0755) >= 0); + assert_se(c = path_join(b, "dir")); + assert_se(mkdir(c, 0755) >= 0); + free(c); + assert_se(c = path_join(b, "reg")); + assert_se(mknod(c, S_IFREG|0755, 0) >= 0); + free(c); + assert_se(c = path_join(b, "fifo")); + assert_se(mknod(c, S_IFIFO|0755, 0) >= 0); + + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL) == -EEXIST); + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE) == 0); + + assert_se(write_string_file(b, "ttss", WRITE_STRING_FILE_CREATE) >= 0); + + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL) == -EEXIST); + assert_se(install_file(AT_FDCWD, b, AT_FDCWD, a, INSTALL_FSYNC_FULL|INSTALL_REPLACE) == 0); +} + +int main(int argc, char *argv[]) { + test_setup_logging(LOG_INFO); + + test_install_file(); + + return 0; +} |