7c1344bf3eebe208d7aa818d2b69f663bbba9b80
[akaros.git] / tools / compilers / gcc-glibc / glibc-2.19-akaros / sysdeps / akaros / openat.c
1 /* Copyright (C) 2005-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <kernel-features.h>
25
26 /* Some mostly-generic code (e.g. sysdeps/posix/getcwd.c) uses this variable
27    if __ASSUME_ATFCTS is not defined.  */
28 #ifndef __ASSUME_ATFCTS
29 int __have_atfcts;
30 #endif
31
32 /* Open FILE with access OFLAG.  Interpret relative paths relative to
33    the directory associated with FD.  If OFLAG includes O_CREAT, a
34    third argument is the file protection.  */
35 int
36 __openat (fd, file, oflag)
37      int fd;
38      const char *file;
39      int oflag;
40 {
41   int mode = 0;
42
43   if (file == NULL)
44     {
45       __set_errno (EINVAL);
46       return -1;
47     }
48
49   if (fd != AT_FDCWD && file[0] != '/')
50     {
51       /* Check FD is associated with a directory.  */
52       struct stat64 st;
53       if (__fxstat64 (_STAT_VER, fd, &st) != 0)
54         return -1;
55
56       if (!S_ISDIR (st.st_mode))
57         {
58           __set_errno (ENOTDIR);
59           return -1;
60         }
61     }
62
63   if (oflag & O_CREAT)
64     {
65       va_list arg;
66       va_start (arg, oflag);
67       mode = va_arg (arg, int);
68       va_end (arg);
69     }
70
71
72         /* TODO: actually implement openat as the primary kernel interface.  for
73          * now, only allow absolute or relative-to-CWD paths. */
74         if (fd != AT_FDCWD && file[0] != '/') {
75                 werrstr("openat not implemented");
76                 __set_errno (ENOSYS);
77                 return -1;
78         }
79         return ros_syscall(SYS_open, file, strlen(file), oflag, mode, 0, 0);
80 }
81 libc_hidden_def (__openat)
82 weak_alias (__openat, openat)
83
84 /* openat64 is the same as openat for akaros */
85 weak_alias (__openat, __openat64)
86 libc_hidden_weak (__openat64)
87 weak_alias (__openat, openat64)