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
23 #include <kernel_stat.h>
24 #include <kernel-features.h>
26 #ifdef STAT_IS_KERNEL_STAT
36 #if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64
38 __xstat_conv (int vers
, struct kernel_stat
*kbuf
, void *ubuf
)
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
46 *(struct kernel_stat
*) ubuf
= *kbuf
;
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
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
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
;
78 buf
->st_atime
= kbuf
->st_atime
;
79 buf
->st_mtime
= kbuf
->st_mtime
;
80 buf
->st_ctime
= kbuf
->st_ctime
;
82 #ifdef _HAVE_STAT___UNUSED1
85 #ifdef _HAVE_STAT___UNUSED2
88 #ifdef _HAVE_STAT___UNUSED3
91 #ifdef _HAVE_STAT___UNUSED4
94 #ifdef _HAVE_STAT___UNUSED5
101 __set_errno (EINVAL
);
110 __xstat64_conv (int vers
, struct kernel_stat
*kbuf
, void *ubuf
)
112 #ifdef XSTAT_IS_XSTAT64
113 return __xstat_conv (vers
, kbuf
, ubuf
);
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
126 buf
->st_ino
= kbuf
->st_ino
;
127 #ifdef _HAVE_STAT64___ST_INO
128 buf
->__st_ino
= kbuf
->st_ino
;
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
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
;
149 buf
->st_atime
= kbuf
->st_atime
;
150 buf
->st_mtime
= kbuf
->st_mtime
;
151 buf
->st_ctime
= kbuf
->st_ctime
;
153 #ifdef _HAVE_STAT64___UNUSED1
156 #ifdef _HAVE_STAT64___UNUSED2
159 #ifdef _HAVE_STAT64___UNUSED3
162 #ifdef _HAVE_STAT64___UNUSED4
165 #ifdef _HAVE_STAT64___UNUSED5
171 /* If struct stat64 is different from struct stat then
172 _STAT_VER_KERNEL does not make sense. */
173 case _STAT_VER_KERNEL
:
175 __set_errno (EINVAL
);
184 __xstat32_conv (int vers
, struct stat64
*kbuf
, struct stat
*buf
)
188 case _STAT_VER_LINUX
:
190 /* Convert current kernel version of `struct stat64' to
192 buf
->st_dev
= kbuf
->st_dev
;
193 #ifdef _HAVE_STAT___PAD1
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
;
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
);
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
);
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
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
);
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
);
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
;
253 buf
->st_atime
= kbuf
->st_atime
;
254 buf
->st_mtime
= kbuf
->st_mtime
;
255 buf
->st_ctime
= kbuf
->st_ctime
;
258 #ifdef _HAVE_STAT___UNUSED1
261 #ifdef _HAVE_STAT___UNUSED2
264 #ifdef _HAVE_STAT___UNUSED3
267 #ifdef _HAVE_STAT___UNUSED4
270 #ifdef _HAVE_STAT___UNUSED5
276 /* If struct stat64 is different from struct stat then
277 _STAT_VER_KERNEL does not make sense. */
278 case _STAT_VER_KERNEL
:
280 __set_errno (EINVAL
);