Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
1efae756
Commit
1efae756
authored
Sep 21, 2007
by
Hans Leidekker
Committed by
Alexandre Julliard
Sep 24, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Implement _wspawnv{, e, p, pe}.
parent
7d3d98eb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
195 additions
and
13 deletions
+195
-13
file.c
dlls/msvcrt/file.c
+7
-7
msvcrt.h
dlls/msvcrt/msvcrt.h
+2
-1
msvcrt.spec
dlls/msvcrt/msvcrt.spec
+4
-4
process.c
dlls/msvcrt/process.c
+182
-1
No files found.
dlls/msvcrt/file.c
View file @
1efae756
...
@@ -283,23 +283,23 @@ static int msvcrt_init_fp(MSVCRT_FILE* file, int fd, unsigned stream_flags)
...
@@ -283,23 +283,23 @@ static int msvcrt_init_fp(MSVCRT_FILE* file, int fd, unsigned stream_flags)
* 04 char file flags (wxflag): repeated for each fd
* 04 char file flags (wxflag): repeated for each fd
* 4+NBFD HANDLE file handle: repeated for each fd
* 4+NBFD HANDLE file handle: repeated for each fd
*/
*/
unsigned
msvcrt_create_io_inherit_block
(
STARTUPINFOA
*
si
)
unsigned
msvcrt_create_io_inherit_block
(
WORD
*
size
,
BYTE
**
block
)
{
{
int
fd
;
int
fd
;
char
*
wxflag_ptr
;
char
*
wxflag_ptr
;
HANDLE
*
handle_ptr
;
HANDLE
*
handle_ptr
;
si
->
cbReserved2
=
sizeof
(
unsigned
)
+
(
sizeof
(
char
)
+
sizeof
(
HANDLE
))
*
MSVCRT_fdend
;
*
size
=
sizeof
(
unsigned
)
+
(
sizeof
(
char
)
+
sizeof
(
HANDLE
))
*
MSVCRT_fdend
;
si
->
lpReserved2
=
MSVCRT_calloc
(
si
->
cbReserved2
,
1
);
*
block
=
MSVCRT_calloc
(
*
size
,
1
);
if
(
!
si
->
lpReserved2
)
if
(
!
*
block
)
{
{
si
->
cbReserved2
=
0
;
*
size
=
0
;
return
FALSE
;
return
FALSE
;
}
}
wxflag_ptr
=
(
char
*
)
si
->
lpReserved2
+
sizeof
(
unsigned
);
wxflag_ptr
=
(
char
*
)
*
block
+
sizeof
(
unsigned
);
handle_ptr
=
(
HANDLE
*
)(
wxflag_ptr
+
MSVCRT_fdend
*
sizeof
(
char
));
handle_ptr
=
(
HANDLE
*
)(
wxflag_ptr
+
MSVCRT_fdend
*
sizeof
(
char
));
*
(
unsigned
*
)
si
->
lpReserved2
=
MSVCRT_fdend
;
*
(
unsigned
*
)
*
block
=
MSVCRT_fdend
;
for
(
fd
=
0
;
fd
<
MSVCRT_fdend
;
fd
++
)
for
(
fd
=
0
;
fd
<
MSVCRT_fdend
;
fd
++
)
{
{
/* to be inherited, we need it to be open, and that DONTINHERIT isn't set */
/* to be inherited, we need it to be open, and that DONTINHERIT isn't set */
...
...
dlls/msvcrt/msvcrt.h
View file @
1efae756
...
@@ -152,7 +152,7 @@ extern void msvcrt_free_args(void);
...
@@ -152,7 +152,7 @@ extern void msvcrt_free_args(void);
extern
void
msvcrt_init_signals
(
void
);
extern
void
msvcrt_init_signals
(
void
);
extern
void
msvcrt_free_signals
(
void
);
extern
void
msvcrt_free_signals
(
void
);
extern
unsigned
msvcrt_create_io_inherit_block
(
STARTUPINFOA
*
);
extern
unsigned
msvcrt_create_io_inherit_block
(
WORD
*
,
BYTE
*
*
);
/* run-time error codes */
/* run-time error codes */
#define _RT_STACK 0
#define _RT_STACK 0
...
@@ -652,6 +652,7 @@ int MSVCRT__dup(int);
...
@@ -652,6 +652,7 @@ int MSVCRT__dup(int);
int
MSVCRT__dup2
(
int
,
int
);
int
MSVCRT__dup2
(
int
,
int
);
int
MSVCRT__pipe
(
int
*
,
unsigned
int
,
int
);
int
MSVCRT__pipe
(
int
*
,
unsigned
int
,
int
);
MSVCRT_wchar_t
*
_wgetenv
(
const
MSVCRT_wchar_t
*
);
MSVCRT_wchar_t
*
_wgetenv
(
const
MSVCRT_wchar_t
*
);
void
_wsearchenv
(
const
MSVCRT_wchar_t
*
,
const
MSVCRT_wchar_t
*
,
MSVCRT_wchar_t
*
);
#endif
#endif
#endif
/* __WINE_MSVCRT_H */
#endif
/* __WINE_MSVCRT_H */
dlls/msvcrt/msvcrt.spec
View file @
1efae756
...
@@ -559,10 +559,10 @@
...
@@ -559,10 +559,10 @@
@ stub _wspawnle #(long wstr wstr) varargs
@ stub _wspawnle #(long wstr wstr) varargs
@ stub _wspawnlp #(long wstr wstr) varargs
@ stub _wspawnlp #(long wstr wstr) varargs
@ stub _wspawnlpe #(long wstr wstr) varargs
@ stub _wspawnlpe #(long wstr wstr) varargs
@ st
ub _wspawnv #
(long wstr ptr)
@ st
dcall _wspawnv
(long wstr ptr)
@ st
ub _wspawnve #
(long wstr ptr ptr)
@ st
dcall _wspawnve
(long wstr ptr ptr)
@ st
ub _wspawnvp #
(long wstr ptr)
@ st
dcall _wspawnvp
(long wstr ptr)
@ st
ub _wspawnvpe #
(long wstr ptr ptr)
@ st
dcall _wspawnvpe
(long wstr ptr ptr)
@ cdecl _wsplitpath(wstr wstr wstr wstr wstr)
@ cdecl _wsplitpath(wstr wstr wstr wstr wstr)
@ cdecl _wstat(wstr ptr) MSVCRT__wstat
@ cdecl _wstat(wstr ptr) MSVCRT__wstat
@ cdecl _wstati64(wstr ptr) MSVCRT__wstati64
@ cdecl _wstati64(wstr ptr) MSVCRT__wstati64
...
...
dlls/msvcrt/process.c
View file @
1efae756
...
@@ -31,6 +31,7 @@
...
@@ -31,6 +31,7 @@
#include "msvcrt.h"
#include "msvcrt.h"
#include "wine/debug.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
msvcrt
);
WINE_DEFAULT_DEBUG_CHANNEL
(
msvcrt
);
...
@@ -48,7 +49,7 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const char* exe, char* cmdline, c
...
@@ -48,7 +49,7 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const char* exe, char* cmdline, c
memset
(
&
si
,
0
,
sizeof
(
si
));
memset
(
&
si
,
0
,
sizeof
(
si
));
si
.
cb
=
sizeof
(
si
);
si
.
cb
=
sizeof
(
si
);
msvcrt_create_io_inherit_block
(
&
si
);
msvcrt_create_io_inherit_block
(
&
si
.
cbReserved2
,
&
si
.
lpReserved2
);
if
(
!
CreateProcessA
(
exe
,
cmdline
,
NULL
,
NULL
,
TRUE
,
if
(
!
CreateProcessA
(
exe
,
cmdline
,
NULL
,
NULL
,
TRUE
,
flags
==
MSVCRT__P_DETACH
?
DETACHED_PROCESS
:
0
,
flags
==
MSVCRT__P_DETACH
?
DETACHED_PROCESS
:
0
,
env
,
NULL
,
&
si
,
&
pi
))
env
,
NULL
,
&
si
,
&
pi
))
...
@@ -81,6 +82,52 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const char* exe, char* cmdline, c
...
@@ -81,6 +82,52 @@ static MSVCRT_intptr_t msvcrt_spawn(int flags, const char* exe, char* cmdline, c
return
-
1
;
/* can't reach here */
return
-
1
;
/* can't reach here */
}
}
static
MSVCRT_intptr_t
msvcrt_spawn_wide
(
int
flags
,
const
MSVCRT_wchar_t
*
exe
,
MSVCRT_wchar_t
*
cmdline
,
MSVCRT_wchar_t
*
env
)
{
STARTUPINFOW
si
;
PROCESS_INFORMATION
pi
;
if
((
unsigned
)
flags
>
MSVCRT__P_DETACH
)
{
*
MSVCRT__errno
()
=
MSVCRT_EINVAL
;
return
-
1
;
}
memset
(
&
si
,
0
,
sizeof
(
si
));
si
.
cb
=
sizeof
(
si
);
msvcrt_create_io_inherit_block
(
&
si
.
cbReserved2
,
&
si
.
lpReserved2
);
if
(
!
CreateProcessW
(
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
:
WaitForSingleObject
(
pi
.
hProcess
,
INFINITE
);
GetExitCodeProcess
(
pi
.
hProcess
,
&
pi
.
dwProcessId
);
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
return
pi
.
dwProcessId
;
case
MSVCRT__P_DETACH
:
CloseHandle
(
pi
.
hProcess
);
pi
.
hProcess
=
0
;
/* fall through */
case
MSVCRT__P_NOWAIT
:
case
MSVCRT__P_NOWAITO
:
CloseHandle
(
pi
.
hThread
);
return
(
MSVCRT_intptr_t
)
pi
.
hProcess
;
case
MSVCRT__P_OVERLAY
:
MSVCRT__exit
(
0
);
}
return
-
1
;
/* can't reach here */
}
/* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
/* INTERNAL: Convert argv list to a single 'delim'-separated string, with an
* extra '\0' to terminate it
* extra '\0' to terminate it
*/
*/
...
@@ -126,6 +173,48 @@ static char* msvcrt_argvtos(const char* const* arg, char delim)
...
@@ -126,6 +173,48 @@ static char* msvcrt_argvtos(const char* const* arg, char delim)
return
ret
;
return
ret
;
}
}
static
MSVCRT_wchar_t
*
msvcrt_argvtos_wide
(
const
MSVCRT_wchar_t
*
const
*
arg
,
MSVCRT_wchar_t
delim
)
{
const
MSVCRT_wchar_t
*
const
*
a
;
long
size
;
MSVCRT_wchar_t
*
p
;
MSVCRT_wchar_t
*
ret
;
if
(
!
arg
&&
!
delim
)
{
/* Return NULL for an empty environment list */
return
NULL
;
}
/* get length */
a
=
arg
;
size
=
0
;
while
(
*
a
)
{
size
+=
strlenW
(
*
a
)
+
1
;
a
++
;
}
ret
=
MSVCRT_malloc
((
size
+
1
)
*
sizeof
(
MSVCRT_wchar_t
));
if
(
!
ret
)
return
NULL
;
/* fill string */
a
=
arg
;
p
=
ret
;
while
(
*
a
)
{
int
len
=
strlenW
(
*
a
);
memcpy
(
p
,
*
a
,
len
*
sizeof
(
MSVCRT_wchar_t
));
p
+=
len
;
*
p
++
=
delim
;
a
++
;
}
if
(
delim
&&
p
>
ret
)
p
[
-
1
]
=
0
;
else
*
p
=
0
;
return
ret
;
}
/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
/* INTERNAL: Convert va_list to a single 'delim'-separated string, with an
* extra '\0' to terminate it
* extra '\0' to terminate it
*/
*/
...
@@ -488,6 +577,63 @@ MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* a
...
@@ -488,6 +577,63 @@ MSVCRT_intptr_t CDECL _spawnve(int flags, const char* name, const char* const* a
}
}
/*********************************************************************
/*********************************************************************
* _wspawnve (MSVCRT.@)
*
* Unicode version of _spawnve
*/
MSVCRT_intptr_t
CDECL
_wspawnve
(
int
flags
,
const
MSVCRT_wchar_t
*
name
,
const
MSVCRT_wchar_t
*
const
*
argv
,
const
MSVCRT_wchar_t
*
const
*
envv
)
{
MSVCRT_wchar_t
*
args
=
msvcrt_argvtos_wide
(
argv
,
' '
);
MSVCRT_wchar_t
*
envs
=
msvcrt_argvtos_wide
(
envv
,
0
);
MSVCRT_wchar_t
fullname
[
MAX_PATH
];
const
MSVCRT_wchar_t
*
p
;
int
len
;
MSVCRT_intptr_t
ret
=
-
1
;
TRACE
(
":call (%s), params (%s), env (%s)
\n
"
,
debugstr_w
(
name
),
debugstr_w
(
args
),
envs
?
"Custom"
:
"Null"
);
/* no check for NULL name.
native doesn't do it */
p
=
memchrW
(
name
,
'\0'
,
MAX_PATH
);
if
(
!
p
)
p
=
name
+
MAX_PATH
-
1
;
len
=
p
-
name
;
/* extra-long names are silently truncated. */
memcpy
(
fullname
,
name
,
len
*
sizeof
(
MSVCRT_wchar_t
));
for
(
p
--
;
p
>=
name
;
p
--
)
{
if
(
*
p
==
'\\'
||
*
p
==
'/'
||
*
p
==
':'
||
*
p
==
'.'
)
break
;
}
/* if no extension is given, assume .exe */
if
(
(
p
<
name
||
*
p
!=
'.'
)
&&
len
<=
MAX_PATH
-
5
)
{
static
const
MSVCRT_wchar_t
dotexe
[]
=
{
'.'
,
'e'
,
'x'
,
'e'
};
FIXME
(
"only trying .exe when no extension given
\n
"
);
memcpy
(
fullname
+
len
,
dotexe
,
4
*
sizeof
(
MSVCRT_wchar_t
));
len
+=
4
;
}
fullname
[
len
]
=
'\0'
;
if
(
args
)
{
ret
=
msvcrt_spawn_wide
(
flags
,
fullname
,
args
,
envs
);
MSVCRT_free
(
args
);
}
MSVCRT_free
(
envs
);
return
ret
;
}
/*********************************************************************
* _spawnv (MSVCRT.@)
* _spawnv (MSVCRT.@)
*
*
* Like on Windows, this function does not handle arguments with spaces
* Like on Windows, this function does not handle arguments with spaces
...
@@ -499,6 +645,16 @@ MSVCRT_intptr_t CDECL _spawnv(int flags, const char* name, const char* const* ar
...
@@ -499,6 +645,16 @@ MSVCRT_intptr_t CDECL _spawnv(int flags, const char* name, const char* const* ar
}
}
/*********************************************************************
/*********************************************************************
* _wspawnv (MSVCRT.@)
*
* Unicode version of _spawnv
*/
MSVCRT_intptr_t
CDECL
_wspawnv
(
int
flags
,
const
MSVCRT_wchar_t
*
name
,
const
MSVCRT_wchar_t
*
const
*
argv
)
{
return
_wspawnve
(
flags
,
name
,
argv
,
NULL
);
}
/*********************************************************************
* _spawnvpe (MSVCRT.@)
* _spawnvpe (MSVCRT.@)
*
*
* Like on Windows, this function does not handle arguments with spaces
* Like on Windows, this function does not handle arguments with spaces
...
@@ -513,6 +669,21 @@ MSVCRT_intptr_t CDECL _spawnvpe(int flags, const char* name, const char* const*
...
@@ -513,6 +669,21 @@ MSVCRT_intptr_t CDECL _spawnvpe(int flags, const char* name, const char* const*
}
}
/*********************************************************************
/*********************************************************************
* _wspawnvpe (MSVCRT.@)
*
* Unicode version of _spawnvpe
*/
MSVCRT_intptr_t
CDECL
_wspawnvpe
(
int
flags
,
const
MSVCRT_wchar_t
*
name
,
const
MSVCRT_wchar_t
*
const
*
argv
,
const
MSVCRT_wchar_t
*
const
*
envv
)
{
static
const
MSVCRT_wchar_t
path
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
,
0
};
MSVCRT_wchar_t
fullname
[
MAX_PATH
];
_wsearchenv
(
name
,
path
,
fullname
);
return
_wspawnve
(
flags
,
fullname
[
0
]
?
fullname
:
name
,
argv
,
envv
);
}
/*********************************************************************
* _spawnvp (MSVCRT.@)
* _spawnvp (MSVCRT.@)
*
*
* Like on Windows, this function does not handle arguments with spaces
* Like on Windows, this function does not handle arguments with spaces
...
@@ -524,6 +695,16 @@ MSVCRT_intptr_t CDECL _spawnvp(int flags, const char* name, const char* const* a
...
@@ -524,6 +695,16 @@ MSVCRT_intptr_t CDECL _spawnvp(int flags, const char* name, const char* const* a
}
}
/*********************************************************************
/*********************************************************************
* _wspawnvp (MSVCRT.@)
*
* Unicode version of _spawnvp
*/
MSVCRT_intptr_t
CDECL
_wspawnvp
(
int
flags
,
const
MSVCRT_wchar_t
*
name
,
const
MSVCRT_wchar_t
*
const
*
argv
)
{
return
_wspawnvpe
(
flags
,
name
,
argv
,
NULL
);
}
/*********************************************************************
* _popen (MSVCRT.@)
* _popen (MSVCRT.@)
* FIXME: convert to _wpopen and call that from here instead? But it
* FIXME: convert to _wpopen and call that from here instead? But it
* would have to convert the command back to ANSI to call msvcrt_spawn,
* would have to convert the command back to ANSI to call msvcrt_spawn,
...
...
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