/* Reentrant versions of open system call. */ #include <reent.h> #include <unistd.h> #include <fcntl.h> #include <_syslist.h> #include <sys/errno.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <sys/kos_io.h> /* Some targets provides their own versions of this functions. Those targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS. */ #ifdef _REENT_ONLY #ifndef REENTRANT_SYSCALLS_PROVIDED #define REENTRANT_SYSCALLS_PROVIDED #endif #endif #ifndef REENTRANT_SYSCALLS_PROVIDED /* We use the errno variable used by the system dependent layer. */ /* FUNCTION <<_open_r>>---Reentrant version of open INDEX _open_r ANSI_SYNOPSIS #include <reent.h> int _open_r(struct _reent *<[ptr]>, const char *<[file]>, int <[flags]>, int <[mode]>); TRAD_SYNOPSIS #include <reent.h> int _open_r(<[ptr]>, <[file]>, <[flags]>, <[mode]>) struct _reent *<[ptr]>; char *<[file]>; int <[flags]>; int <[mode]>; DESCRIPTION This is a reentrant version of <<open>>. It takes a pointer to the global data block, which holds <<errno>>. */ #define NULL_HANDLE (int)-1 #define DUMMY_HANDLE (int)-2 #define _READ 0x0001 /* file opened for reading */ #define _WRITE 0x0002 /* file opened for writing */ #define _UNGET 0x0004 /* ungetc has been done */ #define _BIGBUF 0x0008 /* big buffer allocated */ #define _EOF 0x0010 /* EOF has occurred */ #define _SFERR 0x0020 /* error has occurred on this file */ #define _APPEND 0x0080 /* file opened for append */ #define _BINARY 0x0040 /* file is binary, skip CRLF processing */ #define _TMPFIL 0x0800 /* this is a temporary file */ #define _DIRTY 0x1000 /* buffer has been modified */ #define _ISTTY 0x2000 /* is console device */ #define _DYNAMIC 0x4000 /* FILE is dynamically allocated */ #define _FILEEXT 0x8000 /* lseek with positive offset has been done */ #define _COMMIT 0x0001 /* extended flag: commit OS buffers on flush */ extern int _fmode; static inline void debug_out(const char val) { __asm__ __volatile__( "int $0x40 \n\t" ::"a"(63), "b"(1),"c"(val)); } int debugwrite(const char *path, const void *buff, size_t offset, size_t count, size_t *writes) { int ret = count; const char *p = buff; while (count--) { debug_out(*p++); }; *writes = ret; return ret; }; static int __openFileHandle(const char *path, int mode, int *err) { fileinfo_t info; __file_handle *handle; // path = getfullpath(name); *err = get_fileinfo(path, &info); if( mode & O_EXCL && mode & O_CREAT ) { if( ! *err) { *err = EEXIST; return -1; }; } if( *err) { if(mode & O_CREAT) *err=create_file(path); if( *err) { return -1; }; }; if( mode & O_TRUNC ) set_file_size(path, 0); if ( !(handle=(__file_handle*)malloc(sizeof( __file_handle) ))) { *err = ENOMEM; return -1; }; handle->name = strdup(path); handle->offset = 0; handle->write = write_file; *err = 0; return (int)handle; }; int _DEFUN (_open_r, (ptr, file, flags, dmode), struct _reent *ptr _AND _CONST char *file _AND int flags _AND int dmode) { int hid; int handle; int err = 0; unsigned iomode_flags; int rwmode; /* if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC)) { ptr->_errno = ENOSYS; return -1; } */ // First try to get the required slot. // No point in creating a file only to not use it. JBS 99/10/26 hid = __allocPOSIXHandle( DUMMY_HANDLE ); if( hid == -1 ) { ptr->_errno = EMFILE; return( -1 ); } handle = __openFileHandle( file, flags, &err); if( handle == -1 ) { __freePOSIXHandle( hid ); ptr->_errno = err; return( -1 ); } __setOSHandle( hid, handle ); // JBS 99/11/01 rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT ); iomode_flags = 0; if( rwmode == O_RDWR ) iomode_flags |= _READ | _WRITE; else if( rwmode == O_RDONLY) iomode_flags |= _READ; else if( rwmode == O_WRONLY) iomode_flags |= _WRITE; if( flags & O_APPEND ) iomode_flags |= _APPEND; if( flags & (O_BINARY|O_TEXT) ) { if( flags & O_BINARY ) iomode_flags |= _BINARY; } else { if( _fmode == O_BINARY ) iomode_flags |= _BINARY; } __SetIOMode( hid, iomode_flags ); ptr->_errno = 0; return (hid); } int _DEFUN (open, (file, flags, ...), const char *file _AND int flags _DOTS) { va_list ap; int ret; va_start (ap, flags); ret = _open_r (_REENT, file, flags, va_arg (ap, int)); va_end (ap); return ret; } #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */