Back to index

glibc  2.9
xstatconv.c
Go to the documentation of this file.
00001 /* Convert between the kernel's `struct stat' format, and libc's.
00002    Copyright (C) 1991,1995-1997,2000,2002,2003,2007
00003    Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <errno.h>
00022 #include <sys/stat.h>
00023 #include <kernel_stat.h>
00024 #include <kernel-features.h>
00025 
00026 #ifdef STAT_IS_KERNEL_STAT
00027 
00028 /* Dummy.  */
00029 struct kernel_stat;
00030 
00031 #else
00032 
00033 #include <string.h>
00034 
00035 
00036 #if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64
00037 int
00038 __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
00039 {
00040   switch (vers)
00041     {
00042     case _STAT_VER_KERNEL:
00043       /* Nothing to do.  The struct is in the form the kernel expects.
00044          We should have short-circuted before we got here, but for
00045          completeness... */
00046       *(struct kernel_stat *) ubuf = *kbuf;
00047       break;
00048 
00049     case _STAT_VER_LINUX:
00050       {
00051        struct stat *buf = ubuf;
00052 
00053        /* Convert to current kernel version of `struct stat'.  */
00054        buf->st_dev = kbuf->st_dev;
00055 #ifdef _HAVE_STAT___PAD1
00056        buf->__pad1 = 0;
00057 #endif
00058        buf->st_ino = kbuf->st_ino;
00059        buf->st_mode = kbuf->st_mode;
00060        buf->st_nlink = kbuf->st_nlink;
00061        buf->st_uid = kbuf->st_uid;
00062        buf->st_gid = kbuf->st_gid;
00063        buf->st_rdev = kbuf->st_rdev;
00064 #ifdef _HAVE_STAT___PAD2
00065        buf->__pad2 = 0;
00066 #endif
00067        buf->st_size = kbuf->st_size;
00068        buf->st_blksize = kbuf->st_blksize;
00069        buf->st_blocks = kbuf->st_blocks;
00070 #ifdef _HAVE_STAT_NSEC
00071        buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
00072        buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
00073        buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
00074        buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
00075        buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
00076        buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
00077 #else
00078        buf->st_atime = kbuf->st_atime;
00079        buf->st_mtime = kbuf->st_mtime;
00080        buf->st_ctime = kbuf->st_ctime;
00081 #endif
00082 #ifdef _HAVE_STAT___UNUSED1
00083        buf->__unused1 = 0;
00084 #endif
00085 #ifdef _HAVE_STAT___UNUSED2
00086        buf->__unused2 = 0;
00087 #endif
00088 #ifdef _HAVE_STAT___UNUSED3
00089        buf->__unused3 = 0;
00090 #endif
00091 #ifdef _HAVE_STAT___UNUSED4
00092        buf->__unused4 = 0;
00093 #endif
00094 #ifdef _HAVE_STAT___UNUSED5
00095        buf->__unused5 = 0;
00096 #endif
00097       }
00098       break;
00099 
00100     default:
00101       __set_errno (EINVAL);
00102       return -1;
00103     }
00104 
00105   return 0;
00106 }
00107 #endif
00108 
00109 int
00110 __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
00111 {
00112 #ifdef XSTAT_IS_XSTAT64
00113   return __xstat_conv (vers, kbuf, ubuf);
00114 #else
00115   switch (vers)
00116     {
00117     case _STAT_VER_LINUX:
00118       {
00119        struct stat64 *buf = ubuf;
00120 
00121        /* Convert to current kernel version of `struct stat64'.  */
00122        buf->st_dev = kbuf->st_dev;
00123 #ifdef _HAVE_STAT64___PAD1
00124        buf->__pad1 = 0;
00125 #endif
00126        buf->st_ino = kbuf->st_ino;
00127 #ifdef _HAVE_STAT64___ST_INO
00128        buf->__st_ino = kbuf->st_ino;
00129 #endif
00130        buf->st_mode = kbuf->st_mode;
00131        buf->st_nlink = kbuf->st_nlink;
00132        buf->st_uid = kbuf->st_uid;
00133        buf->st_gid = kbuf->st_gid;
00134        buf->st_rdev = kbuf->st_rdev;
00135 #ifdef _HAVE_STAT64___PAD2
00136        buf->__pad2 = 0;
00137 #endif
00138        buf->st_size = kbuf->st_size;
00139        buf->st_blksize = kbuf->st_blksize;
00140        buf->st_blocks = kbuf->st_blocks;
00141 #ifdef _HAVE_STAT64_NSEC
00142        buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
00143        buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
00144        buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
00145        buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
00146        buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
00147        buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
00148 #else
00149        buf->st_atime = kbuf->st_atime;
00150        buf->st_mtime = kbuf->st_mtime;
00151        buf->st_ctime = kbuf->st_ctime;
00152 #endif
00153 #ifdef _HAVE_STAT64___UNUSED1
00154        buf->__unused1 = 0;
00155 #endif
00156 #ifdef _HAVE_STAT64___UNUSED2
00157        buf->__unused2 = 0;
00158 #endif
00159 #ifdef _HAVE_STAT64___UNUSED3
00160        buf->__unused3 = 0;
00161 #endif
00162 #ifdef _HAVE_STAT64___UNUSED4
00163        buf->__unused4 = 0;
00164 #endif
00165 #ifdef _HAVE_STAT64___UNUSED5
00166        buf->__unused5 = 0;
00167 #endif
00168       }
00169       break;
00170 
00171       /* If struct stat64 is different from struct stat then
00172         _STAT_VER_KERNEL does not make sense.  */
00173     case _STAT_VER_KERNEL:
00174     default:
00175       __set_errno (EINVAL);
00176       return -1;
00177     }
00178 
00179   return 0;
00180 #endif
00181 }
00182 
00183 int
00184 __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
00185 {
00186   switch (vers)
00187     {
00188     case _STAT_VER_LINUX:
00189       {
00190        /* Convert current kernel version of `struct stat64' to
00191            `struct stat'.  */
00192        buf->st_dev = kbuf->st_dev;
00193 #ifdef _HAVE_STAT___PAD1
00194        buf->__pad1 = 0;
00195 #endif
00196 #ifdef _HAVE_STAT64___ST_INO
00197 # if __ASSUME_ST_INO_64_BIT == 0
00198        if (kbuf->st_ino == 0)
00199          buf->st_ino = kbuf->__st_ino;
00200        else
00201 # endif
00202          {
00203            buf->st_ino = kbuf->st_ino;
00204            if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
00205               && buf->st_ino != kbuf->st_ino)
00206              {
00207               __set_errno (EOVERFLOW);
00208               return -1;
00209              }
00210          }
00211 #else
00212        buf->st_ino = kbuf->st_ino;
00213        if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino)
00214            && buf->st_ino != kbuf->st_ino)
00215          {
00216            __set_errno (EOVERFLOW);
00217            return -1;
00218          }
00219 #endif
00220        buf->st_mode = kbuf->st_mode;
00221        buf->st_nlink = kbuf->st_nlink;
00222        buf->st_uid = kbuf->st_uid;
00223        buf->st_gid = kbuf->st_gid;
00224        buf->st_rdev = kbuf->st_rdev;
00225 #ifdef _HAVE_STAT___PAD2
00226        buf->__pad2 = 0;
00227 #endif
00228        buf->st_size = kbuf->st_size;
00229        /* Check for overflow.  */
00230        if (sizeof (buf->st_size) != sizeof (kbuf->st_size)
00231            && buf->st_size != kbuf->st_size)
00232          {
00233            __set_errno (EOVERFLOW);
00234            return -1;
00235          }
00236        buf->st_blksize = kbuf->st_blksize;
00237        buf->st_blocks = kbuf->st_blocks;
00238        /* Check for overflow.  */
00239        if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks)
00240            && buf->st_blocks != kbuf->st_blocks)
00241          {
00242            __set_errno (EOVERFLOW);
00243            return -1;
00244          }
00245 #ifdef _HAVE_STAT_NSEC
00246        buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
00247        buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
00248        buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
00249        buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
00250        buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
00251        buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
00252 #else
00253        buf->st_atime = kbuf->st_atime;
00254        buf->st_mtime = kbuf->st_mtime;
00255        buf->st_ctime = kbuf->st_ctime;
00256 #endif
00257 
00258 #ifdef _HAVE_STAT___UNUSED1
00259        buf->__unused1 = 0;
00260 #endif
00261 #ifdef _HAVE_STAT___UNUSED2
00262        buf->__unused2 = 0;
00263 #endif
00264 #ifdef _HAVE_STAT___UNUSED3
00265        buf->__unused3 = 0;
00266 #endif
00267 #ifdef _HAVE_STAT___UNUSED4
00268        buf->__unused4 = 0;
00269 #endif
00270 #ifdef _HAVE_STAT___UNUSED5
00271        buf->__unused5 = 0;
00272 #endif
00273       }
00274       break;
00275 
00276       /* If struct stat64 is different from struct stat then
00277         _STAT_VER_KERNEL does not make sense.  */
00278     case _STAT_VER_KERNEL:
00279     default:
00280       __set_errno (EINVAL);
00281       return -1;
00282     }
00283 
00284   return 0;
00285 }
00286 
00287 #endif