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
;
116 err
= dopacket2(DOSBase
, NULL
, port
, ACTION_FH_FROM_LOCK
, MKBADDR(fh
), lock
);
119 fh
->fh_Interactive
= DOSFALSE
;
123 if (err
!= DOSFALSE
) {
125 if (fh
->fh_Interactive
)
126 SetVBuf(MKBADDR(fh
), NULL
, BUF_LINE
, -1);
128 SetVBuf(MKBADDR(fh
), NULL
, BUF_NONE
, -1);
135 /* Try to open name recursively calling itself in case it's a soft link.
136 Store result in handle. Return boolean value indicating result. */
137 static LONG
InternalOpen(CONST_STRPTR name
, LONG accessMode
,
138 struct FileHandle
*handle
, LONG soft_nesting
, struct DosLibrary
*DOSBase
)
140 /* Get pointer to process structure */
141 struct Process
*me
= (struct Process
*)FindTask(NULL
);
146 ASSERT_VALID_PROCESS(me
);
148 D(bug("[Open] %s: 0x%p \"%s\", Name: \"%s\" File: %p\n",
149 __is_process(me
) ? "Process" : "Task", me
, me
->pr_Task
.tc_Node
.ln_Name
,
150 name
, MKBADDR(handle
)));
152 if(soft_nesting
== 0)
154 SetIoErr(ERROR_TOO_MANY_LEVELS
);
158 /* IN:, OUT:, ERR: pseudodevices
160 if (pseudoLock(name
, (accessMode
== MODE_OLDFILE
) ? ACCESS_READ
:
161 ((accessMode
== MODE_NEWFILE
) ? ACCESS_WRITE
: 0),
162 &ast
, &ret
, DOSBase
)) {
163 return dupHandle(handle
, ast
, DOSBase
);
167 * Special case for NIL:, since it has no
168 * device task attached to it.
170 if (!Stricmp(name
, "NIL:"))
174 handle
->fh_Type
= BNULL
;
175 /* NIL: is not considered interactive */
176 handle
->fh_Interactive
= DOSFALSE
;
185 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
190 ast
= con
= me
->pr_CIS
;
194 SetIoErr(ERROR_NOT_IMPLEMENTED
);
198 if (!Stricmp(name
, "CONSOLE:"))
199 error
= fs_Open(handle
, me
->pr_ConsoleTask
, con
, accessMode
, name
, DOSBase
);
200 else if (!Stricmp(name
, "*"))
201 error
= fs_Open(handle
, me
->pr_ConsoleTask
, ast
, accessMode
, name
, DOSBase
);
205 struct DevProc
*dvp
= NULL
;
206 STRPTR filename
= strchr(name
, ':');
210 struct MsgPort
*port
;
212 /* No ':', pathname relative to current dir */
213 cur
= me
->pr_CurrentDir
;
215 if (cur
&& cur
!= (BPTR
)-1) {
216 port
= ((struct FileLock
*)BADDR(cur
))->fl_Task
;
218 port
= DOSBase
->dl_Root
->rn_BootProc
;
222 error
= fs_Open(handle
, port
, cur
, accessMode
, name
, DOSBase
);
229 if ((dvp
= GetDeviceProc(name
, dvp
)) == NULL
)
235 error
= fs_Open(handle
, dvp
->dvp_Port
, dvp
->dvp_Lock
, accessMode
, filename
, DOSBase
);
236 } while(error
== ERROR_OBJECT_NOT_FOUND
&& accessMode
!= MODE_NEWFILE
);
238 if (error
== ERROR_NO_MORE_ENTRIES
)
239 error
= ERROR_OBJECT_NOT_FOUND
;
242 if (error
== ERROR_IS_SOFT_LINK
)
244 STRPTR softname
= ResolveSoftlink(cur
, dvp
, name
, DOSBase
);
253 olddir
= me
->pr_CurrentDir
;
254 error
= RootDir(dvp
, DOSBase
);
261 ret
= InternalOpen(softname
, accessMode
, handle
, soft_nesting
- 1, DOSBase
);
262 error
= ret
? 0 : IoErr();
265 UnLock(CurrentDir(olddir
));
279 if (IsInteractive(MKBADDR(handle
)))
280 SetVBuf(MKBADDR(handle
), NULL
, BUF_LINE
, -1);