use same location as .configured, etc, to store .files-touched
[AROS.git] / compiler / clib / lstat.c
blob722c0841cba9a285b4f29928f2e78c9621287a13
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <dos/filesystem.h>
9 #include <proto/dos.h>
11 #include <errno.h>
13 #include "__arosc_privdata.h"
14 #include "__errno.h"
15 #include "__filesystem_support.h"
16 #include "__stat.h"
17 #include "__upath.h"
19 /* like Dos.Lock but no automatick soft link resolution */
20 static BPTR __lock(
21 const char* name,
22 LONG accessMode);
24 /*****************************************************************************
26 NAME */
28 #include <sys/stat.h>
30 int lstat(
32 /* SYNOPSIS */
33 const char *path,
34 struct stat *sb)
36 /* FUNCTION
37 Returns information about a file like stat does except that lstat
38 does not follow symbolic links. Information is stored in stat
39 structure. Consult stat() documentation for detailed description
40 of that structure.
42 INPUTS
43 path - Pathname of the file
44 sb - Pointer to stat structure that will be filled by the lstat() call.
46 RESULT
47 0 on success and -1 on error. If an error occurred, the global
48 variable errno is set.
50 NOTES
52 EXAMPLE
54 BUGS
56 SEE ALSO
57 stat(), fstat()
59 INTERNALS
60 Consult stat() documentation for details.
62 ******************************************************************************/
64 int res = 0;
65 BPTR lock;
67 /* check for empty path before potential conversion from "." to "" */
68 if (__doupath && path && *path == '\0')
70 errno = ENOENT;
71 return -1;
74 path = __path_u2a(path);
75 if (path == NULL)
76 return -1;
78 lock = __lock(path, SHARED_LOCK);
79 if (!lock)
81 if ( IoErr() == ERROR_IS_SOFT_LINK
82 || IoErr() == ERROR_OBJECT_IN_USE)
84 /* either the file is already locked exclusively
85 or it is a soft link, in both cases only way
86 to get info about it is to find it in the
87 parent directory with the ExNext() function
90 SetIoErr(0);
91 return __stat_from_path(path, sb);
94 errno = IoErr2errno(IoErr());
95 return -1;
97 else
98 res = __stat(lock, sb);
100 UnLock(lock);
102 return res;
105 #ifdef AROS_DOS_PACKETS
106 static BPTR __lock(
107 const char* name,
108 LONG accessMode)
110 return Lock(name, accessMode);
112 #else
113 static BPTR __lock(
114 const char* name,
115 LONG accessMode)
117 struct DevProc *dvp;
118 LONG error;
120 if (name == NULL)
121 return BNULL;
123 if (*name == '\0')
124 return Lock(name, accessMode);
126 /* Get pointer to process structure */
127 struct Process *me = (struct Process *)FindTask(NULL);
129 /* Create filehandle */
130 struct FileHandle *
131 ret = (struct FileHandle *)AllocDosObject(DOS_FILEHANDLE, NULL);
133 if (ret != NULL)
135 /* Get pointer to I/O request. Use stackspace for now. */
136 struct IOFileSys iofs;
138 /* Prepare I/O request. */
139 InitIOFS(&iofs, FSA_OPEN, DOSBase);
141 switch (accessMode)
143 case EXCLUSIVE_LOCK:
144 iofs.io_Union.io_OPEN.io_FileMode = FMF_LOCK | FMF_READ;
145 break;
147 case SHARED_LOCK:
148 iofs.io_Union.io_OPEN.io_FileMode = FMF_READ;
149 break;
151 default:
152 D(bug("[Lock] incompatible mode %d\n", accessMode));
153 FreeDosObject(DOS_FILEHANDLE, ret);
154 SetIoErr(ERROR_ACTION_NOT_KNOWN);
155 return BNULL;
158 iofs.io_Union.io_OPEN.io_Filename = StripVolume(name);
160 dvp = NULL;
162 do {
163 if ((dvp = GetDeviceProc(name, dvp)) == NULL) {
164 error = IoErr();
165 break;
168 error = DoIOFS(&iofs, dvp, NULL, DOSBase);
169 } while (error == ERROR_OBJECT_NOT_FOUND);
171 if (error == ERROR_NO_MORE_ENTRIES)
172 error = me->pr_Result2 = ERROR_OBJECT_NOT_FOUND;
174 FreeDeviceProc(dvp);
176 if (!error)
178 ret->fh_Device = iofs.IOFS.io_Device;
179 ret->fh_Unit = iofs.IOFS.io_Unit;
181 return MKBADDR(ret);
183 else
185 FreeDosObject(DOS_FILEHANDLE, ret);
188 else
190 SetIoErr(ERROR_NO_FREE_STORE);
193 return BNULL;
195 #endif /* AROS_DOS_PACKETS */