ntdll: Move the wineserver exec support to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
67bc4a6d76
commit
dec38ffb07
|
@ -99,7 +99,6 @@ extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
|
|||
extern void init_unix_codepage(void) DECLSPEC_HIDDEN;
|
||||
extern void init_locale( HMODULE module ) DECLSPEC_HIDDEN;
|
||||
extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN;
|
||||
extern void init_paths(void) DECLSPEC_HIDDEN;
|
||||
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -127,8 +127,6 @@ const char *build_dir = NULL;
|
|||
const char *data_dir = NULL;
|
||||
const char *config_dir = NULL;
|
||||
static const char *server_dir;
|
||||
static const char *bin_dir;
|
||||
static const char *argv0;
|
||||
|
||||
unsigned int server_cpus = 0;
|
||||
BOOL is_wow64 = FALSE;
|
||||
|
@ -191,47 +189,6 @@ static void fatal_perror( const char *err, ... )
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/* canonicalize path and return its directory name */
|
||||
static char *realpath_dirname( const char *name )
|
||||
{
|
||||
char *p, *fullpath = realpath( name, NULL );
|
||||
|
||||
if (fullpath)
|
||||
{
|
||||
p = strrchr( fullpath, '/' );
|
||||
if (p == fullpath) p++;
|
||||
if (p) *p = 0;
|
||||
}
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
/* if string ends with tail, remove it */
|
||||
static char *remove_tail( const char *str, const char *tail )
|
||||
{
|
||||
size_t len = strlen( str );
|
||||
size_t tail_len = strlen( tail );
|
||||
char *ret;
|
||||
|
||||
if (len < tail_len) return NULL;
|
||||
if (strcmp( str + len - tail_len, tail )) return NULL;
|
||||
ret = malloc( len - tail_len + 1 );
|
||||
memcpy( ret, str, len - tail_len );
|
||||
ret[len - tail_len] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* build a path from the specified dir and name */
|
||||
static char *build_path( const char *dir, const char *name )
|
||||
{
|
||||
size_t len = strlen( dir );
|
||||
char *ret = malloc( len + strlen( name ) + 2 );
|
||||
|
||||
memcpy( ret, dir, len );
|
||||
if (len && ret[len - 1] != '/') ret[len++] = '/';
|
||||
strcpy( ret + len, name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* server_protocol_error
|
||||
*/
|
||||
|
@ -1223,83 +1180,6 @@ int server_pipe( int fd[2] )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* exec_wineserver
|
||||
*
|
||||
* Exec a new wine server.
|
||||
*/
|
||||
static void exec_wineserver( char **argv )
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (build_dir)
|
||||
{
|
||||
if (!is_win64) /* look for 64-bit server */
|
||||
{
|
||||
char *loader = realpath_dirname( build_path( build_dir, "loader/wine64" ));
|
||||
if (loader)
|
||||
{
|
||||
argv[0] = build_path( loader, "../server/wineserver" );
|
||||
execv( argv[0], argv );
|
||||
}
|
||||
}
|
||||
argv[0] = build_path( build_dir, "server/wineserver" );
|
||||
execv( argv[0], argv );
|
||||
return;
|
||||
}
|
||||
|
||||
argv[0] = build_path( bin_dir, "wineserver" );
|
||||
execv( argv[0], argv );
|
||||
|
||||
argv[0] = getenv( "WINESERVER" );
|
||||
if (argv[0]) execv( argv[0], argv );
|
||||
|
||||
if ((path = getenv( "PATH" )))
|
||||
{
|
||||
for (path = strtok( strdup( path ), ":" ); path; path = strtok( NULL, ":" ))
|
||||
{
|
||||
argv[0] = build_path( path, "wineserver" );
|
||||
execvp( argv[0], argv );
|
||||
}
|
||||
}
|
||||
|
||||
argv[0] = build_path( BINDIR, "wineserver" );
|
||||
execv( argv[0], argv );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* start_server
|
||||
*
|
||||
* Start a new wine server.
|
||||
*/
|
||||
static void start_server(void)
|
||||
{
|
||||
static BOOL started; /* we only try once */
|
||||
char *argv[3];
|
||||
static char debug[] = "-d";
|
||||
|
||||
if (!started)
|
||||
{
|
||||
int status;
|
||||
int pid = fork();
|
||||
if (pid == -1) fatal_perror( "fork" );
|
||||
if (!pid)
|
||||
{
|
||||
argv[1] = TRACE_ON(server) ? debug : NULL;
|
||||
argv[2] = NULL;
|
||||
exec_wineserver( argv );
|
||||
fatal_error( "could not exec wineserver\n" );
|
||||
}
|
||||
waitpid( pid, &status, 0 );
|
||||
status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
|
||||
if (status == 2) return; /* server lock held by someone else, will retry later */
|
||||
if (status) exit(status); /* server failed */
|
||||
started = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* init_server_dir
|
||||
*/
|
||||
|
@ -1332,43 +1212,6 @@ static const char *init_server_dir( dev_t dev, ino_t ino )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* init_paths
|
||||
*/
|
||||
void init_paths(void)
|
||||
{
|
||||
const char *dll_dir = NULL;
|
||||
|
||||
#ifdef HAVE_DLADDR
|
||||
Dl_info info;
|
||||
|
||||
if (dladdr( init_paths, &info ) && info.dli_fname[0] == '/')
|
||||
dll_dir = realpath_dirname( info.dli_fname );
|
||||
#endif
|
||||
|
||||
argv0 = strdup( __wine_main_argv[0] );
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
|
||||
bin_dir = realpath_dirname( "/proc/self/exe" );
|
||||
#elif defined (__FreeBSD__) || defined(__DragonFly__)
|
||||
bin_dir = realpath_dirname( "/proc/curproc/file" );
|
||||
#else
|
||||
bin_dir = realpath_dirname( argv0 );
|
||||
#endif
|
||||
|
||||
if (dll_dir) build_dir = remove_tail( dll_dir, "/dlls/ntdll" );
|
||||
else if (bin_dir) build_dir = remove_tail( bin_dir, "/loader" );
|
||||
|
||||
if (!build_dir)
|
||||
{
|
||||
if (!bin_dir) bin_dir = dll_dir ? build_path( dll_dir, DLL_TO_BINDIR ) : BINDIR;
|
||||
else if (!dll_dir) dll_dir = build_path( bin_dir, BIN_TO_DLLDIR );
|
||||
}
|
||||
|
||||
unix_funcs->get_paths( &build_dir, &data_dir, &config_dir );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* setup_config_dir
|
||||
*
|
||||
|
@ -1467,7 +1310,7 @@ static int server_connect(void)
|
|||
if (chdir( server_dir ) == -1)
|
||||
{
|
||||
if (errno != ENOENT) fatal_perror( "chdir to %s", server_dir );
|
||||
start_server();
|
||||
unix_funcs->start_server( TRACE_ON(server) );
|
||||
if (chdir( server_dir ) == -1) fatal_perror( "chdir to %s", server_dir );
|
||||
}
|
||||
|
||||
|
@ -1482,13 +1325,13 @@ static int server_connect(void)
|
|||
if (retry)
|
||||
{
|
||||
usleep( 100000 * retry * retry );
|
||||
start_server();
|
||||
unix_funcs->start_server( TRACE_ON(server) );
|
||||
if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */
|
||||
}
|
||||
else if (lstat( SOCKETNAME, &st ) == -1) /* check for an already existing socket */
|
||||
{
|
||||
if (errno != ENOENT) fatal_perror( "lstat %s/%s", server_dir, SOCKETNAME );
|
||||
start_server();
|
||||
unix_funcs->start_server( TRACE_ON(server) );
|
||||
if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */
|
||||
}
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ TEB *thread_init(void)
|
|||
thread_data->wait_fd[1] = -1;
|
||||
|
||||
unix_funcs->dbg_init();
|
||||
init_paths();
|
||||
unix_funcs->get_paths( &build_dir, &data_dir, &config_dir );
|
||||
set_process_name( __wine_main_argc, __wine_main_argv );
|
||||
|
||||
/* initialize time values in user_shared_data */
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <CoreFoundation/CoreFoundation.h>
|
||||
# define LoadResource MacLoadResource
|
||||
|
@ -484,6 +487,83 @@ static NTSTATUS CDECL exec_wineloader( char **argv, int socketfd, int is_child_6
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* exec_wineserver
|
||||
*
|
||||
* Exec a new wine server.
|
||||
*/
|
||||
static void exec_wineserver( char **argv )
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (build_dir)
|
||||
{
|
||||
if (!is_win64) /* look for 64-bit server */
|
||||
{
|
||||
char *loader = realpath_dirname( build_path( build_dir, "loader/wine64" ));
|
||||
if (loader)
|
||||
{
|
||||
argv[0] = build_path( loader, "../server/wineserver" );
|
||||
execv( argv[0], argv );
|
||||
}
|
||||
}
|
||||
argv[0] = build_path( build_dir, "server/wineserver" );
|
||||
execv( argv[0], argv );
|
||||
return;
|
||||
}
|
||||
|
||||
argv[0] = build_path( bin_dir, "wineserver" );
|
||||
execv( argv[0], argv );
|
||||
|
||||
argv[0] = getenv( "WINESERVER" );
|
||||
if (argv[0]) execv( argv[0], argv );
|
||||
|
||||
if ((path = getenv( "PATH" )))
|
||||
{
|
||||
for (path = strtok( strdup( path ), ":" ); path; path = strtok( NULL, ":" ))
|
||||
{
|
||||
argv[0] = build_path( path, "wineserver" );
|
||||
execvp( argv[0], argv );
|
||||
}
|
||||
}
|
||||
|
||||
argv[0] = build_path( BINDIR, "wineserver" );
|
||||
execv( argv[0], argv );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* start_server
|
||||
*
|
||||
* Start a new wine server.
|
||||
*/
|
||||
static void CDECL start_server( BOOL debug )
|
||||
{
|
||||
static BOOL started; /* we only try once */
|
||||
char *argv[3];
|
||||
static char debug_flag[] = "-d";
|
||||
|
||||
if (!started)
|
||||
{
|
||||
int status;
|
||||
int pid = fork();
|
||||
if (pid == -1) fatal_error( "fork: %s", strerror(errno) );
|
||||
if (!pid)
|
||||
{
|
||||
argv[1] = debug ? debug_flag : NULL;
|
||||
argv[2] = NULL;
|
||||
exec_wineserver( argv );
|
||||
fatal_error( "could not exec wineserver\n" );
|
||||
}
|
||||
waitpid( pid, &status, 0 );
|
||||
status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
|
||||
if (status == 2) return; /* server lock held by someone else, will retry later */
|
||||
if (status) exit(status); /* server failed */
|
||||
started = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* map_so_dll
|
||||
*
|
||||
|
@ -760,6 +840,7 @@ static struct unix_funcs unix_funcs =
|
|||
get_build_id,
|
||||
get_host_version,
|
||||
exec_wineloader,
|
||||
start_server,
|
||||
map_so_dll,
|
||||
mmap_add_reserved_area,
|
||||
mmap_remove_reserved_area,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "wine/debug.h"
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 5
|
||||
#define NTDLL_UNIXLIB_VERSION 6
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -39,6 +39,7 @@ struct unix_funcs
|
|||
/* loader functions */
|
||||
NTSTATUS (CDECL *exec_wineloader)( char **argv, int socketfd, int is_child_64bit,
|
||||
ULONGLONG res_start, ULONGLONG res_end );
|
||||
void (CDECL *start_server)( BOOL debug );
|
||||
|
||||
/* virtual memory functions */
|
||||
NTSTATUS (CDECL *map_so_dll)( const IMAGE_NT_HEADERS *nt_descr, HMODULE module );
|
||||
|
|
Loading…
Reference in New Issue