Back to index

glibc  2.9
fxstatat.c
Go to the documentation of this file.
00001 /* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #define __fxstatat64 __fxstatat64_disable
00020 
00021 #include <errno.h>
00022 #include <fcntl.h>
00023 #include <stddef.h>
00024 #include <stdio.h>
00025 #include <sys/stat.h>
00026 #include <kernel_stat.h>
00027 #include <sysdep.h>
00028 #include <sys/syscall.h>
00029 #include <xstatconv.h>
00030 
00031 #undef __fxstatat64
00032 
00033 
00034 /* Get information about the file NAME in BUF.  */
00035 int
00036 __fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
00037 {
00038   if (flag & ~AT_SYMLINK_NOFOLLOW)
00039     {
00040       __set_errno (EINVAL);
00041       return -1;
00042     }
00043 
00044   char *buf = NULL;
00045 
00046   if (fd != AT_FDCWD && file[0] != '/')
00047     {
00048       size_t filelen = strlen (file);
00049       static const char procfd[] = "/proc/self/fd/%d/%s";
00050       /* Buffer for the path name we are going to use.  It consists of
00051         - the string /proc/self/fd/
00052         - the file descriptor number
00053         - the file name provided.
00054         The final NUL is included in the sizeof.   A bit of overhead
00055         due to the format elements compensates for possible negative
00056         numbers.  */
00057       size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
00058       buf = alloca (buflen);
00059 
00060       __snprintf (buf, buflen, procfd, fd, file);
00061       file = buf;
00062     }
00063 
00064   INTERNAL_SYSCALL_DECL (err);
00065   int result, errno_out;
00066   struct kernel_stat kst;
00067 
00068   if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
00069     {
00070       if (flag & AT_SYMLINK_NOFOLLOW)
00071        result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
00072       else
00073        result = INTERNAL_SYSCALL (stat64, err, 2, file, st);
00074 
00075       if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
00076        return result;
00077       errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
00078       if (errno_out != ENOSYS)
00079        goto fail;
00080       __libc_missing_axp_stat64 = 1;
00081     }
00082 
00083   if (flag & AT_SYMLINK_NOFOLLOW)
00084     result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
00085   else
00086     result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);
00087 
00088   if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
00089     return __xstat_conv (vers, &kst, st);
00090   errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
00091 
00092  fail:
00093   __atfct_seterrno (errno_out, fd, buf);
00094 
00095   return -1;
00096 }
00097 libc_hidden_def (__fxstatat)
00098 strong_alias (__fxstatat, __fxstatat64);
00099 libc_hidden_ver(__fxstatat, __fxstatat64);