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/stdio.h>
16 #include <proto/dos.h>
17 #include <proto/utility.h>
19 #include "dos_intern.h"
21 static LONG
InternalOpen(CONST_STRPTR name
, LONG accessMode
,
22 struct FileHandle
*handle
, LONG soft_nesting
, struct DosLibrary
*DOSBase
);
24 #define MAX_SOFT_LINK_NESTING 16 /* Maximum level of soft links nesting */
26 /*****************************************************************************
29 #include <proto/dos.h>
34 AROS_LHA(CONST_STRPTR
, name
, D1
),
35 AROS_LHA(LONG
, accessMode
, D2
),
38 struct DosLibrary
*, DOSBase
, 5, Dos
)
41 Opens a file for read and/or write depending on the accessmode given.
44 name - NUL terminated name of the file.
45 accessMode - One of MODE_OLDFILE - open existing file
46 MODE_NEWFILE - delete old, create new file
48 MODE_READWRITE - open new one if it doesn't exist
51 Handle to the file or 0 if the file couldn't be opened.
52 IoErr() gives additional information in that case.
64 *****************************************************************************/
68 struct FileHandle
*ret
;
72 if (name
== NULL
) return BNULL
;
74 /* Create filehandle */
75 ret
= (struct FileHandle
*)AllocDosObject(DOS_FILEHANDLE
,NULL
);
79 LONG ok
= InternalOpen(name
, accessMode
, ret
, MAX_SOFT_LINK_NESTING
, DOSBase
);
80 D(bug("[Open] = %p, Error = %d\n", ok
? MKBADDR(ret
) : BNULL
, IoErr()));
88 FreeDosObject(DOS_FILEHANDLE
,ret
);
92 error
= ERROR_NO_FREE_STORE
;
101 static LONG
dupHandle(struct FileHandle
*fh
, BPTR lock
, struct DosLibrary
*DOSBase
)
104 struct MsgPort
*port
;
113 err
= dopacket2(DOSBase
, NULL
, port
, ACTION_FH_FROM_LOCK
, MKBADDR(fh
), lock
);
115 if (err
!= DOSFALSE
) {
117 if (fh
->fh_Interactive
)
118 SetVBuf(MKBADDR(fh
), NULL
, BUF_LINE
, -1);
120 SetVBuf(MKBADDR(fh
), NULL
, BUF_NONE
, -1);
127 /* Try to open name recursively calling itself in case it's a soft link.
128 Store result in handle. Return boolean value indicating result. */
129 static LONG
InternalOpen(CONST_STRPTR name
, LONG accessMode
,
130 struct FileHandle
*handle
, LONG soft_nesting
, struct DosLibrary
*DOSBase
)
132 /* Get pointer to process structure */
133 struct Process
*me
= (struct Process
*)FindTask(NULL
);
138 ASSERT_VALID_PROCESS(me
);
140 D(bug("[Open] %s: 0x%p \"%s\", Name: \"%s\" File: %p\n",
141 __is_process(me
) ? "Process" : "Task", me
, me
->pr_Task
.tc_Node
.ln_Name
,
142 name
, MKBADDR(handle
)));
144 if(soft_nesting
== 0)
146 SetIoErr(ERROR_TOO_MANY_LEVELS
);
150 /* IN:, OUT:, ERR: pseudodevices
152 if (pseudoLock(name
, (accessMode
== MODE_OLDFILE
) ? ACCESS_READ
:
153 ((accessMode
== MODE_NEWFILE
) ? ACCESS_WRITE
: 0),
154 &ast
, &ret
, DOSBase
)) {
155 return dupHandle(handle
, ast
, DOSBase
);
163 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
168 ast
= con
= me
->pr_CIS
;
172 SetIoErr(ERROR_NOT_IMPLEMENTED
);
176 if (!Stricmp(name
, "CONSOLE:"))
177 error
= fs_Open(handle
, me
->pr_ConsoleTask
, con
, accessMode
, name
, DOSBase
);
178 else if (!Stricmp(name
, "*"))
179 error
= fs_Open(handle
, me
->pr_ConsoleTask
, ast
, accessMode
, name
, DOSBase
);
180 else if (!Stricmp(name
, "NIL:"))
182 error
= fs_Open(handle
, BNULL
, BNULL
, accessMode
, name
, DOSBase
);
188 struct DevProc
*dvp
= NULL
;
189 STRPTR filename
= strchr(name
, ':');
193 struct MsgPort
*port
;
195 /* No ':', pathname relative to current dir */
196 cur
= me
->pr_CurrentDir
;
198 if (cur
&& cur
!= (BPTR
)-1) {
199 port
= ((struct FileLock
*)BADDR(cur
))->fl_Task
;
201 port
= DOSBase
->dl_Root
->rn_BootProc
;
205 error
= fs_Open(handle
, port
, cur
, accessMode
, name
, DOSBase
);
212 if ((dvp
= GetDeviceProc(name
, dvp
)) == NULL
)
218 error
= fs_Open(handle
, dvp
->dvp_Port
, dvp
->dvp_Lock
, accessMode
, filename
, DOSBase
);
219 } while(error
== ERROR_OBJECT_NOT_FOUND
&& accessMode
!= MODE_NEWFILE
);
221 if (error
== ERROR_NO_MORE_ENTRIES
)
222 error
= ERROR_OBJECT_NOT_FOUND
;
225 if (error
== ERROR_IS_SOFT_LINK
)
227 STRPTR softname
= ResolveSoftlink(cur
, dvp
, name
, DOSBase
);
236 olddir
= me
->pr_CurrentDir
;
237 error
= RootDir(dvp
, DOSBase
);
244 ret
= InternalOpen(softname
, accessMode
, handle
, soft_nesting
- 1, DOSBase
);
245 error
= ret
? 0 : IoErr();
248 UnLock(CurrentDir(olddir
));
262 if (IsInteractive(MKBADDR(handle
)))
263 SetVBuf(MKBADDR(handle
), NULL
, BUF_LINE
, -1);