Merge glibc-ports into ports/ directory.
[platform/upstream/glibc.git] / hurd / lookup-at.c
1 /* Lookup helper function for Hurd implementation of *at functions.
2    Copyright (C) 2006,2010 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library 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 GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <hurd.h>
20 #include <hurd/lookup.h>
21 #include <hurd/fd.h>
22 #include <string.h>
23 #include <fcntl.h>
24
25 file_t
26 __file_name_lookup_at (int fd, int at_flags,
27                        const char *file_name, int flags, mode_t mode)
28 {
29   error_t err;
30   file_t result;
31
32   if ((at_flags & AT_SYMLINK_FOLLOW) && (at_flags & AT_SYMLINK_NOFOLLOW))
33     return (__hurd_fail (EINVAL), MACH_PORT_NULL);
34
35   flags |= (at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
36   at_flags &= ~AT_SYMLINK_NOFOLLOW;
37   if (at_flags & AT_SYMLINK_FOLLOW)
38     flags &= ~O_NOLINK;
39   at_flags &= ~AT_SYMLINK_FOLLOW;
40   if (at_flags != 0)
41     return (__hurd_fail (EINVAL), MACH_PORT_NULL);
42
43   if (fd == AT_FDCWD || file_name[0] == '/')
44     return __file_name_lookup (file_name, flags, mode);
45
46   file_t startdir;
47   error_t use_init_port (int which, error_t (*operate) (mach_port_t))
48     {
49       return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
50               _hurd_ports_use (which, operate));
51     }
52
53   err = HURD_DPORT_USE (fd, (startdir = port,
54                              __hurd_file_name_lookup (&use_init_port,
55                                                       &__getdport, NULL,
56                                                       file_name,
57                                                       flags,
58                                                       mode & ~_hurd_umask,
59                                                       &result)));
60
61   return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
62 }
63
64 file_t
65 __file_name_split_at (int fd, const char *file_name, char **name)
66 {
67   error_t err;
68   file_t result;
69
70   if (fd == AT_FDCWD || file_name[0] == '/')
71     return __file_name_split (file_name, name);
72
73   err = __hurd_file_name_split (&_hurd_ports_use, &__getdport, 0,
74                                 file_name, &result, name);
75
76   file_t startdir;
77   error_t use_init_port (int which, error_t (*operate) (mach_port_t))
78   {
79     return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
80             _hurd_ports_use (which, operate));
81   }
82
83   err = HURD_DPORT_USE (fd, (startdir = port,
84                              __hurd_file_name_split (&use_init_port,
85                                                      &__getdport, 0,
86                                                      file_name,
87                                                      &result, name)));
88
89   return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
90 }
91
92 file_t
93 __directory_name_split_at (int fd, const char *directory_name, char **name)
94 {
95   error_t err;
96   file_t result;
97
98   if (fd == AT_FDCWD || directory_name[0] == '/')
99     return __directory_name_split (directory_name, name);
100
101   file_t startdir;
102   error_t use_init_port (int which, error_t (*operate) (mach_port_t))
103     {
104       return (which == INIT_PORT_CWDIR ? (*operate) (startdir) :
105               _hurd_ports_use (which, operate));
106     }
107
108   err = HURD_DPORT_USE (fd, (startdir = port,
109                              __hurd_directory_name_split (&use_init_port,
110                                                           &__getdport, 0,
111                                                           directory_name,
112                                                           &result, name)));
113
114   return err ? (__hurd_dfail (fd, err), MACH_PORT_NULL) : result;
115 }