lazysphere/command/sync.c

83 lines
1.5 KiB
C
Raw Normal View History

2023-05-12 22:35:41 +00:00
#include "command.h"
#include "lslib.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
static struct {
bool sync_fs;
bool sync_data;
} flags;
static void help (void) {
printf("Usage: sync [-df] [FILE]...\n\n");
printf("Write all buffered blocks (in FILEs) to disk\n\n");
printf("\t-d\tAvoid syncing metadata\n");
#ifdef _GNU_SOURCE
printf("\t-f\tSync filesystems underlying FILEs\n");
#endif
}
static int short_arg (char c, char* next) {
UNUSED(next);
switch (c) {
case 'd':
flags.sync_data = true;
break;
#ifdef _GNU_SOURCE
case 'f':
flags.sync_fs = true;
break;
#endif
default:
return ARG_INVALID;
}
return ARG_UNUSED;
}
static bool sync_file(char* path) {
int fd;
int ret;
fd = open(path, O_NOCTTY | O_RDONLY | O_NONBLOCK);
if (fd < 0) {
return false;
}
if (flags.sync_fs) {
#ifdef _GNU_SOURCE
ret = syncfs(fd) >= 0;
#else
ret = 0;
#endif
} else {
ret = flags.sync_data ? fdatasync(fd) : fsync(fd);
if (ret < 0) {
2023-05-15 01:43:02 +00:00
error_s("failed to sync '%s'", path);
2023-05-12 22:35:41 +00:00
}
}
close(fd);
return ret;
}
COMMAND(sync_cmd) {
int start, i, ret = EXIT_SUCCESS;
start = parse_args(argc, argv, help, short_arg, NULL);
if (argc - start < 1) {
sync();
return EXIT_SUCCESS;
}
for (i = start; i < argc; i++) {
if (!sync_file(argv[i])) ret = EXIT_FAILURE;
}
return ret;
}