File: fileutil.c

package info (click to toggle)
tarsnap 1.0.41-3
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 3,712 kB
  • sloc: ansic: 50,148; sh: 1,025; makefile: 684; python: 661; awk: 345
file content (83 lines) | stat: -rw-r--r-- 1,684 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "platform.h"

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include "warnp.h"

#include "fileutil.h"

/**
 * fileutil_open_noatime(path, flags, noatime):
 * Act the same as open(2), except that if the OS supports O_NOATIME and
 * ${noatime} is non-zero, attempt to open the path with that set.  If the
 * O_NOATIME attempt fails, do not give any warnings, and attempt a normal
 * open().
 */
int
fileutil_open_noatime(const char * path, int flags, int noatime)
{
	int fd = -1;

#if defined(O_NOATIME)
	/* If requested, attempt to open with O_NOATIME. */
	if (noatime)
		fd = open(path, flags | O_NOATIME);
#else
	(void)noatime; /* UNUSED */
#endif

	/* If it failed (or wasn't supported / requested), open normally. */
	if ((fd == -1) && ((fd = open(path, flags)) == -1))
		goto err0;

	/* Success! */
	return (fd);

err0:
	/* Failure! */
	return (fd);
}

/**
 * fileutil_fsync(fp, name):
 * Attempt to write the contents of ${fp} to disk.  Do not close ${fp}.
 *
 * Caveat: "Disks lie" - Kirk McKusick.
 */
int
fileutil_fsync(FILE * fp, const char * name)
{
	int fd;

	if (fflush(fp)) {
		warnp("fflush(%s)", name);
		goto err0;
	}
	if ((fd = fileno(fp)) == -1) {
		warnp("fileno(%s)", name);
		goto err0;
	}
	if (fsync(fd)) {
		warnp("fsync(%s)", name);
		goto err0;
	}

#ifdef F_FULLFSYNC
	/*
	 * MacOS-specific "ask the drive to flush all buffered data".
	 * Not supported on all filesystems.  Even on supported filesystems,
	 * some FireWire drives are known to ignore this request.  As such,
	 * don't pay attention to the return code from fcntl().
	 */
	fcntl(fd, F_FULLFSYNC);
#endif

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}