added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / rom / dos / open.c
blobb7f9683524c4def9a7ac313250120faecca288cd
1 /*
2 Copyright © 1995-2007, 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 /* 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);
77 * CurrentDir(old);
79 if (*name == '\0')
80 return OpenFromLock(DupLock(me->pr_CurrentDir));
82 /* Create filehandle */
83 ret = (struct FileHandle *)AllocDosObject(DOS_FILEHANDLE,NULL);
85 if(ret != NULL)
87 LONG doappend = 0;
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);
95 switch(accessMode)
97 case MODE_OLDFILE:
98 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_OLDFILE;
99 ast = con = me->pr_CIS;
100 break;
102 case MODE_NEWFILE:
103 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_NEWFILE;
104 con = me->pr_COS;
105 ast = me->pr_CES ? me->pr_CES : me->pr_COS;
106 break;
108 case MODE_READWRITE:
109 iofs.io_Union.io_OPEN_FILE.io_FileMode = FMF_MODE_READWRITE;
110 con = me->pr_COS;
111 ast = me->pr_CES ? me->pr_CES : me->pr_COS;
112 break;
114 default:
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;
123 break;
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 = "";
133 DosDoIO(&iofs.IOFS);
134 error = me->pr_Result2 = iofs.io_DosError;
136 else
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 = "";
142 DosDoIO(&iofs.IOFS);
143 error = me->pr_Result2 = iofs.io_DosError;
145 else {
146 struct DevProc *dvp = NULL;
148 iofs.io_Union.io_OPEN_FILE.io_Filename = StripVolume(name);
150 do {
151 if ((dvp = GetDeviceProc(name, dvp)) == NULL) {
152 error = IoErr();
153 break;
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;
162 FreeDeviceProc(dvp);
165 if(error == 0)
167 ret->fh_Device = iofs.IOFS.io_Device;
168 ret->fh_Unit = iofs.IOFS.io_Unit;
169 if (doappend)
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);
181 return MKBADDR(ret);
184 FreeDosObject(DOS_FILEHANDLE,ret);
187 else
188 SetIoErr(ERROR_NO_FREE_STORE);
190 return 0;
192 AROS_LIBFUNC_EXIT
193 } /* Open */