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,1996,1997,1998,2000,2003 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <sys/stat.h>
00022 #include <kernel_stat.h>
00023 
00024 #include <string.h>
00025 
00026 int
00027 __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
00028 {
00029   switch (vers)
00030     {
00031     case _STAT_VER_KERNEL:
00032       /* Nothing to do.  The struct is in the form the kernel expects.
00033          We should have short-circuted before we got here, but for
00034          completeness... */
00035       *(struct kernel_stat *) ubuf = *kbuf;
00036       break;
00037 
00038     case _STAT_VER_LINUX:
00039       {
00040        struct stat *buf = ubuf;
00041 
00042        /* Convert to current kernel version of `struct stat'.  */
00043        buf->st_dev = kbuf->st_dev;
00044        memset (&buf->st_pad1, 0, sizeof (buf->st_pad1));
00045        buf->st_ino = kbuf->st_ino;
00046        /* Check for overflow.  */
00047        if (buf->st_ino != kbuf->st_ino)
00048          {
00049            __set_errno (EOVERFLOW);
00050            return -1;
00051          }
00052        buf->st_mode = kbuf->st_mode;
00053        buf->st_nlink = kbuf->st_nlink;
00054        buf->st_uid = kbuf->st_uid;
00055        buf->st_gid = kbuf->st_gid;
00056        buf->st_rdev = kbuf->st_rdev;
00057        memset (&buf->st_pad2, 0, sizeof (buf->st_pad2));
00058        buf->st_size = kbuf->st_size;
00059        /* Check for overflow.  */
00060        if (buf->st_size != kbuf->st_size)
00061          {
00062            __set_errno (EOVERFLOW);
00063            return -1;
00064          }
00065        buf->st_pad3 = 0;
00066        buf->st_atim.tv_sec = kbuf->st_atime_sec;
00067        buf->st_atim.tv_nsec = kbuf->st_atime_nsec;
00068        buf->st_mtim.tv_sec = kbuf->st_mtime_sec;
00069        buf->st_mtim.tv_nsec = kbuf->st_mtime_nsec;
00070        buf->st_ctim.tv_sec = kbuf->st_ctime_sec;
00071        buf->st_ctim.tv_nsec = kbuf->st_ctime_nsec;
00072        buf->st_blksize = kbuf->st_blksize;
00073        buf->st_blocks = kbuf->st_blocks;
00074        /* Check for overflow.  */
00075        if (buf->st_blocks != kbuf->st_blocks)
00076          {
00077            __set_errno (EOVERFLOW);
00078            return -1;
00079          }
00080        memset (&buf->st_pad5, 0, sizeof (buf->st_pad5));
00081       }
00082       break;
00083 
00084     default:
00085       __set_errno (EINVAL);
00086       return -1;
00087     }
00088 
00089   return 0;
00090 }
00091 
00092 int
00093 __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
00094 {
00095 #ifdef XSTAT_IS_XSTAT64
00096   return xstat_conv (vers, kbuf, ubuf);
00097 #else
00098   switch (vers)
00099     {
00100     case _STAT_VER_LINUX:
00101       {
00102        struct stat64 *buf = ubuf;
00103 
00104        buf->st_dev = kbuf->st_dev;
00105        memset (&buf->st_pad1, 0, sizeof (buf->st_pad1));
00106        buf->st_ino = kbuf->st_ino;
00107        buf->st_mode = kbuf->st_mode;
00108        buf->st_nlink = kbuf->st_nlink;
00109        buf->st_uid = kbuf->st_uid;
00110        buf->st_gid = kbuf->st_gid;
00111        buf->st_rdev = kbuf->st_rdev;
00112        memset (&buf->st_pad2, 0, sizeof (buf->st_pad2));
00113        buf->st_pad3 = 0;
00114        buf->st_size = kbuf->st_size;
00115        buf->st_blksize = kbuf->st_blksize;
00116        buf->st_blocks = kbuf->st_blocks;
00117 
00118        buf->st_atim.tv_sec = kbuf->st_atime_sec;
00119        buf->st_atim.tv_nsec = kbuf->st_atime_nsec;
00120        buf->st_mtim.tv_sec = kbuf->st_mtime_sec;
00121        buf->st_mtim.tv_nsec = kbuf->st_mtime_nsec;
00122        buf->st_ctim.tv_sec = kbuf->st_ctime_sec;
00123        buf->st_ctim.tv_nsec = kbuf->st_ctime_nsec;
00124 
00125        memset (&buf->st_pad4, 0, sizeof (buf->st_pad4));
00126       }
00127       break;
00128 
00129       /* If struct stat64 is different from struct stat then
00130         _STAT_VER_KERNEL does not make sense.  */
00131     case _STAT_VER_KERNEL:
00132     default:
00133       __set_errno (EINVAL);
00134       return -1;
00135     }
00136 
00137   return 0;
00138 #endif
00139 }
00140 
00141 #if _MIPS_SIM == _ABIO32
00142 int
00143 __xstat32_conv (int vers, struct stat64 *kbuf, struct stat *buf)
00144 {
00145   switch (vers)
00146     {
00147     case _STAT_VER_LINUX:
00148       /* Convert current kernel version of `struct stat64' to
00149         `struct stat'.  The layout of the fields in the kernel's
00150         stat64 is the same as that in the user stat64; the only
00151         difference is that the latter has more trailing padding.  */
00152       buf->st_dev = kbuf->st_dev;
00153       memset (&buf->st_pad1, 0, sizeof (buf->st_pad1));
00154       buf->st_ino = kbuf->st_ino;
00155       /* Check for overflow.  */
00156       if (buf->st_ino != kbuf->st_ino)
00157        {
00158          __set_errno (EOVERFLOW);
00159          return -1;
00160        }
00161       buf->st_mode = kbuf->st_mode;
00162       buf->st_nlink = kbuf->st_nlink;
00163       buf->st_uid = kbuf->st_uid;
00164       buf->st_gid = kbuf->st_gid;
00165       buf->st_rdev = kbuf->st_rdev;
00166       memset (&buf->st_pad2, 0, sizeof (buf->st_pad2));
00167       buf->st_size = kbuf->st_size;
00168       /* Check for overflow.  */
00169       if (buf->st_size != kbuf->st_size)
00170        {
00171          __set_errno (EOVERFLOW);
00172          return -1;
00173        }
00174       buf->st_pad3 = 0;
00175       buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
00176       buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
00177       buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
00178       buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
00179       buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
00180       buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
00181       buf->st_blksize = kbuf->st_blksize;
00182       buf->st_blocks = kbuf->st_blocks;
00183       /* Check for overflow.  */
00184       if (buf->st_blocks != kbuf->st_blocks)
00185        {
00186          __set_errno (EOVERFLOW);
00187          return -1;
00188        }
00189       memset (&buf->st_pad5, 0, sizeof (buf->st_pad5));
00190       break;
00191 
00192       /* If struct stat64 is different from struct stat then
00193         _STAT_VER_KERNEL does not make sense.  */
00194     case _STAT_VER_KERNEL:
00195     default:
00196       __set_errno (EINVAL);
00197       return -1;
00198     }
00199 
00200   return 0;
00201 }
00202 #endif /* _MIPS_SIM == _ABIO32 */