Commit 0bfb1cbc authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- msvcrt: the file descriptors are now inherited between parent/child

processes - kernel32.CreateProcess: make use of the *reserved2 fields for C-RunTime data inheritance
parent 77994cce
......@@ -439,8 +439,8 @@ void ENV_CopyStartupInformation(void)
startup_infoW.dwFillAttribute = rupp->dwFillAttribute;
startup_infoW.dwFlags = rupp->dwFlags;
startup_infoW.wShowWindow = rupp->wShowWindow;
startup_infoW.cbReserved2 = 0;
startup_infoW.lpReserved2 = NULL;
startup_infoW.cbReserved2 = rupp->RuntimeInfo.Length;
startup_infoW.lpReserved2 = (void*)rupp->RuntimeInfo.Buffer;
startup_infoW.hStdInput = rupp->hStdInput;
startup_infoW.hStdOutput = rupp->hStdOutput;
startup_infoW.hStdError = rupp->hStdError;
......@@ -462,8 +462,8 @@ void ENV_CopyStartupInformation(void)
startup_infoA.dwFillAttribute = rupp->dwFillAttribute;
startup_infoA.dwFlags = rupp->dwFlags;
startup_infoA.wShowWindow = rupp->wShowWindow;
startup_infoA.cbReserved2 = 0;
startup_infoA.lpReserved2 = NULL;
startup_infoA.cbReserved2 = rupp->RuntimeInfo.Length;
startup_infoA.lpReserved2 = (void*)rupp->RuntimeInfo.Buffer;
startup_infoA.hStdInput = rupp->hStdInput;
startup_infoA.hStdOutput = rupp->hStdOutput;
startup_infoA.hStdError = rupp->hStdError;
......
......@@ -1386,7 +1386,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST
const STARTUPINFOW *startup )
{
RTL_USER_PROCESS_PARAMETERS *params;
UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title;
UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title, runtime;
NTSTATUS status;
WCHAR buffer[MAX_PATH];
......@@ -1400,13 +1400,19 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST
if (cur_dir) RtlInitUnicodeString( &curdir_str, cur_dir );
if (startup->lpDesktop) RtlInitUnicodeString( &desktop, startup->lpDesktop );
if (startup->lpTitle) RtlInitUnicodeString( &title, startup->lpTitle );
if (startup->lpReserved2 && startup->cbReserved2)
{
runtime.Length = runtime.MaximumLength = startup->cbReserved2;
runtime.Buffer = (WCHAR*)startup->lpReserved2;
}
status = RtlCreateProcessParameters( &params, &image_str, NULL,
cur_dir ? &curdir_str : NULL,
&cmdline_str, env,
startup->lpTitle ? &title : NULL,
startup->lpDesktop ? &desktop : NULL,
NULL, NULL );
NULL,
(startup->lpReserved2 && startup->cbReserved2) ? &runtime : NULL );
if (status != STATUS_SUCCESS)
{
SetLastError( RtlNtStatusToDosError(status) );
......
......@@ -53,7 +53,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* _access() bit flags FIXME: incomplete */
#define MSVCRT_W_OK 0x02
/* values for xflag */
/* values for wxflag in file descriptor */
#define WX_OPEN 0x01
#define WX_ATEOF 0x02
#define WX_DONTINHERIT 0x10
......@@ -65,7 +65,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
static struct {
HANDLE handle;
unsigned char xflag;
unsigned char wxflag;
} MSVCRT_fdesc[MSVCRT_MAX_FILES];
MSVCRT_FILE MSVCRT__iob[3];
......@@ -115,7 +115,7 @@ static void msvcrt_cp_from_stati64(const struct MSVCRT__stati64 *bufi64, struct
static inline BOOL msvcrt_is_valid_fd(int fd)
{
return fd >= 0 && fd < MSVCRT_fdend && (MSVCRT_fdesc[fd].xflag & WX_OPEN);
return fd >= 0 && fd < MSVCRT_fdend && (MSVCRT_fdesc[fd].wxflag & WX_OPEN);
}
/* INTERNAL: Get the HANDLE for a fd */
......@@ -136,7 +136,7 @@ static HANDLE msvcrt_fdtoh(int fd)
static void msvcrt_free_fd(int fd)
{
MSVCRT_fdesc[fd].handle = INVALID_HANDLE_VALUE;
MSVCRT_fdesc[fd].xflag = 0;
MSVCRT_fdesc[fd].wxflag = 0;
TRACE(":fd (%d) freed\n",fd);
if (fd < 3) /* don't use 0,1,2 for user files */
{
......@@ -168,16 +168,13 @@ static int msvcrt_alloc_fd(HANDLE hand, int flag)
return -1;
}
MSVCRT_fdesc[fd].handle = hand;
MSVCRT_fdesc[fd].xflag = WX_OPEN;
if (flag & MSVCRT__O_NOINHERIT) MSVCRT_fdesc[fd].xflag |= WX_DONTINHERIT;
if (flag & MSVCRT__O_APPEND) MSVCRT_fdesc[fd].xflag |= WX_APPEND;
if (flag & MSVCRT__O_TEXT) MSVCRT_fdesc[fd].xflag |= WX_TEXT;
MSVCRT_fdesc[fd].wxflag = WX_OPEN | (flag & (WX_DONTINHERIT | WX_APPEND | WX_TEXT));
/* locate next free slot */
if (fd == MSVCRT_fdend)
MSVCRT_fdstart = ++MSVCRT_fdend;
else
while(MSVCRT_fdstart < MSVCRT_fdend &&
while (MSVCRT_fdstart < MSVCRT_fdend &&
MSVCRT_fdesc[MSVCRT_fdstart].handle != INVALID_HANDLE_VALUE)
MSVCRT_fdstart++;
......@@ -232,37 +229,118 @@ static int msvcrt_init_fp(MSVCRT_FILE* file, int fd, unsigned stream_flags)
return 0;
}
/* INTERNAL: Create an inheritance data block (for spawned process)
* The inheritance block is made of:
* 00 int nb of file descriptor (NBFD)
* 04 char file flags (wxflag): repeated for each fd
* 4+NBFD HANDLE file handle: repeated for each fd
*/
unsigned msvcrt_create_io_inherit_block(STARTUPINFOA* si)
{
int fd;
char* wxflag_ptr;
HANDLE* handle_ptr;
si->cbReserved2 = sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * MSVCRT_fdend;
si->lpReserved2 = MSVCRT_calloc(si->cbReserved2, 1);
if (!si->lpReserved2)
{
si->cbReserved2 = 0;
return FALSE;
}
wxflag_ptr = (char*)si->lpReserved2 + sizeof(unsigned);
handle_ptr = (HANDLE*)(wxflag_ptr + MSVCRT_fdend * sizeof(char));
*(unsigned*)si->lpReserved2 = MSVCRT_fdend;
for (fd = 0; fd < MSVCRT_fdend; fd++)
{
/* to be inherited, we need it to be open, and that DONTINHERIT isn't set */
if ((MSVCRT_fdesc[fd].wxflag & (WX_OPEN | WX_DONTINHERIT)) == WX_OPEN)
{
*wxflag_ptr = MSVCRT_fdesc[fd].wxflag;
*handle_ptr = MSVCRT_fdesc[fd].handle;
}
else
{
*wxflag_ptr = 0;
*handle_ptr = INVALID_HANDLE_VALUE;
}
wxflag_ptr++; handle_ptr++;
}
return TRUE;
}
/* INTERNAL: Set up stdin, stderr and stdout */
/* INTERNAL: Set up all file descriptors,
* as well as default streams (stdin, stderr and stdout)
*/
void msvcrt_init_io(void)
{
int i;
STARTUPINFOA si;
int i;
memset(MSVCRT__iob,0,3*sizeof(MSVCRT_FILE));
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[0].handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[0].xflag = WX_OPEN;
MSVCRT__iob[0]._flag = MSVCRT__IOREAD;
MSVCRT__iob[0]._tmpfname = NULL;
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[1].handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[1].xflag = WX_OPEN;
MSVCRT__iob[1]._flag = MSVCRT__IOWRT;
MSVCRT__iob[1]._tmpfname = NULL;
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[2].handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[2].xflag = WX_OPEN;
MSVCRT__iob[2]._flag = MSVCRT__IOWRT;
MSVCRT__iob[2]._tmpfname = NULL;
GetStartupInfoA(&si);
if (si.cbReserved2 != 0 && si.lpReserved2 != NULL)
{
char* wxflag_ptr;
HANDLE* handle_ptr;
MSVCRT_fdend = *(unsigned*)si.lpReserved2;
wxflag_ptr = (char*)(si.lpReserved2 + sizeof(unsigned));
handle_ptr = (HANDLE*)(wxflag_ptr + MSVCRT_fdend * sizeof(char));
MSVCRT_fdend = min(MSVCRT_fdend, sizeof(MSVCRT_fdesc) / sizeof(MSVCRT_fdesc[0]));
for (i = 0; i < MSVCRT_fdend; i++)
{
if ((*wxflag_ptr & WX_OPEN) && *handle_ptr != INVALID_HANDLE_VALUE)
{
MSVCRT_fdesc[i].wxflag = *wxflag_ptr;
MSVCRT_fdesc[i].handle = *handle_ptr;
}
else
{
MSVCRT_fdesc[i].wxflag = 0;
MSVCRT_fdesc[i].handle = INVALID_HANDLE_VALUE;
}
wxflag_ptr++; handle_ptr++;
}
for (MSVCRT_fdstart = 3; MSVCRT_fdstart < MSVCRT_fdend; MSVCRT_fdstart++)
if (MSVCRT_fdesc[MSVCRT_fdstart].handle == INVALID_HANDLE_VALUE) break;
}
if (!(MSVCRT_fdesc[0].wxflag & WX_OPEN) || MSVCRT_fdesc[0].handle == INVALID_HANDLE_VALUE)
{
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[0].handle, 0, FALSE,
DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[0].wxflag = WX_OPEN | WX_TEXT;
}
if (!(MSVCRT_fdesc[1].wxflag & WX_OPEN) || MSVCRT_fdesc[1].handle == INVALID_HANDLE_VALUE)
{
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[1].handle, 0, FALSE,
DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[1].wxflag = WX_OPEN | WX_TEXT;
}
if (!(MSVCRT_fdesc[2].wxflag & WX_OPEN) || MSVCRT_fdesc[2].handle == INVALID_HANDLE_VALUE)
{
DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
GetCurrentProcess(), &MSVCRT_fdesc[2].handle, 0, FALSE,
DUPLICATE_SAME_ACCESS);
MSVCRT_fdesc[2].wxflag = WX_OPEN | WX_TEXT;
}
TRACE(":handles (%p)(%p)(%p)\n",MSVCRT_fdesc[0].handle,
MSVCRT_fdesc[1].handle,MSVCRT_fdesc[2].handle);
memset(MSVCRT__iob,0,3*sizeof(MSVCRT_FILE));
for (i = 0; i < 3; i++)
{
/* FILE structs for stdin/out/err are static and never deleted */
MSVCRT_fstreams[i] = &MSVCRT__iob[i];
MSVCRT__iob[i]._file = i;
MSVCRT__iob[i]._tmpfname = NULL;
MSVCRT__iob[i]._flag = (i == 0) ? MSVCRT__IOREAD : MSVCRT__IOWRT;
}
MSVCRT_stream_idx = 3;
}
......@@ -570,7 +648,7 @@ int _eof(int fd)
if (hand == INVALID_HANDLE_VALUE)
return -1;
if (MSVCRT_fdesc[fd].xflag & WX_ATEOF) return TRUE;
if (MSVCRT_fdesc[fd].wxflag & WX_ATEOF) return TRUE;
/* Otherwise we do it the hard way */
hcurpos = hendpos = 0;
......@@ -636,7 +714,7 @@ __int64 _lseeki64(int fd, __int64 offset, int whence)
ret = SetFilePointer(hand, (long)offset, &hoffset, whence);
if (ret != INVALID_SET_FILE_POINTER || !GetLastError())
{
MSVCRT_fdesc[fd].xflag &= ~WX_ATEOF;
MSVCRT_fdesc[fd].wxflag &= ~WX_ATEOF;
/* FIXME: What if we seek _to_ EOF - is EOF set? */
return ((__int64)hoffset << 32) | ret;
......@@ -1079,6 +1157,25 @@ MSVCRT_wchar_t *_wmktemp(MSVCRT_wchar_t *pattern)
return NULL;
}
static unsigned split_oflags(unsigned oflags)
{
int wxflags = 0;
if (oflags & MSVCRT__O_APPEND) wxflags |= WX_APPEND;
if (oflags & MSVCRT__O_BINARY) ;
else if (oflags & MSVCRT__O_TEXT) wxflags |= WX_TEXT;
else if (*__p__fmode() & MSVCRT__O_BINARY) ;
else wxflags |= WX_TEXT; /* default to TEXT*/
if (oflags & MSVCRT__O_NOINHERIT) wxflags |= WX_DONTINHERIT;
if (oflags & ~(MSVCRT__O_BINARY|MSVCRT__O_TEXT|MSVCRT__O_APPEND|MSVCRT__O_TRUNC|
MSVCRT__O_EXCL|MSVCRT__O_CREAT|MSVCRT__O_RDWR|MSVCRT__O_WRONLY|
MSVCRT__O_TEMPORARY|MSVCRT__O_NOINHERIT))
ERR(":unsupported oflags 0x%04x\n",oflags);
return wxflags;
}
/*********************************************************************
* _sopen (MSVCRT.@)
*/
......@@ -1088,7 +1185,7 @@ int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
int pmode;
DWORD access = 0, creation = 0, attrib;
DWORD sharing;
int ioflag = 0, fd;
int wxflag = 0, fd;
HANDLE hand;
SECURITY_ATTRIBUTES sa;
......@@ -1096,20 +1193,12 @@ int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n",
path, oflags, shflags);
switch(oflags & (MSVCRT__O_RDONLY | MSVCRT__O_WRONLY | MSVCRT__O_RDWR))
wxflag = split_oflags(oflags);
switch (oflags & (MSVCRT__O_RDONLY | MSVCRT__O_WRONLY | MSVCRT__O_RDWR))
{
case MSVCRT__O_RDONLY:
access |= GENERIC_READ;
ioflag |= MSVCRT__IOREAD;
break;
case MSVCRT__O_WRONLY:
access |= GENERIC_WRITE;
ioflag |= MSVCRT__IOWRT;
break;
case MSVCRT__O_RDWR:
access |= GENERIC_WRITE | GENERIC_READ;
ioflag |= MSVCRT__IORW;
break;
case MSVCRT__O_RDONLY: access |= GENERIC_READ; break;
case MSVCRT__O_WRONLY: access |= GENERIC_WRITE; break;
case MSVCRT__O_RDWR: access |= GENERIC_WRITE | GENERIC_READ; break;
}
if (oflags & MSVCRT__O_CREAT)
......@@ -1137,17 +1226,6 @@ int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
else
creation = OPEN_EXISTING;
}
if (oflags & MSVCRT__O_APPEND)
ioflag |= MSVCRT__O_APPEND;
if (oflags & MSVCRT__O_BINARY)
ioflag |= MSVCRT__O_BINARY;
else if (oflags & MSVCRT__O_TEXT)
ioflag |= MSVCRT__O_TEXT;
else if (*__p__fmode() & MSVCRT__O_BINARY)
ioflag |= MSVCRT__O_BINARY;
else
ioflag |= MSVCRT__O_TEXT; /* default to TEXT*/
switch( shflags )
{
......@@ -1176,10 +1254,6 @@ int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
sharing |= FILE_SHARE_DELETE;
}
if (oflags & ~(MSVCRT__O_BINARY|MSVCRT__O_TEXT|MSVCRT__O_APPEND|MSVCRT__O_TRUNC|MSVCRT__O_EXCL
|MSVCRT__O_CREAT|MSVCRT__O_RDWR|MSVCRT__O_WRONLY|MSVCRT__O_TEMPORARY|MSVCRT__O_NOINHERIT))
ERR(":unsupported oflags 0x%04x\n",oflags);
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = (oflags & MSVCRT__O_NOINHERIT) ? FALSE : TRUE;
......@@ -1192,7 +1266,7 @@ int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
return -1;
}
fd = msvcrt_alloc_fd(hand, ioflag);
fd = msvcrt_alloc_fd(hand, wxflag);
TRACE(":fd (%d) handle (%p)\n",fd, hand);
......@@ -1295,7 +1369,7 @@ int _wcreat(const MSVCRT_wchar_t *path, int flags)
/*********************************************************************
* _open_osfhandle (MSVCRT.@)
*/
int _open_osfhandle(long hand, int flags)
int _open_osfhandle(long handle, int oflags)
{
int fd;
......@@ -1305,13 +1379,13 @@ int _open_osfhandle(long hand, int flags)
* text - it never sets MSVCRT__O_BINARY.
*/
/* FIXME: handle more flags */
if (!(flags & (MSVCRT__O_BINARY | MSVCRT__O_TEXT)) && (*__p__fmode() & MSVCRT__O_BINARY))
flags |= MSVCRT__O_BINARY;
if (!(oflags & (MSVCRT__O_BINARY | MSVCRT__O_TEXT)) && (*__p__fmode() & MSVCRT__O_BINARY))
oflags |= MSVCRT__O_BINARY;
else
flags |= MSVCRT__O_TEXT;
oflags |= MSVCRT__O_TEXT;
fd = msvcrt_alloc_fd((HANDLE)hand,flags);
TRACE(":handle (%ld) fd (%d) flags 0x%08x\n",hand,fd,flags);
fd = msvcrt_alloc_fd((HANDLE)handle, split_oflags(oflags));
TRACE(":handle (%ld) fd (%d) flags 0x%08x\n", handle, fd, oflags);
return fd;
}
......@@ -1375,15 +1449,15 @@ int _read(int fd, void *buf, unsigned int count)
if (num_read != (count - all_read))
{
TRACE(":EOF\n");
MSVCRT_fdesc[fd].xflag |= WX_ATEOF;
if (MSVCRT_fdesc[fd].xflag & WX_TEXT)
MSVCRT_fdesc[fd].wxflag |= WX_ATEOF;
if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
num_read -= remove_cr(bufstart+all_read,num_read);
all_read += num_read;
if (count > 4)
TRACE("%s\n",debugstr_an(buf,all_read));
return all_read;
}
if (MSVCRT_fdesc[fd].xflag & WX_TEXT)
if (MSVCRT_fdesc[fd].wxflag & WX_TEXT)
{
num_read -= remove_cr(bufstart+all_read,num_read);
}
......@@ -1421,13 +1495,13 @@ int MSVCRT__getw(MSVCRT_FILE* file)
*/
int _setmode(int fd,int mode)
{
int ret = MSVCRT_fdesc[fd].xflag & WX_TEXT ? MSVCRT__O_TEXT : MSVCRT__O_BINARY;
int ret = MSVCRT_fdesc[fd].wxflag & WX_TEXT ? MSVCRT__O_TEXT : MSVCRT__O_BINARY;
if (mode & (~(MSVCRT__O_TEXT|MSVCRT__O_BINARY)))
FIXME("fd (%d) mode (0x%08x) unknown\n",fd,mode);
if ((mode & MSVCRT__O_TEXT) == MSVCRT__O_TEXT)
MSVCRT_fdesc[fd].xflag |= WX_TEXT;
MSVCRT_fdesc[fd].wxflag |= WX_TEXT;
else
MSVCRT_fdesc[fd].xflag &= ~WX_TEXT;
MSVCRT_fdesc[fd].wxflag &= ~WX_TEXT;
return ret;
}
......@@ -1700,10 +1774,10 @@ int _write(int fd, const void* buf, unsigned int count)
}
/* If appending, go to EOF */
if (MSVCRT_fdesc[fd].xflag & WX_APPEND)
if (MSVCRT_fdesc[fd].wxflag & WX_APPEND)
_lseek(fd, 0, FILE_END);
if (!(MSVCRT_fdesc[fd].xflag & WX_TEXT))
if (!(MSVCRT_fdesc[fd].wxflag & WX_TEXT))
{
if (WriteFile(hand, buf, count, &num_written, NULL)
&& (num_written == count))
......@@ -1714,7 +1788,7 @@ int _write(int fd, const void* buf, unsigned int count)
else
{
unsigned int i, j, nr_lf;
char *s=(char*)buf, *buf_start=(char*)buf, *p;
char *s =(char*)buf, *buf_start=(char*)buf, *p;
/* find number of \n ( without preceeding \r */
for ( nr_lf=0,i = 0; i <count; i++)
{
......@@ -1916,7 +1990,7 @@ MSVCRT_wint_t MSVCRT_fgetwc(MSVCRT_FILE* file)
{
char c;
if (!(MSVCRT_fdesc[file->_file].xflag & WX_TEXT))
if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT))
{
MSVCRT_wchar_t wc;
int r;
......@@ -2006,7 +2080,7 @@ MSVCRT_size_t MSVCRT_fwrite(const void *ptr, MSVCRT_size_t size, MSVCRT_size_t n
file->_ptr += pcnt;
written = pcnt;
wrcnt -= pcnt;
ptr = (char*)ptr + pcnt;
ptr = (const char*)ptr + pcnt;
} else if(!(file->_flag & MSVCRT__IOWRT)) {
if(file->_flag & MSVCRT__IORW) {
file->_flag |= MSVCRT__IOWRT;
......@@ -2294,7 +2368,7 @@ int MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
int MSVCRT_fputs(const char *s, MSVCRT_FILE* file)
{
size_t i, len = strlen(s);
if (!(MSVCRT_fdesc[file->_file].xflag & WX_TEXT))
if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT))
return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
for (i=0; i<len; i++)
if (MSVCRT_fputc(s[i], file) == MSVCRT_EOF)
......@@ -2308,7 +2382,7 @@ int MSVCRT_fputs(const char *s, MSVCRT_FILE* file)
int MSVCRT_fputws(const MSVCRT_wchar_t *s, MSVCRT_FILE* file)
{
size_t i, len = strlenW(s);
if (!(MSVCRT_fdesc[file->_file].xflag & WX_TEXT))
if (!(MSVCRT_fdesc[file->_file].wxflag & WX_TEXT))
return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
for (i=0; i<len; i++)
{
......
......@@ -126,6 +126,8 @@ extern void msvcrt_free_console(void);
extern void msvcrt_init_args(void);
extern void msvcrt_free_args(void);
extern unsigned msvcrt_create_io_inherit_block(STARTUPINFOA*);
/* run-time error codes */
#define _RT_STACK 0
#define _RT_NULLPTR 1
......
......@@ -49,19 +49,19 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
return -1;
}
FIXME(":must dup/kill streams for child process\n");
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
msvcrt_create_io_inherit_block(&si);
if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
flags == MSVCRT__P_DETACH ? DETACHED_PROCESS : 0,
env, NULL, &si, &pi))
{
msvcrt_set_errno(GetLastError());
MSVCRT_free(&si.lpReserved2);
return -1;
}
MSVCRT_free(&si.lpReserved2);
switch(flags)
{
case MSVCRT__P_WAIT:
......
......@@ -28,6 +28,8 @@
#include <windef.h>
#include <winbase.h>
#include <winnls.h>
#include <process.h>
#include <errno.h>
static void test_fdopen( void )
{
......@@ -233,6 +235,58 @@ static void test_file_write_read( void )
ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
}
static void test_file_inherit_child(const char* fd_s)
{
int fd = atoi(fd_s);
char buffer[32];
ok(write(fd, "Success", 8) == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
lseek(fd, 0, SEEK_SET);
ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
}
static void test_file_inherit_child_no(const char* fd_s)
{
int fd = atoi(fd_s);
ok(write(fd, "Success", 8) == -1 && errno == EBADF,
"Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
}
static void test_file_inherit( const char* selfname )
{
int fd;
const char* arg_v[5];
char buffer[16];
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
ok(fd != -1, "Couldn't create test file\n ");
arg_v[0] = selfname;
arg_v[1] = "tests/file.c";
arg_v[2] = buffer; sprintf(buffer, "%d", fd);
arg_v[3] = 0;
_spawnvp(_P_WAIT, selfname, arg_v);
ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
lseek(fd, 0, SEEK_SET);
ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
close (fd);
ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
ok(fd != -1, "Couldn't create test file\n ");
arg_v[0] = selfname;
arg_v[1] = "tests/file.c";
arg_v[2] = buffer; sprintf(buffer, "%d", fd);
arg_v[3] = buffer;
arg_v[4] = 0;
_spawnvp(_P_WAIT, selfname, arg_v);
ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
close (fd);
ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
}
static void test_tmpnam( void )
{
char name[MAX_PATH] = "abc";
......@@ -249,17 +303,29 @@ static void test_tmpnam( void )
ok(res == name, "supplied buffer was not used\n");
ok(res[0] == '\\', "first character is not a backslash\n");
ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
ok(res[strlen(res)-1] != '.', "second call - last character is not a dot\n");
ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
}
START_TEST(file)
{
int arg_c;
char** arg_v;
arg_c = winetest_get_mainargs( &arg_v );
if (arg_c >= 3)
{
if (arg_c == 3) test_file_inherit_child(arg_v[2]); else test_file_inherit_child_no(arg_v[2]);
return;
}
test_fdopen();
test_fileops();
test_fgetwc();
test_file_put_get();
test_file_write_read();
test_file_inherit(arg_v[0]);
test_tmpnam();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment