Don't call ReadArgs() if started from WB.
[tangerine.git] / compiler / clib / __open.c
bloba2445fe0827857389c2f42f5ed97ccb703adec51
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 File descriptors handling internals.
6 */
8 #include "__arosc_privdata.h"
10 #include <string.h>
11 #include <fcntl.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <errno.h>
16 #define DEBUG 0
18 #include <proto/exec.h>
19 #include <proto/dos.h>
20 #include <exec/memory.h>
21 #include <dos/dos.h>
22 #include <dos/filesystem.h>
23 #include <aros/symbolsets.h>
24 #include <aros/debug.h>
25 #include "__errno.h"
26 #include "__open.h"
27 #include "__upath.h"
29 int c;
31 fdesc *__getfdesc(register int fd)
33 return ((__numslots>fd) && (fd>=0))?__fd_array[fd]:NULL;
36 void __setfdesc(register int fd, fdesc *desc)
38 /* FIXME: Check if fd is in valid range... */
39 __fd_array[fd] = desc;
42 int __getfirstfd(register int startfd)
44 /* FIXME: Check if fd is in valid range... */
45 for (
47 startfd < __numslots && __fd_array[startfd];
48 startfd++
51 return startfd;
54 int __getfdslot(int wanted_fd)
56 AROS_GET_SYSBASE_OK
58 if (wanted_fd>=__numslots)
60 void *tmp;
62 tmp = malloc((wanted_fd+1)*sizeof(fdesc *));
64 if (!tmp) return -1;
66 if (__fd_array)
68 CopyMem(__fd_array, tmp, __numslots*sizeof(fdesc *));
69 free(__fd_array);
72 __fd_array = tmp;
74 bzero(__fd_array + __numslots, (wanted_fd - __numslots + 1) * sizeof(fdesc *));
75 __numslots = wanted_fd+1;
77 else if (wanted_fd < 0)
79 errno = EINVAL;
80 return -1;
82 else if (__fd_array[wanted_fd])
84 close(wanted_fd);
87 return wanted_fd;
90 LONG __oflags2amode(int flags)
92 LONG openmode = 0;
94 /* filter out invalid modes */
95 switch (flags & (O_CREAT|O_TRUNC|O_EXCL))
97 case O_EXCL:
98 case O_EXCL|O_TRUNC:
99 return -1;
102 if (flags & O_WRITE) openmode |= FMF_WRITE;
103 if (flags & O_READ) openmode |= FMF_READ;
104 if (flags & O_EXEC) openmode |= FMF_EXECUTE;
105 if (flags & O_TRUNC) openmode |= FMF_CLEAR;
106 if (flags & O_CREAT) openmode |= FMF_CREATE;
107 if (flags & O_NONBLOCK) openmode |= FMF_NONBLOCK;
108 if (flags & O_APPEND) openmode |= FMF_APPEND;
110 return openmode;
113 int __open(int wanted_fd, const char *pathname, int flags, int mode)
115 BPTR fh = NULL, lock = NULL;
116 fdesc *currdesc = NULL;
117 struct FileInfoBlock *fib = NULL;
118 LONG openmode = __oflags2amode(flags);
119 AROS_GET_SYSBASE_OK
120 AROS_GET_DOSBASE
122 if (__doupath && pathname[0] == '\0')
124 /* On *nix "" is not really a valid file name. */
125 errno = ENOENT;
126 return -1;
129 pathname = __path_u2a(pathname);
130 if (!pathname) return -1;
132 D(bug("__open: entering, wanted fd = %d, path = %s, flags = %d, mode = %d\n", wanted_fd, pathname, flags, mode));
134 if (openmode == -1)
136 errno = EINVAL;
137 D(bug( "__open: exiting with error EINVAL\n"));
138 return -1;
141 currdesc = malloc(sizeof(fdesc));
142 if (!currdesc) { D(bug("__open: no memory [1]\n")); goto err; }
144 wanted_fd = __getfdslot(wanted_fd);
145 if (wanted_fd == -1) { D(bug("__open: no free fd\n")); goto err; }
147 lock = Lock((char *)pathname, SHARED_LOCK);
148 if (!lock)
152 (IoErr() != ERROR_OBJECT_NOT_FOUND) ||
153 /* If the file doesn't exist and the flag O_CREAT is not set return an error */
154 (IoErr() == ERROR_OBJECT_NOT_FOUND && !(flags & O_CREAT))
157 errno = IoErr2errno(IoErr());
158 goto err;
161 else
163 /* If the file exists, but O_EXCL is set, then return an error */
164 if (flags & O_EXCL)
166 errno = EEXIST;
167 goto err;
170 fib = AllocDosObject(DOS_FIB, NULL);
171 if (!fib)
173 errno = IoErr2errno(IoErr());
174 goto err;
177 if (!Examine(lock, fib))
180 The filesystem in which the files resides doesn't support
181 the EXAMINE action. It might be broken or migth also not
182 be a filesystem at all. So let's assume the file is not a
183 diretory.
185 fib->fib_DirEntryType = 0;
188 # warning implement softlink handling
190 /* Check if it's a directory or a softlink.
191 Softlinks are not handled yet, though */
192 if (fib->fib_DirEntryType > 0)
194 /* A directory cannot be opened for writing */
195 if (openmode & FMF_WRITE)
197 errno = EISDIR;
198 goto err;
201 fh = lock;
202 FreeDosObject(DOS_FIB, fib);
204 goto success;
206 FreeDosObject(DOS_FIB, fib);
207 fib = NULL;
210 /* the file exists and it's not a directory or the file doesn't exist */
212 if (!(fh = Open ((char *)pathname, openmode)) )
214 errno = IoErr2errno (IoErr ());
215 goto err;
218 if (lock) UnLock(lock);
220 success:
221 currdesc->fh = fh;
222 currdesc->flags = flags;
223 currdesc->opencount = 1;
225 __setfdesc(wanted_fd, currdesc);
227 D(bug("__open: exiting\n"));
229 return wanted_fd;
231 err:
232 if (fib) FreeDosObject(DOS_FIB, fib);
233 if (currdesc) free(currdesc);
234 if (fh && fh != lock) Close(fh);
235 if (lock) UnLock(lock);
237 D(bug("__open: exiting with error %d\n", errno ));
239 return -1;
243 #warning perhaps this has to be handled in a different way...
244 int __init_stdfiles(void)
246 struct Process *me;
247 fdesc *indesc=NULL, *outdesc=NULL, *errdesc=NULL;
248 int res = __getfdslot(2);
249 AROS_GET_SYSBASE_OK
250 AROS_GET_DOSBASE
254 res == -1 ||
255 !(indesc = malloc(sizeof(fdesc))) ||
256 !(outdesc = malloc(sizeof(fdesc))) ||
257 !(errdesc = malloc(sizeof(fdesc)))
260 SetIoErr(ERROR_NO_FREE_STORE);
261 return 0;
264 me = (struct Process *)FindTask (NULL);
265 indesc->fh = __stdfiles[STDIN_FILENO] = Input();
266 outdesc->fh = __stdfiles[STDOUT_FILENO] = Output();
267 errdesc->fh = __stdfiles[STDERR_FILENO] = me->pr_CES ? me->pr_CES : me->pr_COS;
269 indesc->flags = O_RDONLY;
270 outdesc->flags = O_WRONLY | O_APPEND;
271 errdesc->flags = O_WRONLY | O_APPEND;
273 indesc->opencount = outdesc->opencount = errdesc->opencount = 1;
275 __fd_array[STDIN_FILENO] = indesc;
276 __fd_array[STDOUT_FILENO] = outdesc;
277 __fd_array[STDERR_FILENO] = errdesc;
279 return 1;
283 void __exit_stdfiles(void)
285 int i = __numslots;
286 while (i)
288 close(--i);
292 #include <stdio.h>
294 void __updatestdio(void)
296 struct Process *me;
297 AROS_GET_SYSBASE_OK
298 AROS_GET_DOSBASE
300 me = (struct Process *)FindTask(NULL);
302 fflush(stdin);
303 fflush(stdout);
304 fflush(stderr);
306 __fd_array[STDIN_FILENO]->fh = __stdfiles[STDIN_FILENO] = Input();
307 __fd_array[STDOUT_FILENO]->fh = __stdfiles[STDOUT_FILENO] = Output();
308 __fd_array[STDERR_FILENO]->fh = __stdfiles[STDERR_FILENO] = me->pr_CES ? me->pr_CES : me->pr_COS;
311 ADD2INIT(__init_stdfiles, 2);
312 ADD2EXIT(__exit_stdfiles, 2);