start service tasks separately in-case platforms need to perform additional set-up...
[AROS.git] / compiler / posixc / access.c
blob404dcf21fcf8409f9314e7eaeadd3cdcb10c3399
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX.1-2008 function access().
6 */
8 #include <errno.h>
9 #include <proto/dos.h>
10 #include <string.h>
12 #include <aros/debug.h>
14 #include "__upath.h"
15 #include "__posixc_intbase.h"
17 /*****************************************************************************
19 NAME */
20 #include <unistd.h>
22 int access (
24 /* SYNOPSIS */
25 const char *path,
26 int mode)
28 /* FUNCTION
29 Check access permissions of a file or pathname
31 INPUTS
32 path - the path of the file being checked
33 mode - the bitwise inclusive OR of the access permissions
34 to be checked:
36 W_OK - for write permission
37 R_OK - for readpermissions
38 X_OK - for execute permission
39 F_OK - Just to see whether the file exists
41 RESULT
42 If path cannot be found or if any of the desired access
43 modes would not be granted, then a -1 value is returned;
44 otherwise a 0 value is returned.
46 NOTES
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 open(), ftruncate()
55 INTERNALS
57 ******************************************************************************/
59 struct PosixCIntBase *PosixCBase =
60 (struct PosixCIntBase *)__aros_getbase_PosixCBase();
61 BPTR lock = BNULL;
62 struct FileInfoBlock *fib = NULL;
63 int result = -1;
64 char vol[32];
65 struct DosList *dl = NULL;
66 const char *apath;
68 if (!path) /* safety check */
70 errno = EFAULT;
71 return -1;
74 D(bug("[access] Path: %s\n", path));
75 if (!strlen(path)) /* empty path */
77 errno = ENOENT;
78 return -1;
81 /* POSIX root is (poorly) emulated, its contents is accessible */
82 if (PosixCBase->doupath && (path[0] == '/') && (path[1] == '\0'))
84 if (mode & (W_OK|R_OK)) {
85 errno = EACCES;
86 return -1;
87 } else
88 return 0;
91 apath = __path_u2a(path);
92 D(bug("[access] AROS path: %s\n", apath));
93 /* Check if the volume exists. Calling Lock on non-existing volume will bring up System Requester */
94 if (SplitName(apath, ':', vol, 0, sizeof(vol)-1) != -1)
96 D(bug("[access] Volume name: %s\n", vol));
97 if(strcmp(vol, "PROGDIR") != 0)
99 dl = LockDosList(LDF_ALL | LDF_READ);
100 dl = FindDosEntry(dl, vol, LDF_ALL);
101 UnLockDosList(LDF_ALL | LDF_READ);
102 /* Volume / Assign / Device not found */
103 if (dl == NULL)
105 errno = ENOENT;
106 return -1;
111 /* Create a lock and examine a lock */
113 lock = Lock(apath, SHARED_LOCK);
114 if (lock == BNULL)
116 errno = __stdc_ioerr2errno(IoErr());
117 return -1;
120 fib = AllocDosObject(DOS_FIB, NULL);
121 if (!fib)
123 errno = __stdc_ioerr2errno(IoErr());
124 UnLock(lock);
125 return -1;
128 if (Examine(lock, fib))
130 /* Notice : protection flags are 'low-active' (0 means access is granted) */
131 result = 0;
132 if ((mode & R_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_READ)))
134 errno = EACCES;
135 result = -1;
137 if ((mode & W_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_WRITE)))
139 errno = EACCES;
140 result = -1;
142 if ((mode & X_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_EXECUTE)))
144 errno = EACCES;
145 result = -1;
148 else
150 /* We get here if Examine() failed. However it can be a character device
151 (NIL:, ZERO:, etc) which does not support EXAMINE action.
152 Currently we consider them read-write. If really needded, the routine
153 can be modified in order to try to open the device in different modes. */
154 BOOL ischar = FALSE;
155 BPTR fh = OpenFromLock(lock);
157 if (fh)
159 ischar = IsInteractive(fh);
161 Close(fh);
162 lock = BNULL;
165 if (ischar)
167 if (mode & X_OK)
169 /* Character devices are not executable in any way */
170 errno = EACCES;
171 result = -1;
173 else
174 result = 0;
176 else
178 errno = EBADF;
179 result = -1;
183 FreeDosObject(DOS_FIB, fib);
184 if (lock);
185 UnLock(lock);
187 return result;