forked from Mirrors/wine-wine
Made server launching somewhat cleaner and faster.
parent
35870f95a0
commit
d804111dc5
|
@ -17,6 +17,9 @@
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#ifdef HAVE_SYS_MMAN_H
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -54,6 +57,7 @@ static void *boot_thread_id;
|
||||||
|
|
||||||
|
|
||||||
/* die on a fatal error; use only during initialization */
|
/* die on a fatal error; use only during initialization */
|
||||||
|
static void fatal_error( const char *err, ... ) WINE_NORETURN;
|
||||||
static void fatal_error( const char *err, ... )
|
static void fatal_error( const char *err, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -66,6 +70,7 @@ static void fatal_error( const char *err, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* die on a fatal error; use only during initialization */
|
/* die on a fatal error; use only during initialization */
|
||||||
|
static void fatal_perror( const char *err, ... ) WINE_NORETURN;
|
||||||
static void fatal_perror( const char *err, ... )
|
static void fatal_perror( const char *err, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -334,6 +339,7 @@ static void start_server( const char *oldcwd )
|
||||||
static int started; /* we only try once */
|
static int started; /* we only try once */
|
||||||
if (!started)
|
if (!started)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
if (pid == -1) fatal_perror( "fork" );
|
if (pid == -1) fatal_perror( "fork" );
|
||||||
if (!pid)
|
if (!pid)
|
||||||
|
@ -359,6 +365,9 @@ static void start_server( const char *oldcwd )
|
||||||
fatal_error( "could not exec wineserver\n" );
|
fatal_error( "could not exec wineserver\n" );
|
||||||
}
|
}
|
||||||
started = 1;
|
started = 1;
|
||||||
|
waitpid( pid, &status, 0 );
|
||||||
|
status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
|
||||||
|
if (status) exit(status); /* server failed */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,27 +383,34 @@ static int server_connect( const char *oldcwd, const char *serverdir )
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int s, slen;
|
int s, slen;
|
||||||
|
|
||||||
|
/* chdir to the server directory */
|
||||||
if (chdir( serverdir ) == -1)
|
if (chdir( serverdir ) == -1)
|
||||||
{
|
{
|
||||||
if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
|
if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
|
||||||
start_server( NULL );
|
start_server( NULL );
|
||||||
return -1;
|
if (chdir( serverdir ) == -1) fatal_perror( "chdir to %s", serverdir );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure we are at the right place */
|
||||||
if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
|
if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
|
||||||
if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
|
if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
|
||||||
if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );
|
if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );
|
||||||
|
|
||||||
|
/* check for an existing socket */
|
||||||
if (lstat( SOCKETNAME, &st ) == -1)
|
if (lstat( SOCKETNAME, &st ) == -1)
|
||||||
{
|
{
|
||||||
if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
|
if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
|
||||||
start_server( oldcwd );
|
start_server( oldcwd );
|
||||||
return -1;
|
if (lstat( SOCKETNAME, &st ) == -1) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure the socket is sane */
|
||||||
if (!S_ISSOCK(st.st_mode))
|
if (!S_ISSOCK(st.st_mode))
|
||||||
fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
|
fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
|
||||||
if (st.st_uid != getuid())
|
if (st.st_uid != getuid())
|
||||||
fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
|
fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
|
||||||
|
|
||||||
|
/* try to connect to it */
|
||||||
if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
|
if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
strcpy( addr.sun_path, SOCKETNAME );
|
strcpy( addr.sun_path, SOCKETNAME );
|
||||||
|
@ -404,8 +420,12 @@ static int server_connect( const char *oldcwd, const char *serverdir )
|
||||||
#endif
|
#endif
|
||||||
if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
|
if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
|
||||||
{
|
{
|
||||||
close( s );
|
usleep( 50000 ); /* in case the server was starting right now */
|
||||||
return -2;
|
if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
|
||||||
|
fatal_error( "'%s/%s' exists,\n"
|
||||||
|
" but I cannot connect to it; maybe the server has crashed?\n"
|
||||||
|
" If this is the case, you should remove the socket file and try again.\n",
|
||||||
|
serverdir, SOCKETNAME );
|
||||||
}
|
}
|
||||||
fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
|
fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
|
||||||
return s;
|
return s;
|
||||||
|
@ -419,7 +439,7 @@ static int server_connect( const char *oldcwd, const char *serverdir )
|
||||||
*/
|
*/
|
||||||
int CLIENT_InitServer(void)
|
int CLIENT_InitServer(void)
|
||||||
{
|
{
|
||||||
int delay, fd, size;
|
int fd, size;
|
||||||
const char *env_fd;
|
const char *env_fd;
|
||||||
char hostname[64];
|
char hostname[64];
|
||||||
char *oldcwd, *serverdir;
|
char *oldcwd, *serverdir;
|
||||||
|
@ -452,23 +472,9 @@ int CLIENT_InitServer(void)
|
||||||
strcat( serverdir, SERVERDIR );
|
strcat( serverdir, SERVERDIR );
|
||||||
strcat( serverdir, hostname );
|
strcat( serverdir, hostname );
|
||||||
|
|
||||||
/* try to connect, leaving some time for the server to start up */
|
/* connect to the server */
|
||||||
for (delay = 10000; delay < 500000; delay += delay / 2)
|
fd = server_connect( oldcwd, serverdir );
|
||||||
{
|
|
||||||
if ((fd = server_connect( oldcwd, serverdir )) >= 0) goto done;
|
|
||||||
usleep( delay );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd == -2)
|
|
||||||
{
|
|
||||||
fatal_error( "'%s/%s' exists,\n"
|
|
||||||
" but I cannot connect to it; maybe the server has crashed?\n"
|
|
||||||
" If this is the case, you should remove the socket file and try again.\n",
|
|
||||||
serverdir, SOCKETNAME );
|
|
||||||
}
|
|
||||||
fatal_error( "could not start wineserver, giving up\n" );
|
|
||||||
|
|
||||||
done:
|
|
||||||
/* switch back to the starting directory */
|
/* switch back to the starting directory */
|
||||||
if (oldcwd)
|
if (oldcwd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,19 +60,6 @@ static void sigterm_handler()
|
||||||
/* initialize signal handling */
|
/* initialize signal handling */
|
||||||
static void signal_init(void)
|
static void signal_init(void)
|
||||||
{
|
{
|
||||||
if (!debug_level)
|
|
||||||
{
|
|
||||||
switch(fork())
|
|
||||||
{
|
|
||||||
case -1:
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
setsid();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signal( SIGPIPE, SIG_IGN );
|
signal( SIGPIPE, SIG_IGN );
|
||||||
signal( SIGHUP, sigterm_handler );
|
signal( SIGHUP, sigterm_handler );
|
||||||
signal( SIGINT, sigterm_handler );
|
signal( SIGINT, sigterm_handler );
|
||||||
|
|
|
@ -103,6 +103,7 @@ void fatal_protocol_error( struct thread *thread, const char *err, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* die on a fatal error */
|
/* die on a fatal error */
|
||||||
|
static void fatal_error( const char *err, ... ) WINE_NORETURN;
|
||||||
static void fatal_error( const char *err, ... )
|
static void fatal_error( const char *err, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -115,6 +116,7 @@ static void fatal_error( const char *err, ... )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* die on a fatal error */
|
/* die on a fatal error */
|
||||||
|
static void fatal_perror( const char *err, ... ) WINE_NORETURN;
|
||||||
static void fatal_perror( const char *err, ... )
|
static void fatal_perror( const char *err, ... )
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -392,6 +394,18 @@ void open_master_socket(void)
|
||||||
if (!(master_socket = alloc_object( &master_socket_ops, fd )))
|
if (!(master_socket = alloc_object( &master_socket_ops, fd )))
|
||||||
fatal_error( "out of memory\n" );
|
fatal_error( "out of memory\n" );
|
||||||
set_select_events( &master_socket->obj, POLLIN );
|
set_select_events( &master_socket->obj, POLLIN );
|
||||||
|
|
||||||
|
/* go in the background */
|
||||||
|
switch(fork())
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
fatal_perror( "fork" );
|
||||||
|
case 0:
|
||||||
|
setsid();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_exit(0); /* do not call atexit functions */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close the master socket and stop waiting for new clients */
|
/* close the master socket and stop waiting for new clients */
|
||||||
|
|
Loading…
Reference in New Issue