]>
Commit | Line | Data |
---|---|---|
1cab5444 | 1 | /* Convert between the kernel's `struct stat' format, and libc's. |
bfff8b1b | 2 | Copyright (C) 1991-2017 Free Software Foundation, Inc. |
1cab5444 UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
1cab5444 UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
1cab5444 | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
1cab5444 | 18 | |
9c7ff11a UD |
19 | #include <errno.h> |
20 | #include <sys/stat.h> | |
21 | #include <kernel_stat.h> | |
f8de5057 | 22 | #include <kernel-features.h> |
9c7ff11a | 23 | |
c84d1f2e RM |
24 | #ifdef STAT_IS_KERNEL_STAT |
25 | ||
26 | /* Dummy. */ | |
27 | struct kernel_stat; | |
28 | ||
29 | #else | |
30 | ||
1cab5444 UD |
31 | #include <string.h> |
32 | ||
33 | ||
d2e1e973 | 34 | #if XSTAT_IS_XSTAT64 |
9c7ff11a UD |
35 | int |
36 | __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) | |
1cab5444 UD |
37 | { |
38 | switch (vers) | |
39 | { | |
40 | case _STAT_VER_KERNEL: | |
41 | /* Nothing to do. The struct is in the form the kernel expects. | |
42 | We should have short-circuted before we got here, but for | |
43 | completeness... */ | |
cc3fa755 | 44 | *(struct kernel_stat *) ubuf = *kbuf; |
1cab5444 UD |
45 | break; |
46 | ||
47 | case _STAT_VER_LINUX: | |
48 | { | |
49 | struct stat *buf = ubuf; | |
50 | ||
51 | /* Convert to current kernel version of `struct stat'. */ | |
52 | buf->st_dev = kbuf->st_dev; | |
56ddf355 | 53 | #ifdef _HAVE_STAT___PAD1 |
1cab5444 UD |
54 | buf->__pad1 = 0; |
55 | #endif | |
56 | buf->st_ino = kbuf->st_ino; | |
57 | buf->st_mode = kbuf->st_mode; | |
58 | buf->st_nlink = kbuf->st_nlink; | |
59 | buf->st_uid = kbuf->st_uid; | |
60 | buf->st_gid = kbuf->st_gid; | |
61 | buf->st_rdev = kbuf->st_rdev; | |
56ddf355 | 62 | #ifdef _HAVE_STAT___PAD2 |
1cab5444 UD |
63 | buf->__pad2 = 0; |
64 | #endif | |
65 | buf->st_size = kbuf->st_size; | |
66 | buf->st_blksize = kbuf->st_blksize; | |
67 | buf->st_blocks = kbuf->st_blocks; | |
a5dfb0e6 | 68 | #ifdef _HAVE_STAT_NSEC |
8cac677c UD |
69 | buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; |
70 | buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; | |
71 | buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; | |
72 | buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; | |
73 | buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; | |
74 | buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; | |
a5dfb0e6 AJ |
75 | #else |
76 | buf->st_atime = kbuf->st_atime; | |
77 | buf->st_mtime = kbuf->st_mtime; | |
78 | buf->st_ctime = kbuf->st_ctime; | |
79 | #endif | |
80 | #ifdef _HAVE_STAT___UNUSED1 | |
d1d9eaf4 | 81 | buf->__glibc_reserved1 = 0; |
a5dfb0e6 AJ |
82 | #endif |
83 | #ifdef _HAVE_STAT___UNUSED2 | |
d1d9eaf4 | 84 | buf->__glibc_reserved2 = 0; |
a5dfb0e6 AJ |
85 | #endif |
86 | #ifdef _HAVE_STAT___UNUSED3 | |
d1d9eaf4 | 87 | buf->__glibc_reserved3 = 0; |
a5dfb0e6 | 88 | #endif |
56ddf355 | 89 | #ifdef _HAVE_STAT___UNUSED4 |
d1d9eaf4 | 90 | buf->__glibc_reserved4 = 0; |
1cab5444 | 91 | #endif |
56ddf355 | 92 | #ifdef _HAVE_STAT___UNUSED5 |
d1d9eaf4 | 93 | buf->__glibc_reserved5 = 0; |
1cab5444 UD |
94 | #endif |
95 | } | |
96 | break; | |
97 | ||
98 | default: | |
2caca60d | 99 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); |
1cab5444 UD |
100 | } |
101 | ||
102 | return 0; | |
103 | } | |
9c7ff11a | 104 | #endif |
9756dfe1 | 105 | |
9c7ff11a UD |
106 | int |
107 | __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf) | |
9756dfe1 | 108 | { |
d2e1e973 | 109 | #if XSTAT_IS_XSTAT64 |
2f7f7bc6 | 110 | return __xstat_conv (vers, kbuf, ubuf); |
9756dfe1 UD |
111 | #else |
112 | switch (vers) | |
113 | { | |
114 | case _STAT_VER_LINUX: | |
115 | { | |
116 | struct stat64 *buf = ubuf; | |
117 | ||
118 | /* Convert to current kernel version of `struct stat64'. */ | |
119 | buf->st_dev = kbuf->st_dev; | |
56ddf355 | 120 | #ifdef _HAVE_STAT64___PAD1 |
9756dfe1 UD |
121 | buf->__pad1 = 0; |
122 | #endif | |
123 | buf->st_ino = kbuf->st_ino; | |
56ddf355 UD |
124 | #ifdef _HAVE_STAT64___ST_INO |
125 | buf->__st_ino = kbuf->st_ino; | |
126 | #endif | |
9756dfe1 UD |
127 | buf->st_mode = kbuf->st_mode; |
128 | buf->st_nlink = kbuf->st_nlink; | |
129 | buf->st_uid = kbuf->st_uid; | |
130 | buf->st_gid = kbuf->st_gid; | |
131 | buf->st_rdev = kbuf->st_rdev; | |
56ddf355 | 132 | #ifdef _HAVE_STAT64___PAD2 |
9756dfe1 UD |
133 | buf->__pad2 = 0; |
134 | #endif | |
135 | buf->st_size = kbuf->st_size; | |
136 | buf->st_blksize = kbuf->st_blksize; | |
137 | buf->st_blocks = kbuf->st_blocks; | |
a5dfb0e6 | 138 | #ifdef _HAVE_STAT64_NSEC |
8cac677c UD |
139 | buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; |
140 | buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; | |
141 | buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; | |
142 | buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; | |
143 | buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; | |
144 | buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; | |
a5dfb0e6 AJ |
145 | #else |
146 | buf->st_atime = kbuf->st_atime; | |
147 | buf->st_mtime = kbuf->st_mtime; | |
148 | buf->st_ctime = kbuf->st_ctime; | |
149 | #endif | |
150 | #ifdef _HAVE_STAT64___UNUSED1 | |
d1d9eaf4 | 151 | buf->__glibc_reserved1 = 0; |
a5dfb0e6 AJ |
152 | #endif |
153 | #ifdef _HAVE_STAT64___UNUSED2 | |
d1d9eaf4 | 154 | buf->__glibc_reserved2 = 0; |
a5dfb0e6 AJ |
155 | #endif |
156 | #ifdef _HAVE_STAT64___UNUSED3 | |
d1d9eaf4 | 157 | buf->__glibc_reserved3 = 0; |
a5dfb0e6 | 158 | #endif |
56ddf355 | 159 | #ifdef _HAVE_STAT64___UNUSED4 |
d1d9eaf4 | 160 | buf->__glibc_reserved4 = 0; |
9756dfe1 | 161 | #endif |
56ddf355 | 162 | #ifdef _HAVE_STAT64___UNUSED5 |
d1d9eaf4 | 163 | buf->__glibc_reserved5 = 0; |
9756dfe1 UD |
164 | #endif |
165 | } | |
166 | break; | |
167 | ||
168 | /* If struct stat64 is different from struct stat then | |
169 | _STAT_VER_KERNEL does not make sense. */ | |
170 | case _STAT_VER_KERNEL: | |
171 | default: | |
2caca60d | 172 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); |
9756dfe1 UD |
173 | } |
174 | ||
175 | return 0; | |
176 | #endif | |
177 | } | |
a8481a8c | 178 | |
9c7ff11a UD |
179 | int |
180 | __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf) | |
a8481a8c UD |
181 | { |
182 | switch (vers) | |
183 | { | |
184 | case _STAT_VER_LINUX: | |
185 | { | |
56ddf355 UD |
186 | /* Convert current kernel version of `struct stat64' to |
187 | `struct stat'. */ | |
a8481a8c | 188 | buf->st_dev = kbuf->st_dev; |
56ddf355 | 189 | #ifdef _HAVE_STAT___PAD1 |
a8481a8c UD |
190 | buf->__pad1 = 0; |
191 | #endif | |
56ddf355 | 192 | #ifdef _HAVE_STAT64___ST_INO |
327792ce | 193 | # if !__ASSUME_ST_INO_64_BIT |
56ddf355 UD |
194 | if (kbuf->st_ino == 0) |
195 | buf->st_ino = kbuf->__st_ino; | |
196 | else | |
197 | # endif | |
198 | { | |
199 | buf->st_ino = kbuf->st_ino; | |
0f6b172f | 200 | if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) |
56ddf355 | 201 | && buf->st_ino != kbuf->st_ino) |
2caca60d | 202 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); |
56ddf355 UD |
203 | } |
204 | #else | |
0f6b172f UD |
205 | buf->st_ino = kbuf->st_ino; |
206 | if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) | |
56ddf355 | 207 | && buf->st_ino != kbuf->st_ino) |
2caca60d | 208 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); |
56ddf355 | 209 | #endif |
a8481a8c UD |
210 | buf->st_mode = kbuf->st_mode; |
211 | buf->st_nlink = kbuf->st_nlink; | |
212 | buf->st_uid = kbuf->st_uid; | |
213 | buf->st_gid = kbuf->st_gid; | |
214 | buf->st_rdev = kbuf->st_rdev; | |
56ddf355 | 215 | #ifdef _HAVE_STAT___PAD2 |
a8481a8c UD |
216 | buf->__pad2 = 0; |
217 | #endif | |
218 | buf->st_size = kbuf->st_size; | |
219 | /* Check for overflow. */ | |
56ddf355 UD |
220 | if (sizeof (buf->st_size) != sizeof (kbuf->st_size) |
221 | && buf->st_size != kbuf->st_size) | |
2caca60d | 222 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); |
a8481a8c UD |
223 | buf->st_blksize = kbuf->st_blksize; |
224 | buf->st_blocks = kbuf->st_blocks; | |
225 | /* Check for overflow. */ | |
56ddf355 UD |
226 | if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks) |
227 | && buf->st_blocks != kbuf->st_blocks) | |
2caca60d | 228 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); |
a5dfb0e6 | 229 | #ifdef _HAVE_STAT_NSEC |
8cac677c UD |
230 | buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; |
231 | buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; | |
232 | buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; | |
233 | buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; | |
234 | buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; | |
235 | buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; | |
a5dfb0e6 AJ |
236 | #else |
237 | buf->st_atime = kbuf->st_atime; | |
238 | buf->st_mtime = kbuf->st_mtime; | |
239 | buf->st_ctime = kbuf->st_ctime; | |
240 | #endif | |
241 | ||
242 | #ifdef _HAVE_STAT___UNUSED1 | |
d1d9eaf4 | 243 | buf->__glibc_reserved1 = 0; |
a5dfb0e6 AJ |
244 | #endif |
245 | #ifdef _HAVE_STAT___UNUSED2 | |
d1d9eaf4 | 246 | buf->__glibc_reserved2 = 0; |
a5dfb0e6 AJ |
247 | #endif |
248 | #ifdef _HAVE_STAT___UNUSED3 | |
d1d9eaf4 | 249 | buf->__glibc_reserved3 = 0; |
a5dfb0e6 | 250 | #endif |
56ddf355 | 251 | #ifdef _HAVE_STAT___UNUSED4 |
d1d9eaf4 | 252 | buf->__glibc_reserved4 = 0; |
a8481a8c | 253 | #endif |
56ddf355 | 254 | #ifdef _HAVE_STAT___UNUSED5 |
d1d9eaf4 | 255 | buf->__glibc_reserved5 = 0; |
a8481a8c UD |
256 | #endif |
257 | } | |
258 | break; | |
259 | ||
260 | /* If struct stat64 is different from struct stat then | |
261 | _STAT_VER_KERNEL does not make sense. */ | |
262 | case _STAT_VER_KERNEL: | |
263 | default: | |
2caca60d | 264 | return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); |
a8481a8c UD |
265 | } |
266 | ||
267 | return 0; | |
268 | } | |
c84d1f2e RM |
269 | |
270 | #endif |