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
c316f0e4
Commit
c316f0e4
authored
Jul 19, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Simplify process creation.
Pass the socket for the new process from the parent through the environment. Perform initialisations during the new_process request.
parent
718716b7
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
247 additions
and
289 deletions
+247
-289
process.c
dlls/kernel/process.c
+90
-116
server.c
dlls/ntdll/server.c
+17
-6
server_protocol.h
include/wine/server_protocol.h
+11
-10
process.c
server/process.c
+95
-125
process.h
server/process.h
+1
-1
protocol.def
server/protocol.def
+19
-18
request.c
server/request.c
+1
-1
trace.c
server/trace.c
+13
-12
No files found.
dlls/kernel/process.c
View file @
c316f0e4
...
...
@@ -31,6 +31,12 @@
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_PRCTL_H
# include <sys/prctl.h>
#endif
...
...
@@ -1104,6 +1110,7 @@ static char **build_envp( const WCHAR *envW )
{
if
(
*
p
==
'='
)
continue
;
/* skip drive curdirs, this crashes some unix apps */
if
(
!
strncmp
(
p
,
"WINEPRELOADRESERVE="
,
sizeof
(
"WINEPRELOADRESERVE="
)
-
1
))
continue
;
if
(
!
strncmp
(
p
,
"WINESERVERSOCKET="
,
sizeof
(
"WINESERVERSOCKET="
)
-
1
))
continue
;
if
(
is_special_env_var
(
p
))
/* prefix it with "WINE" */
*
envptr
++
=
alloc_env_string
(
"WINE"
,
p
);
else
...
...
@@ -1210,9 +1217,18 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST
if
(
flags
&
CREATE_NEW_PROCESS_GROUP
)
params
->
ConsoleFlags
=
1
;
if
(
flags
&
CREATE_NEW_CONSOLE
)
params
->
ConsoleHandle
=
(
HANDLE
)
1
;
/* FIXME: cf. kernel_main.c */
params
->
hStdInput
=
startup
->
hStdInput
;
params
->
hStdOutput
=
startup
->
hStdOutput
;
params
->
hStdError
=
startup
->
hStdError
;
if
(
startup
->
dwFlags
&
STARTF_USESTDHANDLES
)
{
params
->
hStdInput
=
startup
->
hStdInput
;
params
->
hStdOutput
=
startup
->
hStdOutput
;
params
->
hStdError
=
startup
->
hStdError
;
}
else
{
params
->
hStdInput
=
GetStdHandle
(
STD_INPUT_HANDLE
);
params
->
hStdOutput
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
params
->
hStdError
=
GetStdHandle
(
STD_ERROR_HANDLE
);
}
params
->
dwX
=
startup
->
dwX
;
params
->
dwY
=
startup
->
dwY
;
params
->
dwXSize
=
startup
->
dwXSize
;
...
...
@@ -1243,12 +1259,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
WCHAR
*
env_end
;
char
*
winedebug
=
NULL
;
RTL_USER_PROCESS_PARAMETERS
*
params
;
int
startfd
[
2
];
int
execfd
[
2
];
int
socketfd
[
2
];
pid_t
pid
;
int
err
;
char
dummy
=
0
;
char
preloader_reserve
[
64
];
if
(
!
env
)
RtlAcquirePebLock
();
...
...
@@ -1271,96 +1284,34 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
}
env_end
++
;
sprintf
(
preloader_reserve
,
"WINEPRELOADRESERVE=%lx-%lx%c"
,
(
unsigned
long
)
res_start
,
(
unsigned
long
)
res_end
,
0
);
/* create the socket for the new process */
/* create the synchronization pipes */
if
(
pipe
(
startfd
)
==
-
1
)
if
(
socketpair
(
PF_UNIX
,
SOCK_STREAM
,
0
,
socketfd
)
==
-
1
)
{
if
(
!
env
)
RtlReleasePebLock
();
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
SetLastError
(
ERROR_TOO_MANY_OPEN_FILES
);
RtlDestroyProcessParameters
(
params
);
return
FALSE
;
}
if
(
pipe
(
execfd
)
==
-
1
)
{
if
(
!
env
)
RtlReleasePebLock
();
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
SetLastError
(
ERROR_TOO_MANY_OPEN_FILES
);
close
(
startfd
[
0
]
);
close
(
startfd
[
1
]
);
RtlDestroyProcessParameters
(
params
);
return
FALSE
;
}
fcntl
(
execfd
[
1
],
F_SETFD
,
1
);
/* set close on exec */
/* create the child process */
if
(
!
(
pid
=
fork
()))
/* child */
{
char
**
argv
=
build_argv
(
cmd_line
,
1
);
close
(
startfd
[
1
]
);
close
(
execfd
[
0
]
);
/* wait for parent to tell us to start */
if
(
read
(
startfd
[
0
],
&
dummy
,
1
)
!=
1
)
_exit
(
1
);
close
(
startfd
[
0
]
);
if
(
flags
&
(
CREATE_NEW_PROCESS_GROUP
|
CREATE_NEW_CONSOLE
|
DETACHED_PROCESS
))
setsid
();
/* Reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
signal
(
SIGCHLD
,
SIG_DFL
);
putenv
(
preloader_reserve
);
if
(
winedebug
)
putenv
(
winedebug
);
if
(
unixdir
)
chdir
(
unixdir
);
if
(
argv
)
wine_exec_wine_binary
(
NULL
,
argv
,
getenv
(
"WINELOADER"
)
);
err
=
errno
;
write
(
execfd
[
1
],
&
err
,
sizeof
(
err
)
);
_exit
(
1
);
}
/* this is the parent */
close
(
startfd
[
0
]
);
close
(
execfd
[
1
]
);
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
if
(
pid
==
-
1
)
{
if
(
!
env
)
RtlReleasePebLock
();
close
(
startfd
[
1
]
);
close
(
execfd
[
0
]
);
FILE_SetDosError
();
RtlDestroyProcessParameters
(
params
);
return
FALSE
;
}
wine_server_send_fd
(
socketfd
[
1
]
);
close
(
socketfd
[
1
]
);
/* create the process on the server side */
SERVER_START_REQ
(
new_process
)
{
req
->
inherit_all
=
inherit
;
req
->
create_flags
=
flags
;
req
->
unix_pid
=
pid
;
req
->
exe_file
=
hFile
;
if
(
startup
->
dwFlags
&
STARTF_USESTDHANDLES
)
{
req
->
hstdin
=
startup
->
hStdInput
;
req
->
hstdout
=
startup
->
hStdOutput
;
req
->
hstderr
=
startup
->
hStdError
;
}
else
{
req
->
hstdin
=
GetStdHandle
(
STD_INPUT_HANDLE
);
req
->
hstdout
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
req
->
hstderr
=
GetStdHandle
(
STD_ERROR_HANDLE
);
}
req
->
inherit_all
=
inherit
;
req
->
create_flags
=
flags
;
req
->
socket_fd
=
socketfd
[
1
];
req
->
exe_file
=
hFile
;
req
->
process_access
=
PROCESS_ALL_ACCESS
;
req
->
process_attr
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
req
->
thread_access
=
THREAD_ALL_ACCESS
;
req
->
thread_attr
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
req
->
hstdin
=
params
->
hStdInput
;
req
->
hstdout
=
params
->
hStdOutput
;
req
->
hstderr
=
params
->
hStdError
;
if
((
flags
&
(
CREATE_NEW_CONSOLE
|
DETACHED_PROCESS
))
!=
0
)
{
...
...
@@ -1378,7 +1329,13 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
wine_server_add_data
(
req
,
params
,
params
->
Size
);
wine_server_add_data
(
req
,
params
->
Environment
,
(
env_end
-
params
->
Environment
)
*
sizeof
(
WCHAR
)
);
ret
=
!
wine_server_call_err
(
req
);
if
((
ret
=
!
wine_server_call_err
(
req
)))
{
info
->
dwProcessId
=
(
DWORD
)
reply
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
reply
->
tid
;
info
->
hProcess
=
reply
->
phandle
;
info
->
hThread
=
reply
->
thandle
;
}
process_info
=
reply
->
info
;
}
SERVER_END_REQ
;
...
...
@@ -1387,57 +1344,74 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
RtlDestroyProcessParameters
(
params
);
if
(
!
ret
)
{
close
(
s
tartfd
[
1
]
);
close
(
execfd
[
0
]
);
close
(
s
ocketfd
[
0
]
);
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
return
FALSE
;
}
/* tell child to start and wait for it to exec */
/* create the child process */
if
(
!
(
pid
=
fork
()))
/* child */
{
char
preloader_reserve
[
64
],
socket_env
[
64
];
char
**
argv
=
build_argv
(
cmd_line
,
1
);
if
(
flags
&
(
CREATE_NEW_PROCESS_GROUP
|
CREATE_NEW_CONSOLE
|
DETACHED_PROCESS
))
setsid
();
/* Reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
signal
(
SIGCHLD
,
SIG_DFL
);
sprintf
(
socket_env
,
"WINESERVERSOCKET=%u"
,
socketfd
[
0
]
);
sprintf
(
preloader_reserve
,
"WINEPRELOADRESERVE=%lx-%lx"
,
(
unsigned
long
)
res_start
,
(
unsigned
long
)
res_end
);
putenv
(
preloader_reserve
);
putenv
(
socket_env
);
if
(
winedebug
)
putenv
(
winedebug
);
if
(
unixdir
)
chdir
(
unixdir
);
if
(
argv
)
wine_exec_wine_binary
(
NULL
,
argv
,
getenv
(
"WINELOADER"
)
);
_exit
(
1
);
}
write
(
startfd
[
1
],
&
dummy
,
1
);
close
(
startfd
[
1
]
);
/* this is the parent */
if
(
read
(
execfd
[
0
],
&
err
,
sizeof
(
err
)
)
>
0
)
/* exec failed */
close
(
socketfd
[
0
]
);
HeapFree
(
GetProcessHeap
(),
0
,
winedebug
);
if
(
pid
==
-
1
)
{
errno
=
err
;
FILE_SetDosError
();
close
(
execfd
[
0
]
);
CloseHandle
(
process_info
);
return
FALSE
;
goto
error
;
}
close
(
execfd
[
0
]
);
/* wait for the new process info to be ready */
WaitForSingleObject
(
process_info
,
INFINITE
);
SERVER_START_REQ
(
get_new_process_info
)
{
req
->
info
=
process_info
;
req
->
process_access
=
PROCESS_ALL_ACCESS
;
req
->
process_attr
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
req
->
thread_access
=
THREAD_ALL_ACCESS
;
req
->
thread_attr
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
)
?
OBJ_INHERIT
:
0
;
if
((
ret
=
!
wine_server_call_err
(
req
)))
{
info
->
dwProcessId
=
(
DWORD
)
reply
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
reply
->
tid
;
info
->
hProcess
=
reply
->
phandle
;
info
->
hThread
=
reply
->
thandle
;
success
=
reply
->
success
;
}
req
->
info
=
process_info
;
wine_server_call
(
req
);
success
=
reply
->
success
;
err
=
reply
->
exit_code
;
}
SERVER_END_REQ
;
if
(
ret
&&
!
success
)
/* new process failed to start */
if
(
!
success
)
{
DWORD
exitcode
;
if
(
GetExitCodeProcess
(
info
->
hProcess
,
&
exitcode
))
SetLastError
(
exitcode
);
CloseHandle
(
info
->
hThread
);
CloseHandle
(
info
->
hProcess
);
ret
=
FALSE
;
SetLastError
(
err
?
err
:
ERROR_INTERNAL_ERROR
);
goto
error
;
}
CloseHandle
(
process_info
);
return
ret
;
return
success
;
error:
CloseHandle
(
process_info
);
CloseHandle
(
info
->
hProcess
);
CloseHandle
(
info
->
hThread
);
info
->
hProcess
=
info
->
hThread
=
0
;
info
->
dwProcessId
=
info
->
dwThreadId
=
0
;
return
FALSE
;
}
...
...
dlls/ntdll/server.c
View file @
c316f0e4
...
...
@@ -843,16 +843,27 @@ static void create_config_dir(void)
void
server_init_process
(
void
)
{
obj_handle_t
dummy_handle
;
const
char
*
server_dir
=
wine_get_server_dir
(
);
const
char
*
env_socket
=
getenv
(
"WINESERVERSOCKET"
);
if
(
!
server_dir
)
/* this means the config dir doesn't exist */
if
(
env_socket
)
{
create_config_dir
();
server_dir
=
wine_get_server_dir
();
fd_socket
=
atoi
(
env_socket
);
if
(
fcntl
(
fd_socket
,
F_SETFD
,
1
)
==
-
1
)
fatal_perror
(
"Bad server socket %d"
,
fd_socket
);
}
else
{
const
char
*
server_dir
=
wine_get_server_dir
();
if
(
!
server_dir
)
/* this means the config dir doesn't exist */
{
create_config_dir
();
server_dir
=
wine_get_server_dir
();
}
/* connect to the server */
fd_socket
=
server_connect
(
server_dir
);
/* connect to the server */
fd_socket
=
server_connect
(
server_dir
);
}
/* setup the signal mask */
sigemptyset
(
&
block_set
);
...
...
include/wine/server_protocol.h
View file @
c316f0e4
...
...
@@ -193,11 +193,15 @@ struct new_process_request
struct
request_header
__header
;
int
inherit_all
;
unsigned
int
create_flags
;
int
unix_pi
d
;
int
socket_f
d
;
obj_handle_t
exe_file
;
obj_handle_t
hstdin
;
obj_handle_t
hstdout
;
obj_handle_t
hstderr
;
unsigned
int
process_access
;
unsigned
int
process_attr
;
unsigned
int
thread_access
;
unsigned
int
thread_attr
;
/* VARARG(info,startup_info); */
/* VARARG(env,unicode_str); */
};
...
...
@@ -205,6 +209,10 @@ struct new_process_reply
{
struct
reply_header
__header
;
obj_handle_t
info
;
process_id_t
pid
;
obj_handle_t
phandle
;
thread_id_t
tid
;
obj_handle_t
thandle
;
};
...
...
@@ -213,19 +221,12 @@ struct get_new_process_info_request
{
struct
request_header
__header
;
obj_handle_t
info
;
unsigned
int
process_access
;
unsigned
int
process_attr
;
unsigned
int
thread_access
;
unsigned
int
thread_attr
;
};
struct
get_new_process_info_reply
{
struct
reply_header
__header
;
process_id_t
pid
;
obj_handle_t
phandle
;
thread_id_t
tid
;
obj_handle_t
thandle
;
int
success
;
int
exit_code
;
};
...
...
@@ -4382,6 +4383,6 @@ union generic_reply
struct
query_symlink_reply
query_symlink_reply
;
};
#define SERVER_PROTOCOL_VERSION 23
7
#define SERVER_PROTOCOL_VERSION 23
8
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/process.c
View file @
c316f0e4
...
...
@@ -94,17 +94,11 @@ static const struct fd_ops process_fd_ops =
struct
startup_info
{
struct
object
obj
;
/* object header */
struct
list
entry
;
/* entry in list of startup infos */
int
inherit_all
;
/* inherit all handles from parent */
unsigned
int
create_flags
;
/* creation flags */
int
unix_pid
;
/* Unix pid of new process */
obj_handle_t
hstdin
;
/* handle for stdin */
obj_handle_t
hstdout
;
/* handle for stdout */
obj_handle_t
hstderr
;
/* handle for stderr */
struct
file
*
exe_file
;
/* file handle for main exe */
struct
thread
*
owner
;
/* owner thread (the one that created the new process) */
struct
process
*
process
;
/* created process */
struct
thread
*
thread
;
/* created thread */
size_t
data_size
;
/* size of startup data */
void
*
data
;
/* data for startup info */
};
...
...
@@ -130,8 +124,6 @@ static const struct object_ops startup_info_ops =
};
static
struct
list
startup_info_list
=
LIST_INIT
(
startup_info_list
);
struct
ptid_entry
{
void
*
ptr
;
/* entry ptr */
...
...
@@ -226,13 +218,18 @@ static void set_process_startup_state( struct process *process, enum startup_sta
}
/* create a new process and its main thread */
struct
thread
*
create_process
(
int
fd
)
/* if the function fails the fd is closed */
struct
thread
*
create_process
(
int
fd
,
struct
thread
*
parent_thread
,
int
inherit_all
)
{
struct
process
*
process
;
struct
thread
*
thread
=
NULL
;
int
request_pipe
[
2
];
if
(
!
(
process
=
alloc_object
(
&
process_ops
)))
goto
error
;
if
(
!
(
process
=
alloc_object
(
&
process_ops
)))
{
close
(
fd
);
goto
error
;
}
process
->
parent
=
NULL
;
process
->
debugger
=
NULL
;
process
->
handles
=
NULL
;
...
...
@@ -261,9 +258,24 @@ struct thread *create_process( int fd )
gettimeofday
(
&
process
->
start_time
,
NULL
);
list_add_head
(
&
process_list
,
&
process
->
entry
);
if
(
!
(
process
->
id
=
process
->
group_id
=
alloc_ptid
(
process
)))
goto
error
;
if
(
!
(
process
->
id
=
process
->
group_id
=
alloc_ptid
(
process
)))
{
close
(
fd
);
goto
error
;
}
if
(
!
(
process
->
msg_fd
=
create_anonymous_fd
(
&
process_fd_ops
,
fd
,
&
process
->
obj
)))
goto
error
;
/* create the handle table */
if
(
!
parent_thread
)
process
->
handles
=
alloc_handle_table
(
process
,
0
);
else
{
struct
process
*
parent
=
parent_thread
->
process
;
process
->
parent
=
(
struct
process
*
)
grab_object
(
parent
);
process
->
handles
=
inherit_all
?
copy_handle_table
(
process
,
parent
)
:
alloc_handle_table
(
process
,
0
);
}
if
(
!
process
->
handles
)
goto
error
;
/* create the main thread */
if
(
pipe
(
request_pipe
)
==
-
1
)
{
...
...
@@ -290,82 +302,13 @@ struct thread *create_process( int fd )
return
NULL
;
}
/* find the startup info for a given Unix process */
inline
static
struct
startup_info
*
find_startup_info
(
int
unix_pid
)
{
struct
list
*
ptr
;
LIST_FOR_EACH
(
ptr
,
&
startup_info_list
)
{
struct
startup_info
*
info
=
LIST_ENTRY
(
ptr
,
struct
startup_info
,
entry
);
if
(
info
->
unix_pid
==
unix_pid
)
return
info
;
}
return
NULL
;
}
/* initialize the current process and fill in the request */
size_t
init_process
(
struct
thread
*
thread
)
{
struct
process
*
process
=
thread
->
process
;
struct
thread
*
parent_thread
=
NULL
;
struct
process
*
parent
=
NULL
;
struct
startup_info
*
info
;
if
(
process
->
startup_info
)
return
process
->
startup_info
->
data_size
;
/* already initialized */
if
((
info
=
find_startup_info
(
thread
->
unix_pid
)))
{
if
(
info
->
thread
)
return
info
->
data_size
;
/* already initialized */
info
->
thread
=
(
struct
thread
*
)
grab_object
(
thread
);
info
->
process
=
(
struct
process
*
)
grab_object
(
process
);
process
->
startup_info
=
(
struct
startup_info
*
)
grab_object
(
info
);
parent_thread
=
info
->
owner
;
parent
=
parent_thread
->
process
;
process
->
parent
=
(
struct
process
*
)
grab_object
(
parent
);
/* set the process flags */
process
->
create_flags
=
info
->
create_flags
;
if
(
info
->
inherit_all
)
process
->
handles
=
copy_handle_table
(
process
,
parent
);
}
/* create the handle table */
if
(
!
process
->
handles
)
process
->
handles
=
alloc_handle_table
(
process
,
0
);
if
(
!
process
->
handles
)
{
set_error
(
STATUS_NO_MEMORY
);
return
0
;
}
/* connect to the window station */
connect_process_winstation
(
process
,
parent_thread
);
struct
startup_info
*
info
=
process
->
startup_info
;
if
(
!
info
)
return
0
;
/* thread will be actually suspended in init_done */
if
(
info
->
create_flags
&
CREATE_SUSPENDED
)
thread
->
suspend
++
;
/* set the process console */
if
(
!
(
info
->
create_flags
&
(
DETACHED_PROCESS
|
CREATE_NEW_CONSOLE
)))
{
/* FIXME: some better error checking should be done...
* like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
inherit_console
(
parent_thread
,
process
,
info
->
inherit_all
?
info
->
hstdin
:
0
);
}
/* attach to the debugger if requested */
if
(
process
->
create_flags
&
(
DEBUG_PROCESS
|
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent_thread
);
else
if
(
parent
->
debugger
&&
!
(
parent
->
create_flags
&
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent
->
debugger
);
if
(
!
(
process
->
create_flags
&
CREATE_NEW_PROCESS_GROUP
))
process
->
group_id
=
parent
->
group_id
;
return
info
->
data_size
;
}
...
...
@@ -426,12 +369,9 @@ static void startup_info_destroy( struct object *obj )
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
list_remove
(
&
info
->
entry
);
if
(
info
->
data
)
free
(
info
->
data
);
if
(
info
->
exe_file
)
release_object
(
info
->
exe_file
);
if
(
info
->
process
)
release_object
(
info
->
process
);
if
(
info
->
thread
)
release_object
(
info
->
thread
);
if
(
info
->
owner
)
release_object
(
info
->
owner
);
}
static
void
startup_info_dump
(
struct
object
*
obj
,
int
verbose
)
...
...
@@ -439,8 +379,8 @@ static void startup_info_dump( struct object *obj, int verbose )
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
fprintf
(
stderr
,
"Startup info
flags=%x
in=%p out=%p err=%p
\n
"
,
info
->
create_flags
,
info
->
hstdin
,
info
->
hstdout
,
info
->
hstderr
);
fprintf
(
stderr
,
"Startup info in=%p out=%p err=%p
\n
"
,
info
->
hstdin
,
info
->
hstdout
,
info
->
hstderr
);
}
static
int
startup_info_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
...
...
@@ -792,20 +732,30 @@ struct module_snapshot *module_snap( struct process *process, int *count )
DECL_HANDLER
(
new_process
)
{
struct
startup_info
*
info
;
struct
thread
*
thread
;
struct
process
*
process
;
struct
process
*
parent
=
current
->
process
;
int
socket_fd
=
thread_get_inflight_fd
(
current
,
req
->
socket_fd
);
if
(
socket_fd
==
-
1
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
if
(
fcntl
(
socket_fd
,
F_SETFL
,
O_NONBLOCK
)
==
-
1
)
{
set_error
(
STATUS_INVALID_HANDLE
);
close
(
socket_fd
);
return
;
}
/* build the startup info for a new process */
if
(
!
(
info
=
alloc_object
(
&
startup_info_ops
)))
return
;
list_add_head
(
&
startup_info_list
,
&
info
->
entry
);
info
->
inherit_all
=
req
->
inherit_all
;
info
->
create_flags
=
req
->
create_flags
;
info
->
unix_pid
=
req
->
unix_pid
;
info
->
hstdin
=
req
->
hstdin
;
info
->
hstdout
=
req
->
hstdout
;
info
->
hstderr
=
req
->
hstderr
;
info
->
exe_file
=
NULL
;
info
->
owner
=
(
struct
thread
*
)
grab_object
(
current
);
info
->
process
=
NULL
;
info
->
thread
=
NULL
;
info
->
data_size
=
get_req_data_size
();
info
->
data
=
NULL
;
...
...
@@ -814,7 +764,56 @@ DECL_HANDLER(new_process)
goto
done
;
if
(
!
(
info
->
data
=
memdup
(
get_req_data
(),
info
->
data_size
)))
goto
done
;
if
(
!
(
thread
=
create_process
(
socket_fd
,
current
,
req
->
inherit_all
)))
goto
done
;
process
=
thread
->
process
;
process
->
create_flags
=
req
->
create_flags
;
process
->
startup_info
=
(
struct
startup_info
*
)
grab_object
(
info
);
/* connect to the window station */
connect_process_winstation
(
process
,
current
);
/* thread will be actually suspended in init_done */
if
(
req
->
create_flags
&
CREATE_SUSPENDED
)
thread
->
suspend
++
;
/* set the process console */
if
(
!
(
req
->
create_flags
&
(
DETACHED_PROCESS
|
CREATE_NEW_CONSOLE
)))
{
/* FIXME: some better error checking should be done...
* like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
inherit_console
(
current
,
process
,
req
->
inherit_all
?
req
->
hstdin
:
0
);
}
if
(
!
req
->
inherit_all
&&
!
(
req
->
create_flags
&
CREATE_NEW_CONSOLE
))
{
info
->
hstdin
=
duplicate_handle
(
parent
,
req
->
hstdin
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
info
->
hstdout
=
duplicate_handle
(
parent
,
req
->
hstdout
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
info
->
hstderr
=
duplicate_handle
(
parent
,
req
->
hstderr
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
/* some handles above may have been invalid; this is not an error */
if
(
get_error
()
==
STATUS_INVALID_HANDLE
||
get_error
()
==
STATUS_OBJECT_TYPE_MISMATCH
)
clear_error
();
}
/* attach to the debugger if requested */
if
(
req
->
create_flags
&
(
DEBUG_PROCESS
|
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
current
);
else
if
(
parent
->
debugger
&&
!
(
parent
->
create_flags
&
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent
->
debugger
);
if
(
!
(
req
->
create_flags
&
CREATE_NEW_PROCESS_GROUP
))
process
->
group_id
=
parent
->
group_id
;
info
->
process
=
(
struct
process
*
)
grab_object
(
process
);
reply
->
info
=
alloc_handle
(
current
->
process
,
info
,
SYNCHRONIZE
,
0
);
reply
->
pid
=
get_process_id
(
process
);
reply
->
tid
=
get_thread_id
(
thread
);
reply
->
phandle
=
alloc_handle
(
parent
,
process
,
req
->
process_access
,
req
->
process_attr
);
reply
->
thandle
=
alloc_handle
(
parent
,
thread
,
req
->
thread_access
,
req
->
thread_attr
);
done
:
release_object
(
info
);
...
...
@@ -828,23 +827,10 @@ DECL_HANDLER(get_new_process_info)
if
((
info
=
(
struct
startup_info
*
)
get_handle_obj
(
current
->
process
,
req
->
info
,
0
,
&
startup_info_ops
)))
{
reply
->
pid
=
get_process_id
(
info
->
process
);
reply
->
tid
=
get_thread_id
(
info
->
thread
);
reply
->
phandle
=
alloc_handle
(
current
->
process
,
info
->
process
,
req
->
process_access
,
req
->
process_attr
);
reply
->
thandle
=
alloc_handle
(
current
->
process
,
info
->
thread
,
req
->
thread_access
,
req
->
thread_attr
);
reply
->
success
=
is_process_init_done
(
info
->
process
);
reply
->
exit_code
=
info
->
process
->
exit_code
;
release_object
(
info
);
}
else
{
reply
->
pid
=
0
;
reply
->
tid
=
0
;
reply
->
phandle
=
0
;
reply
->
thandle
=
0
;
reply
->
success
=
0
;
}
}
/* Retrieve the new process startup info */
...
...
@@ -859,25 +845,9 @@ DECL_HANDLER(get_startup_info)
if
(
info
->
exe_file
&&
!
(
reply
->
exe_file
=
alloc_handle
(
process
,
info
->
exe_file
,
GENERIC_READ
,
0
)))
return
;
if
(
!
info
->
inherit_all
&&
!
(
info
->
create_flags
&
CREATE_NEW_CONSOLE
))
{
struct
process
*
parent_process
=
info
->
owner
->
process
;
reply
->
hstdin
=
duplicate_handle
(
parent_process
,
info
->
hstdin
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
reply
->
hstdout
=
duplicate_handle
(
parent_process
,
info
->
hstdout
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
reply
->
hstderr
=
duplicate_handle
(
parent_process
,
info
->
hstderr
,
process
,
0
,
OBJ_INHERIT
,
DUPLICATE_SAME_ACCESS
);
/* some handles above may have been invalid; this is not an error */
if
(
get_error
()
==
STATUS_INVALID_HANDLE
||
get_error
()
==
STATUS_OBJECT_TYPE_MISMATCH
)
clear_error
();
}
else
{
reply
->
hstdin
=
info
->
hstdin
;
reply
->
hstdout
=
info
->
hstdout
;
reply
->
hstderr
=
info
->
hstderr
;
}
reply
->
hstdin
=
info
->
hstdin
;
reply
->
hstdout
=
info
->
hstdout
;
reply
->
hstderr
=
info
->
hstderr
;
/* we return the data directly without making a copy so this can only be called once */
size
=
info
->
data_size
;
...
...
server/process.h
View file @
c316f0e4
...
...
@@ -102,7 +102,7 @@ struct module_snapshot
extern
unsigned
int
alloc_ptid
(
void
*
ptr
);
extern
void
free_ptid
(
unsigned
int
id
);
extern
void
*
get_ptid_entry
(
unsigned
int
id
);
extern
struct
thread
*
create_process
(
int
fd
);
extern
struct
thread
*
create_process
(
int
fd
,
struct
thread
*
parent_thread
,
int
inherit_all
);
extern
size_t
init_process
(
struct
thread
*
thread
);
extern
struct
thread
*
get_process_first_thread
(
struct
process
*
process
);
extern
struct
process
*
get_process_from_id
(
process_id_t
id
);
...
...
server/protocol.def
View file @
c316f0e4
...
...
@@ -205,33 +205,34 @@ struct token_groups
/* Create a new process from the context of the parent */
@REQ(new_process)
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
int unix_pid; /* Unix pid of new process */
obj_handle_t exe_file; /* file handle for main exe */
obj_handle_t hstdin; /* handle for stdin */
obj_handle_t hstdout; /* handle for stdout */
obj_handle_t hstderr; /* handle for stderr */
VARARG(info,startup_info); /* startup information */
VARARG(env,unicode_str); /* environment for new process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */
obj_handle_t exe_file; /* file handle for main exe */
obj_handle_t hstdin; /* handle for stdin */
obj_handle_t hstdout; /* handle for stdout */
obj_handle_t hstderr; /* handle for stderr */
unsigned int process_access; /* access rights for process object */
unsigned int process_attr; /* attributes for process object */
unsigned int thread_access; /* access rights for thread object */
unsigned int thread_attr; /* attributes for thread object */
VARARG(info,startup_info); /* startup information */
VARARG(env,unicode_str); /* environment for new process */
@REPLY
obj_handle_t info; /* new process info handle */
obj_handle_t info; /* new process info handle */
process_id_t pid; /* process id */
obj_handle_t phandle; /* process handle (in the current process) */
thread_id_t tid; /* thread id */
obj_handle_t thandle; /* thread handle (in the current process) */
@END
/* Retrieve information about a newly started process */
@REQ(get_new_process_info)
obj_handle_t info; /* info handle returned from new_process_request */
unsigned int process_access; /* access rights for process object */
unsigned int process_attr; /* attributes for process object */
unsigned int thread_access; /* access rights for thread object */
unsigned int thread_attr; /* attributes for thread object */
@REPLY
process_id_t pid; /* process id */
obj_handle_t phandle; /* process handle (in the current process) */
thread_id_t tid; /* thread id */
obj_handle_t thandle; /* thread handle (in the current process) */
int success; /* did the process start successfully? */
int exit_code; /* process exit code if failed */
@END
...
...
server/request.c
View file @
c316f0e4
...
...
@@ -508,7 +508,7 @@ static void master_socket_poll_event( struct fd *fd, int event )
sock
->
timeout
=
NULL
;
}
fcntl
(
client
,
F_SETFL
,
O_NONBLOCK
);
create_process
(
client
);
create_process
(
client
,
NULL
,
0
);
}
}
...
...
server/trace.c
View file @
c316f0e4
...
...
@@ -606,11 +606,15 @@ static void dump_new_process_request( const struct new_process_request *req )
{
fprintf
(
stderr
,
" inherit_all=%d,"
,
req
->
inherit_all
);
fprintf
(
stderr
,
" create_flags=%08x,"
,
req
->
create_flags
);
fprintf
(
stderr
,
"
unix_pid=%d,"
,
req
->
unix_pi
d
);
fprintf
(
stderr
,
"
socket_fd=%d,"
,
req
->
socket_f
d
);
fprintf
(
stderr
,
" exe_file=%p,"
,
req
->
exe_file
);
fprintf
(
stderr
,
" hstdin=%p,"
,
req
->
hstdin
);
fprintf
(
stderr
,
" hstdout=%p,"
,
req
->
hstdout
);
fprintf
(
stderr
,
" hstderr=%p,"
,
req
->
hstderr
);
fprintf
(
stderr
,
" process_access=%08x,"
,
req
->
process_access
);
fprintf
(
stderr
,
" process_attr=%08x,"
,
req
->
process_attr
);
fprintf
(
stderr
,
" thread_access=%08x,"
,
req
->
thread_access
);
fprintf
(
stderr
,
" thread_attr=%08x,"
,
req
->
thread_attr
);
fprintf
(
stderr
,
" info="
);
dump_varargs_startup_info
(
cur_size
);
fputc
(
','
,
stderr
);
...
...
@@ -620,25 +624,22 @@ static void dump_new_process_request( const struct new_process_request *req )
static
void
dump_new_process_reply
(
const
struct
new_process_reply
*
req
)
{
fprintf
(
stderr
,
" info=%p"
,
req
->
info
);
fprintf
(
stderr
,
" info=%p,"
,
req
->
info
);
fprintf
(
stderr
,
" pid=%04x,"
,
req
->
pid
);
fprintf
(
stderr
,
" phandle=%p,"
,
req
->
phandle
);
fprintf
(
stderr
,
" tid=%04x,"
,
req
->
tid
);
fprintf
(
stderr
,
" thandle=%p"
,
req
->
thandle
);
}
static
void
dump_get_new_process_info_request
(
const
struct
get_new_process_info_request
*
req
)
{
fprintf
(
stderr
,
" info=%p,"
,
req
->
info
);
fprintf
(
stderr
,
" process_access=%08x,"
,
req
->
process_access
);
fprintf
(
stderr
,
" process_attr=%08x,"
,
req
->
process_attr
);
fprintf
(
stderr
,
" thread_access=%08x,"
,
req
->
thread_access
);
fprintf
(
stderr
,
" thread_attr=%08x"
,
req
->
thread_attr
);
fprintf
(
stderr
,
" info=%p"
,
req
->
info
);
}
static
void
dump_get_new_process_info_reply
(
const
struct
get_new_process_info_reply
*
req
)
{
fprintf
(
stderr
,
" pid=%04x,"
,
req
->
pid
);
fprintf
(
stderr
,
" phandle=%p,"
,
req
->
phandle
);
fprintf
(
stderr
,
" tid=%04x,"
,
req
->
tid
);
fprintf
(
stderr
,
" thandle=%p,"
,
req
->
thandle
);
fprintf
(
stderr
,
" success=%d"
,
req
->
success
);
fprintf
(
stderr
,
" success=%d,"
,
req
->
success
);
fprintf
(
stderr
,
" exit_code=%d"
,
req
->
exit_code
);
}
static
void
dump_new_thread_request
(
const
struct
new_thread_request
*
req
)
...
...
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