|
1 Changes to implement: |
|
2 16575074 stat could support birthtime/crtime on ZFS |
|
3 |
|
4 These changes have already been accepted upstream. See: |
|
5 http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=ea916c70a5fc47ee6036a05416bc7462fd8dc1cd |
|
6 |
|
7 --- coreutils-8.16/configure.ac.orig 2014-03-18 20:12:23.362356112 -0700 |
|
8 +++ coreutils-8.16/configure.ac 2014-03-18 20:13:47.327463395 -0700 |
|
9 @@ -240,6 +240,13 @@ |
|
10 AC_DEFINE([LOCALTIME_CACHE], [1], [FIXME]) |
|
11 fi |
|
12 |
|
13 +# Assume that if getattrat exists, it's compatible with Solaris 11. |
|
14 +AC_CHECK_FUNCS([getattrat]) |
|
15 +if test $ac_cv_func_getattrat = yes; then |
|
16 + LIB_NVPAIR=-lnvpair |
|
17 + AC_SUBST([LIB_NVPAIR]) |
|
18 +fi |
|
19 + |
|
20 # SCO-ODT-3.0 is reported to need -los to link programs using initgroups |
|
21 AC_CHECK_FUNCS([initgroups]) |
|
22 if test $ac_cv_func_initgroups = no; then |
|
23 --- coreutils-8.16/src/Makefile.am.orig 2014-03-18 20:19:34.447566111 -0700 |
|
24 +++ coreutils-8.16/src/Makefile.am 2014-03-18 20:20:20.876086076 -0700 |
|
25 @@ -326,6 +326,9 @@ |
|
26 runcon_LDADD += $(LIB_SELINUX) |
|
27 stat_LDADD += $(LIB_SELINUX) |
|
28 |
|
29 +# for nvlist_lookup_uint64_array |
|
30 +stat_LDADD += $(LIB_NVPAIR) |
|
31 + |
|
32 # for gettime, settime, utimecmp, utimens |
|
33 copy_LDADD += $(LIB_CLOCK_GETTIME) |
|
34 date_LDADD += $(LIB_CLOCK_GETTIME) |
|
35 --- coreutils-8.16/src/stat.c.orig 2014-03-16 16:55:52.605732676 -0700 |
|
36 +++ coreutils-8.16/src/stat.c 2014-03-18 20:27:04.302699124 -0700 |
|
37 @@ -148,6 +148,11 @@ |
|
38 # endif |
|
39 #endif |
|
40 |
|
41 +#if HAVE_GETATTRAT |
|
42 +# include <attr.h> |
|
43 +# include <sys/nvpair.h> |
|
44 +#endif |
|
45 + |
|
46 /* FIXME: these are used by printf.c, too */ |
|
47 #define isodigit(c) ('0' <= (c) && (c) <= '7') |
|
48 #define octtobin(c) ((c) - '0') |
|
49 @@ -689,7 +694,7 @@ |
|
50 /* Print statfs info. Return zero upon success, nonzero upon failure. */ |
|
51 static bool ATTRIBUTE_WARN_UNUSED_RESULT |
|
52 print_statfs (char *pformat, size_t prefix_len, unsigned int m, |
|
53 - char const *filename, |
|
54 + int fd, char const *filename, |
|
55 void const *data) |
|
56 { |
|
57 STRUCT_STATVFS const *statfsbuf = data; |
|
58 @@ -861,6 +866,38 @@ |
|
59 return fail; |
|
60 } |
|
61 |
|
62 +static struct timespec |
|
63 +get_birthtime (int fd, char const *filename, struct stat const *st) |
|
64 +{ |
|
65 + struct timespec ts = get_stat_birthtime (st); |
|
66 + |
|
67 +#if HAVE_GETATTRAT |
|
68 + if (ts.tv_nsec < 0) |
|
69 + { |
|
70 + nvlist_t *response; |
|
71 + if ((fd < 0 |
|
72 + ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response) |
|
73 + : fgetattr (fd, XATTR_VIEW_READWRITE, &response)) |
|
74 + == 0) |
|
75 + { |
|
76 + uint64_t *val; |
|
77 + uint_t n; |
|
78 + if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0 |
|
79 + && 2 <= n |
|
80 + && val[0] <= TYPE_MAXIMUM (time_t) |
|
81 + && val[1] < 1000000000 * 2 /* for leap seconds */) |
|
82 + { |
|
83 + ts.tv_sec = val[0]; |
|
84 + ts.tv_nsec = val[1]; |
|
85 + } |
|
86 + nvlist_free (response); |
|
87 + } |
|
88 + } |
|
89 +#endif |
|
90 + |
|
91 + return ts; |
|
92 +} |
|
93 + |
|
94 /* Map a TS with negative TS.tv_nsec to {0,0}. */ |
|
95 static inline struct timespec |
|
96 neg_to_zero (struct timespec ts) |
|
97 @@ -874,7 +911,7 @@ |
|
98 /* Print stat info. Return zero upon success, nonzero upon failure. */ |
|
99 static bool |
|
100 print_stat (char *pformat, size_t prefix_len, unsigned int m, |
|
101 - char const *filename, void const *data) |
|
102 + int fd, char const *filename, void const *data) |
|
103 { |
|
104 struct stat *statbuf = (struct stat *) data; |
|
105 struct passwd *pw_ent; |
|
106 @@ -967,7 +1004,7 @@ |
|
107 break; |
|
108 case 'w': |
|
109 { |
|
110 - struct timespec t = get_stat_birthtime (statbuf); |
|
111 + struct timespec t = get_birthtime (fd, filename, statbuf); |
|
112 if (t.tv_nsec < 0) |
|
113 out_string (pformat, prefix_len, "-"); |
|
114 else |
|
115 @@ -976,7 +1013,7 @@ |
|
116 break; |
|
117 case 'W': |
|
118 out_epoch_sec (pformat, prefix_len, statbuf, |
|
119 - neg_to_zero (get_stat_birthtime (statbuf))); |
|
120 + neg_to_zero (get_birthtime (fd, filename, statbuf))); |
|
121 break; |
|
122 case 'x': |
|
123 out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf))); |
|
124 @@ -1051,9 +1088,9 @@ |
|
125 calling PRINT_FUNC for each %-directive encountered. |
|
126 Return zero upon success, nonzero upon failure. */ |
|
127 static bool ATTRIBUTE_WARN_UNUSED_RESULT |
|
128 -print_it (char const *format, char const *filename, |
|
129 +print_it (char const *format, int fd, char const *filename, |
|
130 bool (*print_func) (char *, size_t, unsigned int, |
|
131 - char const *, void const *), |
|
132 + int, char const *, void const *), |
|
133 void const *data) |
|
134 { |
|
135 bool fail = false; |
|
136 @@ -1102,7 +1139,8 @@ |
|
137 putchar ('%'); |
|
138 break; |
|
139 default: |
|
140 - fail |= print_func (dest, len + 1, fmt_code, filename, data); |
|
141 + fail |= print_func (dest, len + 1, fmt_code, |
|
142 + fd, filename, data); |
|
143 break; |
|
144 } |
|
145 break; |
|
146 @@ -1185,7 +1223,7 @@ |
|
147 return false; |
|
148 } |
|
149 |
|
150 - bool fail = print_it (format, filename, print_statfs, &statfsbuf); |
|
151 + bool fail = print_it (format, -1, filename, print_statfs, &statfsbuf); |
|
152 return ! fail; |
|
153 } |
|
154 |
|
155 @@ -1194,11 +1232,12 @@ |
|
156 do_stat (char const *filename, char const *format, |
|
157 char const *format2) |
|
158 { |
|
159 + int fd = STREQ (filename, "-") ? 0 : -1; |
|
160 struct stat statbuf; |
|
161 |
|
162 - if (STREQ (filename, "-")) |
|
163 + if (0 <= fd) |
|
164 { |
|
165 - if (fstat (STDIN_FILENO, &statbuf) != 0) |
|
166 + if (fstat (fd, &statbuf) != 0) |
|
167 { |
|
168 error (0, errno, _("cannot stat standard input")); |
|
169 return false; |
|
170 @@ -1218,7 +1257,7 @@ |
|
171 if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode)) |
|
172 format = format2; |
|
173 |
|
174 - bool fail = print_it (format, filename, print_stat, &statbuf); |
|
175 + bool fail = print_it (format, fd, filename, print_stat, &statbuf); |
|
176 return ! fail; |
|
177 } |
|
178 |