#include #include #include #include #include #include extern StdFileDes **__stdfiledes; extern unsigned __stdfilesize; #ifdef __posix_threads__ unsigned __stdLock[2]; #endif StdFileDes *__allocfd(void); extern void _setup_file(StdFileDes *fp); extern void __seterrno(void); /** * open a file * * @return the file descriptor. */ int open(const char *path, int flags, ...) { extern char *__amigapath(const char *path); StdFileDes *sfd; #ifdef IXPATHS if((path=__amigapath(path))==NULL) return -1; #endif if ((sfd = __allocfd())) { long mode; sfd->lx_oflags = flags; mode = flags&O_TRUNC?MODE_NEWFILE: flags&O_CREAT?MODE_READWRITE:MODE_OLDFILE; sfd->lx_fh = (int)Open((CONST_STRPTR)path, mode); // workaround for RAM: and maybe other handlers which do not create a file on MODE_READWRITE. if (!sfd->lx_fh && (flags&O_CREAT)) sfd->lx_fh = (int)Open((CONST_STRPTR)path, MODE_NEWFILE); if (sfd->lx_fh) { _setup_file(sfd); return sfd->lx_pos; } __seterrno(); sfd->lx_inuse = 0; } return -1; } #ifdef __posix_threads__ static StdFileDes *__allocfd2(void); #endif /** * Reuse or allocate a StdFileDes object. */ StdFileDes *__allocfd(void) { #ifdef __posix_threads__ __spinLock(__stdLock); StdFileDes * sfd = __allocfd2(); __spinUnlock(__stdLock); return sfd; } static StdFileDes *__allocfd2(void) { #endif StdFileDes *fp, **sfd; int file, max; for (sfd = __stdfiledes, max = __stdfilesize, file = 0; file < max; sfd++, file++) if (!sfd[0] || !sfd[0]->lx_inuse) break; if (file == SHRT_MAX) { errno = EMFILE; return NULL; } if (file == max) { if ((sfd = (StdFileDes **)realloc(__stdfiledes, (file + 1) * sizeof(fp))) == NULL) { errno = ENOMEM; return NULL; } __stdfiledes = sfd; *(sfd = &sfd[file]) = 0; ++__stdfilesize; } if ((fp = sfd[0]) == NULL) { if ((sfd[0] = fp = (StdFileDes *)malloc(sizeof(*fp))) == NULL) { errno = ENOMEM; return NULL; } fp->lx_pos = file; } return fp; }