root/lib/dirfd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _gl_register_dirp_fd
  2. _gl_unregister_dirp_fd
  3. dirfd

     1 /* dirfd.c -- return the file descriptor associated with an open DIR*
     2 
     3    Copyright (C) 2001, 2006, 2008-2023 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 #if GNULIB_defined_DIR
    26 # include "dirent-private.h"
    27 #endif
    28 
    29 #ifdef __KLIBC__
    30 # include <stdlib.h>
    31 # include <io.h>
    32 
    33 static struct dirp_fd_list
    34 {
    35   DIR *dirp;
    36   int fd;
    37   struct dirp_fd_list *next;
    38 } *dirp_fd_start = NULL;
    39 
    40 /* Register fd associated with dirp to dirp_fd_list. */
    41 int
    42 _gl_register_dirp_fd (int fd, DIR *dirp)
    43 {
    44   struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd);
    45   if (!new_dirp_fd)
    46     return -1;
    47 
    48   new_dirp_fd->dirp = dirp;
    49   new_dirp_fd->fd = fd;
    50   new_dirp_fd->next = dirp_fd_start;
    51 
    52   dirp_fd_start = new_dirp_fd;
    53 
    54   return 0;
    55 }
    56 
    57 /* Unregister fd from dirp_fd_list with closing it */
    58 void
    59 _gl_unregister_dirp_fd (int fd)
    60 {
    61   struct dirp_fd_list *dirp_fd;
    62   struct dirp_fd_list *dirp_fd_prev;
    63 
    64   for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
    65        dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
    66     {
    67       if (dirp_fd->fd == fd)
    68         {
    69           if (dirp_fd_prev)
    70             dirp_fd_prev->next = dirp_fd->next;
    71           else  /* dirp_fd == dirp_fd_start */
    72             dirp_fd_start = dirp_fd_start->next;
    73 
    74           close (fd);
    75           free (dirp_fd);
    76           break;
    77         }
    78     }
    79 }
    80 #endif
    81 
    82 int
    83 dirfd (DIR *dir_p)
    84 {
    85 #if GNULIB_defined_DIR
    86   int fd = dir_p->fd_to_close;
    87   if (fd == -1)
    88     errno = EINVAL;
    89   return fd;
    90 #else
    91   int fd = DIR_TO_FD (dir_p);
    92   if (fd == -1)
    93 # ifndef __KLIBC__
    94     errno = ENOTSUP;
    95 # else
    96     {
    97       struct dirp_fd_list *dirp_fd;
    98 
    99       for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
   100         if (dirp_fd->dirp == dir_p)
   101           return dirp_fd->fd;
   102 
   103       errno = EINVAL;
   104     }
   105 # endif
   106 
   107   return fd;
   108 #endif
   109 }

/* [<][>][^][v][top][bottom][index][help] */