2 Copyright © 1995-2008, 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 /* Create filehandle */
73 ret
= (struct FileHandle
*)AllocDosObject(DOS_FILEHANDLE
,NULL
);
79 /* Get pointer to I/O request. Use stackspace for now. */
80 struct IOFileSys iofs
;
82 /* Prepare I/O request. */
83 InitIOFS(&iofs
, FSA_OPEN_FILE
, DOSBase
);
88 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_OLDFILE
;
89 ast
= con
= me
->pr_CIS
;
93 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_NEWFILE
;
95 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
99 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= FMF_MODE_READWRITE
;
101 ast
= me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
105 /* See if the user requested append mode */
106 doappend
= accessMode
& FMF_APPEND
;
108 /* The append mode is all taken care by dos.library */
109 accessMode
&= ~FMF_APPEND
;
111 iofs
.io_Union
.io_OPEN_FILE
.io_FileMode
= accessMode
;
112 ast
= con
= me
->pr_CIS
;
116 iofs
.io_Union
.io_OPEN_FILE
.io_Protection
= 0;
118 /* check for an empty filename. this supports this form that was
119 * required pre-2.0, which didn't have OpenFromLock():
121 * old = CurrentDir(lock);
122 * fh = Open("", MODE_OLDFILE);
127 struct FileHandle
*fh
;
129 cur
= me
->pr_CurrentDir
;
131 cur
= DOSBase
->dl_SYSLock
;
136 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= "";
138 iofs
.IOFS
.io_Device
= fh
->fh_Device
;
139 iofs
.IOFS
.io_Unit
= fh
->fh_Unit
;
143 error
= me
->pr_Result2
= iofs
.io_DosError
;
145 error
= ERROR_OBJECT_NOT_FOUND
;
150 if(!Stricmp(name
, "CONSOLE:"))
152 iofs
.IOFS
.io_Device
= ((struct FileHandle
*)BADDR(con
))->fh_Device
;
153 iofs
.IOFS
.io_Unit
= ((struct FileHandle
*)BADDR(con
))->fh_Unit
;
154 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= "";
156 error
= me
->pr_Result2
= iofs
.io_DosError
;
159 if(!Stricmp(name
, "*"))
161 iofs
.IOFS
.io_Device
= ((struct FileHandle
*)BADDR(ast
))->fh_Device
;
162 iofs
.IOFS
.io_Unit
= ((struct FileHandle
*)BADDR(ast
))->fh_Unit
;
163 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= "";
165 error
= me
->pr_Result2
= iofs
.io_DosError
;
168 struct DevProc
*dvp
= NULL
;
170 iofs
.io_Union
.io_OPEN_FILE
.io_Filename
= StripVolume(name
);
173 if ((dvp
= GetDeviceProc(name
, dvp
)) == NULL
) {
178 error
= DoIOFS(&iofs
, dvp
, NULL
, DOSBase
);
179 } while(error
== ERROR_OBJECT_NOT_FOUND
&& accessMode
!= MODE_NEWFILE
);
181 if (error
== ERROR_NO_MORE_ENTRIES
)
182 error
= me
->pr_Result2
= ERROR_OBJECT_NOT_FOUND
;
189 ret
->fh_Device
= iofs
.IOFS
.io_Device
;
190 ret
->fh_Unit
= iofs
.IOFS
.io_Unit
;
193 /* See if the handler supports FSA_SEEK */
194 if (Seek(MKBADDR(ret
), 0, OFFSET_END
) != -1)
196 /* if so then set the proper flag in the FileHandle struct */
197 ret
->fh_Flags
|= FHF_APPEND
;
200 if (IsInteractive(MKBADDR(ret
)))
201 SetVBuf(MKBADDR(ret
), NULL
, BUF_LINE
, -1);
206 FreeDosObject(DOS_FILEHANDLE
,ret
);
210 SetIoErr(ERROR_NO_FREE_STORE
);