Back to index

glibc  2.9
Defines | Functions
opendir.c File Reference
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dirstream.h>
#include <not-cancel.h>
#include <kernel-features.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define EXTRA_FLAGS   0

Functions

DIR * __opendir (const char *name)
 weak_alias (__opendir, opendir)
DIR *internal_function __alloc_dir (int fd, bool close_fd, const struct stat64 *statp)

Define Documentation

#define EXTRA_FLAGS   0

Definition at line 75 of file opendir.c.


Function Documentation

DIR* internal_function __alloc_dir ( int  fd,
bool  close_fd,
const struct stat64 statp 
)

Definition at line 161 of file opendir.c.

{
  /* We always have to set the close-on-exit flag if the user provided
     the file descriptor.  Otherwise only if we have no working
     O_CLOEXEC support.  */
#ifdef O_CLOEXEC
  if (! close_fd || ! check_have_o_cloexec (fd))
#endif
    {
      if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
       goto lose;
    }

  const size_t default_allocation = (BUFSIZ < sizeof (struct dirent64)
                                 ? sizeof (struct dirent64) : BUFSIZ);
  size_t allocation;
#ifdef _STATBUF_ST_BLKSIZE
  if (__builtin_expect ((size_t) statp->st_blksize >= sizeof (struct dirent64),
                     1))
    allocation = statp->st_blksize;
  else
#endif
    allocation = default_allocation;

  DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation);
  if (dirp == NULL)
    {
#ifdef _STATBUF_ST_BLKSIZE
      if (allocation == statp->st_blksize
         && allocation != default_allocation)
       {
         allocation = default_allocation;
         dirp = (DIR *) malloc (sizeof (DIR) + allocation);
       }
      if (dirp == NULL)
#endif
      lose:
       {
         if (close_fd)
           {
             int save_errno = errno;
             close_not_cancel_no_status (fd);
             __set_errno (save_errno);
           }
         return NULL;
       }
    }

  dirp->fd = fd;
#ifndef NOT_IN_libc
  __libc_lock_init (dirp->lock);
#endif
  dirp->allocation = allocation;
  dirp->size = 0;
  dirp->offset = 0;
  dirp->filepos = 0;

  return dirp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

DIR* __opendir ( const char *  name)

Definition at line 81 of file opendir.c.

{
  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 flags = O_RDONLY|O_NDELAY|EXTRA_FLAGS|O_LARGEFILE;
#ifdef O_CLOEXEC
  flags |= O_CLOEXEC;
#endif
  int fd = open_not_cancel_2 (name, flags);
  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);
}

Here is the call graph for this function:

Definition at line 143 of file opendir.c.

{
  if (__have_o_cloexec == 0)
    __have_o_cloexec = (__fcntl (fd, F_GETFD, 0) & FD_CLOEXEC) == 0 ? -1 : 1;
  return __have_o_cloexec > 0;
}

Here is the call graph for this function: