2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Open a file with the specified mode.
9 #include <aros/debug.h>
10 #include <exec/memory.h>
11 #include <exec/lists.h>
12 #include <proto/exec.h>
13 #include <utility/tagitem.h>
14 #include <dos/dosextens.h>
15 #include <dos/filesystem.h>
16 #include <dos/stdio.h>
17 #include <proto/dos.h>
18 #include <proto/utility.h>
20 #include "dos_intern.h"
22 static LONG
InternalOpen(CONST_STRPTR name
, LONG accessMode
,
23 struct FileHandle
*handle
, LONG soft_nesting
, struct DosLibrary
*DOSBase
);
25 #define MAX_SOFT_LINK_NESTING 16 /* Maximum level of soft links nesting */
27 /*****************************************************************************
30 #include <proto/dos.h>
35 AROS_LHA(CONST_STRPTR
, name
, D1
),
36 AROS_LHA(LONG
, accessMode
, D2
),
39 struct DosLibrary
*, DOSBase
, 5, Dos
)
42 Opens a file for read and/or write depending on the accessmode given.
45 name - NUL terminated name of the file.
46 accessMode - One of MODE_OLDFILE - open existing file
47 MODE_NEWFILE - delete old, create new file
49 MODE_READWRITE - open new one if it doesn't exist
52 Handle to the file or 0 if the file couldn't be opened.
53 IoErr() gives additional information in that case.
65 *****************************************************************************/
69 struct FileHandle
*ret
;
73 if (name
== NULL
) return BNULL
;
75 /* Create filehandle */
76 ret
= (struct FileHandle
*)AllocDosObject(DOS_FILEHANDLE
,NULL
);
80 LONG ok
= InternalOpen(name
, accessMode
, ret
, MAX_SOFT_LINK_NESTING
, DOSBase
);
81 D(bug("[Open] = %d Error = %d\n", ok
, IoErr()));
89 FreeDosObject(DOS_FILEHANDLE
,ret
);
93 error
= ERROR_NO_FREE_STORE
;
101 /* Try to open name recursively calling itself in case it's a soft link.
102 Store result in handle. Return boolean value indicating result. */
103 static LONG
InternalOpen(CONST_STRPTR name
, LONG accessMode
,
104 struct FileHandle
*handle
, LONG soft_nesting
, struct DosLibrary
*DOSBase
)
106 /* Get pointer to process structure */
107 struct Process
*me
= (struct Process
*)FindTask(NULL
);
112 D(bug("[Open] Process: 0x%p \"%s\", Window: 0x%p, Name: \"%s\" FH: 0x%p\n", me
, me
->pr_Task
.tc_Node
.ln_Name
, me
->pr_WindowPtr
, name
, handle
));
114 if(soft_nesting
== 0)
116 SetIoErr(ERROR_TOO_MANY_LEVELS
);
125 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
129 ast
= con
= me
->pr_CIS
;
133 if (accessMode
& (FMF_CREATE
|FMF_CLEAR
))
136 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
139 ast
= con
= me
->pr_CIS
;
143 if (!Stricmp(name
, "CONSOLE:"))
144 error
= fs_Open(handle
, REF_CONSOLE
, con
, accessMode
, name
, DOSBase
);
145 else if (!Stricmp(name
, "*"))
146 error
= fs_Open(handle
, REF_CONSOLE
, ast
, accessMode
, name
, DOSBase
);
147 #ifdef AROS_DOS_PACKETS
148 /* Special case for NIL:, unsupported by IOFS */
149 else if (!Stricmp(name
, "NIL:"))
153 handle
->fh_Type
= BNULL
;
154 /* NIL: is considered interactive */
155 handle
->fh_Port
= (struct MsgPort
*)DOSTRUE
;
162 struct DevProc
*dvp
= NULL
;
163 STRPTR filename
= strchr(name
, ':');
167 /* No ':', pathname relative to current dir */
168 cur
= me
->pr_CurrentDir
;
171 cur
= DOSBase
->dl_SYSLock
;
174 error
= fs_Open(handle
, REF_LOCK
, cur
, accessMode
, name
, DOSBase
);
177 * This can be reached if we attempt to load disk-based library or
178 * device before dl_SYSLock is assigned. This can happen, for example,
179 * when attempting to mount a handler at boottime which is missing
180 * from the kickstart.
182 error
= ERROR_OBJECT_NOT_FOUND
;
189 if ((dvp
= GetDeviceProc(name
, dvp
)) == NULL
)
195 error
= fs_Open(handle
, REF_DEVICE
, MKBADDR(dvp
), accessMode
, filename
, DOSBase
);
196 } while(error
== ERROR_OBJECT_NOT_FOUND
&& accessMode
!= MODE_NEWFILE
);
198 if (error
== ERROR_NO_MORE_ENTRIES
)
199 error
= ERROR_OBJECT_NOT_FOUND
;
202 if (error
== ERROR_IS_SOFT_LINK
)
204 STRPTR softname
= ResolveSoftlink(cur
, dvp
, name
, DOSBase
);
213 olddir
= me
->pr_CurrentDir
;
214 error
= RootDir(dvp
, DOSBase
);
221 ret
= InternalOpen(softname
, accessMode
, handle
, soft_nesting
- 1, DOSBase
);
222 error
= ret
? 0 : IoErr();
225 UnLock(CurrentDir(olddir
));
239 if (IsInteractive(MKBADDR(handle
)))
240 SetVBuf(MKBADDR(handle
), NULL
, BUF_LINE
, -1);