2 * Client part of the client/server communication
4 * Copyright (C) 1998 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
34 #include <sys/types.h>
35 #ifdef HAVE_SYS_SOCKET_H
36 # include <sys/socket.h>
38 #ifdef HAVE_SYS_WAIT_H
42 #ifdef HAVE_SYS_MMAN_H
51 #include "wine/library.h"
52 #include "wine/server.h"
56 /* Some versions of glibc don't define this */
61 #define SOCKETNAME "socket" /* name of the socket file */
62 #define LOCKNAME "lock" /* name of the lock file */
64 #ifndef HAVE_MSGHDR_ACCRIGHTS
65 /* data structure used to pass an fd with sendmsg/recvmsg */
68 int len; /* sizeof structure */
69 int level; /* SOL_SOCKET */
70 int type; /* SCM_RIGHTS */
71 int fd; /* fd to pass */
73 #endif /* HAVE_MSGHDR_ACCRIGHTS */
75 static void *boot_thread_id;
76 static sigset_t block_set; /* signals to block during server calls */
77 static int fd_socket; /* socket to exchange file descriptors with the server */
80 static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
81 static void fatal_perror( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
82 static void server_connect_error( const char *serverdir ) __attribute__((noreturn));
85 /* die on a fatal error; use only during initialization */
86 static void fatal_error( const char *err, ... )
90 va_start( args, err );
91 fprintf( stderr, "wine: " );
92 vfprintf( stderr, err, args );
97 /* die on a fatal error; use only during initialization */
98 static void fatal_perror( const char *err, ... )
102 va_start( args, err );
103 fprintf( stderr, "wine: " );
104 vfprintf( stderr, err, args );
110 /***********************************************************************
111 * server_protocol_error
113 void server_protocol_error( const char *err, ... )
117 va_start( args, err );
118 fprintf( stderr, "wine client error:%p: ", NtCurrentTeb()->tid );
119 vfprintf( stderr, err, args );
121 SYSDEPS_AbortThread(1);
125 /***********************************************************************
126 * server_protocol_perror
128 void server_protocol_perror( const char *err )
130 fprintf( stderr, "wine client error:%p: ", NtCurrentTeb()->tid );
132 SYSDEPS_AbortThread(1);
136 /***********************************************************************
139 * Send a request to the server.
141 static void send_request( const struct __server_request_info *req )
145 if (!req->u.req.request_header.request_size)
147 if ((ret = write( NtCurrentTeb()->request_fd, &req->u.req,
148 sizeof(req->u.req) )) == sizeof(req->u.req)) return;
153 struct iovec vec[__SERVER_MAX_DATA+1];
155 vec[0].iov_base = (void *)&req->u.req;
156 vec[0].iov_len = sizeof(req->u.req);
157 for (i = 0; i < req->data_count; i++)
159 vec[i+1].iov_base = (void *)req->data[i].ptr;
160 vec[i+1].iov_len = req->data[i].size;
162 if ((ret = writev( NtCurrentTeb()->request_fd, vec, i+1 )) ==
163 req->u.req.request_header.request_size + sizeof(req->u.req)) return;
166 if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
167 if (errno == EPIPE) SYSDEPS_AbortThread(0);
168 server_protocol_perror( "sendmsg" );
172 /***********************************************************************
175 * Read data from the reply buffer; helper for wait_reply.
177 static void read_reply_data( void *buffer, size_t size )
183 if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0)
185 if (!(size -= ret)) return;
186 buffer = (char *)buffer + ret;
190 if (errno == EINTR) continue;
191 if (errno == EPIPE) break;
192 server_protocol_perror("read");
194 /* the server closed the connection; time to die... */
195 SYSDEPS_AbortThread(0);
199 /***********************************************************************
202 * Wait for a reply from the server.
204 inline static void wait_reply( struct __server_request_info *req )
206 read_reply_data( &req->u.reply, sizeof(req->u.reply) );
207 if (req->u.reply.reply_header.reply_size)
208 read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
212 /***********************************************************************
213 * wine_server_call (NTDLL.@)
215 * Perform a server call.
217 unsigned int wine_server_call( void *req_ptr )
219 struct __server_request_info * const req = req_ptr;
222 memset( (char *)&req->u.req + req->size, 0, sizeof(req->u.req) - req->size );
223 sigprocmask( SIG_BLOCK, &block_set, &old_set );
226 sigprocmask( SIG_SETMASK, &old_set, NULL );
227 return req->u.reply.reply_header.error;
231 /***********************************************************************
232 * wine_server_send_fd
234 * Send a file descriptor to the server.
236 void wine_server_send_fd( int fd )
238 #ifndef HAVE_MSGHDR_ACCRIGHTS
242 struct msghdr msghdr;
246 vec.iov_base = (void *)&data;
247 vec.iov_len = sizeof(data);
249 msghdr.msg_name = NULL;
250 msghdr.msg_namelen = 0;
251 msghdr.msg_iov = &vec;
252 msghdr.msg_iovlen = 1;
254 #ifdef HAVE_MSGHDR_ACCRIGHTS
255 msghdr.msg_accrights = (void *)&fd;
256 msghdr.msg_accrightslen = sizeof(fd);
257 #else /* HAVE_MSGHDR_ACCRIGHTS */
258 cmsg.len = sizeof(cmsg);
259 cmsg.level = SOL_SOCKET;
260 cmsg.type = SCM_RIGHTS;
262 msghdr.msg_control = &cmsg;
263 msghdr.msg_controllen = sizeof(cmsg);
264 msghdr.msg_flags = 0;
265 #endif /* HAVE_MSGHDR_ACCRIGHTS */
267 data.tid = (void *)GetCurrentThreadId();
272 if ((ret = sendmsg( fd_socket, &msghdr, 0 )) == sizeof(data)) return;
273 if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
274 if (errno == EINTR) continue;
275 if (errno == EPIPE) SYSDEPS_AbortThread(0);
276 server_protocol_perror( "sendmsg" );
281 /***********************************************************************
284 * Receive a file descriptor passed from the server.
286 static int receive_fd( obj_handle_t *handle )
291 #ifdef HAVE_MSGHDR_ACCRIGHTS
292 struct msghdr msghdr;
295 msghdr.msg_accrights = (void *)&fd;
296 msghdr.msg_accrightslen = sizeof(fd);
297 #else /* HAVE_MSGHDR_ACCRIGHTS */
298 struct msghdr msghdr;
301 cmsg.len = sizeof(cmsg);
302 cmsg.level = SOL_SOCKET;
303 cmsg.type = SCM_RIGHTS;
305 msghdr.msg_control = &cmsg;
306 msghdr.msg_controllen = sizeof(cmsg);
307 msghdr.msg_flags = 0;
308 #endif /* HAVE_MSGHDR_ACCRIGHTS */
310 msghdr.msg_name = NULL;
311 msghdr.msg_namelen = 0;
312 msghdr.msg_iov = &vec;
313 msghdr.msg_iovlen = 1;
314 vec.iov_base = (void *)handle;
315 vec.iov_len = sizeof(*handle);
319 if ((ret = recvmsg( fd_socket, &msghdr, 0 )) > 0)
321 #ifndef HAVE_MSGHDR_ACCRIGHTS
324 if (fd == -1) server_protocol_error( "no fd received for handle %d\n", *handle );
325 fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
329 if (errno == EINTR) continue;
330 if (errno == EPIPE) break;
331 server_protocol_perror("recvmsg");
333 /* the server closed the connection; time to die... */
334 SYSDEPS_AbortThread(0);
338 /***********************************************************************
341 * Store the cached fd value for a given handle back into the server.
342 * Returns the new fd, which can be different if there was already an
343 * fd in the cache for that handle.
345 inline static int store_cached_fd( int fd, obj_handle_t handle )
347 SERVER_START_REQ( set_handle_info )
349 req->handle = handle;
353 if (!wine_server_call( req ))
355 if (reply->cur_fd != fd)
357 /* someone was here before us */
373 /***********************************************************************
374 * wine_server_fd_to_handle (NTDLL.@)
376 * Allocate a file handle for a Unix fd.
378 int wine_server_fd_to_handle( int fd, unsigned int access, int inherit, obj_handle_t *handle )
383 wine_server_send_fd( fd );
385 SERVER_START_REQ( alloc_file_handle )
387 req->access = access;
388 req->inherit = inherit;
390 if (!(ret = wine_server_call( req ))) *handle = reply->handle;
397 /***********************************************************************
398 * wine_server_handle_to_fd (NTDLL.@)
400 * Retrieve the Unix fd corresponding to a file handle.
402 int wine_server_handle_to_fd( obj_handle_t handle, unsigned int access, int *unix_fd,
403 enum fd_type *type, int *flags )
405 obj_handle_t fd_handle;
411 SERVER_START_REQ( get_handle_fd )
413 req->handle = handle;
414 req->access = access;
415 if (!(ret = wine_server_call( req ))) fd = reply->fd;
416 if (type) *type = reply->type;
417 if (flags) *flags = reply->flags;
424 /* it wasn't in the cache, get it from the server */
425 fd = receive_fd( &fd_handle );
426 /* and store it back into the cache */
427 fd = store_cached_fd( fd, fd_handle );
429 if (fd_handle == handle) break;
430 /* if we received a different handle this means there was
431 * a race with another thread; we restart everything from
432 * scratch in this case.
436 if ((fd != -1) && ((fd = dup(fd)) == -1)) return STATUS_TOO_MANY_OPENED_FILES;
438 return STATUS_SUCCESS;
442 /***********************************************************************
445 * Start a new wine server.
447 static void start_server( const char *oldcwd )
449 static int started; /* we only try once */
455 if (pid == -1) fatal_perror( "fork" );
458 /* if server is explicitly specified, use this */
459 if ((p = getenv("WINESERVER")))
461 if (p[0] != '/' && oldcwd[0] == '/') /* make it an absolute path */
463 if (!(path = malloc( strlen(oldcwd) + strlen(p) + 1 )))
464 fatal_error( "out of memory\n" );
465 sprintf( path, "%s/%s", oldcwd, p );
469 fatal_perror( "could not exec the server '%s'\n"
470 " specified in the WINESERVER environment variable", p );
473 /* first try the installation dir */
474 execl( BINDIR "/wineserver", "wineserver", NULL );
476 /* now try the dir we were launched from */
479 if (!(path = malloc( strlen(full_argv0) + 20 )))
480 fatal_error( "out of memory\n" );
481 if ((p = strrchr( strcpy( path, full_argv0 ), '/' )))
483 strcpy( p, "/wineserver" );
484 execl( path, path, NULL );
489 /* finally try the path */
490 execlp( "wineserver", "wineserver", NULL );
491 fatal_error( "could not exec wineserver\n" );
493 waitpid( pid, &status, 0 );
494 status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
495 if (status == 2) return; /* server lock held by someone else, will retry later */
496 if (status) exit(status); /* server failed */
502 /***********************************************************************
503 * server_connect_error
505 * Try to display a meaningful explanation of why we couldn't connect
508 static void server_connect_error( const char *serverdir )
513 if ((fd = open( LOCKNAME, O_WRONLY )) == -1)
514 fatal_error( "for some mysterious reason, the wine server never started.\n" );
517 fl.l_whence = SEEK_SET;
520 if (fcntl( fd, F_GETLK, &fl ) != -1)
522 if (fl.l_type == F_WRLCK) /* the file is locked */
523 fatal_error( "a wine server seems to be running, but I cannot connect to it.\n"
524 " You probably need to kill that process (it might be pid %d).\n",
526 fatal_error( "for some mysterious reason, the wine server failed to run.\n" );
528 fatal_error( "the file system of '%s' doesn't support locks,\n"
529 " and there is a 'socket' file in that directory that prevents wine from starting.\n"
530 " You should make sure no wine server is running, remove that file and try again.\n",
535 /***********************************************************************
538 * Attempt to connect to an existing server socket.
539 * We need to be in the server directory already.
541 static int server_connect( const char *oldcwd, const char *serverdir )
543 struct sockaddr_un addr;
547 /* chdir to the server directory */
548 if (chdir( serverdir ) == -1)
550 if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
552 if (chdir( serverdir ) == -1) fatal_perror( "chdir to %s", serverdir );
555 /* make sure we are at the right place */
556 if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
557 if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
558 if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );
560 for (retry = 0; retry < 6; retry++)
562 /* if not the first try, wait a bit to leave the previous server time to exit */
565 usleep( 100000 * retry * retry );
566 start_server( oldcwd );
567 if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */
569 else if (lstat( SOCKETNAME, &st ) == -1) /* check for an already existing socket */
571 if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
572 start_server( oldcwd );
573 if (lstat( SOCKETNAME, &st ) == -1) continue; /* still no socket, wait a bit more */
576 /* make sure the socket is sane (ISFIFO needed for Solaris) */
577 if (!S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode))
578 fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
579 if (st.st_uid != getuid())
580 fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
582 /* try to connect to it */
583 addr.sun_family = AF_UNIX;
584 strcpy( addr.sun_path, SOCKETNAME );
585 slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
586 #ifdef HAVE_SOCKADDR_SUN_LEN
589 if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
590 if (connect( s, (struct sockaddr *)&addr, slen ) != -1)
592 fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
597 server_connect_error( serverdir );
601 /***********************************************************************
604 * Start the server and create the initial socket pair.
606 void CLIENT_InitServer(void)
610 obj_handle_t dummy_handle;
612 /* retrieve the current directory */
613 for (size = 512; ; size *= 2)
615 if (!(oldcwd = malloc( size ))) break;
616 if (getcwd( oldcwd, size )) break;
618 if (errno == ERANGE) continue;
623 /* if argv[0] is a relative path, make it absolute */
625 if (oldcwd && argv0[0] != '/' && strchr( argv0, '/' ))
627 char *new_argv0 = malloc( strlen(oldcwd) + strlen(argv0) + 2 );
630 strcpy( new_argv0, oldcwd );
631 strcat( new_argv0, "/" );
632 strcat( new_argv0, argv0 );
633 full_argv0 = new_argv0;
637 /* connect to the server */
638 fd_socket = server_connect( oldcwd, wine_get_server_dir() );
640 /* switch back to the starting directory */
647 /* setup the signal mask */
648 sigemptyset( &block_set );
649 sigaddset( &block_set, SIGALRM );
650 sigaddset( &block_set, SIGIO );
651 sigaddset( &block_set, SIGINT );
652 sigaddset( &block_set, SIGHUP );
654 /* receive the first thread request fd on the main socket */
655 NtCurrentTeb()->request_fd = receive_fd( &dummy_handle );
661 /***********************************************************************
664 * Send an init thread request. Return 0 if OK.
666 void CLIENT_InitThread(void)
668 TEB *teb = NtCurrentTeb();
672 /* ignore SIGPIPE so that we get a EPIPE error instead */
673 signal( SIGPIPE, SIG_IGN );
674 /* automatic child reaping to avoid zombies */
675 signal( SIGCHLD, SIG_IGN );
677 /* create the server->client communication pipes */
678 if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
679 if (pipe( teb->wait_fd ) == -1) server_protocol_perror( "pipe" );
680 wine_server_send_fd( reply_pipe[1] );
681 wine_server_send_fd( teb->wait_fd[1] );
682 teb->reply_fd = reply_pipe[0];
683 close( reply_pipe[1] );
685 /* set close on exec flag */
686 fcntl( teb->reply_fd, F_SETFD, 1 );
687 fcntl( teb->wait_fd[0], F_SETFD, 1 );
688 fcntl( teb->wait_fd[1], F_SETFD, 1 );
690 SERVER_START_REQ( init_thread )
692 req->unix_pid = getpid();
694 req->entry = teb->entry_point;
695 req->reply_fd = reply_pipe[1];
696 req->wait_fd = teb->wait_fd[1];
697 ret = wine_server_call( req );
698 teb->pid = reply->pid;
699 teb->tid = reply->tid;
700 version = reply->version;
701 if (reply->boot) boot_thread_id = teb->tid;
702 else if (boot_thread_id == teb->tid) boot_thread_id = 0;
706 if (ret) server_protocol_error( "init_thread failed with status %x\n", ret );
707 if (version != SERVER_PROTOCOL_VERSION)
708 server_protocol_error( "version mismatch %d/%d.\n"
709 "Your %s binary was not upgraded correctly,\n"
710 "or you have an older one somewhere in your PATH.\n"
711 "Or maybe the wrong wineserver is still running?\n",
712 version, SERVER_PROTOCOL_VERSION,
713 (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
717 /***********************************************************************
720 * Signal that we have finished booting, and set debug level.
722 void CLIENT_BootDone( int debug_level )
724 SERVER_START_REQ( boot_done )
726 req->debug_level = debug_level;
727 wine_server_call( req );
733 /***********************************************************************
734 * CLIENT_IsBootThread
736 * Return TRUE if current thread is the boot thread.
738 int CLIENT_IsBootThread(void)
740 return (GetCurrentThreadId() == (DWORD)boot_thread_id);