purge remaining gpl code from clib, and make clib build again
[tangerine.git] / compiler / clib / __open.c
blob6cb904541a3d1e688b974d1fed2e5db8ec9cd87d
1 /*
2 Copyright © 1995-2007, 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 if (wanted_fd>=__numslots)
58 void *tmp;
60 tmp = malloc((wanted_fd+1)*sizeof(fdesc *));
62 if (!tmp) return -1;
64 if (__fd_array)
66 CopyMem(__fd_array, tmp, __numslots*sizeof(fdesc *));
67 free(__fd_array);
70 __fd_array = tmp;
72 bzero(__fd_array + __numslots, (wanted_fd - __numslots + 1) * sizeof(fdesc *));
73 __numslots = wanted_fd+1;
75 else if (wanted_fd < 0)
77 errno = EINVAL;
78 return -1;
80 else if (__fd_array[wanted_fd])
82 close(wanted_fd);
85 return wanted_fd;
88 LONG __oflags2amode(int flags)
90 LONG openmode = 0;
92 /* filter out invalid modes */
93 switch (flags & (O_CREAT|O_TRUNC|O_EXCL))
95 case O_EXCL:
96 case O_EXCL|O_TRUNC:
97 return -1;
100 if (flags & O_WRITE) openmode |= FMF_WRITE;
101 if (flags & O_READ) openmode |= FMF_READ;
102 if (flags & O_EXEC) openmode |= FMF_EXECUTE;
103 if (flags & O_TRUNC) openmode |= FMF_CLEAR;
104 if (flags & O_CREAT) openmode |= FMF_CREATE;
105 if (flags & O_NONBLOCK) openmode |= FMF_NONBLOCK;
106 if (flags & O_APPEND) openmode |= FMF_APPEND;
108 return openmode;
111 int __open(int wanted_fd, const char *pathname, int flags, int mode)
113 BPTR fh = NULL, lock = NULL;
114 fdesc *currdesc = NULL;
115 struct FileInfoBlock *fib = NULL;
116 LONG openmode = __oflags2amode(flags);
118 if (__doupath && pathname[0] == '\0')
120 /* On *nix "" is not really a valid file name. */
121 errno = ENOENT;
122 return -1;
125 pathname = __path_u2a(pathname);
126 if (!pathname) return -1;
128 D(bug("__open: entering, wanted fd = %d, path = %s, flags = %d, mode = %d\n", wanted_fd, pathname, flags, mode));
130 if (openmode == -1)
132 errno = EINVAL;
133 D(bug( "__open: exiting with error EINVAL\n"));
134 return -1;
137 currdesc = malloc(sizeof(fdesc));
138 if (!currdesc) { D(bug("__open: no memory [1]\n")); goto err; }
140 wanted_fd = __getfdslot(wanted_fd);
141 if (wanted_fd == -1) { D(bug("__open: no free fd\n")); goto err; }
143 lock = Lock((char *)pathname, SHARED_LOCK);
144 if (!lock)
148 (IoErr() != ERROR_OBJECT_NOT_FOUND) ||
149 /* If the file doesn't exist and the flag O_CREAT is not set return an error */
150 (IoErr() == ERROR_OBJECT_NOT_FOUND && !(flags & O_CREAT))
153 errno = IoErr2errno(IoErr());
154 goto err;
157 else
159 /* If the file exists, but O_EXCL is set, then return an error */
160 if (flags & O_EXCL)
162 errno = EEXIST;
163 goto err;
166 fib = AllocDosObject(DOS_FIB, NULL);
167 if (!fib)
169 errno = IoErr2errno(IoErr());
170 goto err;
173 if (!Examine(lock, fib))
176 The filesystem in which the files resides doesn't support
177 the EXAMINE action. It might be broken or migth also not
178 be a filesystem at all. So let's assume the file is not a
179 diretory.
181 fib->fib_DirEntryType = 0;
184 # warning implement softlink handling
186 /* Check if it's a directory or a softlink.
187 Softlinks are not handled yet, though */
188 if (fib->fib_DirEntryType > 0)
190 /* A directory cannot be opened for writing */
191 if (openmode & FMF_WRITE)
193 errno = EISDIR;
194 goto err;
197 fh = lock;
198 FreeDosObject(DOS_FIB, fib);
200 goto success;
202 FreeDosObject(DOS_FIB, fib);
203 fib = NULL;
206 /* the file exists and it's not a directory or the file doesn't exist */
208 if (!(fh = Open ((char *)pathname, openmode)) )
210 errno = IoErr2errno (IoErr ());
211 goto err;
214 if (lock) UnLock(lock);
216 success:
217 currdesc->fh = fh;
218 currdesc->flags = flags;
219 currdesc->opencount = 1;
221 __setfdesc(wanted_fd, currdesc);
223 D(bug("__open: exiting fd=%d\n", wanted_fd));
225 return wanted_fd;
227 err:
228 if (fib) FreeDosObject(DOS_FIB, fib);
229 if (currdesc) free(currdesc);
230 if (fh && fh != lock) Close(fh);
231 if (lock) UnLock(lock);
233 D(bug("__open: exiting with error %d\n", errno ));
235 return -1;
239 #warning perhaps this has to be handled in a different way...
240 int __init_stdfiles(void)
242 struct Process *me;
243 fdesc *indesc=NULL, *outdesc=NULL, *errdesc=NULL;
244 int res = __getfdslot(2);
248 res == -1 ||
249 !(indesc = malloc(sizeof(fdesc))) ||
250 !(outdesc = malloc(sizeof(fdesc))) ||
251 !(errdesc = malloc(sizeof(fdesc)))
254 SetIoErr(ERROR_NO_FREE_STORE);
255 return 0;
258 me = (struct Process *)FindTask (NULL);
259 indesc->fh = __stdfiles[STDIN_FILENO] = Input();
260 outdesc->fh = __stdfiles[STDOUT_FILENO] = Output();
261 errdesc->fh = __stdfiles[STDERR_FILENO] = me->pr_CES ? me->pr_CES : me->pr_COS;
263 indesc->flags = O_RDONLY;
264 outdesc->flags = O_WRONLY | O_APPEND;
265 errdesc->flags = O_WRONLY | O_APPEND;
267 indesc->opencount = outdesc->opencount = errdesc->opencount = 1;
269 __fd_array[STDIN_FILENO] = indesc;
270 __fd_array[STDOUT_FILENO] = outdesc;
271 __fd_array[STDERR_FILENO] = errdesc;
273 return 1;
276 void __exit_stdfiles(void)
278 int i = __numslots;
279 while (i)
281 if (__fd_array[--i])
282 close(i);
286 #include <stdio.h>
288 void __updatestdio(void)
290 struct Process *me;
292 me = (struct Process *)FindTask(NULL);
294 fflush(stdin);
295 fflush(stdout);
296 fflush(stderr);
298 __fd_array[STDIN_FILENO]->fh = __stdfiles[STDIN_FILENO] = Input();
299 __fd_array[STDOUT_FILENO]->fh = __stdfiles[STDOUT_FILENO] = Output();
300 __fd_array[STDERR_FILENO]->fh = __stdfiles[STDERR_FILENO] = me->pr_CES ? me->pr_CES : me->pr_COS;
303 ADD2INIT(__init_stdfiles, 2);
304 ADD2EXIT(__exit_stdfiles, 2);