kolibrios/programs/develop/libraries/newlib/reent/openr.c
Sergey Semyonov (Serge) 2336060a0c newlib: update
git-svn-id: svn://kolibrios.org@1906 a494cfbc-eb01-0410-851d-a64ba20cac60
2011-03-11 18:52:24 +00:00

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) */