reactos/reactos/lib/crtdll/io/open.c
Boudewijn Dekker 62cdaf7f99 no message
svn path=/trunk/; revision=561
1999-06-24 21:59:41 +00:00

273 lines
6.2 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crtdll/io/open.c
* PURPOSE: Opens a file and translates handles to fileno
* PROGRAMER: Boudewijn Dekker
* UPDATE HISTORY:
* 28/12/98: Created
*/
// rember to interlock the allocation of fileno when making this thread safe
// possibly store extra information at the handle
#include <windows.h>
#include <crtdll/io.h>
#include <crtdll/fcntl.h>
#include <crtdll/sys/stat.h>
#include <crtdll/stdlib.h>
#include <crtdll/internal/file.h>
#include <crtdll/string.h>
#include <crtdll/share.h>
typedef struct _fileno_modes_type
{
HANDLE hFile;
int mode;
int fd;
} fileno_modes_type;
fileno_modes_type *fileno_modes = NULL;
int maxfno = 5;
int minfno = 5;
char __is_text_file(FILE *p)
{
if ( p == NULL || fileno_modes == NULL )
return FALSE;
return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT));
}
int __fileno_alloc(HANDLE hFile, int mode);
int _open(const char *_path, int _oflag,...)
{
HANDLE hFile;
DWORD dwDesiredAccess = 0;
DWORD dwShareMode = 0;
DWORD dwCreationDistribution = 0;
DWORD dwFlagsAndAttributes = 0;
if (( _oflag & S_IREAD ) == S_IREAD)
dwShareMode = FILE_SHARE_READ;
else if ( ( _oflag & S_IWRITE) == S_IWRITE ) {
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
}
/*
*
* _O_BINARY Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)
* _O_TEXT Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)
*
*/
if (( _oflag & _O_RDWR ) == _O_RDWR )
dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ | FILE_READ_DATA |
FILE_WRITE_DATA | FILE_READ_ATTRIBUTES |
FILE_WRITE_ATTRIBUTES;
else if (( _oflag & O_RDONLY ) == O_RDONLY )
dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES;
else if (( _oflag & _O_WRONLY ) == _O_WRONLY )
dwDesiredAccess |= GENERIC_WRITE | FILE_WRITE_DATA |
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES;
if (( _oflag & S_IREAD ) == S_IREAD )
dwShareMode |= FILE_SHARE_READ;
if (( _oflag & S_IWRITE ) == S_IWRITE )
dwShareMode |= FILE_SHARE_WRITE;
if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
dwCreationDistribution |= CREATE_NEW;
else if (( _oflag & O_TRUNC ) == O_TRUNC ) {
if (( _oflag & O_CREAT ) == O_CREAT )
dwCreationDistribution |= CREATE_ALWAYS;
else if (( _oflag & O_RDONLY ) != O_RDONLY )
dwCreationDistribution |= TRUNCATE_EXISTING;
}
else if (( _oflag & _O_APPEND ) == _O_APPEND )
dwCreationDistribution |= OPEN_EXISTING;
else if (( _oflag & _O_CREAT ) == _O_CREAT )
dwCreationDistribution |= OPEN_ALWAYS;
else
dwCreationDistribution |= OPEN_EXISTING;
if (( _oflag & _O_RANDOM ) == _O_RANDOM )
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
if (( _oflag & _O_SEQUENTIAL ) == _O_SEQUENTIAL )
dwFlagsAndAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
if (( _oflag & _O_TEMPORARY ) == _O_TEMPORARY )
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
hFile = CreateFileA(_path,
dwDesiredAccess,
dwShareMode,
NULL,
dwCreationDistribution,
dwFlagsAndAttributes,
NULL);
if (hFile == (HANDLE)-1)
return -1;
return __fileno_alloc(hFile,_oflag);
// _O_APPEND Moves file pointer to end of file before every write operation.
}
int
__fileno_alloc(HANDLE hFile, int mode)
{
int i;
/* Check for bogus values */
if (hFile < 0)
return -1;
for(i=minfno;i<maxfno;i++) {
if (fileno_modes[i].fd == -1 ) {
fileno_modes[i].fd = i;
fileno_modes[i].mode = mode;
fileno_modes[i].hFile = hFile;
return i;
}
}
/* See if we need to expand the tables. Check this BEFORE it might fail,
so that when we hit the count'th request, we've already up'd it. */
if ( i == maxfno)
{
int oldcount = maxfno;
fileno_modes_type *old_fileno_modes = fileno_modes;
maxfno += 255;
fileno_modes = (fileno_modes_type *)malloc(maxfno * sizeof(fileno_modes_type));
if ( old_fileno_modes != NULL )
memcpy(fileno_modes, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
memset(fileno_modes + oldcount, 0, (maxfno-oldcount)*sizeof(fileno_modes));
free ( old_fileno_modes );
}
/* Fill in the value */
fileno_modes[i].fd = i;
fileno_modes[i].mode = mode;
fileno_modes[i].hFile = hFile;
return i;
}
void *filehnd(int fileno)
{
if ( fileno < 0 )
return (void *)-1;
#define STD_AUX_HANDLE 3
#define STD_PRINTER_HANDLE 4
switch(fileno)
{
case 0:
return GetStdHandle(STD_INPUT_HANDLE);
case 1:
return GetStdHandle(STD_OUTPUT_HANDLE);
case 2:
return GetStdHandle(STD_ERROR_HANDLE);
case 3:
return GetStdHandle(STD_AUX_HANDLE);
case 4:
return GetStdHandle(STD_PRINTER_HANDLE);
default:
break;
}
if ( fileno >= maxfno )
return (void *)-1;
if ( fileno_modes[fileno].fd == -1 )
return (void *)-1;
return fileno_modes[fileno].hFile;
}
int __fileno_dup2( int handle1, int handle2 )
{
if ( handle1 >= maxfno )
return -1;
if ( handle1 < 0 )
return -1;
if ( handle2 >= maxfno )
return -1;
if ( handle2 < 0 )
return -1;
memcpy(&fileno_modes[handle1],&fileno_modes[handle2],sizeof(fileno_modes));
return handle1;
}
int __fileno_setmode(int _fd, int _newmode)
{
int m;
if ( _fd < minfno )
return -1;
if ( _fd >= maxfno )
return -1;
m = fileno_modes[_fd].mode;
fileno_modes[_fd].mode = _newmode;
return m;
}
int __fileno_getmode(int _fd)
{
if ( _fd < minfno )
return -1;
if ( _fd >= maxfno )
return -1;
return fileno_modes[_fd].mode;
}
int __fileno_close(int _fd)
{
if ( _fd < 0 )
return -1;
if ( _fd >= maxfno )
return -1;
fileno_modes[_fd].fd = -1;
fileno_modes[_fd].hFile = (HANDLE)-1;
return 0;
}
int _open_osfhandle (void *osfhandle, int flags )
{
return __fileno_alloc((HANDLE)osfhandle, flags);
}
void *_get_osfhandle( int fileno )
{
return filehnd(fileno);
}