use same location as .configured, etc, to store .files-touched
[AROS.git] / compiler / clib / access.c
blob6d04385f67dfa2d81b1ff9dae0af972a6af5af9e
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 POSIX function access().
6 */
8 #include <aros/debug.h>
9 #include <errno.h>
10 #include <proto/dos.h>
11 #include <dos/filesystem.h>
12 #include <string.h>
14 #include <aros/debug.h>
16 #include "__arosc_privdata.h"
17 #include "__errno.h"
18 #include "__upath.h"
20 /*****************************************************************************
22 NAME */
23 #include <unistd.h>
25 int access (
27 /* SYNOPSIS */
28 const char *path,
29 int mode)
31 /* FUNCTION
32 Check access permissions of a file or pathname
34 INPUTS
35 path - the path of the file being checked
36 mode - the bitwise inclusive OR of the access permissions
37 to be checked:
39 W_OK - for write permission
40 R_OK - for readpermissions
41 X_OK - for execute permission
42 F_OK - Just to see whether the file exists
44 RESULT
45 If path cannot be found or if any of the desired access
46 modes would not be granted, then a -1 value is returned;
47 otherwise a 0 value is returned.
49 NOTES
51 EXAMPLE
53 BUGS
55 SEE ALSO
56 open(), ftruncate()
58 INTERNALS
60 ******************************************************************************/
62 BPTR lock = BNULL;
63 struct FileInfoBlock *fib = NULL;
64 int result = -1;
65 char vol[32];
66 struct DosList *dl = NULL;
67 const char *apath;
69 if (!path) /* safety check */
71 errno = EFAULT;
72 return -1;
75 D(bug("[access] Path: %s\n", path));
76 if (!strlen(path)) /* empty path */
78 errno = ENOENT;
79 return -1;
82 /* POSIX root is (poorly) emulated, its contents is accessible */
83 if (__doupath && (path[0] == '/') && (path[1] == '\0'))
85 if (mode & (W_OK|R_OK)) {
86 errno = EACCES;
87 return -1;
88 } else
89 return 0;
92 apath = __path_u2a(path);
93 D(bug("[access] AROS path: %s\n", apath));
94 /* Check if the volume exists. Calling Lock on non-existing volume will bring up System Requester */
95 if (SplitName(apath, ':', vol, 0, sizeof(vol)-1) != -1)
97 D(bug("[access] Volume name: %s\n", vol));
98 if(strcmp(vol, "PROGDIR") != 0)
100 dl = LockDosList(LDF_ALL | LDF_READ);
101 dl = FindDosEntry(dl, vol, LDF_ALL);
102 UnLockDosList(LDF_ALL | LDF_READ);
103 /* Volume / Assign / Device not found */
104 if (dl == NULL)
106 errno = ENOENT;
107 return -1;
112 /* Create a lock and examine a lock */
114 lock = Lock(apath, SHARED_LOCK);
115 if (lock == BNULL)
117 errno = IoErr2errno(IoErr());
118 return -1;
121 fib = AllocDosObject(DOS_FIB, NULL);
122 if (!fib)
124 errno = IoErr2errno(IoErr());
125 UnLock(lock);
126 return -1;
129 if (Examine(lock, fib))
131 /* Notice : protection flags are 'low-active' (0 means access is granted) */
132 result = 0;
133 if ((mode & R_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_READ)))
135 errno = EACCES;
136 result = -1;
138 if ((mode & W_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_WRITE)))
140 errno = EACCES;
141 result = -1;
143 if ((mode & X_OK) && (result == 0) && (fib->fib_Protection & (1 << FIBB_EXECUTE)))
145 errno = EACCES;
146 result = -1;
149 else
151 /* We get here if Examine() failed. However it can be a character device
152 (NIL:, ZERO:, etc) which does not support EXAMINE action.
153 Currently we consider them read-write. If really needded, the routine
154 can be modified in order to try to open the device in different modes. */
155 BOOL ischar = FALSE;
156 BPTR fh = OpenFromLock(lock);
158 if (fh)
160 ischar = IsInteractive(fh);
162 Close(fh);
163 lock = BNULL;
166 if (ischar)
168 if (mode & X_OK)
170 /* Character devices are not executable in any way */
171 errno = EACCES;
172 result = -1;
174 else
175 result = 0;
177 else
179 errno = EBADF;
180 result = -1;
184 FreeDosObject(DOS_FIB, fib);
185 if (lock);
186 UnLock(lock);
188 return result;