Added missing properties.
[tangerine.git] / rom / dos / open.c
blob4b25b53d87533f164147523cf36a80c3bec8baaf
1 /*
2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Open a file with the specified mode.
6 Lang: english
7 */
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 /*****************************************************************************
21 NAME */
22 #include <proto/dos.h>
24 AROS_LH2(BPTR, Open,
26 /* SYNOPSIS */
27 AROS_LHA(CONST_STRPTR, name, D1),
28 AROS_LHA(LONG, accessMode, D2),
30 /* LOCATION */
31 struct DosLibrary *, DOSBase, 5, Dos)
33 /* FUNCTION
34 Opens a file for read and/or write depending on the accessmode given.
36 INPUTS
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
40 exclusive lock
41 MODE_READWRITE - open new one if it doesn't exist
43 RESULT
44 Handle to the file or 0 if the file couldn't be opened.
45 IoErr() gives additional information in that case.
47 NOTES
49 EXAMPLE
51 BUGS
53 SEE ALSO
55 INTERNALS
57 *****************************************************************************/
59 AROS_LIBFUNC_INIT
61 struct FileHandle *ret;
62 BPTR con, ast;
63 LONG error;
64 struct Process *me;
66 /* Sanity check */
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);
75 if(ret != NULL)
77 LONG doappend = 0;
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);
85 switch(accessMode)
87 case MODE_OLDFILE:
88 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_OLDFILE;
89 ast = con = me->pr_CIS;
90 break;
92 case MODE_NEWFILE:
93 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_NEWFILE;
94 con = me->pr_COS;
95 ast = me->pr_CES ? me->pr_CES : me->pr_COS;
96 break;
98 case MODE_READWRITE:
99 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_READWRITE;
100 con = me->pr_COS;
101 ast = me->pr_CES ? me->pr_CES : me->pr_COS;
102 break;
104 default:
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;
113 break;
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);
123 * CurrentDir(old);
125 if (*name == '\0') {
126 BPTR cur;
127 struct FileHandle *fh;
129 cur = me->pr_CurrentDir;
130 if (!cur)
131 cur = DOSBase->dl_SYSLock;
133 if (cur) {
134 fh = BADDR(cur);
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;
141 DosDoIO(&iofs.IOFS);
143 error = me->pr_Result2 = iofs.io_DosError;
144 } else {
145 error = ERROR_OBJECT_NOT_FOUND;
146 SetIoErr(error);
149 else
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 = "";
155 DosDoIO(&iofs.IOFS);
156 error = me->pr_Result2 = iofs.io_DosError;
158 else
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 = "";
164 DosDoIO(&iofs.IOFS);
165 error = me->pr_Result2 = iofs.io_DosError;
167 else {
168 struct DevProc *dvp = NULL;
170 iofs.io_Union.io_OPEN_FILE.io_Filename = StripVolume(name);
172 do {
173 if ((dvp = GetDeviceProc(name, dvp)) == NULL) {
174 error = IoErr();
175 break;
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;
184 FreeDeviceProc(dvp);
187 if(error == 0)
189 ret->fh_Device = iofs.IOFS.io_Device;
190 ret->fh_Unit = iofs.IOFS.io_Unit;
191 if (doappend)
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);
203 return MKBADDR(ret);
206 FreeDosObject(DOS_FILEHANDLE,ret);
209 else
210 SetIoErr(ERROR_NO_FREE_STORE);
212 return 0;
214 AROS_LIBFUNC_EXIT
215 } /* Open */