annotate lib/utimecmp.c @ 40235:5a52ef2d4772

all: Update URLs to msdn.microsoft.com. * lib/stat-w32.c et al.: Update URLs after most of msdn.microsoft.com was moved to docs.microsoft.com.
author Bruno Haible <bruno@clisp.org>
date Thu, 14 Mar 2019 09:49:24 +0100
parents b06060465f09
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
1 /* utimecmp.c -- compare file timestamps
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
2
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19595
diff changeset
3 Copyright (C) 2004-2007, 2009-2019 Free Software Foundation, Inc.
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
4
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8223
diff changeset
5 This program is free software: you can redistribute it and/or modify
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
9309
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8223
diff changeset
7 the Free Software Foundation; either version 3 of the License, or
bbbbbf4cd1c5 Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents: 8223
diff changeset
8 (at your option) any later version.
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
9
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
13 GNU General Public License for more details.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
14
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18842
diff changeset
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
17
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
18 /* Written by Paul Eggert. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
19
7302
8a1a9361108c * _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents: 7162
diff changeset
20 #include <config.h>
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
21
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
22 #include "utimecmp.h"
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
23
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
24 #include <fcntl.h>
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
25 #include <limits.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
26 #include <stdbool.h>
7162
19c2e5121b2f Add and change modules to make it easier for coreutils to use
Paul Eggert <eggert@cs.ucla.edu>
parents: 6323
diff changeset
27 #include <stdint.h>
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
28 #include <stdlib.h>
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
29 #include <sys/stat.h>
8223
ca249819379f * lib/getdate.h (includes): Include <time.h>, not "timespec.h".
Eric Blake <ebb9@byu.net>
parents: 7406
diff changeset
30 #include <time.h>
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
31 #include <unistd.h>
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
32
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
33 #include "dirname.h"
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
34 #include "hash.h"
5691
ec62790f0938 Factor int-properties macros into a single file, except for
Paul Eggert <eggert@cs.ucla.edu>
parents: 5148
diff changeset
35 #include "intprops.h"
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
36 #include "stat-time.h"
6323
af09cfa36fd5 * modules/exclude (Depends-on): Depend on verify.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
37 #include "verify.h"
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
38
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
39 #ifndef MAX
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
40 # define MAX(a, b) ((a) > (b) ? (a) : (b))
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
41 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
42
12727
fd5b0bf2a8e9 utimecmp: avoid new warning from upcoming gcc-4.5.0
Jim Meyering <meyering@redhat.com>
parents: 12559
diff changeset
43 #define BILLION (1000 * 1000 * 1000)
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
44
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
45 /* Best possible resolution that utimens can set and stat can return,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
46 due to system-call limitations. It must be a power of 10 that is
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
47 no greater than 1 billion. */
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
48 #if HAVE_UTIMENSAT
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
49 enum { SYSCALL_RESOLUTION = 1 };
19595
beb2ad957aca Simplify code. Drop support for Borland C++ on Windows.
Bruno Haible <bruno@clisp.org>
parents: 19534
diff changeset
50 #elif defined _WIN32 && ! defined __CYGWIN__
18842
3f720a2a9979 utimecmp: Add support for native Windows.
Bruno Haible <bruno@clisp.org>
parents: 18663
diff changeset
51 /* On native Windows, file times have 100 ns resolution. See
40235
5a52ef2d4772 all: Update URLs to msdn.microsoft.com.
Bruno Haible <bruno@clisp.org>
parents: 40057
diff changeset
52 <https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime> */
18842
3f720a2a9979 utimecmp: Add support for native Windows.
Bruno Haible <bruno@clisp.org>
parents: 18663
diff changeset
53 enum { SYSCALL_RESOLUTION = 100 };
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
54 #elif ((HAVE_FUTIMESAT || HAVE_WORKING_UTIMES) \
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
55 && (defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
56 || defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
57 || defined HAVE_STRUCT_STAT_ST_ATIMENSEC \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
58 || defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC \
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
59 || defined HAVE_STRUCT_STAT_ST_SPARE1))
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
60 enum { SYSCALL_RESOLUTION = 1000 };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
61 #else
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
62 enum { SYSCALL_RESOLUTION = BILLION };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
63 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
64
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
65 /* Describe a file system and its timestamp resolution in nanoseconds. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
66 struct fs_res
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
67 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
68 /* Device number of file system. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
69 dev_t dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
70
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
71 /* An upper bound on the timestamp resolution of this file system,
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
72 ignoring any resolution that cannot be set via utimens. It is
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
73 represented by an integer count of nanoseconds. It must be
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
74 either 2 billion, or a power of 10 that is no greater than a
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
75 billion and is no less than SYSCALL_RESOLUTION. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
76 int resolution;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
77
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
78 /* True if RESOLUTION is known to be exact, and is not merely an
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
79 upper bound on the true resolution. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
80 bool exact;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
81 };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
82
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
83 /* Hash some device info. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
84 static size_t
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
85 dev_info_hash (void const *x, size_t table_size)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
86 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
87 struct fs_res const *p = x;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
88
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
89 /* Beware signed arithmetic gotchas. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
90 if (TYPE_SIGNED (dev_t) && SIZE_MAX < MAX (INT_MAX, TYPE_MAXIMUM (dev_t)))
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
91 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
92 uintmax_t dev = p->dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
93 return dev % table_size;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
94 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
95
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
96 return p->dev % table_size;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
97 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
98
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
99 /* Compare two dev_info structs. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
100 static bool
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
101 dev_info_compare (void const *x, void const *y)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
102 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
103 struct fs_res const *a = x;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
104 struct fs_res const *b = y;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
105 return a->dev == b->dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
106 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
107
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
108 /* Return -1, 0, 1 based on whether the destination file (relative
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
109 to openat-like directory file descriptor DFD with name
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
110 DST_NAME and status DST_STAT) is older than SRC_STAT, the same age
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
111 as SRC_STAT, or newer than SRC_STAT, respectively.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
112
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
113 DST_NAME may be NULL if OPTIONS is 0.
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
114
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
115 If OPTIONS & UTIMECMP_TRUNCATE_SOURCE, do the comparison after SRC is
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
116 converted to the destination's timestamp resolution as filtered through
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
117 utimens. In this case, return -2 if the exact answer cannot be
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
118 determined; this can happen only if the timestamps are very close and
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
119 there is some trouble accessing the file system (e.g., the user does not
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
120 have permission to futz with the destination's timestamps). */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
121
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
122 int
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
123 utimecmp (char const *dst_name,
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
124 struct stat const *dst_stat,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
125 struct stat const *src_stat,
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
126 int options)
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
127 {
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
128 return utimecmpat (AT_FDCWD, dst_name, dst_stat, src_stat, options);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
129 }
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
130
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
131 int
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
132 utimecmpat (int dfd, char const *dst_name,
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
133 struct stat const *dst_stat,
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
134 struct stat const *src_stat,
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
135 int options)
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
136 {
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
137 /* Things to watch out for:
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
138
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
139 The code uses a static hash table internally and is not safe in the
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
140 presence of signals, multiple threads, etc. However, memory pressure
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
141 that prevents use of the hash table is not fatal - we just fall back
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
142 to redoing the computations on every call in that case.
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
143
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
144 int and long int might be 32 bits. Many of the calculations store
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
145 numbers up to 2 billion, and multiply by 10; they have to avoid
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
146 multiplying 2 billion by 10, as this exceeds 32-bit capabilities.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
147
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
148 time_t might be unsigned. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
149
6323
af09cfa36fd5 * modules/exclude (Depends-on): Depend on verify.
Paul Eggert <eggert@cs.ucla.edu>
parents: 6259
diff changeset
150 verify (TYPE_IS_INTEGER (time_t));
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
151
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
152 /* Destination and source timestamps. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
153 time_t dst_s = dst_stat->st_mtime;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
154 time_t src_s = src_stat->st_mtime;
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
155 int dst_ns = get_stat_mtime_ns (dst_stat);
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
156 int src_ns = get_stat_mtime_ns (src_stat);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
157
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
158 if (options & UTIMECMP_TRUNCATE_SOURCE)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
159 {
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
160 /* Look up the timestamp resolution for the destination device. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
161
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
162 /* Hash table for caching information learned about devices. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
163 static Hash_table *ht;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
164
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
165 /* Information about the destination file system. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
166 static struct fs_res *new_dst_res;
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
167 struct fs_res *dst_res = NULL;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
168 struct fs_res tmp_dst_res;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
169
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
170 /* timestamp resolution in nanoseconds. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
171 int res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
172
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
173 /* Quick exit, if possible. Since the worst resolution is 2
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
174 seconds, anything that differs by more than that does not
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
175 needs source truncation. */
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
176 if (dst_s == src_s && dst_ns == src_ns)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
177 return 0;
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
178 if (dst_s <= src_s - 2)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
179 return -1;
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
180 if (src_s <= dst_s - 2)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
181 return 1;
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
182
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
183 /* Try to do a hash lookup, but fall back to stack variables and
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
184 recomputation on low memory situations. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
185 if (! ht)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
186 ht = hash_initialize (16, NULL, dev_info_hash, dev_info_compare, free);
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
187 if (ht)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
188 {
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
189 if (! new_dst_res)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
190 {
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
191 new_dst_res = malloc (sizeof *new_dst_res);
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
192 if (!new_dst_res)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
193 goto low_memory;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
194 new_dst_res->resolution = 2 * BILLION;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
195 new_dst_res->exact = false;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
196 }
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
197 new_dst_res->dev = dst_stat->st_dev;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
198 dst_res = hash_insert (ht, new_dst_res);
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
199 if (! dst_res)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
200 goto low_memory;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
201
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
202 if (dst_res == new_dst_res)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
203 {
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
204 /* NEW_DST_RES is now in use in the hash table, so allocate a
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
205 new entry next time. */
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
206 new_dst_res = NULL;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
207 }
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
208 }
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
209 else
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
210 {
14642
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
211 low_memory:
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
212 if (ht)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
213 {
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
214 tmp_dst_res.dev = dst_stat->st_dev;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
215 dst_res = hash_lookup (ht, &tmp_dst_res);
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
216 }
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
217 if (!dst_res)
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
218 {
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
219 dst_res = &tmp_dst_res;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
220 dst_res->resolution = 2 * BILLION;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
221 dst_res->exact = false;
1e0bf20577a1 utimecmp: drop dependency on xmalloc
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
222 }
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
223 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
224
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
225 res = dst_res->resolution;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
226
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
227 #ifdef _PC_TIMESTAMP_RESOLUTION
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
228 /* If the system will tell us the resolution, we're set! */
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
229 if (! dst_res->exact)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
230 {
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
231 res = -1;
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
232 if (dfd == AT_FDCWD)
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
233 res = pathconf (dst_name, _PC_TIMESTAMP_RESOLUTION);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
234 else
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
235 {
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
236 char *dstdir = mdir_name (dst_name);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
237 if (dstdir)
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
238 {
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
239 int destdirfd = openat (dfd, dstdir,
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
240 O_SEARCH | O_CLOEXEC | O_DIRECTORY);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
241 if (0 <= destdirfd)
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
242 {
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
243 res = fpathconf (destdirfd, _PC_TIMESTAMP_RESOLUTION);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
244 close (destdirfd);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
245 }
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
246 free (dstdir);
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
247 }
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
248 }
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
249 if (0 < res)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
250 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
251 dst_res->resolution = res;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
252 dst_res->exact = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
253 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
254 }
12159
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
255 #endif
0ae159ba1adf utimecmp: support symlink timestamps
Eric Blake <ebb9@byu.net>
parents: 9309
diff changeset
256
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
257 if (! dst_res->exact)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
258 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
259 /* This file system's resolution is not known exactly.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
260 Deduce it, and store the result in the hash table. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
261
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
262 time_t dst_a_s = dst_stat->st_atime;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
263 time_t dst_c_s = dst_stat->st_ctime;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
264 time_t dst_m_s = dst_s;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
265 int dst_a_ns = get_stat_atime_ns (dst_stat);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
266 int dst_c_ns = get_stat_ctime_ns (dst_stat);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
267 int dst_m_ns = dst_ns;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
268
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
269 /* Set RES to an upper bound on the file system resolution
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
270 (after truncation due to SYSCALL_RESOLUTION) by inspecting
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
271 the atime, ctime and mtime of the existing destination.
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
272 We don't know of any file system that stores atime or
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
273 ctime with a higher precision than mtime, so it's valid to
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
274 look at them too. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
275 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
276 bool odd_second = (dst_a_s | dst_c_s | dst_m_s) & 1;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
277
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
278 if (SYSCALL_RESOLUTION == BILLION)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
279 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
280 if (odd_second | dst_a_ns | dst_c_ns | dst_m_ns)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
281 res = BILLION;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
282 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
283 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
284 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
285 int a = dst_a_ns;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
286 int c = dst_c_ns;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
287 int m = dst_m_ns;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
288
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
289 /* Write it this way to avoid mistaken GCC warning
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
290 about integer overflow in constant expression. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
291 int SR10 = SYSCALL_RESOLUTION; SR10 *= 10;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
292
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
293 if ((a % SR10 | c % SR10 | m % SR10) != 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
294 res = SYSCALL_RESOLUTION;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
295 else
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
296 for (res = SR10, a /= SR10, c /= SR10, m /= SR10;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
297 (res < dst_res->resolution
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
298 && (a % 10 | c % 10 | m % 10) == 0);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
299 res *= 10, a /= 10, c /= 10, m /= 10)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
300 if (res == BILLION)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
301 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
302 if (! odd_second)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
303 res *= 2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
304 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
305 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
306 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
307
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
308 dst_res->resolution = res;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
309 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
310
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
311 if (SYSCALL_RESOLUTION < res)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
312 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
313 struct timespec timespec[2];
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
314 struct stat dst_status;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
315
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
316 /* Ignore source timestamp information that must necessarily
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
317 be lost when filtered through utimens. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
318 src_ns -= src_ns % SYSCALL_RESOLUTION;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
319
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
320 /* If the timestamps disagree widely enough, there's no need
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
321 to interrogate the file system to deduce the exact
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
322 timestamp resolution; return the answer directly. */
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
323 {
18441
c204ad2f4289 utimecmp: avoid new GCC 7 warning from -Wbool-operation
Jim Meyering <meyering@fb.com>
parents: 18294
diff changeset
324 time_t s = src_s & ~ (res == 2 * BILLION ? 1 : 0);
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
325 if (src_s < dst_s || (src_s == dst_s && src_ns <= dst_ns))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
326 return 1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
327 if (dst_s < s
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
328 || (dst_s == s && dst_ns < src_ns - src_ns % res))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
329 return -1;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
330 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
331
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
332 /* Determine the actual timestamp resolution for the
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
333 destination file system (after truncation due to
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
334 SYSCALL_RESOLUTION) by setting the access timestamp of the
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
335 destination to the existing access time, except with
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
336 trailing nonzero digits. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
337
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
338 timespec[0].tv_sec = dst_a_s;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
339 timespec[0].tv_nsec = dst_a_ns;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
340 timespec[1].tv_sec = dst_m_s | (res == 2 * BILLION);
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
341 timespec[1].tv_nsec = dst_m_ns + res / 9;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
342
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
343 if (utimensat (dfd, dst_name, timespec, AT_SYMLINK_NOFOLLOW))
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
344 return -2;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
345
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
346 /* Read the modification time that was set. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
347 {
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
348 int stat_result
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
349 = fstatat (dfd, dst_name, &dst_status, AT_SYMLINK_NOFOLLOW);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
350
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
351 if (stat_result
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
352 | (dst_status.st_mtime ^ dst_m_s)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
353 | (get_stat_mtime_ns (&dst_status) ^ dst_m_ns))
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
354 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
355 /* The modification time changed, or we can't tell whether
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
356 it changed. Change it back as best we can. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
357 timespec[1].tv_sec = dst_m_s;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
358 timespec[1].tv_nsec = dst_m_ns;
19534
e64c6a43dc9c utimecmp: new function utimecmpat
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
359 utimensat (dfd, dst_name, timespec, AT_SYMLINK_NOFOLLOW);
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
360 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
361
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
362 if (stat_result != 0)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
363 return -2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
364 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
365
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
366 /* Determine the exact resolution from the modification time
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
367 that was read back. */
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
368 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
369 int old_res = res;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
370 int a = (BILLION * (dst_status.st_mtime & 1)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
371 + get_stat_mtime_ns (&dst_status));
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
372
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
373 res = SYSCALL_RESOLUTION;
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
374
13914
cc15a32c0446 utimecmp: fine-grained src to nearby coarse-grained dest
Paul Eggert <eggert@cs.ucla.edu>
parents: 12727
diff changeset
375 for (a /= res; a % 10 == 0; a /= 10)
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
376 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
377 if (res == BILLION)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
378 {
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
379 res *= 2;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
380 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
381 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
382 res *= 10;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
383 if (res == old_res)
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
384 break;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
385 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
386 }
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
387 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
388
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
389 dst_res->resolution = res;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
390 dst_res->exact = true;
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
391 }
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
392
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
393 /* Truncate the source's timestamp according to the resolution. */
18441
c204ad2f4289 utimecmp: avoid new GCC 7 warning from -Wbool-operation
Jim Meyering <meyering@fb.com>
parents: 18294
diff changeset
394 src_s &= ~ (res == 2 * BILLION ? 1 : 0);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
395 src_ns -= src_ns % res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
396 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
397
18663
caf9d6314c8f maint: time stamp -> timestamp
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
398 /* Compare the timestamps and return -1, 0, 1 accordingly. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
399 return (dst_s < src_s ? -1
12421
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
400 : dst_s > src_s ? 1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
401 : dst_ns < src_ns ? -1
e8d2c6fc33ad Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents: 12159
diff changeset
402 : dst_ns > src_ns);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
403 }