Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
0bfb1cbc
Commit
0bfb1cbc
authored
Sep 03, 2004
by
Eric Pouech
Committed by
Alexandre Julliard
Sep 03, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- 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
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
232 additions
and
84 deletions
+232
-84
environ.c
dlls/kernel/environ.c
+4
-4
process.c
dlls/kernel/process.c
+8
-2
file.c
dlls/msvcrt/file.c
+148
-74
msvcrt.h
dlls/msvcrt/msvcrt.h
+2
-0
process.c
dlls/msvcrt/process.c
+3
-3
file.c
dlls/msvcrt/tests/file.c
+67
-1
No files found.
dlls/kernel/environ.c
View file @
0bfb1cbc
...
...
@@ -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
;
...
...
dlls/kernel/process.c
View file @
0bfb1cbc
...
...
@@ -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
)
);
...
...
dlls/msvcrt/file.c
View file @
0bfb1cbc
...
...
@@ -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
w
xflag
;
}
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
].
w
xflag
&
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
].
w
xflag
=
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
));
/* INTERNAL: Set up stdin, stderr and stdout */
*
(
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 all file descriptors,
* as well as default streams (stdin, stderr and stdout)
*/
void
msvcrt_init_io
(
void
)
{
STARTUPINFOA
si
;
int
i
;
memset
(
MSVCRT__iob
,
0
,
3
*
sizeof
(
MSVCRT_FILE
));
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
].
xflag
=
WX_OPEN
;
MSVCRT__iob
[
0
].
_flag
=
MSVCRT__IOREAD
;
MSVCRT__iob
[
0
].
_tmpfname
=
NULL
;
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
].
xflag
=
WX_OPEN
;
MSVCRT__iob
[
1
].
_flag
=
MSVCRT__IOWRT
;
MSVCRT__iob
[
1
].
_tmpfname
=
NULL
;
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
].
xflag
=
WX_OPEN
;
MSVCRT__iob
[
2
].
_flag
=
MSVCRT__IOWR
T
;
MSVCRT__iob
[
2
].
_tmpfname
=
NULL
;
GetCurrentProcess
(),
&
MSVCRT_fdesc
[
2
].
handle
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
)
;
MSVCRT_fdesc
[
2
].
wxflag
=
WX_OPEN
|
WX_TEX
T
;
}
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
].
w
xflag
&
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
].
w
xflag
&=
~
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
io
flag
=
0
,
fd
;
int
wx
flag
=
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
,
io
flag
);
fd
=
msvcrt_alloc_fd
(
hand
,
wx
flag
);
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
hand
le
,
int
o
flags
)
{
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
(
!
(
o
flags
&
(
MSVCRT__O_BINARY
|
MSVCRT__O_TEXT
))
&&
(
*
__p__fmode
()
&
MSVCRT__O_BINARY
))
o
flags
|=
MSVCRT__O_BINARY
;
else
flags
|=
MSVCRT__O_TEXT
;
o
flags
|=
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
)
hand
le
,
split_oflags
(
oflags
)
);
TRACE
(
":handle (%ld) fd (%d) flags 0x%08x
\n
"
,
handle
,
fd
,
o
flags
);
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
].
w
xflag
|=
WX_ATEOF
;
if
(
MSVCRT_fdesc
[
fd
].
w
xflag
&
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
].
w
xflag
&
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
].
w
xflag
&
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
].
w
xflag
|=
WX_TEXT
;
else
MSVCRT_fdesc
[
fd
].
xflag
&=
~
WX_TEXT
;
MSVCRT_fdesc
[
fd
].
w
xflag
&=
~
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
].
w
xflag
&
WX_APPEND
)
_lseek
(
fd
,
0
,
FILE_END
);
if
(
!
(
MSVCRT_fdesc
[
fd
].
xflag
&
WX_TEXT
))
if
(
!
(
MSVCRT_fdesc
[
fd
].
w
xflag
&
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
].
w
xflag
&
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
].
w
xflag
&
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
].
w
xflag
&
WX_TEXT
))
return
MSVCRT_fwrite
(
s
,
sizeof
(
*
s
),
len
,
file
)
==
len
?
0
:
MSVCRT_EOF
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
...
...
dlls/msvcrt/msvcrt.h
View file @
0bfb1cbc
...
...
@@ -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
...
...
dlls/msvcrt/process.c
View file @
0bfb1cbc
...
...
@@ -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
:
...
...
dlls/msvcrt/tests/file.c
View file @
0bfb1cbc
...
...
@@ -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
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment