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:
M | cmd/sync.1 | 19 | +++++++++++++++---- |
M | cmd/sync.c | 82 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
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;
}