diff --git a/server/mach.c b/server/mach.c index 9d8d911cb7c..e5a532dc6c0 100644 --- a/server/mach.c +++ b/server/mach.c @@ -90,7 +90,7 @@ void init_tracing_mechanism(void) server_mach_port, MACH_MSG_TYPE_MAKE_SEND ) != KERN_SUCCESS) fatal_error("Error inserting rights\n"); - if (bootstrap_register(bp, (char*)wine_get_server_dir(), server_mach_port) != KERN_SUCCESS) + if (bootstrap_register(bp, server_dir, server_mach_port) != KERN_SUCCESS) fatal_error("Can't check in server_mach_port\n"); mach_port_deallocate(mach_task_self(), bp); } diff --git a/server/request.c b/server/request.c index 5610d392cf9..4aad126eec2 100644 --- a/server/request.c +++ b/server/request.c @@ -127,6 +127,7 @@ static const struct fd_ops master_socket_fd_ops = struct thread *current = NULL; /* thread handling the current request */ unsigned int global_error = 0; /* global error code for when no thread is current */ timeout_t server_start_time = 0; /* server startup time */ +char *server_dir = NULL; /* server directory */ int server_dir_fd = -1; /* file descriptor for the server dir */ int config_dir_fd = -1; /* file descriptor for the config dir */ @@ -603,7 +604,7 @@ static void create_dir( const char *name, struct stat *st ) if (lstat( name, st ) == -1) { if (errno != ENOENT) - fatal_error( "lstat %s: %s", name, strerror( errno )); + fatal_error( "lstat %s: %s\n", name, strerror( errno )); if (mkdir( name, 0700 ) == -1 && errno != EEXIST) fatal_error( "mkdir %s: %s\n", name, strerror( errno )); if (lstat( name, st ) == -1) @@ -615,22 +616,52 @@ static void create_dir( const char *name, struct stat *st ) } /* create the server directory and chdir to it */ -static void create_server_dir( const char *dir ) +static char *create_server_dir( int force ) { - char *p, *server_dir; + const char *config_dir = wine_get_config_dir(); + char *p; struct stat st, st2; + size_t len = sizeof("/server-") + 2 * sizeof(st.st_dev) + 2 * sizeof(st.st_ino) + 2; - if (!(server_dir = strdup( dir ))) fatal_error( "out of memory\n" ); + if (chdir( config_dir ) == -1) + { + if (errno != ENOENT || force) fatal_error( "chdir to %s: %s\n", config_dir, strerror( errno )); + return NULL; + } + if ((config_dir_fd = open( ".", O_RDONLY )) == -1) + fatal_error( "open %s: %s\n", config_dir, strerror( errno )); - /* first create the base directory if needed */ + /* create the base directory if needed */ - p = strrchr( server_dir, '/' ); - *p = 0; - create_dir( server_dir, &st ); +#ifdef __ANDROID__ /* there's no /tmp dir on Android */ + len += strlen( config_dir ) + sizeof("/.wineserver"); + if (!(server_dir = malloc( len ))) fatal_error( "out of memory\n" ); + strcpy( server_dir, config_dir ); + strcat( server_dir, "/.wineserver" ); +#else + len += sizeof("/tmp/.wine-") + 12; + if (!(server_dir = malloc( len ))) fatal_error( "out of memory\n" ); + sprintf( server_dir, "/tmp/.wine-%u", getuid() ); +#endif + create_dir( server_dir, &st2 ); /* now create the server directory */ - *p = '/'; + strcat( server_dir, "/server-" ); + p = server_dir + strlen(server_dir); + + if (st.st_dev != (unsigned long)st.st_dev) + p += sprintf( p, "%lx%08lx-", (unsigned long)((unsigned long long)st.st_dev >> 32), + (unsigned long)st.st_dev ); + else + p += sprintf( p, "%lx-", (unsigned long)st.st_dev ); + + if (st.st_ino != (unsigned long)st.st_ino) + sprintf( p, "%lx%08lx", (unsigned long)((unsigned long long)st.st_ino >> 32), + (unsigned long)st.st_ino ); + else + sprintf( p, "%lx", (unsigned long)st.st_ino ); + create_dir( server_dir, &st ); if (chdir( server_dir ) == -1) @@ -642,7 +673,7 @@ static void create_server_dir( const char *dir ) if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino) fatal_error( "chdir did not end up in %s\n", server_dir ); - free( server_dir ); + return server_dir; } /* create the lock file and return its file descriptor */ @@ -654,29 +685,28 @@ static int create_server_lock(void) if (lstat( server_lock_name, &st ) == -1) { if (errno != ENOENT) - fatal_error( "lstat %s/%s: %s", wine_get_server_dir(), server_lock_name, strerror( errno )); + fatal_error( "lstat %s/%s: %s\n", server_dir, server_lock_name, strerror( errno )); } else { if (!S_ISREG(st.st_mode)) - fatal_error( "%s/%s is not a regular file\n", wine_get_server_dir(), server_lock_name ); + fatal_error( "%s/%s is not a regular file\n", server_dir, server_lock_name ); } if ((fd = open( server_lock_name, O_CREAT|O_TRUNC|O_WRONLY, 0600 )) == -1) - fatal_error( "error creating %s/%s: %s", wine_get_server_dir(), server_lock_name, strerror( errno )); + fatal_error( "error creating %s/%s: %s\n", server_dir, server_lock_name, strerror( errno )); return fd; } /* wait for the server lock */ int wait_for_lock(void) { - const char *server_dir = wine_get_server_dir(); int fd, r; struct flock fl; + server_dir = create_server_dir( 0 ); if (!server_dir) return 0; /* no server dir, so no lock to wait on */ - create_server_dir( server_dir ); fd = create_server_lock(); fl.l_type = F_WRLCK; @@ -692,14 +722,13 @@ int wait_for_lock(void) /* kill the wine server holding the lock */ int kill_lock_owner( int sig ) { - const char *server_dir = wine_get_server_dir(); int fd, i, ret = 0; pid_t pid = 0; struct flock fl; + server_dir = create_server_dir( 0 ); if (!server_dir) return 0; /* no server dir, nothing to do */ - create_server_dir( server_dir ); fd = create_server_lock(); for (i = 1; i <= 20; i++) @@ -760,7 +789,7 @@ static void acquire_lock(void) "Warning: a previous instance of the wine server seems to have crashed.\n" "Please run 'gdb %s %s/core',\n" "type 'backtrace' at the gdb prompt and report the results. Thanks.\n\n", - server_argv0, wine_get_server_dir() ); + server_argv0, server_dir ); } unlink( server_socket_name ); /* we got the lock, we can safely remove the socket */ got_lock = 1; @@ -780,7 +809,7 @@ static void acquire_lock(void) case EAGAIN: exit(2); /* we didn't get the lock, exit with special status */ default: - fatal_error( "fcntl %s/%s: %s", wine_get_server_dir(), server_lock_name, strerror( errno )); + fatal_error( "fcntl %s/%s: %s\n", server_dir, server_lock_name, strerror( errno )); } /* it seems we can't use locks on this fs, so we will use the socket existence as lock */ close( fd ); @@ -817,8 +846,6 @@ static void acquire_lock(void) /* open the master server socket and start waiting for new clients */ void open_master_socket(void) { - const char *server_dir = wine_get_server_dir(); - const char *config_dir = wine_get_config_dir(); int fd, pid, status, sync_pipe[2]; char dummy; @@ -830,14 +857,7 @@ void open_master_socket(void) fd = open( "/dev/null", O_RDWR ); while (fd >= 0 && fd <= 2) fd = dup( fd ); - if (!server_dir) - fatal_error( "directory %s cannot be accessed\n", config_dir ); - if (chdir( config_dir ) == -1) - fatal_error( "chdir to %s: %s\n", config_dir, strerror( errno )); - if ((config_dir_fd = open( ".", O_RDONLY )) == -1) - fatal_error( "open %s: %s\n", config_dir, strerror( errno )); - - create_server_dir( server_dir ); + server_dir = create_server_dir( 1 ); if (!foreground) { diff --git a/server/request.h b/server/request.h index 2930b31d723..90a3180a6c5 100644 --- a/server/request.h +++ b/server/request.h @@ -60,6 +60,7 @@ extern void close_master_socket( timeout_t timeout ); extern void shutdown_master_socket(void); extern int wait_for_lock(void); extern int kill_lock_owner( int sig ); +extern char *server_dir; extern int server_dir_fd, config_dir_fd; extern void trace_request(void);