1 /* Convert between the kernel's `struct stat' format, and libc's.
2 Copyright (C) 1991-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
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.
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
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <https://www.gnu.org/licenses/>. */
21 #include <kernel_stat.h>
26 __xstat_conv (int vers
, struct kernel_stat
*kbuf
, void *ubuf
)
30 case _STAT_VER_KERNEL
:
31 /* Nothing to do. The struct is in the form the kernel expects.
32 We should have short-circuted before we got here, but for
34 *(struct kernel_stat
*) ubuf
= *kbuf
;
39 struct stat
*buf
= ubuf
;
41 /* Convert to current kernel version of `struct stat'. */
42 buf
->st_dev
= kbuf
->st_dev
;
43 memset (&buf
->st_pad1
, 0, sizeof (buf
->st_pad1
));
44 buf
->st_ino
= kbuf
->st_ino
;
45 /* Check for overflow. */
46 if (buf
->st_ino
!= kbuf
->st_ino
)
48 __set_errno (EOVERFLOW
);
51 buf
->st_mode
= kbuf
->st_mode
;
52 buf
->st_nlink
= kbuf
->st_nlink
;
53 buf
->st_uid
= kbuf
->st_uid
;
54 buf
->st_gid
= kbuf
->st_gid
;
55 buf
->st_rdev
= kbuf
->st_rdev
;
56 memset (&buf
->st_pad2
, 0, sizeof (buf
->st_pad2
));
57 buf
->st_size
= kbuf
->st_size
;
58 /* Check for overflow. */
59 if (buf
->st_size
!= kbuf
->st_size
)
61 __set_errno (EOVERFLOW
);
65 buf
->st_atim
.tv_sec
= kbuf
->st_atime_sec
;
66 buf
->st_atim
.tv_nsec
= kbuf
->st_atime_nsec
;
67 buf
->st_mtim
.tv_sec
= kbuf
->st_mtime_sec
;
68 buf
->st_mtim
.tv_nsec
= kbuf
->st_mtime_nsec
;
69 buf
->st_ctim
.tv_sec
= kbuf
->st_ctime_sec
;
70 buf
->st_ctim
.tv_nsec
= kbuf
->st_ctime_nsec
;
71 buf
->st_blksize
= kbuf
->st_blksize
;
72 buf
->st_blocks
= kbuf
->st_blocks
;
73 /* Check for overflow. */
74 if (buf
->st_blocks
!= kbuf
->st_blocks
)
76 __set_errno (EOVERFLOW
);
79 memset (&buf
->st_pad5
, 0, sizeof (buf
->st_pad5
));
92 __xstat64_conv (int vers
, struct kernel_stat
*kbuf
, void *ubuf
)
95 return xstat_conv (vers
, kbuf
, ubuf
);
101 struct stat64
*buf
= ubuf
;
103 buf
->st_dev
= kbuf
->st_dev
;
104 memset (&buf
->st_pad1
, 0, sizeof (buf
->st_pad1
));
105 buf
->st_ino
= kbuf
->st_ino
;
106 buf
->st_mode
= kbuf
->st_mode
;
107 buf
->st_nlink
= kbuf
->st_nlink
;
108 buf
->st_uid
= kbuf
->st_uid
;
109 buf
->st_gid
= kbuf
->st_gid
;
110 buf
->st_rdev
= kbuf
->st_rdev
;
111 memset (&buf
->st_pad2
, 0, sizeof (buf
->st_pad2
));
113 buf
->st_size
= kbuf
->st_size
;
114 buf
->st_blksize
= kbuf
->st_blksize
;
115 buf
->st_blocks
= kbuf
->st_blocks
;
117 buf
->st_atim
.tv_sec
= kbuf
->st_atime_sec
;
118 buf
->st_atim
.tv_nsec
= kbuf
->st_atime_nsec
;
119 buf
->st_mtim
.tv_sec
= kbuf
->st_mtime_sec
;
120 buf
->st_mtim
.tv_nsec
= kbuf
->st_mtime_nsec
;
121 buf
->st_ctim
.tv_sec
= kbuf
->st_ctime_sec
;
122 buf
->st_ctim
.tv_nsec
= kbuf
->st_ctime_nsec
;
124 memset (&buf
->st_pad4
, 0, sizeof (buf
->st_pad4
));
128 /* If struct stat64 is different from struct stat then
129 _STAT_VER_KERNEL does not make sense. */
130 case _STAT_VER_KERNEL
:
132 __set_errno (EINVAL
);
140 #if _MIPS_SIM == _ABIO32
142 __xstat32_conv (int vers
, struct stat64
*kbuf
, struct stat
*buf
)
146 case _STAT_VER_LINUX
:
147 /* Convert current kernel version of `struct stat64' to
148 `struct stat'. The layout of the fields in the kernel's
149 stat64 is the same as that in the user stat64; the only
150 difference is that the latter has more trailing padding. */
151 buf
->st_dev
= kbuf
->st_dev
;
152 memset (&buf
->st_pad1
, 0, sizeof (buf
->st_pad1
));
153 buf
->st_ino
= kbuf
->st_ino
;
154 /* Check for overflow. */
155 if (buf
->st_ino
!= kbuf
->st_ino
)
157 __set_errno (EOVERFLOW
);
160 buf
->st_mode
= kbuf
->st_mode
;
161 buf
->st_nlink
= kbuf
->st_nlink
;
162 buf
->st_uid
= kbuf
->st_uid
;
163 buf
->st_gid
= kbuf
->st_gid
;
164 buf
->st_rdev
= kbuf
->st_rdev
;
165 memset (&buf
->st_pad2
, 0, sizeof (buf
->st_pad2
));
166 buf
->st_size
= kbuf
->st_size
;
167 /* Check for overflow. */
168 if (buf
->st_size
!= kbuf
->st_size
)
170 __set_errno (EOVERFLOW
);
174 buf
->st_atim
.tv_sec
= kbuf
->st_atim
.tv_sec
;
175 buf
->st_atim
.tv_nsec
= kbuf
->st_atim
.tv_nsec
;
176 buf
->st_mtim
.tv_sec
= kbuf
->st_mtim
.tv_sec
;
177 buf
->st_mtim
.tv_nsec
= kbuf
->st_mtim
.tv_nsec
;
178 buf
->st_ctim
.tv_sec
= kbuf
->st_ctim
.tv_sec
;
179 buf
->st_ctim
.tv_nsec
= kbuf
->st_ctim
.tv_nsec
;
180 buf
->st_blksize
= kbuf
->st_blksize
;
181 buf
->st_blocks
= kbuf
->st_blocks
;
182 /* Check for overflow. */
183 if (buf
->st_blocks
!= kbuf
->st_blocks
)
185 __set_errno (EOVERFLOW
);
188 memset (&buf
->st_pad5
, 0, sizeof (buf
->st_pad5
));
191 /* If struct stat64 is different from struct stat then
192 _STAT_VER_KERNEL does not make sense. */
193 case _STAT_VER_KERNEL
:
195 __set_errno (EINVAL
);
201 #endif /* _MIPS_SIM == _ABIO32 */