222 lines
5.0 KiB
C
222 lines
5.0 KiB
C
|
/* 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) */
|