xstatconv.c 6.5 KB

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