2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
5 File descriptors handling internals.
8 #include "__arosc_privdata.h"
18 #include <proto/exec.h>
19 #include <proto/dos.h>
20 #include <exec/memory.h>
22 #include <dos/filesystem.h>
23 #include <aros/symbolsets.h>
24 #include <aros/debug.h>
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... */
47 startfd
< __numslots
&& __fd_array
[startfd
];
54 int __getfdslot(int wanted_fd
)
56 if (wanted_fd
>=__numslots
)
60 tmp
= malloc((wanted_fd
+1)*sizeof(fdesc
*));
66 CopyMem(__fd_array
, tmp
, __numslots
*sizeof(fdesc
*));
72 bzero(__fd_array
+ __numslots
, (wanted_fd
- __numslots
+ 1) * sizeof(fdesc
*));
73 __numslots
= wanted_fd
+1;
75 else if (wanted_fd
< 0)
80 else if (__fd_array
[wanted_fd
])
88 LONG
__oflags2amode(int flags
)
92 /* filter out invalid modes */
93 switch (flags
& (O_CREAT
|O_TRUNC
|O_EXCL
))
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
;
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. */
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
));
133 D(bug( "__open: exiting with error EINVAL\n"));
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
);
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());
159 /* If the file exists, but O_EXCL is set, then return an error */
166 fib
= AllocDosObject(DOS_FIB
, NULL
);
169 errno
= IoErr2errno(IoErr());
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
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
)
198 FreeDosObject(DOS_FIB
, fib
);
202 FreeDosObject(DOS_FIB
, fib
);
206 /* the file exists and it's not a directory or the file doesn't exist */
214 if (openmode
& (FMF_APPEND
| FMF_WRITE
))
215 openmode
|= FMF_READ
; /* force filesystem ACTION_FINDUPDATE */
217 if (!(fh
= Open ((char *)pathname
, openmode
)) )
219 ULONG ioerr
= IoErr();
220 D(bug("[clib] Open ioerr=%d\n", ioerr
));
221 errno
= IoErr2errno(ioerr
);
227 currdesc
->flags
= flags
;
228 currdesc
->opencount
= 1;
230 __setfdesc(wanted_fd
, currdesc
);
232 D(bug("__open: exiting fd=%d\n", wanted_fd
));
237 if (fib
) FreeDosObject(DOS_FIB
, fib
);
238 if (currdesc
) free(currdesc
);
239 if (fh
&& fh
!= lock
) Close(fh
);
240 if (lock
) UnLock(lock
);
242 D(bug("__open: exiting with error %d\n", errno
));
248 #warning perhaps this has to be handled in a different way...
249 int __init_stdfiles(void)
252 fdesc
*indesc
=NULL
, *outdesc
=NULL
, *errdesc
=NULL
;
253 int res
= __getfdslot(2);
258 !(indesc
= malloc(sizeof(fdesc
))) ||
259 !(outdesc
= malloc(sizeof(fdesc
))) ||
260 !(errdesc
= malloc(sizeof(fdesc
)))
263 SetIoErr(ERROR_NO_FREE_STORE
);
267 me
= (struct Process
*)FindTask (NULL
);
268 indesc
->fh
= __stdfiles
[STDIN_FILENO
] = Input();
269 outdesc
->fh
= __stdfiles
[STDOUT_FILENO
] = Output();
270 errdesc
->fh
= __stdfiles
[STDERR_FILENO
] = me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
272 indesc
->flags
= O_RDONLY
;
273 outdesc
->flags
= O_WRONLY
| O_APPEND
;
274 errdesc
->flags
= O_WRONLY
| O_APPEND
;
276 indesc
->opencount
= outdesc
->opencount
= errdesc
->opencount
= 1;
278 __fd_array
[STDIN_FILENO
] = indesc
;
279 __fd_array
[STDOUT_FILENO
] = outdesc
;
280 __fd_array
[STDERR_FILENO
] = errdesc
;
285 void __exit_stdfiles(void)
297 void __updatestdio(void)
301 me
= (struct Process
*)FindTask(NULL
);
307 __fd_array
[STDIN_FILENO
]->fh
= __stdfiles
[STDIN_FILENO
] = Input();
308 __fd_array
[STDOUT_FILENO
]->fh
= __stdfiles
[STDOUT_FILENO
] = Output();
309 __fd_array
[STDERR_FILENO
]->fh
= __stdfiles
[STDERR_FILENO
] = me
->pr_CES
? me
->pr_CES
: me
->pr_COS
;
312 ADD2INIT(__init_stdfiles
, 2);
313 ADD2EXIT(__exit_stdfiles
, 2);