/* values for wxflag in file descriptor */
#define WX_OPEN 0x01
#define WX_ATEOF 0x02
+#define WX_READNL 0x04 /* read started with \n */
#define WX_READEOF 0x04 /* like ATEOF, but for underlying file rather than buffer */
#define WX_READCR 0x08 /* underlying file is at \r */
#define WX_DONTINHERIT 0x10
#define WX_APPEND 0x20
#define WX_TEXT 0x80
-/* values for exflag - it's used differently in msvcr90.dll*/
-#define EF_UTF8 0x01
-#define EF_UTF16 0x02
-#define EF_CRIT_INIT 0x04
-#define EF_UNK_UNICODE 0x08
-
-static char utf8_bom[3] = { 0xef, 0xbb, 0xbf };
-static char utf16_bom[2] = { 0xff, 0xfe };
-
/* FIXME: this should be allocated dynamically */
#define MAX_FILES 2048
#define FD_BLOCK_SIZE 64
-/* ioinfo structure size is different in msvcrXX.dll's */
typedef struct {
HANDLE handle;
unsigned char wxflag;
char unk1;
- int exflag;
+ BOOL crit_init;
CRITICAL_SECTION crit;
} ioinfo;
static int get_flags(const wchar_t* mode, int *open_flags, int* stream_flags)
{
int plus = strchrW(mode, '+') != NULL;
-
- while(*mode == ' ') mode++;
-
+
switch(*mode++)
{
case 'R': case 'r':
return -1;
}
- /* FIXME */
- /* *stream_flags |= MSVCRT__commode; */
-
- while (*mode && *mode!=',')
+ while (*mode)
switch (*mode++)
{
case 'B': case 'b':
*open_flags |= _O_TEXT;
*open_flags &= ~_O_BINARY;
break;
- case 'D':
- *open_flags |= _O_TEMPORARY;
- break;
- case 'T':
- *open_flags |= _O_SHORT_LIVED;
- break;
- /* FIXME
- case 'c':
- *stream_flags |= _IOCOMMIT;
- break;
- case 'n':
- *stream_flags &= ~_IOCOMMIT;
- break;
- */
- case 'N':
- *open_flags |= _O_NOINHERIT;
- break;
case '+':
case ' ':
- case 'a':
- case 'w':
- break;
- case 'S':
- case 'R':
- FIXME("ignoring cache optimization flag: %c\n", mode[-1]);
break;
default:
- ERR("incorrect mode flag: %c\n", mode[-1]);
- break;
- }
-
- if(*mode == ',')
- {
- static const WCHAR ccs[] = {'c','c','s'};
- static const WCHAR utf8[] = {'u','t','f','-','8'};
- static const WCHAR utf16le[] = {'u','t','f','-','1','6','l','e'};
- static const WCHAR unicode[] = {'u','n','i','c','o','d','e'};
-
- mode++;
- while(*mode == ' ') mode++;
- if(!MSVCRT_CHECK_PMT(!strncmpW(ccs, mode, sizeof(ccs)/sizeof(ccs[0]))))
- return -1;
- mode += sizeof(ccs)/sizeof(ccs[0]);
- while(*mode == ' ') mode++;
- if(!MSVCRT_CHECK_PMT(*mode == '='))
- return -1;
- mode++;
- while(*mode == ' ') mode++;
-
- if(!strncmpiW(utf8, mode, sizeof(utf8)/sizeof(utf8[0])))
- {
- *open_flags |= _O_U8TEXT;
- mode += sizeof(utf8)/sizeof(utf8[0]);
- }
- else if(!strncmpiW(utf16le, mode, sizeof(utf16le)/sizeof(utf16le[0])))
- {
- *open_flags |= _O_U16TEXT;
- mode += sizeof(utf16le)/sizeof(utf16le[0]);
- }
- else if(!strncmpiW(unicode, mode, sizeof(unicode)/sizeof(unicode[0])))
- {
- *open_flags |= _O_WTEXT;
- mode += sizeof(unicode)/sizeof(unicode[0]);
+ FIXME(":unknown flag %c not supported\n",mode[-1]);
}
- else
- {
- _invalid_parameter(NULL, NULL, NULL, 0, 0);
- *_errno() = EINVAL;
- return -1;
- }
-
- while(*mode == ' ') mode++;
- }
-
- if(!MSVCRT_CHECK_PMT(*mode == 0))
- return -1;
-
return 0;
}
int wxflags = 0;
unsigned unsupp; /* until we support everything */
- if (oflags & _O_APPEND) wxflags |= WX_APPEND;
- if (oflags & _O_BINARY) {/* Nothing to do */}
- else if (oflags & _O_TEXT) wxflags |= WX_TEXT;
- else if (oflags & _O_WTEXT) wxflags |= WX_TEXT;
- else if (oflags & _O_U16TEXT) wxflags |= WX_TEXT;
- else if (oflags & _O_U8TEXT) wxflags |= WX_TEXT;
- else if (*__p__fmode() & _O_BINARY) {/* Nothing to do */}
+ if (oflags & _O_APPEND) wxflags |= WX_APPEND;
+ if (oflags & _O_BINARY) {/* Nothing to do */}
+ else if (oflags & _O_TEXT) wxflags |= WX_TEXT;
+ else if (*__p__fmode() & _O_BINARY) {/* Nothing to do */}
else wxflags |= WX_TEXT; /* default to TEXT*/
- if (oflags & _O_NOINHERIT) wxflags |= WX_DONTINHERIT;
+ if (oflags & _O_NOINHERIT) wxflags |= WX_DONTINHERIT;
if ((unsupp = oflags & ~(
_O_BINARY|_O_TEXT|_O_APPEND|
_O_TRUNC|_O_EXCL|_O_CREAT|
_O_RDWR|_O_WRONLY|_O_TEMPORARY|
_O_NOINHERIT|
- _O_SEQUENTIAL|_O_RANDOM|_O_SHORT_LIVED|
- _O_WTEXT|_O_U16TEXT|_O_U8TEXT
+ _O_SEQUENTIAL|_O_RANDOM|_O_SHORT_LIVED
)))
ERR(":unsupported oflags 0x%04x\n",unsupp);
if (!fd)
{
- MSVCRT_INVALID_PMT("null out fd pointer");
- *_errno() = EINVAL;
+ MSVCRT_INVALID_PMT("null out fd pointer", EINVAL);
return EINVAL;
}
return fd;
}
-static int check_bom(HANDLE h, int oflags, BOOL seek)
-{
- char bom[sizeof(utf8_bom)];
- DWORD r;
-
- oflags &= ~(_O_WTEXT|_O_U16TEXT|_O_U8TEXT);
-
- if (!ReadFile(h, bom, sizeof(utf8_bom), &r, NULL))
- return oflags;
-
- if (r==sizeof(utf8_bom) && !memcmp(bom, utf8_bom, sizeof(utf8_bom))) {
- oflags |= _O_U8TEXT;
- }else if (r>=sizeof(utf16_bom) && !memcmp(bom, utf16_bom, sizeof(utf16_bom))) {
- if (seek && r>2)
- SetFilePointer(h, 2, NULL, FILE_BEGIN);
- oflags |= _O_U16TEXT;
- }else if (seek) {
- SetFilePointer(h, 0, NULL, FILE_BEGIN);
- }
-
- return oflags;
-}
-
/*********************************************************************
* _wsopen_s (MSVCRT.@)
*/
if (!fd)
{
- MSVCRT_INVALID_PMT("null out fd pointer");
- *_errno() = EINVAL;
+ MSVCRT_INVALID_PMT("null out fd pointer", EINVAL);
return EINVAL;
}
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = (oflags & _O_NOINHERIT) ? FALSE : TRUE;
- if ((oflags&(_O_WTEXT|_O_U16TEXT|_O_U8TEXT))
- && (creation==OPEN_ALWAYS || creation==OPEN_EXISTING)
- && !(access&GENERIC_READ))
- {
- hand = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
- &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if (hand != INVALID_HANDLE_VALUE)
- {
- oflags = check_bom(hand, oflags, FALSE);
- CloseHandle(hand);
- }
- else
- oflags &= ~(_O_WTEXT|_O_U16TEXT|_O_U8TEXT);
- }
-
hand = CreateFileW(path, access, sharing, &sa, creation, attrib, 0);
if (hand == INVALID_HANDLE_VALUE) {
return *_errno();
}
- if (oflags & (_O_WTEXT|_O_U16TEXT|_O_U8TEXT))
- {
- if ((access & GENERIC_WRITE) && (creation==CREATE_NEW
- || creation==CREATE_ALWAYS || creation==TRUNCATE_EXISTING
- || (creation==OPEN_ALWAYS && GetLastError()==ERROR_ALREADY_EXISTS)))
- {
- if (oflags & _O_U8TEXT)
- {
- DWORD written = 0, tmp;
-
- while(written!=sizeof(utf8_bom) && WriteFile(hand, (char*)utf8_bom+written,
- sizeof(utf8_bom)-written, &tmp, NULL))
- written += tmp;
- if (written != sizeof(utf8_bom)) {
- WARN("error writing BOM\n");
- CloseHandle(hand);
- *_errno() = GetLastError();
- return *_errno();
- }
- }
- else
- {
- DWORD written = 0, tmp;
-
- while(written!=sizeof(utf16_bom) && WriteFile(hand, (char*)utf16_bom+written,
- sizeof(utf16_bom)-written, &tmp, NULL))
- written += tmp;
- if (written != sizeof(utf16_bom))
- {
- WARN("error writing BOM\n");
- CloseHandle(hand);
- *_errno() = GetLastError();
- return *_errno();
- }
- }
- }
- else if (access & GENERIC_READ)
- oflags = check_bom(hand, oflags, TRUE);
- }
-
*fd = alloc_fd(hand, wxflag);
- if (*fd == -1)
- return *_errno();
-
- if (oflags & _O_WTEXT)
- get_ioinfo(*fd)->exflag |= EF_UTF16|EF_UNK_UNICODE;
- else if (oflags & _O_U16TEXT)
- get_ioinfo(*fd)->exflag |= EF_UTF16;
- else if (oflags & _O_U8TEXT)
- get_ioinfo(*fd)->exflag |= EF_UTF8;
TRACE(":fd (%d) handle (%p)\n", *fd, hand);
return 0;
{
int open_flags, stream_flags, fd;
- TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file->_file);
+ TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file ? file->_file : -1);
LOCK_FILES();
if (!file || ((fd = file->_file) < 0) || fd > fdend)
*/
__int64 CDECL _ftelli64(FILE* file)
{
- /* TODO: just call fgetpos and return lower half of result */
- int off=0;
__int64 pos;
_lock_file(file);
return -1;
}
if(file->_bufsiz) {
- if( file->_flag & _IOWRT ) {
- off = file->_ptr - file->_base;
+ if(file->_flag & _IOWRT) {
+ pos += file->_ptr - file->_base;
+
+ if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+ char *p;
+
+ for(p=file->_base; p<file->_ptr; p++)
+ if(*p == '\n')
+ pos++;
+ }
+ } else if(!file->_cnt) { /* nothing to do */
+ } else if(_lseeki64(file->_file, 0, SEEK_END)==pos) {
+ int i;
+
+ pos -= file->_cnt;
+ if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+ for(i=0; i<file->_cnt; i++)
+ if(file->_ptr[i] == '\n')
+ pos--;
+ }
} else {
- off = -file->_cnt;
- if (get_ioinfo(file->_file)->wxflag & WX_TEXT) {
- /* Black magic correction for CR removal */
- int i;
- for (i=0; i<file->_cnt; i++) {
- if (file->_ptr[i] == '\n')
- off--;
- }
- /* Black magic when reading CR at buffer boundary*/
- if(get_ioinfo(file->_file)->wxflag & WX_READCR)
- off--;
+ char *p;
+
+ if(_lseeki64(file->_file, pos, SEEK_SET) != pos) {
+ _unlock_file(file);
+ return -1;
+ }
+
+ pos -= file->_bufsiz;
+ pos += file->_ptr - file->_base;
+
+ if(get_ioinfo(file->_file)->wxflag & WX_TEXT) {
+ if(get_ioinfo(file->_file)->wxflag & WX_READNL)
+ pos--;
+
+ for(p=file->_base; p<file->_ptr; p++)
+ if(*p == '\n')
+ pos++;
}
}
}
_unlock_file(file);
- return off + pos;
+ return pos;
}
/*********************************************************************