(root)/
bison-3.8.2/
lib/
dirfd.c
       1  /* dirfd.c -- return the file descriptor associated with an open DIR*
       2  
       3     Copyright (C) 2001, 2006, 2008-2021 Free Software Foundation, Inc.
       4  
       5     This file is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     License, or (at your option) any later version.
       9  
      10     This file is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Written by Jim Meyering. */
      19  
      20  #include <config.h>
      21  
      22  #include <dirent.h>
      23  #include <errno.h>
      24  
      25  #ifdef __KLIBC__
      26  # include <stdlib.h>
      27  # include <io.h>
      28  
      29  static struct dirp_fd_list
      30  {
      31    DIR *dirp;
      32    int fd;
      33    struct dirp_fd_list *next;
      34  } *dirp_fd_start = NULL;
      35  
      36  /* Register fd associated with dirp to dirp_fd_list. */
      37  int
      38  _gl_register_dirp_fd (int fd, DIR *dirp)
      39  {
      40    struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd);
      41    if (!new_dirp_fd)
      42      return -1;
      43  
      44    new_dirp_fd->dirp = dirp;
      45    new_dirp_fd->fd = fd;
      46    new_dirp_fd->next = dirp_fd_start;
      47  
      48    dirp_fd_start = new_dirp_fd;
      49  
      50    return 0;
      51  }
      52  
      53  /* Unregister fd from dirp_fd_list with closing it */
      54  void
      55  _gl_unregister_dirp_fd (int fd)
      56  {
      57    struct dirp_fd_list *dirp_fd;
      58    struct dirp_fd_list *dirp_fd_prev;
      59  
      60    for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
      61         dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
      62      {
      63        if (dirp_fd->fd == fd)
      64          {
      65            if (dirp_fd_prev)
      66              dirp_fd_prev->next = dirp_fd->next;
      67            else  /* dirp_fd == dirp_fd_start */
      68              dirp_fd_start = dirp_fd_start->next;
      69  
      70            close (fd);
      71            free (dirp_fd);
      72            break;
      73          }
      74      }
      75  }
      76  #endif
      77  
      78  int
      79  dirfd (DIR *dir_p)
      80  {
      81    int fd = DIR_TO_FD (dir_p);
      82    if (fd == -1)
      83  #ifndef __KLIBC__
      84      errno = ENOTSUP;
      85  #else
      86      {
      87        struct dirp_fd_list *dirp_fd;
      88  
      89        for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
      90          if (dirp_fd->dirp == dir_p)
      91            return dirp_fd->fd;
      92  
      93        errno = EINVAL;
      94      }
      95  #endif
      96  
      97    return fd;
      98  }