Exemplo n.º 1
0
DIR *
__fdopendir (int fd)
{
  struct stat64 statbuf;

  if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
    return NULL;
  if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
    {
      __set_errno (ENOTDIR);
      return NULL;
    }

  /* Make sure the descriptor allows for reading.  */
  int flags = __fcntl (fd, F_GETFL);
  if (__builtin_expect (flags == -1, 0))
    return NULL;
  if (__builtin_expect ((flags & O_ACCMODE) == O_WRONLY, 0))
    {
      __set_errno (EINVAL);
      return NULL;
    }

  return __alloc_dir (fd, false, flags, &statbuf);
}
Exemplo n.º 2
0
/* Open a directory stream on NAME.  */
DIR *
__opendir (const char *name)
{
  struct stat64 statbuf;

  if (__builtin_expect (name[0], '\1') == '\0')
    {
      /* POSIX.1-1990 says an empty name gets ENOENT;
	 but `open' might like it fine.  */
      __set_errno (ENOENT);
      return NULL;
    }

#ifdef O_DIRECTORY
  /* Test whether O_DIRECTORY works.  */
  if (o_directory_works == 0)
    tryopen_o_directory ();

  /* We can skip the expensive `stat' call if O_DIRECTORY works.  */
  if (o_directory_works < 0)
#endif
    {
      /* We first have to check whether the name is for a directory.  We
	 cannot do this after the open() call since the open/close operation
	 performed on, say, a tape device might have undesirable effects.  */
      if (__builtin_expect (__xstat64 (_STAT_VER, name, &statbuf), 0) < 0)
	return NULL;
      if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
	{
	  __set_errno (ENOTDIR);
	  return NULL;
	 }
    }

  int fd = open_not_cancel_2 (name, O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE);
  if (__builtin_expect (fd, 0) < 0)
    return NULL;

  /* Now make sure this really is a directory and nothing changed since
     the `stat' call.  We do not have to perform the test for the
     descriptor being associated with a directory if we know the
     O_DIRECTORY flag is honored by the kernel.  */
  if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
    goto lose;
#ifdef O_DIRECTORY
  if (o_directory_works <= 0)
#endif
    {
      if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
	{
	  __set_errno (ENOTDIR);
	lose:
	  close_not_cancel_no_status (fd);
	  return NULL;
	}
    }

  return __alloc_dir (fd, true, &statbuf);
}
Exemplo n.º 3
0
static DIR *
opendir_tail (int fd)
{
  if (__glibc_unlikely (fd < 0))
    return NULL;

  /* Now make sure this really is a directory and nothing changed since the
     `stat' call.  The S_ISDIR check is superfluous if O_DIRECTORY works,
     but it's cheap and we need the stat call for st_blksize anyway.  */
  struct stat64 statbuf;
  if (__glibc_unlikely (__fxstat64 (_STAT_VER, fd, &statbuf) < 0))
    goto lose;
  if (__glibc_unlikely (! S_ISDIR (statbuf.st_mode)))
    {
      __set_errno (ENOTDIR);
    lose:
      close_not_cancel_no_status (fd);
      return NULL;
    }

  return __alloc_dir (fd, true, 0, &statbuf);
}
Exemplo n.º 4
0
Arquivo: opendir.c Projeto: dreal/tai
internal_function
__opendirat (int dfd, const char *name)
{
  struct stat64 statbuf;
  struct stat64 *statp = NULL;

  if (__builtin_expect (name[0], '\1') == '\0')
    {
      /* POSIX.1-1990 says an empty name gets ENOENT;
	 but `open' might like it fine.  */
      __set_errno (ENOENT);
      return NULL;
    }

#ifdef O_DIRECTORY
  /* Test whether O_DIRECTORY works.  */
  if (o_directory_works == 0)
    tryopen_o_directory ();

  /* We can skip the expensive `stat' call if O_DIRECTORY works.  */
  if (o_directory_works < 0)
#endif
    {
      /* We first have to check whether the name is for a directory.  We
	 cannot do this after the open() call since the open/close operation
	 performed on, say, a tape device might have undesirable effects.  */
      if (__builtin_expect (__xstat64 (_STAT_VER, name, &statbuf), 0) < 0)
	return NULL;
      if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
	{
	  __set_errno (ENOTDIR);
	  return NULL;
	 }
    }

  int flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE;
#ifdef O_CLOEXEC
  flags |= O_CLOEXEC;
#endif
  int fd;
#ifdef IS_IN_rtld
  assert (dfd == AT_FDCWD);
  fd = open_not_cancel_2 (name, flags);
#else
  fd = openat_not_cancel_3 (dfd, name, flags);
#endif
  if (__builtin_expect (fd, 0) < 0)
    return NULL;

#ifdef O_DIRECTORY
  if (o_directory_works <= 0)
#endif
    {
      /* Now make sure this really is a directory and nothing changed since
	 the `stat' call.  */
      if (__builtin_expect (__fxstat64 (_STAT_VER, fd, &statbuf), 0) < 0)
	goto lose;
      if (__builtin_expect (! S_ISDIR (statbuf.st_mode), 0))
	{
	  __set_errno (ENOTDIR);
	lose:
	  close_not_cancel_no_status (fd);
	  return NULL;
	}
      statp = &statbuf;
    }

  return __alloc_dir (fd, true, 0, statp);
}