Example #1
0
internal_function
__alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
{
  /* 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;
}
Example #2
0
internal_function
__alloc_dir (int fd, bool close_fd, int flags, const struct stat64 *statp)
{
  /* 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 && (flags & O_CLOEXEC) == 0)
      || ! check_have_o_cloexec (fd))
#endif
    {
      if (__builtin_expect (__fcntl (fd, F_SETFD, FD_CLOEXEC), 0) < 0)
	goto lose;
    }

  const size_t default_allocation = (4 * BUFSIZ < sizeof (struct dirent64)
				     ? sizeof (struct dirent64) : 4 * BUFSIZ);
  const size_t small_allocation = (BUFSIZ < sizeof (struct dirent64)
				   ? sizeof (struct dirent64) : BUFSIZ);
  size_t allocation = default_allocation;
#ifdef _STATBUF_ST_BLKSIZE
  /* Increase allocation if requested, but not if the value appears to
     be bogus.  */
  if (statp != NULL)
    allocation = MIN (MAX ((size_t) statp->st_blksize, default_allocation),
		      MAX_DIR_BUFFER_SIZE);
#endif

  DIR *dirp = (DIR *) malloc (sizeof (DIR) + allocation);
  if (dirp == NULL)
    {
      allocation = small_allocation;
      dirp = (DIR *) malloc (sizeof (DIR) + allocation);

      if (dirp == NULL)
      lose:
	{
	  if (close_fd)
	    {
	      int save_errno = errno;
	      close_not_cancel_no_status (fd);
	      __set_errno (save_errno);
	    }
	  return NULL;
	}
    }

  dirp->fd = fd;
#if IS_IN (libc)
  __libc_lock_init (dirp->lock);
#endif
  dirp->allocation = allocation;
  dirp->size = 0;
  dirp->offset = 0;
  dirp->filepos = 0;
  dirp->errcode = 0;

  return dirp;
}