Do not try to get stack pointer from invalid ESP field, which coincidentally
[AROS.git] / rom / dos / readlink.c
blob1b74d0bf8bf099f3fe75eb96fc5aa30e66bc6562
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Read the soft-link information.
6 Lang: English
7 */
8 #include "dos_intern.h"
9 #include <dos/filesystem.h>
10 #include <exec/lists.h>
11 #include <proto/exec.h>
13 struct ReadLinkDeviceUnit
15 struct MinNode node;
16 struct Device *device;
17 struct Unit *unit;
20 /*****************************************************************************
22 NAME */
23 #include <proto/dos.h>
25 AROS_LH5(LONG, ReadLink,
27 /* SYNOPSIS */
28 AROS_LHA(struct MsgPort *, port, D1),
29 AROS_LHA(BPTR , lock, D2),
30 AROS_LHA(CONST_STRPTR , path, D3),
31 AROS_LHA(STRPTR , buffer, D4),
32 AROS_LHA(ULONG , size, D5),
34 /* LOCATION */
35 struct DosLibrary *, DOSBase, 73, Dos)
37 /* FUNCTION
38 Read the filename referred to by the soft-linked object contained
39 in |path| (relative to the lock |lock|) into the buffer |buffer|.
40 The variable |path| should contain the name of the object that
41 caused the original OBJECT_IS_SOFT_LINK error.
43 INPUTS
44 port - The handler to send the request to.
45 lock - Object that |path| is relative to.
46 path - Name of the object that caused the error.
47 buffer - Buffer to fill with resolved filename.
48 size - Length of the buffer.
50 RESULT
51 >= 0 length of resolved filename in case of success
52 == -1 failure, see IoErr() for more information
53 == -2 buffer size was too small to store resolved filename
55 NOTES
57 EXAMPLE
59 BUGS
61 SEE ALSO
62 MakeLink()
64 INTERNALS
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 struct IOFileSys iofs;
71 struct FileHandle *fh = BADDR(lock);
72 LONG err = 0;
73 LONG ret = -1;
75 InitIOFS(&iofs, FSA_READ_SOFTLINK, DOSBase);
77 iofs.io_Union.io_READ_SOFTLINK.io_Buffer = buffer;
78 iofs.io_Union.io_READ_SOFTLINK.io_Size = size;
80 if(fh)
82 iofs.IOFS.io_Device = fh->fh_Device;
83 iofs.IOFS.io_Unit = fh->fh_Unit;
85 err = DoIOFS(&iofs, NULL, path, DOSBase);
86 if(!err)
87 ret = iofs.io_Union.io_READ_SOFTLINK.io_Size;
89 else
91 struct DosList *dl = NULL;
92 struct ReadLinkDeviceUnit *deviceunit;
93 struct MinList deviceunits;
94 struct Node *tmpNode;
95 char found = 0;
96 NEWLIST(&deviceunits);
98 /* Quickly get all device units with such port, store them in
99 temporary list. */
100 for (
101 dl = LockDosList(LDF_DEVICES | LDF_READ);
102 dl != NULL;
103 dl = BADDR(dl->dol_Next)
107 dl->dol_Type == DLT_DEVICE && (
108 (struct MsgPort *)dl->dol_Ext.dol_AROS.dol_Device == port)
111 if((deviceunit = AllocMem(
112 sizeof(struct ReadLinkDeviceUnit),
113 MEMF_ANY | MEMF_CLEAR
116 deviceunit->device = dl->dol_Ext.dol_AROS.dol_Device;
117 deviceunit->unit = dl->dol_Ext.dol_AROS.dol_Unit;
118 AddTail(
119 (struct List*) &deviceunits,
120 (struct Node*) deviceunit
123 else
125 err = ERROR_NO_FREE_STORE;
126 break;
130 UnLockDosList(LDF_DEVICES | LDF_READ);
132 if(!err)
134 /* Now try all units from the list */
135 ForeachNode(&deviceunits, deviceunit)
137 iofs.IOFS.io_Device = deviceunit->device;
138 iofs.IOFS.io_Unit = deviceunit->unit;
139 iofs.io_Union.io_READ_SOFTLINK.io_Size = size;
141 err = DoIOFS(&iofs, NULL, path, DOSBase);
142 if(!err)
144 ret = iofs.io_Union.io_READ_SOFTLINK.io_Size;
145 found = 1;
146 break;
150 if(!found)
151 err = ERROR_OBJECT_NOT_FOUND;
154 /* Free our temporary list */
155 ForeachNodeSafe(&deviceunits, deviceunit, tmpNode)
157 Remove((struct Node*) deviceunit);
158 FreeMem(deviceunit, sizeof(struct ReadLinkDeviceUnit));
162 SetIoErr(err);
164 return err == 0 ? ret : -1;
166 AROS_LIBFUNC_EXIT
167 } /* ReadLink */