]>
Commit | Line | Data |
---|---|---|
6d4752d8 | 1 | /* Convert between the kernel's `struct stat' format, and libc's. |
0ecb606c JJ |
2 | Copyright (C) 1991, 1995, 1996, 1997, 2000, 2002, 2003, 2006 |
3 | Free Software Foundation, Inc. | |
6d4752d8 UD |
4 | This file is part of the GNU C Library. |
5 | ||
6 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
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. | |
6d4752d8 UD |
10 | |
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 | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
6d4752d8 | 15 | |
41bdb6e2 AJ |
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. */ | |
6d4752d8 | 20 | |
0ecb606c | 21 | #include <assert.h> |
7efbf47c AJ |
22 | #include <errno.h> |
23 | #include <sys/stat.h> | |
24 | #include <kernel_stat.h> | |
6d4752d8 | 25 | #include <string.h> |
0ecb606c | 26 | #include <kernel-features.h> |
6d4752d8 | 27 | |
7efbf47c AJ |
28 | int |
29 | __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) | |
6d4752d8 UD |
30 | { |
31 | switch (vers) | |
32 | { | |
33 | case _STAT_VER_KERNEL: | |
34 | /* Nothing to do. The struct is in the form the kernel expects. | |
35 | We should have short-circuted before we got here, but for | |
36 | completeness... */ | |
37 | *(struct kernel_stat *) ubuf = *kbuf; | |
38 | break; | |
39 | ||
40 | case _STAT_VER_LINUX: | |
41 | { | |
42 | struct stat *buf = ubuf; | |
43 | ||
44 | /* Convert to current kernel version of `struct stat'. */ | |
45 | buf->st_dev = kbuf->st_dev; | |
0ecb606c | 46 | buf->__pad1 = 0; |
6d4752d8 UD |
47 | buf->st_ino = kbuf->st_ino; |
48 | buf->st_mode = kbuf->st_mode; | |
49 | buf->st_nlink = kbuf->st_nlink; | |
50 | buf->st_uid = kbuf->st_uid; | |
51 | buf->st_gid = kbuf->st_gid; | |
52 | buf->st_rdev = kbuf->st_rdev; | |
0ecb606c | 53 | buf->__pad2 = 0; |
6d4752d8 UD |
54 | buf->st_size = kbuf->st_size; |
55 | buf->st_blksize = kbuf->st_blksize; | |
56 | buf->st_blocks = kbuf->st_blocks; | |
0ecb606c JJ |
57 | buf->st_atim.tv_sec = kbuf->st_atime_sec; |
58 | buf->st_atim.tv_nsec = 0; | |
59 | buf->st_mtim.tv_sec = kbuf->st_mtime_sec; | |
60 | buf->st_mtim.tv_nsec = 0; | |
61 | buf->st_ctim.tv_sec = kbuf->st_ctime_sec; | |
62 | buf->st_ctim.tv_nsec = 0; | |
63 | buf->__unused4 = 0; | |
64 | buf->__unused5 = 0; | |
6d4752d8 UD |
65 | } |
66 | break; | |
67 | ||
68 | default: | |
69 | __set_errno (EINVAL); | |
70 | return -1; | |
71 | } | |
72 | ||
73 | return 0; | |
74 | } | |
75 | ||
7efbf47c | 76 | int |
0ecb606c | 77 | __xstat32_conv (int vers, struct stat64 *sbuf, struct stat *buf) |
6d4752d8 | 78 | { |
0ecb606c JJ |
79 | struct kernel_stat64 *kbuf; |
80 | ||
81 | /* *stat64 syscalls on sparc64 really fill in struct kernel_stat64, | |
82 | rather than struct stat64. But it is the same size as | |
83 | struct kernel_stat64, so use this hack so that we can reuse | |
84 | i386 {,f,l}xstat{,at}.c routines. */ | |
85 | __asm ("" : "=r" (kbuf) : "0" (sbuf)); | |
86 | assert (sizeof (struct stat) == sizeof (struct stat64)); | |
87 | assert (sizeof (struct stat64) >= sizeof (struct kernel_stat64)); | |
88 | ||
6d4752d8 UD |
89 | switch (vers) |
90 | { | |
91 | case _STAT_VER_LINUX: | |
92 | { | |
0ecb606c JJ |
93 | /* Convert current kernel version of `struct stat64' to |
94 | `struct stat'. */ | |
6d4752d8 | 95 | buf->st_dev = kbuf->st_dev; |
0ecb606c | 96 | buf->__pad1 = 0; |
6d4752d8 UD |
97 | buf->st_ino = kbuf->st_ino; |
98 | buf->st_mode = kbuf->st_mode; | |
99 | buf->st_nlink = kbuf->st_nlink; | |
100 | buf->st_uid = kbuf->st_uid; | |
101 | buf->st_gid = kbuf->st_gid; | |
102 | buf->st_rdev = kbuf->st_rdev; | |
0ecb606c | 103 | buf->__pad2 = 0; |
6d4752d8 UD |
104 | buf->st_size = kbuf->st_size; |
105 | buf->st_blksize = kbuf->st_blksize; | |
106 | buf->st_blocks = kbuf->st_blocks; | |
0ecb606c JJ |
107 | buf->st_atim.tv_sec = kbuf->st_atime_sec; |
108 | buf->st_atim.tv_nsec = kbuf->st_atime_nsec; | |
109 | buf->st_mtim.tv_sec = kbuf->st_mtime_sec; | |
110 | buf->st_mtim.tv_nsec = kbuf->st_mtime_nsec; | |
111 | buf->st_ctim.tv_sec = kbuf->st_ctime_sec; | |
112 | buf->st_ctim.tv_nsec = kbuf->st_ctime_nsec; | |
113 | buf->__unused4 = 0; | |
114 | buf->__unused5 = 0; | |
6d4752d8 UD |
115 | } |
116 | break; | |
117 | ||
118 | /* If struct stat64 is different from struct stat then | |
119 | _STAT_VER_KERNEL does not make sense. */ | |
120 | case _STAT_VER_KERNEL: | |
121 | default: | |
122 | __set_errno (EINVAL); | |
123 | return -1; | |
124 | } | |
125 | ||
126 | return 0; | |
6d4752d8 | 127 | } |