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
eee3a4e8
Commit
eee3a4e8
authored
Nov 12, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move support for starting Unix processes to ntdll.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1deefb84
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
173 additions
and
1 deletion
+173
-1
process.c
dlls/kernel32/process.c
+0
-0
env.c
dlls/ntdll/env.c
+68
-0
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
process.c
dlls/ntdll/process.c
+104
-1
No files found.
dlls/kernel32/process.c
View file @
eee3a4e8
This diff is collapsed.
Click to expand it.
dlls/ntdll/env.c
View file @
eee3a4e8
...
...
@@ -509,6 +509,74 @@ static WCHAR *build_initial_environment( char **env )
/***********************************************************************
* build_envp
*
* Build the environment of a new child process.
*/
char
**
build_envp
(
const
WCHAR
*
envW
)
{
static
const
char
*
const
unix_vars
[]
=
{
"PATH"
,
"TEMP"
,
"TMP"
,
"HOME"
};
char
**
envp
;
char
*
env
,
*
p
;
int
count
=
1
,
length
,
lenW
;
unsigned
int
i
;
lenW
=
get_env_length
(
envW
);
length
=
ntdll_wcstoumbs
(
0
,
envW
,
lenW
,
NULL
,
0
,
NULL
,
NULL
);
if
(
!
(
env
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
length
)))
return
NULL
;
ntdll_wcstoumbs
(
0
,
envW
,
lenW
,
env
,
length
,
NULL
,
NULL
);
for
(
p
=
env
;
*
p
;
p
+=
strlen
(
p
)
+
1
)
if
(
is_special_env_var
(
p
))
length
+=
4
;
/* prefix it with "WINE" */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
unix_vars
);
i
++
)
{
if
(
!
(
p
=
getenv
(
unix_vars
[
i
])))
continue
;
length
+=
strlen
(
unix_vars
[
i
])
+
strlen
(
p
)
+
2
;
count
++
;
}
if
((
envp
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
count
*
sizeof
(
*
envp
)
+
length
)))
{
char
**
envptr
=
envp
;
char
*
dst
=
(
char
*
)(
envp
+
count
);
/* some variables must not be modified, so we get them directly from the unix env */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
unix_vars
);
i
++
)
{
if
(
!
(
p
=
getenv
(
unix_vars
[
i
]
)))
continue
;
*
envptr
++
=
strcpy
(
dst
,
unix_vars
[
i
]
);
strcat
(
dst
,
"="
);
strcat
(
dst
,
p
);
dst
+=
strlen
(
dst
)
+
1
;
}
/* now put the Windows environment strings */
for
(
p
=
env
;
*
p
;
p
+=
strlen
(
p
)
+
1
)
{
if
(
*
p
==
'='
)
continue
;
/* skip drive curdirs, this crashes some unix apps */
if
(
!
strncmp
(
p
,
"WINEPRELOADRESERVE="
,
sizeof
(
"WINEPRELOADRESERVE="
)
-
1
))
continue
;
if
(
!
strncmp
(
p
,
"WINELOADERNOEXEC="
,
sizeof
(
"WINELOADERNOEXEC="
)
-
1
))
continue
;
if
(
!
strncmp
(
p
,
"WINESERVERSOCKET="
,
sizeof
(
"WINESERVERSOCKET="
)
-
1
))
continue
;
if
(
is_special_env_var
(
p
))
/* prefix it with "WINE" */
{
*
envptr
++
=
strcpy
(
dst
,
"WINE"
);
strcat
(
dst
,
p
);
}
else
{
*
envptr
++
=
strcpy
(
dst
,
p
);
}
dst
+=
strlen
(
dst
)
+
1
;
}
*
envptr
=
0
;
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
env
);
return
envp
;
}
/***********************************************************************
* get_current_directory
*
* Initialize the current directory from the Unix cwd.
...
...
dlls/ntdll/ntdll_misc.h
View file @
eee3a4e8
...
...
@@ -86,6 +86,7 @@ extern void virtual_init_threading(void) DECLSPEC_HIDDEN;
extern
void
fill_cpu_info
(
void
)
DECLSPEC_HIDDEN
;
extern
void
heap_set_debug_flags
(
HANDLE
handle
)
DECLSPEC_HIDDEN
;
extern
void
init_user_process_params
(
SIZE_T
data_size
)
DECLSPEC_HIDDEN
;
extern
char
**
build_envp
(
const
WCHAR
*
envW
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
restart_process
(
RTL_USER_PROCESS_PARAMETERS
*
params
,
NTSTATUS
status
)
DECLSPEC_HIDDEN
;
/* server support */
...
...
dlls/ntdll/process.c
View file @
eee3a4e8
...
...
@@ -1466,6 +1466,101 @@ static char *get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params )
/***********************************************************************
* fork_and_exec
*
* Fork and exec a new Unix binary, checking for errors.
*/
static
NTSTATUS
fork_and_exec
(
UNICODE_STRING
*
path
,
const
RTL_USER_PROCESS_PARAMETERS
*
params
)
{
pid_t
pid
;
int
fd
[
2
],
stdin_fd
=
-
1
,
stdout_fd
=
-
1
;
char
**
argv
,
**
envp
;
char
*
unixdir
;
ANSI_STRING
unix_name
;
NTSTATUS
status
;
status
=
wine_nt_to_unix_file_name
(
path
,
&
unix_name
,
FILE_OPEN
,
FALSE
);
if
(
status
)
return
status
;
#ifdef HAVE_PIPE2
if
(
pipe2
(
fd
,
O_CLOEXEC
)
==
-
1
)
#endif
{
if
(
pipe
(
fd
)
==
-
1
)
{
RtlFreeAnsiString
(
&
unix_name
);
return
STATUS_TOO_MANY_OPENED_FILES
;
}
fcntl
(
fd
[
0
],
F_SETFD
,
FD_CLOEXEC
);
fcntl
(
fd
[
1
],
F_SETFD
,
FD_CLOEXEC
);
}
wine_server_handle_to_fd
(
params
->
hStdInput
,
FILE_READ_DATA
,
&
stdin_fd
,
NULL
);
wine_server_handle_to_fd
(
params
->
hStdOutput
,
FILE_WRITE_DATA
,
&
stdout_fd
,
NULL
);
argv
=
build_argv
(
&
params
->
CommandLine
,
0
);
envp
=
build_envp
(
params
->
Environment
);
unixdir
=
get_unix_curdir
(
params
);
if
(
!
(
pid
=
fork
()))
/* child */
{
if
(
!
(
pid
=
fork
()))
/* grandchild */
{
close
(
fd
[
0
]
);
if
(
params
->
ConsoleFlags
||
params
->
ConsoleHandle
==
(
HANDLE
)
1
/* KERNEL32_CONSOLE_ALLOC */
||
(
params
->
hStdInput
==
INVALID_HANDLE_VALUE
&&
params
->
hStdOutput
==
INVALID_HANDLE_VALUE
))
{
setsid
();
set_stdio_fd
(
-
1
,
-
1
);
/* close stdin and stdout */
}
else
set_stdio_fd
(
stdin_fd
,
stdout_fd
);
if
(
stdin_fd
!=
-
1
)
close
(
stdin_fd
);
if
(
stdout_fd
!=
-
1
)
close
(
stdout_fd
);
/* Reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
if
(
unixdir
)
chdir
(
unixdir
);
if
(
argv
&&
envp
)
execve
(
unix_name
.
Buffer
,
argv
,
envp
);
}
if
(
pid
<=
0
)
/* grandchild if exec failed or child if fork failed */
{
status
=
FILE_GetNtStatus
();
write
(
fd
[
1
],
&
status
,
sizeof
(
status
)
);
_exit
(
1
);
}
_exit
(
0
);
/* child if fork succeeded */
}
close
(
fd
[
1
]
);
if
(
pid
!=
-
1
)
{
/* reap child */
pid_t
wret
;
do
{
wret
=
waitpid
(
pid
,
NULL
,
0
);
}
while
(
wret
<
0
&&
errno
==
EINTR
);
read
(
fd
[
0
],
&
status
,
sizeof
(
status
)
);
/* if we read something, exec or second fork failed */
}
else
status
=
FILE_GetNtStatus
();
close
(
fd
[
0
]
);
if
(
stdin_fd
!=
-
1
)
close
(
stdin_fd
);
if
(
stdout_fd
!=
-
1
)
close
(
stdout_fd
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
argv
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
envp
);
RtlFreeAnsiString
(
&
unix_name
);
return
status
;
}
/***********************************************************************
* restart_process
*/
NTSTATUS
restart_process
(
RTL_USER_PROCESS_PARAMETERS
*
params
,
NTSTATUS
status
)
...
...
@@ -1575,7 +1670,15 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
TRACE
(
"%s image %s cmdline %s
\n
"
,
debugstr_us
(
path
),
debugstr_us
(
&
params
->
ImagePathName
),
debugstr_us
(
&
params
->
CommandLine
));
if
((
status
=
get_pe_file_info
(
path
,
attributes
,
&
file_handle
,
&
pe_info
)))
goto
done
;
if
((
status
=
get_pe_file_info
(
path
,
attributes
,
&
file_handle
,
&
pe_info
)))
{
if
(
status
==
STATUS_INVALID_IMAGE_NOT_MZ
&&
!
fork_and_exec
(
path
,
params
))
{
memset
(
info
,
0
,
sizeof
(
*
info
)
);
return
STATUS_SUCCESS
;
}
goto
done
;
}
if
(
!
(
startup_info
=
create_startup_info
(
params
,
&
startup_info_size
)))
goto
done
;
env_size
=
get_env_size
(
params
,
&
winedebug
);
unixdir
=
get_unix_curdir
(
params
);
...
...
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