int *__p__fmode(void);
int *__p___mb_cur_max(void);
+extern int _commode;
+
+#ifndef _IOCOMMIT
+#define _IOCOMMIT 0x4000
+#endif
+
#ifdef feof
#undef feof
#endif
/* 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_PIPE 0x08
#define WX_READCR 0x08 /* underlying file is at \r */
#define WX_DONTINHERIT 0x10
#define WX_APPEND 0x20
+#define WX_NOSEEK 0x40
#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 };
typedef struct {
HANDLE handle;
unsigned char wxflag;
- char unk1;
+ char lookahead[3];
int exflag;
CRITICAL_SECTION crit;
} ioinfo;
/* INTERNAL: Allocate an fd slot from a Win32 HANDLE, starting from fd */
/* caller must hold the files lock */
-static int alloc_fd_from(HANDLE hand, int flag, int fd)
+static int set_fd(HANDLE hand, int flag, int fd)
{
ioinfo *fdinfo;
}
fdinfo->handle = hand;
- fdinfo->wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT));
+ fdinfo->wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT | WX_PIPE | WX_NOSEEK));
+ fdinfo->lookahead[0] = '\n';
+ fdinfo->lookahead[1] = '\n';
+ fdinfo->lookahead[2] = '\n';
+ fdinfo->exflag = 0;
/* locate next free slot */
if (fd == fdstart && fd == fdend)
LOCK_FILES();
TRACE(":handle (%p) allocating fd (%d)\n",hand,fdstart);
- ret = alloc_fd_from(hand, flag, fdstart);
+ ret = set_fd(hand, flag, fdstart);
UNLOCK_FILES();
return ret;
}
for (i = 0; i < count; i++)
{
if ((*wxflag_ptr & WX_OPEN) && *handle_ptr != INVALID_HANDLE_VALUE)
- alloc_fd_from(*handle_ptr, *wxflag_ptr, i);
+ set_fd(*handle_ptr, *wxflag_ptr, i);
wxflag_ptr++; handle_ptr++;
}
}
if(!__pioinfo[0])
- alloc_fd_from(INVALID_HANDLE_VALUE, 0, 3);
+ set_fd(INVALID_HANDLE_VALUE, 0, 3);
fdinfo = get_ioinfo(0);
if (!(fdinfo->wxflag & WX_OPEN) || fdinfo->handle == INVALID_HANDLE_VALUE)
if (is_valid_fd(nd))
_close(nd);
- ret = alloc_fd_from(handle, wxflag, nd);
+ ret = set_fd(handle, wxflag, nd);
if (ret == -1)
{
CloseHandle(handle);
static int get_flags(const wchar_t* mode, int *open_flags, int* stream_flags)
{
int plus = strchrW(mode, '+') != NULL;
-
+
+ TRACE("%s\n", debugstr_w(mode));
+
while(*mode == ' ') mode++;
-
+
switch(*mode++)
{
case 'R': case 'r':
*stream_flags = plus ? _IORW : _IOWRT;
break;
default:
- _invalid_parameter(NULL, NULL, NULL, 0, 0);
- *_errno() = EINVAL;
+ MSVCRT_INVALID_PMT(0, EINVAL);
return -1;
}
- /* FIXME */
- /* *stream_flags |= MSVCRT__commode; */
-
+ *stream_flags |= _commode;
+
while (*mode && *mode!=',')
switch (*mode++)
{
case 'T':
*open_flags |= _O_SHORT_LIVED;
break;
- /* FIXME
- case 'c':
+ case 'c':
*stream_flags |= _IOCOMMIT;
break;
case 'n':
*stream_flags &= ~_IOCOMMIT;
- break;
- */
+ break;
case 'N':
*open_flags |= _O_NOINHERIT;
break;
}
else
{
- _invalid_parameter(NULL, NULL, NULL, 0, 0);
- *_errno() = EINVAL;
+ MSVCRT_INVALID_PMT(0, EINVAL);
return -1;
}
while(*mode == ' ') mode++;
}
- if(!MSVCRT_CHECK_PMT(*mode == 0))
+ if(!MSVCRT_CHECK_PMT(*mode == 0))
return -1;
-
return 0;
}
int id;
char letter = 'a';
+ if(!pattern)
+ return NULL;
+
while(*pattern)
numX = (*pattern++ == 'X')? numX + 1 : 0;
- if (numX < 5)
+ if (numX < 6)
return NULL;
pattern--;
id = GetCurrentProcessId();
do
{
*pattern = letter++;
- if (GetFileAttributesA(retVal) == INVALID_FILE_ATTRIBUTES &&
- GetLastError() == ERROR_FILE_NOT_FOUND)
+ if (GetFileAttributesA(retVal) == INVALID_FILE_ATTRIBUTES)
return retVal;
} while(letter <= 'z');
return NULL;
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 (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 */}
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|
return ret;
}
+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;
+}
+
/*********************************************************************
- * _sopen_s (MSVCRT.@)
+ * _wsopen_s (MSVCRT.@)
*/
-int CDECL _sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode )
+int CDECL _wsopen_s( int *fd, const wchar_t* path, int oflags, int shflags, int pmode )
{
DWORD access = 0, creation = 0, attrib;
+ SECURITY_ATTRIBUTES sa;
DWORD sharing;
int wxflag;
HANDLE hand;
- SECURITY_ATTRIBUTES sa;
- TRACE("fd*: %p file: (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
- fd, path, oflags, shflags, pmode);
+ TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
+ fd, debugstr_w(path), oflags, shflags, pmode);
- if (!fd)
- {
- MSVCRT_INVALID_PMT("null out fd pointer");
- *_errno() = EINVAL;
- return EINVAL;
- }
+ if (!MSVCRT_CHECK_PMT( fd != NULL )) return EINVAL;
*fd = -1;
wxflag = split_oflags(oflags);
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = (oflags & _O_NOINHERIT) ? FALSE : TRUE;
+ sa.bInheritHandle = !(oflags & _O_NOINHERIT);
- hand = CreateFileA(path, access, sharing, &sa, creation, attrib, 0);
+ 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) {
- WARN(":failed-last error (%d)\n", GetLastError());
+ WARN(":failed-last error (%d)\n",GetLastError());
_dosmaperr(GetLastError());
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);
+ _dosmaperr(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);
+ _dosmaperr(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;
}
/*********************************************************************
- * _sopen (MSVCRT.@)
+ * _wsopen (MSVCRT.@)
*/
-int CDECL _sopen( const char *path, int oflags, int shflags, ... )
+int CDECL _wsopen( const wchar_t *path, int oflags, int shflags, ... )
{
int pmode;
int fd;
else
pmode = 0;
- _sopen_s(&fd, path, oflags, shflags, pmode);
+ _wsopen_s(&fd, path, oflags, shflags, pmode);
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.@)
+ * _sopen_s (MSVCRT.@)
*/
-int CDECL _wsopen_s( int *fd, const wchar_t* path, int oflags, int shflags, int pmode )
+int CDECL _sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode )
{
DWORD access = 0, creation = 0, attrib;
- SECURITY_ATTRIBUTES sa;
DWORD sharing;
int wxflag;
HANDLE hand;
+ SECURITY_ATTRIBUTES sa;
- TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
- fd, debugstr_w(path), oflags, shflags, pmode);
+ TRACE("fd*: %p file: (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
+ fd, path, oflags, shflags, pmode);
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);
-
+ hand = CreateFileA(path, access, sharing, &sa, creation, attrib, 0);
if (hand == INVALID_HANDLE_VALUE) {
- WARN(":failed-last error (%d)\n",GetLastError());
+ WARN(":failed-last error (%d)\n", GetLastError());
_dosmaperr(GetLastError());
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;
}
/*********************************************************************
- * _wsopen (MSVCRT.@)
+ * _sopen (MSVCRT.@)
*/
-int CDECL _wsopen( const wchar_t *path, int oflags, int shflags, ... )
+int CDECL _sopen( const char *path, int oflags, int shflags, ... )
{
int pmode;
int fd;
else
pmode = 0;
- _wsopen_s(&fd, path, oflags, shflags, pmode);
+ _sopen_s(&fd, path, oflags, shflags, pmode);
return fd;
}
*/
int CDECL _open_osfhandle(intptr_t handle, int oflags)
{
+ DWORD flags;
int fd;
/* _O_RDONLY (0) always matches, so set the read flag
if (!(oflags & (_O_BINARY | _O_TEXT)))
oflags |= _O_BINARY;
- fd = alloc_fd((HANDLE)handle, split_oflags(oflags));
- TRACE(":handle (%ld) fd (%d) flags 0x%08x\n", handle, fd, oflags);
+ flags = GetFileType((HANDLE)handle);
+ if (flags==FILE_TYPE_UNKNOWN && GetLastError()!=NO_ERROR)
+ {
+ _dosmaperr(GetLastError());
+ return -1;
+ }
+
+ if (flags == FILE_TYPE_CHAR)
+ flags = WX_NOSEEK;
+ else if (flags == FILE_TYPE_PIPE)
+ flags = WX_PIPE;
+ else
+ flags = 0;
+ flags |= split_oflags(oflags);
+
+ fd = alloc_fd((HANDLE)handle, flags);
+ TRACE(":handle (%ld) fd (%d) flags 0x%08x\n", handle, fd, flags);
return fd;
}
*/
int CDECL _setmode(int fd,int mode)
{
- int ret = get_ioinfo(fd)->wxflag & WX_TEXT ? _O_TEXT : _O_BINARY;
- if (mode & (~(_O_TEXT|_O_BINARY)))
- FIXME("fd (%d) mode (0x%08x) unknown\n",fd,mode);
- if ((mode & _O_TEXT) == _O_TEXT)
+ int ret = get_ioinfo(fd)->wxflag & WX_TEXT ? _O_TEXT : _O_BINARY;
+ if(ret==_O_TEXT && (get_ioinfo(fd)->exflag & (EF_UTF8|EF_UTF16)))
+ ret = _O_WTEXT;
+
+ if(mode!=_O_TEXT && mode!=_O_BINARY && mode!=_O_WTEXT
+ && mode!=_O_U16TEXT && mode!=_O_U8TEXT) {
+ *_errno() = EINVAL;
+ return -1;
+ }
+
+ if(mode == _O_BINARY) {
+ get_ioinfo(fd)->wxflag &= ~WX_TEXT;
+ get_ioinfo(fd)->exflag &= ~(EF_UTF8|EF_UTF16);
+ return ret;
+ }
+
get_ioinfo(fd)->wxflag |= WX_TEXT;
- else
- get_ioinfo(fd)->wxflag &= ~WX_TEXT;
- return ret;
+ if(mode == _O_TEXT)
+ get_ioinfo(fd)->exflag &= ~(EF_UTF8|EF_UTF16);
+ else if(mode == _O_U8TEXT)
+ get_ioinfo(fd)->exflag = (get_ioinfo(fd)->exflag & ~EF_UTF16) | EF_UTF8;
+ else
+ get_ioinfo(fd)->exflag = (get_ioinfo(fd)->exflag & ~EF_UTF8) | EF_UTF16;
+
+ return ret;
+
}
/*********************************************************************
*/
int CDECL _write(int fd, const void* buf, unsigned int count)
{
- DWORD num_written;
- HANDLE hand = fdtoh(fd);
+ DWORD num_written;
+ ioinfo *info = get_ioinfo(fd);
+ HANDLE hand = info->handle;
- /* Don't trace small writes, it gets *very* annoying */
+ /* Don't trace small writes, it gets *very* annoying */
#if 0
- if (count > 32)
- TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count);
+ if (count > 32)
+ TRACE(":fd (%d) handle (%d) buf (%p) len (%d)\n",fd,hand,buf,count);
#endif
- if (hand == INVALID_HANDLE_VALUE)
+ if (hand == INVALID_HANDLE_VALUE)
{
- *_errno() = EBADF;
- return -1;
+ *_errno() = EBADF;
+ return -1;
}
- /* If appending, go to EOF */
- if (get_ioinfo(fd)->wxflag & WX_APPEND)
- _lseek(fd, 0, FILE_END);
+ if (((info->exflag&EF_UTF8) || (info->exflag&EF_UTF16)) && count&1)
+ {
+ *_errno() = EINVAL;
+ return -1;
+ }
- if (!(get_ioinfo(fd)->wxflag & WX_TEXT))
+ /* If appending, go to EOF */
+ if (info->wxflag & WX_APPEND)
+ _lseek(fd, 0, FILE_END);
+
+ if (!(info->wxflag & WX_TEXT))
{
- if (WriteFile(hand, buf, count, &num_written, NULL)
- && (num_written == count))
- return num_written;
- TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd,
- hand, GetLastError());
- *_errno() = ENOSPC;
+ if (WriteFile(hand, buf, count, &num_written, NULL)
+ && (num_written == count))
+ return num_written;
+ TRACE("WriteFile (fd %d, hand %p) failed-last error (%d)\n", fd,
+ hand, GetLastError());
+ *_errno() = ENOSPC;
}
- else
- {
- unsigned int i, j, nr_lf;
- char *p = NULL;
- const char *q;
- const char *s = buf, *buf_start = buf;
- /* find number of \n ( without preceding \r ) */
- for ( nr_lf=0,i = 0; i <count; i++)
- {
- if (s[i]== '\n')
- {
- nr_lf++;
- /*if ((i >1) && (s[i-1] == '\r')) nr_lf--; */
- }
- }
- if (nr_lf)
- {
- if ((q = p = malloc(count + nr_lf)))
- {
- for (s = buf, i = 0, j = 0; i < count; i++)
- {
- if (s[i]== '\n')
- {
- p[j++] = '\r';
- /*if ((i >1) && (s[i-1] == '\r'))j--;*/
- }
- p[j++] = s[i];
- }
- }
- else
- {
- FIXME("Malloc failed\n");
- nr_lf =0;
- q = buf;
- }
- }
- else
- q = buf;
+ else
+ {
+ unsigned int i, j, nr_lf, size;
+ char *p = NULL;
+ const char *q;
+ const char *s = buf, *buf_start = buf;
- if ((WriteFile(hand, q, count+nr_lf, &num_written, NULL) == 0 ) || (num_written != count+nr_lf))
- {
- TRACE("WriteFile (fd %d, hand %p) failed-last error (%d), num_written %d\n",
- fd, hand, GetLastError(), num_written);
- *_errno() = ENOSPC;
- if(nr_lf)
- free(p);
- return s - buf_start;
- }
- else
- {
- if(nr_lf)
- free(p);
- return count;
- }
- }
- return -1;
+ if (!(info->exflag & (EF_UTF8|EF_UTF16)))
+ {
+ /* find number of \n */
+ for (nr_lf=0, i=0; i<count; i++)
+ if (s[i] == '\n')
+ nr_lf++;
+ if (nr_lf)
+ {
+ size = count+nr_lf;
+ if ((q = p = malloc(size)))
+ {
+ for (s = buf, i = 0, j = 0; i < count; i++)
+ {
+ if (s[i] == '\n')
+ p[j++] = '\r';
+ p[j++] = s[i];
+ }
+ }
+ else
+ {
+ FIXME("Malloc failed\n");
+ nr_lf = 0;
+ size = count;
+ q = buf;
+ }
+ }
+ else
+ {
+ size = count;
+ q = buf;
+ }
+ }
+ else if (info->exflag & EF_UTF16)
+ {
+ for (nr_lf=0, i=0; i<count; i+=2)
+ if (s[i]=='\n' && s[i+1]==0)
+ nr_lf += 2;
+ if (nr_lf)
+ {
+ size = count+nr_lf;
+ if ((q = p = malloc(size)))
+ {
+ for (s=buf, i=0, j=0; i<count; i++)
+ {
+ if (s[i]=='\n' && s[i+1]==0)
+ {
+ p[j++] = '\r';
+ p[j++] = 0;
+ }
+ p[j++] = s[i++];
+ p[j++] = s[i];
+ }
+ }
+ else
+ {
+ FIXME("Malloc failed\n");
+ nr_lf = 0;
+ size = count;
+ q = buf;
+ }
+ }
+ else
+ {
+ size = count;
+ q = buf;
+ }
+ }
+ else
+ {
+ DWORD conv_len;
+
+ for(nr_lf=0, i=0; i<count; i+=2)
+ if (s[i]=='\n' && s[i+1]==0)
+ nr_lf++;
+
+ conv_len = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)buf, count/2, NULL, 0, NULL, NULL);
+ if(!conv_len) {
+ _dosmaperr(GetLastError());
+ free(p);
+ return -1;
+ }
+
+ size = conv_len+nr_lf;
+ if((p = malloc(count+nr_lf*2+size)))
+ {
+ for (s=buf, i=0, j=0; i<count; i++)
+ {
+ if (s[i]=='\n' && s[i+1]==0)
+ {
+ p[j++] = '\r';
+ p[j++] = 0;
+ }
+ p[j++] = s[i++];
+ p[j++] = s[i];
+ }
+ q = p+count+nr_lf*2;
+ WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)p, count/2+nr_lf,
+ p+count+nr_lf*2, conv_len+nr_lf, NULL, NULL);
+ }
+ else
+ {
+ FIXME("Malloc failed\n");
+ nr_lf = 0;
+ size = count;
+ q = buf;
+ }
+ }
+
+ if (!WriteFile(hand, q, size, &num_written, NULL))
+ num_written = -1;
+ if(p)
+ free(p);
+ if (num_written != size)
+ {
+ TRACE("WriteFile (fd %d, hand %p) failed-last error (%d), num_written %d\n",
+ fd, hand, GetLastError(), num_written);
+ *_errno() = ENOSPC;
+ return s - buf_start;
+ }
+ return count;
+ }
+
+ return -1;
}
/*********************************************************************
*/
int CDECL feof(FILE* file)
{
- int ret;
-
- _lock_file(file);
- ret = file->_flag & _IOEOF;
- _unlock_file(file);
-
- return ret;
+ return file->_flag & _IOEOF;
}
/*********************************************************************
*/
int CDECL ferror(FILE* file)
{
- int ret;
-
- _lock_file(file);
- ret = file->_flag & _IOERR;
- _unlock_file(file);
-
- return ret;
+ return file->_flag & _IOERR;
}
/*********************************************************************
unsigned char c;
_lock_file(file);
+ if(file->_flag & _IOSTRG) {
+ _unlock_file(file);
+ return EOF;
+ }
+
/* Allocate buffer if needed */
if(file->_bufsiz == 0 && !(file->_flag & _IONBF))
alloc_buffer(file);
/*********************************************************************
* fgetwc (MSVCRT.@)
- *
- * In _O_TEXT mode, multibyte characters are read from the file, dropping
- * the CR from CR/LF combinations
*/
wint_t CDECL fgetwc(FILE* file)
{
- int c;
+ wint_t ret;
+ int ch;
_lock_file(file);
- if (!(get_ioinfo(file->_file)->wxflag & WX_TEXT))
- {
- wchar_t wc;
- unsigned int i;
- int j;
- char *chp, *wcp;
- wcp = (char *)&wc;
- for(i=0; i<sizeof(wc); i++)
- {
- if (file->_cnt>0)
- {
- file->_cnt--;
- chp = file->_ptr++;
- wcp[i] = *chp;
- }
- else
- {
- j = _filbuf(file);
- if(file->_cnt<=0)
- {
- file->_flag |= (file->_cnt == 0) ? _IOEOF : _IOERR;
- file->_cnt = 0;
- _unlock_file(file);
- return WEOF;
- }
- wcp[i] = j;
- }
- }
+ if((get_ioinfo(file->_file)->exflag & (EF_UTF8 | EF_UTF16))
+ || !(get_ioinfo(file->_file)->wxflag & WX_TEXT)) {
+ char *p;
- _unlock_file(file);
- return wc;
- }
+ for(p=(char*)&ret; (wint_t*)p<&ret+1; p++) {
+ ch = fgetc(file);
+ if(ch == EOF) {
+ ret = WEOF;
+ break;
+ }
+ *p = (char)ch;
+ }
+ }else {
+ char mbs[MB_LEN_MAX];
+ int len = 0;
+
+ ch = fgetc(file);
+ if(ch != EOF) {
+ mbs[0] = (char)ch;
+ if(isleadbyte((unsigned char)mbs[0])) {
+ ch = fgetc(file);
+ if(ch != EOF) {
+ mbs[1] = (char)ch;
+ len = 2;
+ }
+ }else {
+ len = 1;
+ }
+ }
- c = fgetc(file);
- if ((__mb_cur_max > 1) && isleadbyte(c))
- {
- FIXME("Treat Multibyte characters\n");
+ if(!len || mbtowc(&ret, mbs, len)==-1)
+ ret = WEOF;
}
- _unlock_file(file);
- if (c == EOF)
- return WEOF;
- else
- return (wint_t)c;
+ _unlock_file(file);
+ return ret;
}
/*********************************************************************
return 0;
_lock_file(file);
- if(file->_cnt) {
- int pcnt=((unsigned)file->_cnt>wrcnt)? wrcnt: file->_cnt;
- memcpy(file->_ptr, ptr, pcnt);
- file->_cnt -= pcnt;
- file->_ptr += pcnt;
- written = pcnt;
- wrcnt -= pcnt;
- ptr = (const char*)ptr + pcnt;
- } else if(!(file->_flag & _IOWRT)) {
- if(file->_flag & _IORW) {
- file->_flag |= _IOWRT;
- } else {
- _unlock_file(file);
- return 0;
- }
- }
- if(wrcnt) {
- /* Flush buffer */
- int res=flush_buffer(file);
- if(!res) {
- int pwritten = _write(file->_file, ptr, wrcnt);
- if (pwritten <= 0)
- {
+
+ while(wrcnt) {
+ if(file->_cnt) {
+ int pcnt=((unsigned)file->_cnt>wrcnt)? wrcnt: file->_cnt;
+ memcpy(file->_ptr, ptr, pcnt);
+ file->_cnt -= pcnt;
+ file->_ptr += pcnt;
+ written += pcnt;
+ wrcnt -= pcnt;
+ ptr = (const char*)ptr + pcnt;
+ } else if(!file->_bufsiz && (file->_flag & _IONBF)) {
+ if(!(file->_flag & _IOWRT)) {
+ if(file->_flag & _IORW)
+ file->_flag |= _IOWRT;
+ else
+ break;
+ }
+
+ if(_write(file->_file, ptr, wrcnt) <= 0) {
file->_flag |= _IOERR;
- pwritten=0;
+ break;
}
- written += pwritten;
+ written += wrcnt;
+ wrcnt = 0;
+ } else {
+ if(_flsbuf(*(const char*)ptr, file) == EOF)
+ break;
+ written++;
+ wrcnt--;
+ ptr = (const char*)ptr + 1;
}
}
{
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;
}
/*********************************************************************
FILE* file = NULL;
LOCK_FILES();
- fd = _open(filename, _O_CREAT | _O_BINARY | _O_RDWR | _O_TEMPORARY);
+ fd = _open(filename, _O_CREAT | _O_BINARY | _O_RDWR | _O_TEMPORARY,
+ _S_IREAD | _S_IWRITE);
if (fd != -1 && (file = alloc_fp()))
{
- if (init_fp(file, fd, _O_RDWR) == -1)
+ if (init_fp(file, fd, _IORW) == -1)
{
file->_flag = 0;
file = NULL;
}
else file->_tmpfname = _strdup(filename);
}
+
+ if(fd != -1 && !file)
+ _close(fd);
UNLOCK_FILES();
return file;
}