xref: /dflybsd-src/contrib/grep/lib/opendirat.c (revision 91b9ed38d3db6a8a8ac5b66da1d43e6e331e259a)
1*09d4459fSDaniel Fojt /* Open a directory relative to another directory.
2*09d4459fSDaniel Fojt 
3*09d4459fSDaniel Fojt    Copyright 2006-2020 Free Software Foundation, Inc.
4*09d4459fSDaniel Fojt 
5*09d4459fSDaniel Fojt    This program is free software: you can redistribute it and/or modify
6*09d4459fSDaniel Fojt    it under the terms of the GNU General Public License as published by
7*09d4459fSDaniel Fojt    the Free Software Foundation; either version 3 of the License, or
8*09d4459fSDaniel Fojt    (at your option) any later version.
9*09d4459fSDaniel Fojt 
10*09d4459fSDaniel Fojt    This program is distributed in the hope that it will be useful,
11*09d4459fSDaniel Fojt    but WITHOUT ANY WARRANTY; without even the implied warranty of
12*09d4459fSDaniel Fojt    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*09d4459fSDaniel Fojt    GNU General Public License for more details.
14*09d4459fSDaniel Fojt 
15*09d4459fSDaniel Fojt    You should have received a copy of the GNU General Public License
16*09d4459fSDaniel Fojt    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17*09d4459fSDaniel Fojt 
18*09d4459fSDaniel Fojt    Written by Jim Meyering and Paul Eggert.  */
19*09d4459fSDaniel Fojt 
20*09d4459fSDaniel Fojt #include <config.h>
21*09d4459fSDaniel Fojt 
22*09d4459fSDaniel Fojt #include <opendirat.h>
23*09d4459fSDaniel Fojt 
24*09d4459fSDaniel Fojt #include <errno.h>
25*09d4459fSDaniel Fojt #include <fcntl--.h>
26*09d4459fSDaniel Fojt #include <unistd.h>
27*09d4459fSDaniel Fojt 
28*09d4459fSDaniel Fojt /* Relative to DIR_FD, open the directory DIR, passing EXTRA_FLAGS to
29*09d4459fSDaniel Fojt    the underlying openat call.  On success, store into *PNEW_FD the
30*09d4459fSDaniel Fojt    underlying file descriptor of the newly opened directory and return
31*09d4459fSDaniel Fojt    the directory stream.  On failure, return NULL and set errno.
32*09d4459fSDaniel Fojt 
33*09d4459fSDaniel Fojt    On success, *PNEW_FD is at least 3, so this is a "safer" function.  */
34*09d4459fSDaniel Fojt 
35*09d4459fSDaniel Fojt DIR *
opendirat(int dir_fd,char const * dir,int extra_flags,int * pnew_fd)36*09d4459fSDaniel Fojt opendirat (int dir_fd, char const *dir, int extra_flags, int *pnew_fd)
37*09d4459fSDaniel Fojt {
38*09d4459fSDaniel Fojt   int open_flags = (O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_NOCTTY
39*09d4459fSDaniel Fojt                     | O_NONBLOCK | extra_flags);
40*09d4459fSDaniel Fojt   int new_fd = openat (dir_fd, dir, open_flags);
41*09d4459fSDaniel Fojt 
42*09d4459fSDaniel Fojt   if (new_fd < 0)
43*09d4459fSDaniel Fojt     return NULL;
44*09d4459fSDaniel Fojt   DIR *dirp = fdopendir (new_fd);
45*09d4459fSDaniel Fojt   if (dirp)
46*09d4459fSDaniel Fojt     *pnew_fd = new_fd;
47*09d4459fSDaniel Fojt   else
48*09d4459fSDaniel Fojt     {
49*09d4459fSDaniel Fojt       int fdopendir_errno = errno;
50*09d4459fSDaniel Fojt       close (new_fd);
51*09d4459fSDaniel Fojt       errno = fdopendir_errno;
52*09d4459fSDaniel Fojt     }
53*09d4459fSDaniel Fojt   return dirp;
54*09d4459fSDaniel Fojt }
55