Blame lib/dirfd.c

Packit Service c30d13
/* dirfd.c -- return the file descriptor associated with an open DIR*
Packit Service c30d13
Packit Service c30d13
   Copyright (C) 2001, 2006, 2008-2018 Free Software Foundation, Inc.
Packit Service c30d13
Packit Service c30d13
   This program is free software: you can redistribute it and/or modify
Packit Service c30d13
   it under the terms of the GNU General Public License as published by
Packit Service c30d13
   the Free Software Foundation; either version 3 of the License, or
Packit Service c30d13
   (at your option) any later version.
Packit Service c30d13
Packit Service c30d13
   This program is distributed in the hope that it will be useful,
Packit Service c30d13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service c30d13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service c30d13
   GNU General Public License for more details.
Packit Service c30d13
Packit Service c30d13
   You should have received a copy of the GNU General Public License
Packit Service c30d13
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service c30d13
Packit Service c30d13
/* Written by Jim Meyering. */
Packit Service c30d13
Packit Service c30d13
#include <config.h>
Packit Service c30d13
Packit Service c30d13
#include <dirent.h>
Packit Service c30d13
#include <errno.h>
Packit Service c30d13
Packit Service c30d13
#ifdef __KLIBC__
Packit Service c30d13
# include <stdlib.h>
Packit Service c30d13
# include <io.h>
Packit Service c30d13
Packit Service c30d13
static struct dirp_fd_list
Packit Service c30d13
{
Packit Service c30d13
  DIR *dirp;
Packit Service c30d13
  int fd;
Packit Service c30d13
  struct dirp_fd_list *next;
Packit Service c30d13
} *dirp_fd_start = NULL;
Packit Service c30d13
Packit Service c30d13
/* Register fd associated with dirp to dirp_fd_list. */
Packit Service c30d13
int
Packit Service c30d13
_gl_register_dirp_fd (int fd, DIR *dirp)
Packit Service c30d13
{
Packit Service c30d13
  struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd);
Packit Service c30d13
  if (!new_dirp_fd)
Packit Service c30d13
    return -1;
Packit Service c30d13
Packit Service c30d13
  new_dirp_fd->dirp = dirp;
Packit Service c30d13
  new_dirp_fd->fd = fd;
Packit Service c30d13
  new_dirp_fd->next = dirp_fd_start;
Packit Service c30d13
Packit Service c30d13
  dirp_fd_start = new_dirp_fd;
Packit Service c30d13
Packit Service c30d13
  return 0;
Packit Service c30d13
}
Packit Service c30d13
Packit Service c30d13
/* Unregister fd from dirp_fd_list with closing it */
Packit Service c30d13
void
Packit Service c30d13
_gl_unregister_dirp_fd (int fd)
Packit Service c30d13
{
Packit Service c30d13
  struct dirp_fd_list *dirp_fd;
Packit Service c30d13
  struct dirp_fd_list *dirp_fd_prev;
Packit Service c30d13
Packit Service c30d13
  for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
Packit Service c30d13
       dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
Packit Service c30d13
    {
Packit Service c30d13
      if (dirp_fd->fd == fd)
Packit Service c30d13
        {
Packit Service c30d13
          if (dirp_fd_prev)
Packit Service c30d13
            dirp_fd_prev->next = dirp_fd->next;
Packit Service c30d13
          else  /* dirp_fd == dirp_fd_start */
Packit Service c30d13
            dirp_fd_start = dirp_fd_start->next;
Packit Service c30d13
Packit Service c30d13
          close (fd);
Packit Service c30d13
          free (dirp_fd);
Packit Service c30d13
          break;
Packit Service c30d13
        }
Packit Service c30d13
    }
Packit Service c30d13
}
Packit Service c30d13
#endif
Packit Service c30d13
Packit Service c30d13
int
Packit Service c30d13
dirfd (DIR *dir_p)
Packit Service c30d13
{
Packit Service c30d13
  int fd = DIR_TO_FD (dir_p);
Packit Service c30d13
  if (fd == -1)
Packit Service c30d13
#ifndef __KLIBC__
Packit Service c30d13
    errno = ENOTSUP;
Packit Service c30d13
#else
Packit Service c30d13
    {
Packit Service c30d13
      struct dirp_fd_list *dirp_fd;
Packit Service c30d13
Packit Service c30d13
      for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
Packit Service c30d13
        if (dirp_fd->dirp == dir_p)
Packit Service c30d13
          return dirp_fd->fd;
Packit Service c30d13
Packit Service c30d13
      errno = EINVAL;
Packit Service c30d13
    }
Packit Service c30d13
#endif
Packit Service c30d13
Packit Service c30d13
  return fd;
Packit Service c30d13
}