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