Made server launching somewhat cleaner and faster.

oldstable
Alexandre Julliard 2000-04-14 14:42:41 +00:00
parent 35870f95a0
commit d804111dc5
3 changed files with 41 additions and 34 deletions

View File

@ -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)
{ {

View File

@ -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 );

View File

@ -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 */