1 /* Detecting file changes using modification times.
2 Copyright (C) 2017-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
24 #include <sys/types.h>
26 /* Items for identifying a particular file version. Excerpt from
28 struct file_change_detection
30 /* Special values: 0 if file does not exist. -1 to force mismatch
31 with the next comparison. */
35 struct timespec mtime
;
36 struct timespec ctime
;
39 /* Returns true if *LEFT and *RIGHT describe the same version of the
41 static bool __attribute__ ((unused
))
42 file_is_unchanged (const struct file_change_detection
*left
,
43 const struct file_change_detection
*right
)
45 if (left
->size
< 0 || right
->size
< 0)
46 /* Negative sizes are used as markers and never match. */
48 else if (left
->size
== 0 && right
->size
== 0)
49 /* Both files are empty or do not exist, so they have the same
50 content, no matter what the other fields indicate. */
53 return left
->size
== right
->size
54 && left
->ino
== right
->ino
55 && left
->mtime
.tv_sec
== right
->mtime
.tv_sec
56 && left
->mtime
.tv_nsec
== right
->mtime
.tv_nsec
57 && left
->ctime
.tv_sec
== right
->ctime
.tv_sec
58 && left
->ctime
.tv_nsec
== right
->ctime
.tv_nsec
;
61 /* Extract file change information to *FILE from the stat buffer
63 static void __attribute__ ((unused
))
64 file_change_detection_for_stat (struct file_change_detection
*file
,
65 const struct stat64
*st
)
67 if (S_ISDIR (st
->st_mode
))
68 /* Treat as empty file. */
70 else if (!S_ISREG (st
->st_mode
))
71 /* Non-regular files cannot be cached. */
75 file
->size
= st
->st_size
;
76 file
->ino
= st
->st_ino
;
77 file
->mtime
= st
->st_mtim
;
78 file
->ctime
= st
->st_ctim
;
82 /* Writes file change information for PATH to *FILE. Returns true on
83 success. For benign errors, *FILE is cleared, and true is
84 returned. For errors indicating resource outages and the like,
86 static bool __attribute__ ((unused
))
87 file_change_detection_for_path (struct file_change_detection
*file
,
91 if (stat64 (path
, &st
) != 0)
100 /* Ignore errors due to file system contents. Instead, treat
101 the file as empty. */
105 /* Other errors are fatal. */
108 else /* stat64 was successfull. */
110 file_change_detection_for_stat (file
, &st
);
115 /* Writes file change information for the stream FP to *FILE. Returns
116 ture on success, false on failure. If FP is NULL, treat the file
118 static bool __attribute__ ((unused
))
119 file_change_detection_for_fp (struct file_change_detection
*file
,
124 /* The file does not exist. */
131 if (fstat64 (__fileno (fp
), &st
) != 0)
132 /* If we already have a file descriptor, all errors are fatal. */
136 file_change_detection_for_stat (file
, &st
);