annotate lib/utimecmp.c @ 6238:245950d70306

* utimecmp.c: Include stat-time.h. (SYSCALL_RESOLUTION): Depend on whether various struct stat members exist, not on the obsolescent ST_MTIM_NSEC. (utimecmp): Use the new stat-time functions rater than TIMESPEC_NS.
author Paul Eggert <eggert@cs.ucla.edu>
date Fri, 16 Sep 2005 07:16:21 +0000
parents a48fb0e98c8c
children 96c32553b4c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
1 /* utimecmp.c -- compare file time stamps
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
2
5691
ec62790f0938 Factor int-properties macros into a single file, except for
Paul Eggert <eggert@cs.ucla.edu>
parents: 5148
diff changeset
3 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
4
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
5 This program is free software; you can redistribute it and/or modify
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
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
7 the Free Software Foundation; either version 2, or (at your option)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
8 any later version.
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
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
16 along with this program; if not, write to the Free Software Foundation,
5848
a48fb0e98c8c *** empty log message ***
Paul Eggert <eggert@cs.ucla.edu>
parents: 5691
diff changeset
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
18
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
19 /* Written by Paul Eggert. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
20
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
21 #if HAVE_CONFIG_H
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
22 # include <config.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
23 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
24
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
25 #include "utimecmp.h"
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
26
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
27 #if HAVE_INTTYPES_H
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
28 # include <inttypes.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
29 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
30 #if HAVE_STDINT_H
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
31 # include <stdint.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
32 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
33
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
34 #include <limits.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
35 #include <stdbool.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
36 #include <stdlib.h>
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
37 #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
38 #include "intprops.h"
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
39 #include "stat-time.h"
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
40 #include "timespec.h"
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
41 #include "utimens.h"
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
42 #include "xalloc.h"
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
43
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
44 /* Verify a requirement at compile-time (unlike assert, which is runtime). */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
45 #define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
46
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
47 #ifndef MAX
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
48 # define MAX(a, b) ((a) > (b) ? (a) : (b))
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
49 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
50
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
51 #ifndef SIZE_MAX
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
52 # define SIZE_MAX ((size_t) -1)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
53 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
54
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
55 enum { BILLION = 1000 * 1000 * 1000 };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
56
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
57 /* Best possible resolution that utimens can set and stat can return,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
58 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
59 no greater than 1 billion. */
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
60 #if (HAVE_WORKING_UTIMES \
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
61 && (defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC \
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
62 || defined HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC \
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
63 || defined HAVE_STRUCT_STAT_ST_ATIMENSEC \
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
64 || defined HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC \
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
65 || defined HAVE_STRUCT_STAT_ST_SPARE1))
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
66 enum { SYSCALL_RESOLUTION = 1000 };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
67 #else
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
68 enum { SYSCALL_RESOLUTION = BILLION };
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
69 #endif
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
70
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
71 /* Describe a file system and its time stamp resolution in nanoseconds. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
72 struct fs_res
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
73 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
74 /* Device number of file system. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
75 dev_t dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
76
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
77 /* An upper bound on the time stamp resolution of this file system,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
78 ignoring any resolution that cannot be set via utimens. It is
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
79 represented by an integer count of nanoseconds. It must be
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
80 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
81 billion and is no less than SYSCALL_RESOLUTION. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
82 int resolution;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
83
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
84 /* 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
85 upper bound on the true resolution. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
86 bool exact;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
87 };
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 /* Hash some device info. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
90 static size_t
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
91 dev_info_hash (void const *x, size_t table_size)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
92 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
93 struct fs_res const *p = x;
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 /* Beware signed arithmetic gotchas. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
96 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
97 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
98 uintmax_t dev = p->dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
99 return dev % table_size;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
100 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
101
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
102 return p->dev % table_size;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
103 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
104
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
105 /* Compare two dev_info structs. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
106 static bool
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
107 dev_info_compare (void const *x, void const *y)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
108 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
109 struct fs_res const *a = x;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
110 struct fs_res const *b = y;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
111 return a->dev == b->dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
112 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
113
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
114 /* Return -1, 0, 1 based on whether the destination file (with name
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
115 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
116 as SRC_STAT, or newer than SRC_STAT, respectively.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
117
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
118 If OPTIONS & UTIMECMP_TRUNCATE_SOURCE, do the comparison after SRC is
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
119 converted to the destination's timestamp resolution as filtered through
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
120 utimens. In this case, return -2 if the exact answer cannot be
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
121 determined; this can happen only if the time stamps are very close and
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
122 there is some trouble accessing the file system (e.g., the user does not
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
123 have permission to futz with the destination's time stamps). */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
124
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
125 int
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
126 utimecmp (char const *dst_name,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
127 struct stat const *dst_stat,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
128 struct stat const *src_stat,
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
129 int options)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
130 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
131 /* Things to watch out for:
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
132
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
133 The code uses a static hash table internally and is not safe in the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
134 presence of signals, multiple threads, etc.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
135
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
136 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
137 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
138 multiplying 2 billion by 10, as this exceeds 32-bit capabilities.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
139
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
140 time_t might be unsigned. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
141
5691
ec62790f0938 Factor int-properties macros into a single file, except for
Paul Eggert <eggert@cs.ucla.edu>
parents: 5148
diff changeset
142 verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
ec62790f0938 Factor int-properties macros into a single file, except for
Paul Eggert <eggert@cs.ucla.edu>
parents: 5148
diff changeset
143 verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
144
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
145 /* Destination and source time stamps. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
146 time_t dst_s = dst_stat->st_mtime;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
147 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
148 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
149 int src_ns = get_stat_mtime_ns (src_stat);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
150
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
151 if (options & UTIMECMP_TRUNCATE_SOURCE)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
152 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
153 /* Look up the time stamp resolution for the destination device. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
154
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
155 /* Hash table for devices. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
156 static Hash_table *ht;
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 /* Information about the destination file system. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
159 static struct fs_res *new_dst_res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
160 struct fs_res *dst_res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
161
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
162 /* Time stamp resolution in nanoseconds. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
163 int res;
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 if (! ht)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
166 ht = hash_initialize (16, NULL, dev_info_hash, dev_info_compare, free);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
167 if (! new_dst_res)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
168 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
169 new_dst_res = xmalloc (sizeof *new_dst_res);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
170 new_dst_res->resolution = 2 * BILLION;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
171 new_dst_res->exact = false;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
172 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
173 new_dst_res->dev = dst_stat->st_dev;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
174 dst_res = hash_insert (ht, new_dst_res);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
175 if (! dst_res)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
176 xalloc_die ();
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
177
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
178 if (dst_res == new_dst_res)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
179 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
180 /* NEW_DST_RES is now in use in the hash table, so allocate a
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
181 new entry next time. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
182 new_dst_res = NULL;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
183 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
184
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
185 res = dst_res->resolution;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
186
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
187 if (! dst_res->exact)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
188 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
189 /* This file system's resolution is not known exactly.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
190 Deduce it, and store the result in the hash table. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
191
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
192 time_t dst_a_s = dst_stat->st_atime;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
193 time_t dst_c_s = dst_stat->st_ctime;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
194 time_t dst_m_s = dst_s;
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
195 int dst_a_ns = get_stat_atime_ns (dst_stat);
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
196 int dst_c_ns = get_stat_ctime_ns (dst_stat);
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
197 int dst_m_ns = dst_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
198
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
199 /* Set RES to an upper bound on the file system resolution
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
200 (after truncation due to SYSCALL_RESOLUTION) by inspecting
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
201 the atime, ctime and mtime of the existing destination.
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
202 We don't know of any file system that stores atime or
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
203 ctime with a higher precision than mtime, so it's valid to
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
204 look at them too. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
205 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
206 bool odd_second = (dst_a_s | dst_c_s | dst_m_s) & 1;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
207
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
208 if (SYSCALL_RESOLUTION == BILLION)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
209 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
210 if (odd_second | dst_a_ns | dst_c_ns | dst_m_ns)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
211 res = BILLION;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
212 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
213 else
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
214 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
215 int a = dst_a_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
216 int c = dst_c_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
217 int m = dst_m_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
218
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
219 /* Write it this way to avoid mistaken GCC warning
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
220 about integer overflow in constant expression. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
221 int SR10 = SYSCALL_RESOLUTION; SR10 *= 10;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
222
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
223 if ((a % SR10 | c % SR10 | m % SR10) != 0)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
224 res = SYSCALL_RESOLUTION;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
225 else
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
226 for (res = SR10, a /= SR10, c /= SR10, m /= SR10;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
227 (res < dst_res->resolution
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
228 && (a % 10 | c % 10 | m % 10) == 0);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
229 res *= 10, a /= 10, c /= 10, m /= 10)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
230 if (res == BILLION)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
231 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
232 if (! odd_second)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
233 res *= 2;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
234 break;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
235 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
236 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
237
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
238 dst_res->resolution = res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
239 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
240
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
241 if (SYSCALL_RESOLUTION < res)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
242 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
243 struct timespec timespec[2];
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
244 struct stat dst_status;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
245
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
246 /* Ignore source time stamp information that must necessarily
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
247 be lost when filtered through utimens. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
248 src_ns -= src_ns % SYSCALL_RESOLUTION;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
249
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
250 /* If the time stamps disagree widely enough, there's no need
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
251 to interrogate the file system to deduce the exact time
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
252 stamp resolution; return the answer directly. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
253 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
254 time_t s = src_s & ~ (res == 2 * BILLION);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
255 if (src_s < dst_s || (src_s == dst_s && src_ns <= dst_ns))
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
256 return 1;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
257 if (dst_s < s
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
258 || (dst_s == s && dst_ns < src_ns - src_ns % res))
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
259 return -1;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
260 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
261
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
262 /* Determine the actual time stamp resolution for the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
263 destination file system (after truncation due to
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
264 SYSCALL_RESOLUTION) by setting the access time stamp of the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
265 destination to the existing access time, except with
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
266 trailing nonzero digits. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
267
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
268 timespec[0].tv_sec = dst_a_s;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
269 timespec[0].tv_nsec = dst_a_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
270 timespec[1].tv_sec = dst_m_s | (res == 2 * BILLION);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
271 timespec[1].tv_nsec = dst_m_ns + res / 9;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
272
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
273 /* Set the modification time. But don't try to set the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
274 modification time of symbolic links; on many hosts this sets
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
275 the time of the pointed-to file. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
276 if (S_ISLNK (dst_stat->st_mode)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
277 || utimens (dst_name, timespec) != 0)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
278 return -2;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
279
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
280 /* Read the modification time that was set. It's safe to call
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
281 'stat' here instead of worrying about 'lstat'; either the
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
282 caller used 'stat', or the caller used 'lstat' and found
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
283 something other than a symbolic link. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
284 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
285 int stat_result = stat (dst_name, &dst_status);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
286
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
287 if (stat_result
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
288 | (dst_status.st_mtime ^ dst_m_s)
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
289 | (get_stat_mtime_ns (&dst_status) ^ dst_m_ns))
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
290 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
291 /* The modification time changed, or we can't tell whether
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
292 it changed. Change it back as best we can. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
293 timespec[1].tv_sec = dst_m_s;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
294 timespec[1].tv_nsec = dst_m_ns;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
295 utimens (dst_name, timespec);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
296 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
297
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
298 if (stat_result != 0)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
299 return -2;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
300 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
301
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
302 /* Determine the exact resolution from the modification time
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
303 that was read back. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
304 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
305 int old_res = res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
306 int a = (BILLION * (dst_status.st_mtime & 1)
6238
245950d70306 * utimecmp.c: Include stat-time.h.
Paul Eggert <eggert@cs.ucla.edu>
parents: 5848
diff changeset
307 + get_stat_mtime_ns (&dst_status));
5148
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
308
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
309 res = SYSCALL_RESOLUTION;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
310
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
311 for (a /= res; a % 10 != 0; a /= 10)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
312 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
313 if (res == BILLION)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
314 {
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
315 res *= 2;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
316 break;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
317 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
318 res *= 10;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
319 if (res == old_res)
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
320 break;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
321 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
322 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
323 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
324
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
325 dst_res->resolution = res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
326 dst_res->exact = true;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
327 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
328
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
329 /* Truncate the source's time stamp according to the resolution. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
330 src_s &= ~ (res == 2 * BILLION);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
331 src_ns -= src_ns % res;
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
332 }
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
333
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
334 /* Compare the time stamps and return -1, 0, 1 accordingly. */
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
335 return (dst_s < src_s ? -1
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
336 : dst_s > src_s ? 1
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
337 : dst_ns < src_ns ? -1
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
338 : dst_ns > src_ns);
a7cf26af736e Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents:
diff changeset
339 }