xref: /netbsd-src/external/gpl3/gdb/dist/gnulib/import/dirfd.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
18dffb485Schristos /* dirfd.c -- return the file descriptor associated with an open DIR*
28dffb485Schristos 
3*4b169a6bSchristos    Copyright (C) 2001, 2006, 2008-2022 Free Software Foundation, Inc.
48dffb485Schristos 
5*4b169a6bSchristos    This file is free software: you can redistribute it and/or modify
6*4b169a6bSchristos    it under the terms of the GNU Lesser General Public License as
7*4b169a6bSchristos    published by the Free Software Foundation; either version 2.1 of the
8*4b169a6bSchristos    License, or (at your option) any later version.
98dffb485Schristos 
10*4b169a6bSchristos    This file is distributed in the hope that it will be useful,
118dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
128dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*4b169a6bSchristos    GNU Lesser General Public License for more details.
148dffb485Schristos 
15*4b169a6bSchristos    You should have received a copy of the GNU Lesser General Public License
168dffb485Schristos    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
178dffb485Schristos 
188dffb485Schristos /* Written by Jim Meyering. */
198dffb485Schristos 
208dffb485Schristos #include <config.h>
218dffb485Schristos 
228dffb485Schristos #include <dirent.h>
238dffb485Schristos #include <errno.h>
248dffb485Schristos 
258dffb485Schristos #ifdef __KLIBC__
268dffb485Schristos # include <stdlib.h>
278dffb485Schristos # include <io.h>
288dffb485Schristos 
298dffb485Schristos static struct dirp_fd_list
308dffb485Schristos {
318dffb485Schristos   DIR *dirp;
328dffb485Schristos   int fd;
338dffb485Schristos   struct dirp_fd_list *next;
348dffb485Schristos } *dirp_fd_start = NULL;
358dffb485Schristos 
368dffb485Schristos /* Register fd associated with dirp to dirp_fd_list. */
378dffb485Schristos int
_gl_register_dirp_fd(int fd,DIR * dirp)388dffb485Schristos _gl_register_dirp_fd (int fd, DIR *dirp)
398dffb485Schristos {
408dffb485Schristos   struct dirp_fd_list *new_dirp_fd = malloc (sizeof *new_dirp_fd);
418dffb485Schristos   if (!new_dirp_fd)
428dffb485Schristos     return -1;
438dffb485Schristos 
448dffb485Schristos   new_dirp_fd->dirp = dirp;
458dffb485Schristos   new_dirp_fd->fd = fd;
468dffb485Schristos   new_dirp_fd->next = dirp_fd_start;
478dffb485Schristos 
488dffb485Schristos   dirp_fd_start = new_dirp_fd;
498dffb485Schristos 
508dffb485Schristos   return 0;
518dffb485Schristos }
528dffb485Schristos 
538dffb485Schristos /* Unregister fd from dirp_fd_list with closing it */
548dffb485Schristos void
_gl_unregister_dirp_fd(int fd)558dffb485Schristos _gl_unregister_dirp_fd (int fd)
568dffb485Schristos {
578dffb485Schristos   struct dirp_fd_list *dirp_fd;
588dffb485Schristos   struct dirp_fd_list *dirp_fd_prev;
598dffb485Schristos 
608dffb485Schristos   for (dirp_fd_prev = NULL, dirp_fd = dirp_fd_start; dirp_fd;
618dffb485Schristos        dirp_fd_prev = dirp_fd, dirp_fd = dirp_fd->next)
628dffb485Schristos     {
638dffb485Schristos       if (dirp_fd->fd == fd)
648dffb485Schristos         {
658dffb485Schristos           if (dirp_fd_prev)
668dffb485Schristos             dirp_fd_prev->next = dirp_fd->next;
678dffb485Schristos           else  /* dirp_fd == dirp_fd_start */
688dffb485Schristos             dirp_fd_start = dirp_fd_start->next;
698dffb485Schristos 
708dffb485Schristos           close (fd);
718dffb485Schristos           free (dirp_fd);
728dffb485Schristos           break;
738dffb485Schristos         }
748dffb485Schristos     }
758dffb485Schristos }
768dffb485Schristos #endif
778dffb485Schristos 
788dffb485Schristos int
dirfd(DIR * dir_p)798dffb485Schristos dirfd (DIR *dir_p)
808dffb485Schristos {
818dffb485Schristos   int fd = DIR_TO_FD (dir_p);
828dffb485Schristos   if (fd == -1)
838dffb485Schristos #ifndef __KLIBC__
848dffb485Schristos     errno = ENOTSUP;
858dffb485Schristos #else
868dffb485Schristos     {
878dffb485Schristos       struct dirp_fd_list *dirp_fd;
888dffb485Schristos 
898dffb485Schristos       for (dirp_fd = dirp_fd_start; dirp_fd; dirp_fd = dirp_fd->next)
908dffb485Schristos         if (dirp_fd->dirp == dir_p)
918dffb485Schristos           return dirp_fd->fd;
928dffb485Schristos 
938dffb485Schristos       errno = EINVAL;
948dffb485Schristos     }
958dffb485Schristos #endif
968dffb485Schristos 
978dffb485Schristos   return fd;
988dffb485Schristos }
99