logo

utils-std

Collection of commonly available Unix tools
commit: a993092bcd87f3f1c636d3667fcaf9411b106a4e
parent b27b9ab570f546ba313ec35f5c22af23d68af000
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat, 27 Jul 2024 23:59:17 +0200

cmd/sync: Add hook to fsync() and fdatasync()

Diffstat:

Mcmd/sync.119+++++++++++++++----
Mcmd/sync.c82++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/cmd/sync.1 b/cmd/sync.1 @@ -1,7 +1,7 @@ .\" utils-std: Collection of commonly available Unix tools .\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> .\" SPDX-License-Identifier: MPL-2.0 -.Dd 2021-12-27 +.Dd 2024-07-28 .Dt SYNC 1 .Os .Sh NAME @@ -9,13 +9,24 @@ .Nd Schedule file system updates .Sh SYNOPSIS .Nm +.Op Fl d +.Op Ar file... .Sh DESCRIPTION -.Nm -shall cause all information in memory that updates file systems to be scheduled for writing out to all file systems. +Schedule cached writes to filesystems. +If any +.Ar file +is specified, only those files are scheduled, otherwise all filesystems are synchronized. +.Sh OPTIONS +.Bl -tag -width _d +.It Fl d +Sync only file data, not metadata. +.El .Sh EXIT STATUS .Ex -std .Sh SEE ALSO -.Xr sync 2 +.Xr sync 2 , +.Xr fdatasync 2 , +.Xr fsync 2 . .Sh STANDARDS No applicable one known. .Sh AUTHORS diff --git a/cmd/sync.c b/cmd/sync.c @@ -2,13 +2,85 @@ // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> // SPDX-License-Identifier: MPL-2.0 -#define _XOPEN_SOURCE 700 // XSI but not mere POSIX -#include <unistd.h> // sync() +#define _POSIX_C_SOURCE 200809L +#define _XOPEN_SOURCE 700 // sync + +#include <errno.h> +#include <fcntl.h> // open, O_* +#include <stdbool.h> +#include <stdio.h> // fprintf +#include <stdlib.h> // abort +#include <string.h> // strerror +#include <unistd.h> // fsync, sync, getopt int -main(void) +main(int argc, char *argv[]) { - // Maybe consider hooking up to fsync(3p) - sync(); + bool optd = false; + + int c = -1; + while((c = getopt(argc, argv, ":d")) != -1) + { + switch(c) + { + case 'd': + optd = true; + break; + case '?': + fprintf(stderr, "sync: Unrecognized option '-%c'\n", optopt); + break; + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + if(argc == 0) + { + sync(); + return 0; + } + + for(int i = 0; i < argc; i++) + { + int fd = open(argv[i], O_RDONLY); + if(fd < 0) + { + fprintf(stderr, "sync: Failed opening file '%s': %s\n", argv[i], strerror(errno)); + return 1; + } + + if(optd) + { + if(fdatasync(fd) < 0) + { + fprintf(stderr, + "sync: Failed synchronizing data changes of file '%s': %s\n", + argv[i], + strerror(errno)); + return 1; + } + } + else + { + if(fsync(fd) < 0) + { + fprintf(stderr, "sync: Failed synchronizing file '%s': %s\n", argv[i], strerror(errno)); + return 1; + } + } + + if(close(fd) < 0) + { + fprintf(stderr, + "sync: Failed closing file-descriptor of file '%s': %s\n", + argv[i], + strerror(errno)); + return 1; + } + } + return 0; }