-/*
+/* $Id: open.c,v 1.14 2002/12/26 17:26:41 robd Exp $
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
- * FILE: lib/crtdll/io/open.c
+ * FILE: lib/msvcrt/io/open.c
* PURPOSE: Opens a file and translates handles to fileno
* PROGRAMER: Boudewijn Dekker
* UPDATE HISTORY:
// 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>
+#if !defined(NDEBUG) && defined(DBG)
+#include <msvcrt/stdarg.h>
+#endif
+#include <msvcrt/io.h>
+#include <msvcrt/fcntl.h>
+#include <msvcrt/sys/stat.h>
+#include <msvcrt/stdlib.h>
+#include <msvcrt/internal/file.h>
+#include <msvcrt/string.h>
+#include <msvcrt/share.h>
+#include <msvcrt/errno.h>
+
+#define NDEBUG
+#include <msvcrt/msvcrtdbg.h>
+
+//#define _OLD_BUILD_
+
+#define STD_AUX_HANDLE 3
+#define STD_PRINTER_HANDLE 4
+
+
+/////////////////////////////////////////
+#if 0 // from perl sources
+
+#ifndef _INTPTR_T_DEFINED
+typedef int intptr_t;
+#define _INTPTR_T_DEFINED
+#endif
+
+#ifndef _UINTPTR_T_DEFINED
+typedef unsigned int uintptr_t;
+#define _UINTPTR_T_DEFINED
+#endif
+
+/*
+ * Control structure for lowio file handles
+ */
+typedef struct {
+ intptr_t osfhnd;/* underlying OS file HANDLE */
+ char osfile; /* attributes of file (e.g., open in text mode?) */
+ char pipech; /* one char buffer for handles opened on pipes */
+ int lockinitflag;
+ //CRITICAL_SECTION lock;
+} ioinfo;
+
+/*
+ * Array of arrays of control structures for lowio files.
+ */
+//ioinfo* __pioinfo[];
+//ioinfo* __pioinfo[] = { NULL };
+
+#endif
+/////////////////////////////////////////
typedef struct _fileno_modes_type
{
- HANDLE hFile;
- int mode;
- int fd;
+ HANDLE hFile;
+ int mode;
+ char pipech; /* one char buffer for handles opened on pipes */
+ int lockinitflag;
+ /*CRITICAL_SECTION*/int lock;
+ int fd;
} fileno_modes_type;
-fileno_modes_type *fileno_modes = NULL;
+//static fileno_modes_type* fileno_modes = NULL;
+fileno_modes_type* __pioinfo = NULL;
-int maxfno = 5;
-int minfno = 5;
+/////////////////////////////////////////
+int maxfno = 0;
-char __is_text_file(FILE *p)
+char __is_text_file(FILE* p)
{
- if ( p == NULL || fileno_modes == NULL )
+ if ( p == NULL || __pioinfo == NULL )
return FALSE;
- return (!((p)->_flag&_IOSTRG) && (fileno_modes[(p)->_file].mode&O_TEXT));
+ return (!((p)->_flag&_IOSTRG) && (__pioinfo[(p)->_file].mode&O_TEXT));
}
-
-
-
-int __fileno_alloc(HANDLE hFile, int mode);
-
-
-int _open(const char *_path, int _oflag,...)
+int _open(const char* _path, int _oflag,...)
{
+#if !defined(NDEBUG) && defined(DBG)
+ va_list arg;
+ int pmode;
+#endif
HANDLE hFile;
DWORD dwDesiredAccess = 0;
DWORD dwShareMode = 0;
DWORD dwCreationDistribution = 0;
DWORD dwFlagsAndAttributes = 0;
-
- if (( _oflag & S_IREAD ) == S_IREAD)
+ DWORD dwLastError;
+ SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+
+#if !defined(NDEBUG) && defined(DBG)
+ va_start(arg, _oflag);
+ pmode = va_arg(arg, int);
+#endif
+
+// DPRINT("_open('%s', %x, (%x))\n", _path, _oflag, pmode);
+
+ if ((_oflag & S_IREAD ) == S_IREAD)
dwShareMode = FILE_SHARE_READ;
- else if ( ( _oflag & S_IWRITE) == S_IWRITE ) {
+ 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.)
- *
+ *
+ * _O_APPEND Moves file pointer to end of file before every write operation.
*/
- 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 )
+#ifdef _OLD_BUILD_
+ if ((_oflag & _O_RDWR) == _O_RDWR)
+ dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ;
+ else if ((_oflag & O_RDONLY) == O_RDONLY)
+ dwDesiredAccess |= GENERIC_READ;
+ else if ((_oflag & _O_WRONLY) == _O_WRONLY)
+ dwDesiredAccess |= GENERIC_WRITE ;
+#else
+ if ((_oflag & _O_WRONLY) == _O_WRONLY )
+ dwDesiredAccess |= GENERIC_WRITE ;
+ else if ((_oflag & _O_RDWR) == _O_RDWR )
+ dwDesiredAccess |= GENERIC_WRITE|GENERIC_READ;
+ else //if ((_oflag & O_RDONLY) == O_RDONLY)
+ dwDesiredAccess |= GENERIC_READ;
+#endif
+ if (( _oflag & S_IREAD ) == S_IREAD)
dwShareMode |= FILE_SHARE_READ;
- if (( _oflag & S_IWRITE ) == S_IWRITE )
- dwShareMode |= FILE_SHARE_WRITE;
+ if (( _oflag & S_IWRITE ) == S_IWRITE)
+ dwShareMode |= FILE_SHARE_WRITE;
- if (( _oflag & (_O_CREAT | _O_EXCL ) ) == (_O_CREAT | _O_EXCL) )
+ 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_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 )
+ else if ((_oflag & _O_APPEND) == _O_APPEND)
dwCreationDistribution |= OPEN_EXISTING;
- else if (( _oflag & _O_CREAT ) == _O_CREAT )
+ 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 )
+
+ 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 )
+ if ((_oflag & _O_TEMPORARY) == _O_TEMPORARY) {
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
-
- if (( _oflag & _O_SHORT_LIVED ) == _O_SHORT_LIVED )
+ DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
+ }
+ if ((_oflag & _O_SHORT_LIVED) == _O_SHORT_LIVED) {
dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
-
+ DPRINT("FILE_FLAG_DELETE_ON_CLOSE\n");
+ }
+ if (_oflag & _O_NOINHERIT)
+ sa.bInheritHandle = FALSE;
hFile = CreateFileA(_path,
- dwDesiredAccess,
- dwShareMode,
- NULL,
- dwCreationDistribution,
- dwFlagsAndAttributes,
- NULL);
- if (hFile == (HANDLE)-1)
+ dwDesiredAccess,
+ dwShareMode,
+ &sa,
+ dwCreationDistribution,
+ dwFlagsAndAttributes,
+ NULL);
+ if (hFile == (HANDLE)-1) {
+ dwLastError = GetLastError();
+ if (dwLastError == ERROR_ALREADY_EXISTS) {
+ DPRINT("ERROR_ALREADY_EXISTS\n");
+ __set_errno(EEXIST);
+ } else {
+ DPRINT("%x\n", dwLastError);
+ __set_errno(ENOFILE);
+ }
return -1;
- return __fileno_alloc(hFile,_oflag);
-
-// _O_APPEND Moves file pointer to end of file before every write operation.
-
+ }
+ DPRINT("OK\n");
+ if (!(_oflag & (_O_TEXT|_O_BINARY))) {
+ _oflag |= _fmode;
+ }
+ return __fileno_alloc(hFile,_oflag);
}
-
-
-int
-__fileno_alloc(HANDLE hFile, int mode)
+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;
- }
+ return -1;
+
+ for (i = 5; i < maxfno; i++) {
+ if (__pioinfo[i].fd == -1 ) {
+ __pioinfo[i].fd = i;
+ __pioinfo[i].mode = mode;
+ __pioinfo[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)
- {
+ 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 );
-
+ fileno_modes_type* old_fileno_modes = __pioinfo;
+ maxfno += 255;
+ __pioinfo = (fileno_modes_type*)malloc(maxfno * sizeof(fileno_modes_type));
+ if (old_fileno_modes != NULL) {
+ memcpy(__pioinfo, old_fileno_modes, oldcount * sizeof(fileno_modes_type));
+ free(old_fileno_modes);
+ }
+ memset(__pioinfo + oldcount, -1, (maxfno-oldcount)*sizeof(fileno_modes_type));
}
/* Fill in the value */
- fileno_modes[i].fd = i;
- fileno_modes[i].mode = mode;
- fileno_modes[i].hFile = hFile;
+ __pioinfo[i].fd = i;
+ __pioinfo[i].mode = mode;
+ __pioinfo[i].hFile = hFile;
return i;
}
-void *filehnd(int fileno)
+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;
+ if (fileno < 0 || fileno >= maxfno || __pioinfo[fileno].fd == -1) {
+ return (void*)-1;
+ }
+ return __pioinfo[fileno].hFile;
}
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 m;
+ if (_fd < 0 || _fd >= maxfno) {
+ __set_errno(EBADF);
+ return -1;
+ }
+ m = __pioinfo[_fd].mode;
+ __pioinfo[_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;
+ if (_fd < 0 || _fd >= maxfno) {
+ __set_errno(EBADF);
+ return -1;
+ }
+ return __pioinfo[_fd].mode;
}
-
-int __fileno_close(int _fd)
+int __fileno_close(int _fd)
{
- if ( _fd < 0 )
- return -1;
+ if (_fd < 0 || _fd >= maxfno) {
+ __set_errno(EBADF);
+ return -1;
+ }
+ __pioinfo[_fd].fd = -1;
+ __pioinfo[_fd].hFile = (HANDLE)-1;
+ return 0;
+}
- if ( _fd >= maxfno )
- return -1;
+int _open_osfhandle(void* osfhandle, int flags)
+{
+ return __fileno_alloc((HANDLE)osfhandle, flags);
+}
- fileno_modes[_fd].fd = -1;
- fileno_modes[_fd].hFile = (HANDLE)-1;
- return 0;
+void* _get_osfhandle( int fileno )
+{
+ return filehnd(fileno);
}
-int _open_osfhandle (void *osfhandle, int flags )
+int __fileno_dup2(int handle1, int handle2)
{
- return __fileno_alloc((HANDLE)osfhandle, flags);
-}
+ HANDLE hProcess;
+ BOOL result;
+ if (handle1 >= maxfno || handle1 < 0 || handle2 >= maxfno || handle2 < 0) {
+ __set_errno(EBADF);
+ return -1;
+ }
+ if (__pioinfo[handle1].fd == -1) {
+ __set_errno(EBADF);
+ return -1;
+ }
+ if (handle1 == handle2)
+ return handle1;
+ if (__pioinfo[handle2].fd != -1) {
+ _close(handle2);
+ }
+ hProcess = GetCurrentProcess();
+ result = DuplicateHandle(hProcess,
+ __pioinfo[handle1].hFile,
+ hProcess,
+ &__pioinfo[handle2].hFile,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+ if (result) {
+ __pioinfo[handle2].fd = handle2;
+ __pioinfo[handle2].mode = __pioinfo[handle1].mode;
+ switch (handle2) {
+ case 0:
+ SetStdHandle(STD_INPUT_HANDLE, __pioinfo[handle2].hFile);
+ break;
+ case 1:
+ SetStdHandle(STD_OUTPUT_HANDLE, __pioinfo[handle2].hFile);
+ break;
+ case 2:
+ SetStdHandle(STD_ERROR_HANDLE, __pioinfo[handle2].hFile);
+ break;
+ case 3:
+ SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile);
+ break;
+ case 4:
+ SetStdHandle(STD_AUX_HANDLE, __pioinfo[handle2].hFile);
+ break;
+ }
+ return handle1;
+ } else {
+ __set_errno(EMFILE); // Is this the correct error no.?
+ return -1;
+ }
+}
+
-void *_get_osfhandle( int fileno )
+void* malloc(size_t sizeObject);
+
+BOOL __fileno_init(void)
{
- return filehnd(fileno);
+ ULONG count = 0, i;
+ HANDLE* pFile;
+ char* pmode;
+ STARTUPINFO StInfo;
+
+ GetStartupInfoA(&StInfo);
+ if (StInfo.lpReserved2 && StInfo.cbReserved2 >= sizeof(ULONG)) {
+ count = *(ULONG*)StInfo.lpReserved2;
+/*
+ if (sizeof(ULONG) + count * (sizeof(HANDLE) + sizeof(char)) != StInfo.cbReserved2)
+ {
+ count = 0;
+ }
+*/
+ }
+ maxfno = 255;
+ while(count >= maxfno)
+ maxfno += 255;
+
+ {
+#ifdef _OLD_BUILD_
+ // why was this here ???? - robd.
+ int result;
+ result = malloc(50);
+#endif
+ }
+ //__pioinfo = (fileno_modes_type*)malloc(sizeof(fileno_modes_type) * maxfno);
+ __pioinfo = malloc(sizeof(fileno_modes_type) * maxfno);
+ if (__pioinfo == NULL) {
+ return FALSE;
+ }
+ memset(__pioinfo, -1, sizeof(fileno_modes_type) * maxfno);
+ if (count) {
+ pFile = (HANDLE*)(StInfo.lpReserved2 + sizeof(ULONG) + count * sizeof(char));
+ pmode = (char*)(StInfo.lpReserved2 + sizeof(ULONG));
+ for (i = 0; i < count; i++) {
+ if (*pFile != INVALID_HANDLE_VALUE) {
+ __pioinfo[i].fd = i;
+ __pioinfo[i].mode = ((*pmode << 8) & (_O_TEXT|_O_BINARY)) | (*pmode & _O_ACCMODE);
+ __pioinfo[i].hFile = *pFile;
+ }
+ pFile++;
+ pmode++;
+ }
+ }
+ if (__pioinfo[0].fd == -1) {
+ __pioinfo[0].fd = 0;
+ __pioinfo[0].hFile = GetStdHandle(STD_INPUT_HANDLE);
+ __pioinfo[0].mode = _O_RDONLY|_O_TEXT;
+ }
+ if (__pioinfo[1].fd == -1) {
+ __pioinfo[1].fd = 1;
+ __pioinfo[1].hFile = GetStdHandle(STD_OUTPUT_HANDLE);
+ __pioinfo[1].mode = _O_WRONLY|_O_TEXT;
+ }
+ if (__pioinfo[2].fd == -1) {
+ __pioinfo[2].fd = 2;
+ __pioinfo[2].hFile = GetStdHandle(STD_ERROR_HANDLE);
+ __pioinfo[2].mode = _O_WRONLY|_O_TEXT;
+ }
+ if (__pioinfo[3].fd == -1) {
+ __pioinfo[3].fd = 3;
+ __pioinfo[3].hFile = GetStdHandle(STD_AUX_HANDLE);
+ __pioinfo[3].mode = _O_WRONLY|_O_TEXT;
+ }
+ if (__pioinfo[4].fd == -1) {
+ __pioinfo[4].fd = 4;
+ __pioinfo[4].hFile = GetStdHandle(STD_PRINTER_HANDLE);
+ __pioinfo[4].mode = _O_WRONLY|_O_TEXT;
+ }
+ return TRUE;
}