2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 Desc: Open a file with the specified mode.
8 #include <exec/memory.h>
9 #include <exec/lists.h>
10 #include <proto/exec.h>
11 #include <utility/tagitem.h>
12 #include <dos/dosextens.h>
13 #include <dos/filesystem.h>
14 #include <dos/stdio.h>
15 #include <proto/dos.h>
16 #include <proto/utility.h>
17 #include "dos_intern.h"
19 /*****************************************************************************
22 #include <proto/dos.h>
27 AROS_LHA(CONST_STRPTR
, name
, D1
),
28 AROS_LHA(LONG
, accessMode
, D2
),
31 struct DosLibrary
*, DOSBase
, 5, Dos
)
34 Opens a file for read and/or write depending on the accessmode given.
37 name - NUL terminated name of the file.
38 accessMode - One of MODE_OLDFILE - open existing file
39 MODE_NEWFILE - delete old, create new file
41 MODE_READWRITE - open new one if it doesn't exist
44 Handle to the file or 0 if the file couldn't be opened.
45 IoErr() gives additional information in that case.
57 *****************************************************************************/
61 struct FileHandle
*ret
;
67 if (name
== NULL
) return NULL
;
69 /* Get pointer to process structure */
70 me
= (struct Process
*)FindTask(NULL
);
72 /* check for an empty filename. this supports this form that was required
73 * pre-2.0, which didn't have OpenFromLock():
75 * old = CurrentDir(lock);
76 * fh = Open("", MODE_OLDFILE);
80 return OpenFromLock(DupLock(me
->pr_CurrentDir
));
82 /* Create filehandle */
83 ret
= (struct FileHandle
*)AllocDosObject(DOS_FILEHANDLE
,NULL
);
89 /* Get pointer to I/O request. Use stackspace for now. */
90 struct IOFileSys iofs
;
92 /* Prepare I/O request. */
93 InitIOFS(&iofs
, FSA_OPEN_FILE
, DOSBase
);
98 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_OLDFILE
;
99 ast
= con
= me
->pr_CIS
;
103 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_NEWFILE
;
105 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
109 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_READWRITE
;
111 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
115 /* See if the user requested append mode */
116 doappend
= accessMode
& FMF_APPEND
;
118 /* The append mode is all taken care by dos.library */
119 accessMode
&= ~FMF_APPEND
;
121 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= accessMode
;
122 ast
= con
= me
->pr_CIS
;
126 iofs
.io_Union
.io_OPEN_FILE
.io_Protection
= 0;
128 if(!Stricmp(name
, "CONSOLE:"))
130 iofs
.IOFS
.io_Device
= ((struct FileHandle
*)BADDR(con
))->fh_Device
;
131 iofs
.IOFS
.io_Unit
= ((struct FileHandle
*)BADDR(con
))->fh_Unit
;
132 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= "";
134 error
= me
->pr_Result2
= iofs
.io_DosError
;
137 if(!Stricmp(name
, "*"))
139 iofs
.IOFS
.io_Device
= ((struct FileHandle
*)BADDR(ast
))->fh_Device
;
140 iofs
.IOFS
.io_Unit
= ((struct FileHandle
*)BADDR(ast
))->fh_Unit
;
141 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= "";
143 error
= me
->pr_Result2
= iofs
.io_DosError
;
146 struct DevProc
*dvp
= NULL
;
148 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= StripVolume(name
);
151 if ((dvp
= GetDeviceProc(name
, dvp
)) == NULL
) {
156 error
= DoIOFS(&iofs
, dvp
, NULL
, DOSBase
);
157 } while(error
== ERROR_OBJECT_NOT_FOUND
&& accessMode
!= MODE_NEWFILE
);
159 if (error
== ERROR_NO_MORE_ENTRIES
)
160 error
= me
->pr_Result2
= ERROR_OBJECT_NOT_FOUND
;
167 ret
->fh_Device
= iofs
.IOFS
.io_Device
;
168 ret
->fh_Unit
= iofs
.IOFS
.io_Unit
;
171 /* See if the handler supports FSA_SEEK */
172 if (Seek(MKBADDR(ret
), 0, OFFSET_END
) != -1)
174 /* if so then set the proper flag in the FileHandle struct */
175 ret
->fh_Flags
|= FHF_APPEND
;
178 if (IsInteractive(MKBADDR(ret
)))
179 SetVBuf(MKBADDR(ret
), NULL
, BUF_LINE
, -1);
184 FreeDosObject(DOS_FILEHANDLE
,ret
);
188 SetIoErr(ERROR_NO_FREE_STORE
);