2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / xstatconv.c
blob8210798a69fea7bb669086cd4187fa4dcbc0b181
1 /* Convert between the kernel's `struct stat' format, and libc's.
2 Copyright (C) 1991,1995-1997,2000,2002,2003,2007
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <errno.h>
22 #include <sys/stat.h>
23 #include <kernel_stat.h>
24 #include <kernel-features.h>
26 #ifdef STAT_IS_KERNEL_STAT
28 /* Dummy. */
29 struct kernel_stat;
31 #else
33 #include <string.h>
36 #if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64
37 int
38 __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
40 switch (vers)
42 case _STAT_VER_KERNEL:
43 /* Nothing to do. The struct is in the form the kernel expects.
44 We should have short-circuted before we got here, but for
45 completeness... */
46 *(struct kernel_stat *) ubuf = *kbuf;
47 break;
49 case _STAT_VER_LINUX:
51 struct stat *buf = ubuf;
53 /* Convert to current kernel version of `struct stat'. */
54 buf->st_dev = kbuf->st_dev;
55 #ifdef _HAVE_STAT___PAD1
56 buf->__pad1 = 0;
57 #endif
58 buf->st_ino = kbuf->st_ino;
59 buf->st_mode = kbuf->st_mode;
60 buf->st_nlink = kbuf->st_nlink;
61 buf->st_uid = kbuf->st_uid;
62 buf->st_gid = kbuf->st_gid;
63 buf->st_rdev = kbuf->st_rdev;
64 #ifdef _HAVE_STAT___PAD2
65 buf->__pad2 = 0;
66 #endif
67 buf->st_size = kbuf->st_size;
68 buf->st_blksize = kbuf->st_blksize;
69 buf->st_blocks = kbuf->st_blocks;
70 #ifdef _HAVE_STAT_NSEC
71 buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
72 buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
73 buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
74 buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
75 buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
76 buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
77 #else
78 buf->st_atime = kbuf->st_atime;
79 buf->st_mtime = kbuf->st_mtime;
80 buf->st_ctime = kbuf->st_ctime;
81 #endif
82 #ifdef _HAVE_STAT___UNUSED1
83 buf->__unused1 = 0;
84 #endif
85 #ifdef _HAVE_STAT___UNUSED2
86 buf->__unused2 = 0;
87 #endif
88 #ifdef _HAVE_STAT___UNUSED3
89 buf->__unused3 = 0;
90 #endif
91 #ifdef _HAVE_STAT___UNUSED4
92 buf->__unused4 = 0;
93 #endif
94 #ifdef _HAVE_STAT___UNUSED5
95 buf->__unused5 = 0;
96 #endif
98 break;
100 default:
101 __set_errno (EINVAL);
102 return -1;
105 return 0;
107 #endif
110 __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
112 #ifdef XSTAT_IS_XSTAT64
113 return __xstat_conv (vers, kbuf, ubuf);
114 #else
115 switch (vers)
117 case _STAT_VER_LINUX:
119 struct stat64 *buf = ubuf;
121 /* Convert to current kernel version of `struct stat64'. */
122 buf->st_dev = kbuf->st_dev;
123 #ifdef _HAVE_STAT64___PAD1
124 buf->__pad1 = 0;
125 #endif
126 buf->st_ino = kbuf->st_ino;
127 #ifdef _HAVE_STAT64___ST_INO
128 buf->__st_ino = kbuf->st_ino;
129 #endif
130 buf->st_mode = kbuf->st_mode;
131 buf->st_nlink = kbuf->st_nlink;
132 buf->st_uid = kbuf->st_uid;
133 buf->st_gid = kbuf->st_gid;
134 buf->st_rdev = kbuf->st_rdev;
135 #ifdef _HAVE_STAT64___PAD2
136 buf->__pad2 = 0;
137 #endif
138 buf->st_size = kbuf->st_size;
139 buf->st_blksize = kbuf->st_blksize;
140 buf->st_blocks = kbuf->st_blocks;
141 #ifdef _HAVE_STAT64_NSEC
142 buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
143 buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
144 buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
145 buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
146 buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
147 buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
148 #else
149 buf->st_atime = kbuf->st_atime;
150 buf->st_mtime = kbuf->st_mtime;
151 buf->st_ctime = kbuf->st_ctime;
152 #endif
153 #ifdef _HAVE_STAT64___UNUSED1
154 buf->__unused1 = 0;
155 #endif
156 #ifdef _HAVE_STAT64___UNUSED2
157 buf->__unused2 = 0;
158 #endif
159 #ifdef _HAVE_STAT64___UNUSED3
160 buf->__unused3 = 0;
161 #endif
162 #ifdef _HAVE_STAT64___UNUSED4
163 buf->__unused4 = 0;
164 #endif
165 #ifdef _HAVE_STAT64___UNUSED5
166 buf->__unused5 = 0;
167 #endif
169 break;
171 /* If struct stat64 is different from struct stat then
172 _STAT_VER_KERNEL does not make sense. */
173 case _STAT_VER_KERNEL:
174 default:
175 __set_errno (EINVAL);
176 return -1;
179 return 0;
180 #endif
184 __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
186 switch (vers)
188 case _STAT_VER_LINUX:
190 /* Convert current kernel version of `struct stat64' to
191 `struct stat'. */
192 buf->st_dev = kbuf->st_dev;
193 #ifdef _HAVE_STAT___PAD1
194 buf->__pad1 = 0;
195 #endif
196 #ifdef _HAVE_STAT64___ST_INO
197 # if __ASSUME_ST_INO_64_BIT == 0
198 if (kbuf->st_ino == 0)
199 buf->st_ino = kbuf->__st_ino;
200 else
201 # endif
203 buf->st_ino = kbuf->st_ino;
204 if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
205 && buf->st_ino != kbuf->st_ino)
207 __set_errno (EOVERFLOW);
208 return -1;
211 #else
212 buf->st_ino = kbuf->st_ino;
213 if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
214 && buf->st_ino != kbuf->st_ino)
216 __set_errno (EOVERFLOW);
217 return -1;
219 #endif
220 buf->st_mode = kbuf->st_mode;
221 buf->st_nlink = kbuf->st_nlink;
222 buf->st_uid = kbuf->st_uid;
223 buf->st_gid = kbuf->st_gid;
224 buf->st_rdev = kbuf->st_rdev;
225 #ifdef _HAVE_STAT___PAD2
226 buf->__pad2 = 0;
227 #endif
228 buf->st_size = kbuf->st_size;
229 /* Check for overflow. */
230 if (sizeof (buf->st_size) != sizeof (kbuf->st_size)
231 && buf->st_size != kbuf->st_size)
233 __set_errno (EOVERFLOW);
234 return -1;
236 buf->st_blksize = kbuf->st_blksize;
237 buf->st_blocks = kbuf->st_blocks;
238 /* Check for overflow. */
239 if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks)
240 && buf->st_blocks != kbuf->st_blocks)
242 __set_errno (EOVERFLOW);
243 return -1;
245 #ifdef _HAVE_STAT_NSEC
246 buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
247 buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
248 buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
249 buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
250 buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
251 buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
252 #else
253 buf->st_atime = kbuf->st_atime;
254 buf->st_mtime = kbuf->st_mtime;
255 buf->st_ctime = kbuf->st_ctime;
256 #endif
258 #ifdef _HAVE_STAT___UNUSED1
259 buf->__unused1 = 0;
260 #endif
261 #ifdef _HAVE_STAT___UNUSED2
262 buf->__unused2 = 0;
263 #endif
264 #ifdef _HAVE_STAT___UNUSED3
265 buf->__unused3 = 0;
266 #endif
267 #ifdef _HAVE_STAT___UNUSED4
268 buf->__unused4 = 0;
269 #endif
270 #ifdef _HAVE_STAT___UNUSED5
271 buf->__unused5 = 0;
272 #endif
274 break;
276 /* If struct stat64 is different from struct stat then
277 _STAT_VER_KERNEL does not make sense. */
278 case _STAT_VER_KERNEL:
279 default:
280 __set_errno (EINVAL);
281 return -1;
284 return 0;
287 #endif