aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dirfd.c
diff options
context:
space:
mode:
authorPaul Eggert2016-01-24 14:50:47 -0800
committerPaul Eggert2016-01-24 14:51:22 -0800
commit1698036a43d9e2c55ead6216ea7156df8615da47 (patch)
tree60bb61c907536ebc38c6b301fd754028b8a9b542 /lib/dirfd.c
parentfbce4757a874cc43806eb41b8637538b101c3c69 (diff)
downloademacs-1698036a43d9e2c55ead6216ea7156df8615da47.tar.gz
emacs-1698036a43d9e2c55ead6216ea7156df8615da47.zip
Merge from gnulib
This incorporates: 2016-01-24 openat_proc_name: fix last '/' overwritten on OS/2 kLIBC 2016-01-24 closedir, dirfd, opendir: port to OpenSolaris 5.10 2016-01-15 detect utimes() correctly on OS/2 kLIBC 2016-01-15 openat_proc_name: port to OS/2 kLIBC 2016-01-14 stdint: check _INTPTR_T_DECLARED for intptr_t etc. 2016-01-14 opendir, closedir, dirfd, fdopendir: port to OS/2 kLIBC 2016-01-14 dup, dup2, fcntl: support a directory fd on OS/2 kLIBC 2016-01-14 binary-io: don't put fd in binary mode if a console on EMX 2016-01-14 sig2str: list all signals on FreeBSD >= 7 2016-01-13 acl-permissions: port to USE_ACL==0 platforms 2016-01-12 mktime: rename macro to avoid glibc clash 2016-01-12 Port "$@" to OpenIndiana ksh93 2016-01-12 Port Universal Time settings to strict POSIX * build-aux/gitlog-to-changelog, build-aux/update-copyright: * doc/misc/texinfo.tex, lib/acl-internal.c, lib/acl-internal.h: * lib/binary-io.h, lib/dirent.in.h, lib/dirfd.c, lib/dup2.c: * lib/fcntl.c, lib/fdopendir.c, lib/mktime.c, lib/openat-proc.c: * lib/sig2str.h, lib/stdint.in.h, m4/dirfd.m4, m4/dup2.m4: * m4/fcntl.m4, m4/utimes.m4: Copy from gnulib. * m4/gnulib-comp.m4: Regenerate.
Diffstat (limited to 'lib/dirfd.c')
-rw-r--r--lib/dirfd.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/lib/dirfd.c b/lib/dirfd.c
index 1ea2a6373db..a32584856a2 100644
--- a/lib/dirfd.c
+++ b/lib/dirfd.c
@@ -22,11 +22,77 @@
22#include <dirent.h> 22#include <dirent.h>
23#include <errno.h> 23#include <errno.h>
24 24
25#ifdef __KLIBC__
26# include <stdlib.h>
27# include <io.h>
28
29static 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. */
37int
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 */
54void
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
25int 78int
26dirfd (DIR *dir_p) 79dirfd (DIR *dir_p)
27{ 80{
28 int fd = DIR_TO_FD (dir_p); 81 int fd = DIR_TO_FD (dir_p);
29 if (fd == -1) 82 if (fd == -1)
83#ifndef __KLIBC__
30 errno = ENOTSUP; 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
31 return fd; 97 return fd;
32} 98}