Exemplo n.º 1
0
int stat(const char *file_name, struct stat *buf)
{
	struct kernel_stat kbuf;
	char abspath[PATH_MAX], *dpath;
	long ret;
	int sysid;
	void *rbuf, *off;
	size_t sz;

    dpath = sclib_get_path(abspath, file_name, &sysid, &sz);
	if (sysid != SYSCALL_SYSID_LOCAL) {
		rbuf = sclib_memory_alloc(&sclib_data[sysid], sizeof(struct kernel_stat) + sz);
		SCLIB_MEM_RET(rbuf, ret);
		memcpy(rbuf + sizeof(struct kernel_stat), dpath, sz);
		off = sclib_mem(sysid, rbuf);
		ret = SCLIB_REMOTE_CALL(sysid, stat, 2, off + sizeof(struct kernel_stat), off);
		if (ret == 0)
			__xstat_conv(rbuf, buf);
		sclib_memory_free(&sclib_data[sysid], rbuf);
	} else {
		ret = SCLIB_LOCAL_CALL(stat, 2, dpath, &kbuf);
		if (ret == 0)
			__xstat_conv(&kbuf, buf);
	}
error_mem:
	SCLIB_ERR_RET(ret);
	return ret;
}
Exemplo n.º 2
0
int lstat(const char *file_name, struct stat *buf)
{
	int result;
#if defined __NR_lstat64 || defined __NR_fstatat64
	/* normal stat call has limited values for various stat elements
	 * e.g. uid device major/minor etc.
	 * so we use 64 variant if available
	 * in order to get newer versions of stat elements
	 */
	struct kernel_stat64 kbuf;
# ifdef __NR_lstat64
	result = INLINE_SYSCALL(lstat64, 2, file_name, &kbuf);
# else
	result = INLINE_SYSCALL(fstatat64, 4, AT_FDCWD, file_name, &kbuf, AT_SYMLINK_NOFOLLOW);
# endif
	if (result == 0) {
		__xstat32_conv(&kbuf, buf);
	}
#else
	struct kernel_stat kbuf;

	result = INLINE_SYSCALL(lstat, 2, file_name, &kbuf);
	if (result == 0) {
		__xstat_conv(&kbuf, buf);
	}
#endif
	return result;
}
Exemplo n.º 3
0
int stat(const char *file_name, struct stat *buf)
{
	int result;
	struct kernel_stat kbuf;

	result = __syscall_stat(file_name, &kbuf);
	if (result == 0) {
		__xstat_conv(&kbuf, buf);
	}
	return result;
}
Exemplo n.º 4
0
int fstat(int fd, struct stat *buf)
{
	int result;
	struct kernel_stat kbuf;

	result = __syscall_fstat(fd, &kbuf);
	if (result == 0) {
		__xstat_conv(&kbuf, buf);
	}
	return result;
}
Exemplo n.º 5
0
/* Get information about the file FD in BUF.  */
int
__fxstat (int vers, int fd, struct stat *buf)
{
#if __ASSUME_STAT64_SYSCALL == 0
  struct kernel_stat kbuf;
#endif
  int result;

  if (vers == _STAT_VER_KERNEL)
    return INLINE_SYSCALL (fstat, 2, fd, CHECK_1 ((struct kernel_stat *) buf));

#if __ASSUME_STAT64_SYSCALL > 0
  {
    struct stat64 buf64;

    result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));
    if (result == 0)
      result = __xstat32_conv (vers, &buf64, buf);
    return result;
  }
#else

# if defined __NR_stat64
  /* To support 32 bit UIDs, we have to use stat64.  The normal stat call only returns
     16 bit UIDs.  */
  if (! __have_no_stat64)
    {
      struct stat64 buf64;

      result = INLINE_SYSCALL (fstat64, 2, fd, __ptrvalue (&buf64));

      if (result == 0)
	result = __xstat32_conv (vers, &buf64, buf);

      if (result != -1 || errno != ENOSYS)
	return result;

      __have_no_stat64 = 1;
    }
# endif

  result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf));
  if (result == 0)
    result = __xstat_conv (vers, &kbuf, buf);

  return result;
#endif  /* __ASSUME_STAT64_SYSCALL  */
}
Exemplo n.º 6
0
/* Get information about the file NAME in BUF.  */
int
__xstat (int vers, const char *name, struct stat *buf)
{
  if (vers == _STAT_VER_KERNEL)
    return INLINE_SYSCALL (stat, 2, name, buf);

#ifdef STAT_IS_KERNEL_STAT
  return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
#else
  struct kernel_stat kbuf;
  int result;

  result = INLINE_SYSCALL (stat, 2, name, &kbuf);
  if (result == 0)
    result = __xstat_conv (vers, &kbuf, buf);

  return result;
#endif
}
Exemplo n.º 7
0
/* Get information about the file NAME in BUF.  */
int
__xstat (int vers, const char *name, struct stat *buf)
{
  if (vers == _STAT_VER_KERNEL)
    return INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
			   CHECK_1 ((struct kernel_stat *) buf));

#ifdef STAT_IS_KERNEL_STAT
  errno = EINVAL;
  return -1;
#else
  struct kernel_stat kbuf;
  int result;

  result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name),
			   __ptrvalue (&kbuf));
  if (result == 0)
    result = __xstat_conv (vers, &kbuf, buf);

  return result;
#endif
}
Exemplo n.º 8
0
/* Get information about the file NAME in BUF.  */
int
__xstat (int vers, const char *name, struct stat *buf)
{
  INTERNAL_SYSCALL_DECL (err);
  int result;
  struct kernel_stat kbuf;

  if (vers == _STAT_VER_KERNEL64)
    {
      result = INTERNAL_SYSCALL (stat64, err, 2, name, buf);
      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	return result;
      __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
      return -1;
    }

  result = INTERNAL_SYSCALL (stat, err, 2, name, &kbuf);
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat_conv (vers, &kbuf, buf);
  __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
  return -1;
}
Exemplo n.º 9
0
/* Get information about the file NAME in BUF.  */
int
__xstat (int vers, const char *name, struct stat *buf)
{
    INTERNAL_SYSCALL_DECL (err);
    int result;
    struct kernel_stat kbuf;

#if __ASSUME_STAT64_SYSCALL > 0
    if (vers == _STAT_VER_KERNEL64)
    {
        result = INTERNAL_SYSCALL (stat64, err, 2, name, buf);
        if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
            return result;
        __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
        return -1;
    }
#elif defined __NR_stat64
    if (vers == _STAT_VER_KERNEL64 && !__libc_missing_axp_stat64)
    {
        int errno_out;
        result = INTERNAL_SYSCALL (stat64, err, 2, name, buf);
        if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
            return result;
        errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
        if (errno_out != ENOSYS)
        {
            __set_errno (errno_out);
            return -1;
        }
        __libc_missing_axp_stat64 = 1;
    }
#endif

    result = INTERNAL_SYSCALL (stat, err, 2, name, &kbuf);
    if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
        return __xstat_conv (vers, &kbuf, buf);
    __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
    return -1;
}
Exemplo n.º 10
0
int stat(const char *file_name, struct stat *buf)
{
	int result;
# ifdef __NR_stat64
	/* normal stat call has limited values for various stat elements
	 * e.g. uid device major/minor etc.
	 * so we use 64 variant if available
	 * in order to get newer versions of stat elements
	 */
	struct kernel_stat64 kbuf;
	result = INLINE_SYSCALL(stat64, 2, file_name, &kbuf);
	if (result == 0) {
		__xstat32_conv(&kbuf, buf);
	}
# else
	struct kernel_stat kbuf;

	result = INLINE_SYSCALL(stat, 2, file_name, &kbuf);
	if (result == 0) {
		__xstat_conv(&kbuf, buf);
	}
# endif /* __NR_stat64 */
	return result;
}
Exemplo n.º 11
0
/* Get information about the file NAME in BUF.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  int result;
  INTERNAL_SYSCALL_DECL (err);
#ifdef STAT_IS_KERNEL_STAT
# define kst (*st)
#else
  struct kernel_stat kst;
#endif

  result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
  if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    {
#ifdef STAT_IS_KERNEL_STAT
      return 0;
#else
      return __xstat_conv (vers, &kst, st);
#endif
    }
  else
    return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result,
								      err));
}
Exemplo n.º 12
0
/* Get information about the file NAME in BUF.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
    int result;
    INTERNAL_SYSCALL_DECL (err);
#ifdef STAT_IS_KERNEL_STAT
# define kst (*st)
#else
    struct kernel_stat kst;
#endif

#ifdef __NR_newfstatat
# ifndef __ASSUME_ATFCTS
    if (__have_atfcts >= 0)
# endif
    {
        result = INTERNAL_SYSCALL (newfstatat, err, 4, fd, file, &kst, flag);
# ifndef __ASSUME_ATFCTS
        if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
                && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
            __have_atfcts = -1;
        else
# endif
            if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
            {
#ifdef STAT_IS_KERNEL_STAT
                return 0;
#else
                return __xstat_conv (vers, &kst, st);
#endif
            }
            else
            {
                __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
                return -1;
            }
    }
#endif

    if (flag & ~AT_SYMLINK_NOFOLLOW)
    {
        __set_errno (EINVAL);
        return -1;
    }

    char *buf = NULL;

    if (fd != AT_FDCWD && file[0] != '/')
    {
        size_t filelen = strlen (file);
        if (__builtin_expect (filelen == 0, 0))
        {
            __set_errno (ENOENT);
            return -1;
        }

        static const char procfd[] = "/proc/self/fd/%d/%s";
        /* Buffer for the path name we are going to use.  It consists of
        - the string /proc/self/fd/
         - the file descriptor number
         - the file name provided.
         The final NUL is included in the sizeof.   A bit of overhead
         due to the format elements compensates for possible negative
         numbers.  */
        size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
        buf = alloca (buflen);

        __snprintf (buf, buflen, procfd, fd, file);
        file = buf;
    }

    if (vers == _STAT_VER_KERNEL)
    {
        if (flag & AT_SYMLINK_NOFOLLOW)
            result = INTERNAL_SYSCALL (lstat, err, 2, file,
                                       (struct kernel_stat *) st);
        else
            result = INTERNAL_SYSCALL (stat, err, 2, file,
                                       (struct kernel_stat *) st);

        if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
            return result;
    }
#ifdef STAT_IS_KERNEL_STAT
    else
    {
        __set_errno (EINVAL);
        return -1;
    }
#else
    if (flag & AT_SYMLINK_NOFOLLOW)
        result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
    else
        result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);

    if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
        return __xstat_conv (vers, &kst, st);
#endif

    __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);

    return -1;
}
Exemplo n.º 13
0
int
__xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf)
{
#ifdef XSTAT_IS_XSTAT64
  return __xstat_conv (vers, kbuf, ubuf);
#else
  switch (vers)
    {
    case _STAT_VER_LINUX:
      {
	struct stat64 *buf = ubuf;

	/* Convert to current kernel version of `struct stat64'.  */
	buf->st_dev = kbuf->st_dev;
#ifdef _HAVE_STAT64___PAD1
	buf->__pad1 = 0;
#endif
	buf->st_ino = kbuf->st_ino;
#ifdef _HAVE_STAT64___ST_INO
	buf->__st_ino = kbuf->st_ino;
#endif
	buf->st_mode = kbuf->st_mode;
	buf->st_nlink = kbuf->st_nlink;
	buf->st_uid = kbuf->st_uid;
	buf->st_gid = kbuf->st_gid;
	buf->st_rdev = kbuf->st_rdev;
#ifdef _HAVE_STAT64___PAD2
	buf->__pad2 = 0;
#endif
	buf->st_size = kbuf->st_size;
	buf->st_blksize = kbuf->st_blksize;
	buf->st_blocks = kbuf->st_blocks;
#ifdef _HAVE_STAT64_NSEC
	buf->st_atim.tv_sec = kbuf->st_atim.tv_sec;
	buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec;
	buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec;
	buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec;
	buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec;
	buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec;
#else
	buf->st_atime = kbuf->st_atime;
	buf->st_mtime = kbuf->st_mtime;
	buf->st_ctime = kbuf->st_ctime;
#endif
#ifdef _HAVE_STAT64___UNUSED1
	buf->__glibc_reserved1 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED2
	buf->__glibc_reserved2 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED3
	buf->__glibc_reserved3 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED4
	buf->__glibc_reserved4 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED5
	buf->__glibc_reserved5 = 0;
#endif
      }
      break;

      /* If struct stat64 is different from struct stat then
	 _STAT_VER_KERNEL does not make sense.  */
    case _STAT_VER_KERNEL:
    default:
      __set_errno (EINVAL);
      return -1;
    }

  return 0;
#endif
}
Exemplo n.º 14
0
/* Get information about the file NAME relative to FD in ST.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  int result;
  INTERNAL_SYSCALL_DECL (err);
  struct stat64 st64;

#ifdef __NR_fstatat64
# ifndef __ASSUME_ATFCTS
  if (__have_atfcts >= 0)
# endif
    {
      result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, &st64, flag);
# ifndef __ASSUME_ATFCTS
      if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  && INTERNAL_SYSCALL_ERRNO (result, err) == ENOSYS)
	__have_atfcts = -1;
      else
# endif
	if (!__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	  return __xstat32_conv (vers, &st64, st);
	else
	  {
	    __set_errno (INTERNAL_SYSCALL_ERRNO (result, err));
	    return -1;
	  }
    }
#endif

#ifndef __ASSUME_ATFCTS
  if (__builtin_expect (flag & ~AT_SYMLINK_NOFOLLOW, 0))
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

# if __ASSUME_STAT64_SYSCALL == 0
  struct kernel_stat kst;
# endif
  if (vers == _STAT_VER_KERNEL)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));
      else
	result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
				   CHECK_1 ((struct kernel_stat *) st));
      goto out;
    }

# if __ASSUME_STAT64_SYSCALL > 0

  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
			       __ptrvalue (&st64));
  else
    result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
			       __ptrvalue (&st64));
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat32_conv (vers, &st64, st);
# else
#  if defined __NR_stat64
  /* To support 32 bit UIDs, we have to use stat64.  The normal stat
     call only returns 16 bit UIDs.  */
  if (! __have_no_stat64)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat64, err, 2, CHECK_STRING (file),
				   __ptrvalue (&st64));
      else
	result = INTERNAL_SYSCALL (stat64, err, 2, CHECK_STRING (file),
				   __ptrvalue (&st64));

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	result = __xstat32_conv (vers, &st64, st);

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1)
	  || INTERNAL_SYSCALL_ERRNO (result, err) != ENOSYS)
	goto out;

      __have_no_stat64 = 1;
    }
#  endif
  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  else
    result = INTERNAL_SYSCALL (stat, err, 2, CHECK_STRING (file),
			       __ptrvalue (&kst));
  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat_conv (vers, &kst, st);
# endif  /* __ASSUME_STAT64_SYSCALL  */

 out:
  if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (result, err), 0))
    {
      __atfct_seterrno (INTERNAL_SYSCALL_ERRNO (result, err), fd, buf);
      result = -1;
    }

  return result;
#endif
}
Exemplo n.º 15
0
/* Get information about the file NAME in BUF.  */
int
__fxstatat (int vers, int fd, const char *file, struct stat *st, int flag)
{
  INTERNAL_SYSCALL_DECL (err);
  int result, errno_out;

  /* ??? The __fxstatat entry point is new enough that it must be using
     vers == _STAT_VER_KERNEL64.  For the benefit of dl-fxstatat64.c, we
     cannot actually check this, lest the compiler not optimize the rest
     of the function away.  */

#ifdef __NR_fstatat64
  if (__have_atfcts >= 0)
    {
      result = INTERNAL_SYSCALL (fstatat64, err, 4, fd, file, st, flag);
      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	return result;
      errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
#ifndef __ASSUME_ATFCTS
      if (errno_out == ENOSYS)
	__have_atfcts = -1;
      else
#endif
	{
	  __set_errno (errno_out);
	  return -1;
	}
    }
#endif /* __NR_fstatat64 */

  if (flag & ~AT_SYMLINK_NOFOLLOW)
    {
      __set_errno (EINVAL);
      return -1;
    }

  char *buf = NULL;

  if (fd != AT_FDCWD && file[0] != '/')
    {
      size_t filelen = strlen (file);
      if (__builtin_expect (filelen == 0, 0))
        {
          __set_errno (ENOENT);
          return -1;
        }

      static const char procfd[] = "/proc/self/fd/%d/%s";
      /* Buffer for the path name we are going to use.  It consists of
	 - the string /proc/self/fd/
	 - the file descriptor number
	 - the file name provided.
	 The final NUL is included in the sizeof.   A bit of overhead
	 due to the format elements compensates for possible negative
	 numbers.  */
      size_t buflen = sizeof (procfd) + sizeof (int) * 3 + filelen;
      buf = alloca (buflen);

      __snprintf (buf, buflen, procfd, fd, file);
      file = buf;
    }

#ifdef __NR_stat64
  if (!__libc_missing_axp_stat64)
    {
      if (flag & AT_SYMLINK_NOFOLLOW)
	result = INTERNAL_SYSCALL (lstat64, err, 2, file, st);
      else
	result = INTERNAL_SYSCALL (stat64, err, 2, file, st);

      if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
	return result;
      errno_out = INTERNAL_SYSCALL_ERRNO (result, err);
# if __ASSUME_STAT64_SYSCALL == 0
      if (errno_out == ENOSYS)
	__libc_missing_axp_stat64 = 1;
      else
# endif
	goto fail;
    }
#endif /* __NR_stat64 */

  struct kernel_stat kst;

  if (flag & AT_SYMLINK_NOFOLLOW)
    result = INTERNAL_SYSCALL (lstat, err, 2, file, &kst);
  else
    result = INTERNAL_SYSCALL (stat, err, 2, file, &kst);

  if (__builtin_expect (!INTERNAL_SYSCALL_ERROR_P (result, err), 1))
    return __xstat_conv (vers, &kst, st);
  errno_out = INTERNAL_SYSCALL_ERRNO (result, err);

 fail:
  __atfct_seterrno (errno_out, fd, buf);

  return -1;
}