Do not use the PEB lock as loader lock, use a separate critical
[wine] / scheduler / client.c
1 /*
2  * Client part of the client/server communication
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include "config.h"
8 #include "wine/port.h"
9
10 #include <assert.h>
11 #include <ctype.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <pwd.h>
15 #include <signal.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <sys/types.h>
19 #ifdef HAVE_SYS_SOCKET_H
20 # include <sys/socket.h>
21 #endif
22 #ifdef HAVE_SYS_WAIT_H
23 #include <sys/wait.h>
24 #endif
25 #include <sys/un.h>
26 #ifdef HAVE_SYS_MMAN_H
27 #include <sys/mman.h>
28 #endif
29 #include <sys/stat.h>
30 #include <sys/uio.h>
31 #include <unistd.h>
32 #include <stdarg.h>
33
34 #include "thread.h"
35 #include "wine/server.h"
36 #include "winerror.h"
37 #include "options.h"
38
39 /* Some versions of glibc don't define this */
40 #ifndef SCM_RIGHTS
41 #define SCM_RIGHTS 1
42 #endif
43
44 #define CONFDIR    "/.wine"        /* directory for Wine config relative to $HOME */
45 #define SERVERDIR  "/wineserver-"  /* server socket directory (hostname appended) */
46 #define SOCKETNAME "socket"        /* name of the socket file */
47
48 #ifndef HAVE_MSGHDR_ACCRIGHTS
49 /* data structure used to pass an fd with sendmsg/recvmsg */
50 struct cmsg_fd
51 {
52     int len;   /* sizeof structure */
53     int level; /* SOL_SOCKET */
54     int type;  /* SCM_RIGHTS */
55     int fd;    /* fd to pass */
56 };
57 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
58
59 static void *boot_thread_id;
60 static sigset_t block_set;  /* signals to block during server calls */
61 static int fd_socket;  /* socket to exchange file descriptors with the server */
62
63 /* die on a fatal error; use only during initialization */
64 static void fatal_error( const char *err, ... ) WINE_NORETURN;
65 static void fatal_error( const char *err, ... )
66 {
67     va_list args;
68
69     va_start( args, err );
70     fprintf( stderr, "wine: " );
71     vfprintf( stderr, err, args );
72     va_end( args );
73     exit(1);
74 }
75
76 /* die on a fatal error; use only during initialization */
77 static void fatal_perror( const char *err, ... ) WINE_NORETURN;
78 static void fatal_perror( const char *err, ... )
79 {
80     va_list args;
81
82     va_start( args, err );
83     fprintf( stderr, "wine: " );
84     vfprintf( stderr, err, args );
85     perror( " " );
86     va_end( args );
87     exit(1);
88 }
89
90 /***********************************************************************
91  *           server_protocol_error
92  */
93 void server_protocol_error( const char *err, ... )
94 {
95     va_list args;
96
97     va_start( args, err );
98     fprintf( stderr, "wine client error:%p: ", NtCurrentTeb()->tid );
99     vfprintf( stderr, err, args );
100     va_end( args );
101     SYSDEPS_AbortThread(1);
102 }
103
104
105 /***********************************************************************
106  *           server_protocol_perror
107  */
108 void server_protocol_perror( const char *err )
109 {
110     fprintf( stderr, "wine client error:%p: ", NtCurrentTeb()->tid );
111     perror( err );
112     SYSDEPS_AbortThread(1);
113 }
114
115
116 /***********************************************************************
117  *           send_request
118  *
119  * Send a request to the server.
120  */
121 static void send_request( const struct __server_request_info *req )
122 {
123     int i, ret;
124
125     if (!req->u.req.request_header.request_size)
126     {
127         if ((ret = write( NtCurrentTeb()->request_fd, &req->u.req,
128                           sizeof(req->u.req) )) == sizeof(req->u.req)) return;
129
130     }
131     else
132     {
133         struct iovec vec[__SERVER_MAX_DATA+1];
134
135         vec[0].iov_base = (void *)&req->u.req;
136         vec[0].iov_len = sizeof(req->u.req);
137         for (i = 0; i < req->data_count; i++)
138         {
139             vec[i+1].iov_base = (void *)req->data[i].ptr;
140             vec[i+1].iov_len = req->data[i].size;
141         }
142         if ((ret = writev( NtCurrentTeb()->request_fd, vec, i+1 )) ==
143             req->u.req.request_header.request_size + sizeof(req->u.req)) return;
144     }
145
146     if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
147     if (errno == EPIPE) SYSDEPS_AbortThread(0);
148     server_protocol_perror( "sendmsg" );
149 }
150
151
152 /***********************************************************************
153  *           read_reply_data
154  *
155  * Read data from the reply buffer; helper for wait_reply.
156  */
157 static void read_reply_data( void *buffer, size_t size )
158 {
159     int ret;
160
161     for (;;)
162     {
163         if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0)
164         {
165             if (!(size -= ret)) return;
166             buffer = (char *)buffer + ret;
167             continue;
168         }
169         if (!ret) break;
170         if (errno == EINTR) continue;
171         if (errno == EPIPE) break;
172         server_protocol_perror("read");
173     }
174     /* the server closed the connection; time to die... */
175     SYSDEPS_AbortThread(0);
176 }
177
178
179 /***********************************************************************
180  *           wait_reply
181  *
182  * Wait for a reply from the server.
183  */
184 inline static void wait_reply( struct __server_request_info *req )
185 {
186     read_reply_data( &req->u.reply, sizeof(req->u.reply) );
187     if (req->u.reply.reply_header.reply_size)
188         read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size );
189 }
190
191
192 /***********************************************************************
193  *           wine_server_call (NTDLL.@)
194  *
195  * Perform a server call.
196  */
197 unsigned int wine_server_call( void *req_ptr )
198 {
199     struct __server_request_info * const req = req_ptr;
200     sigset_t old_set;
201
202     memset( (char *)&req->u.req + req->size, 0, sizeof(req->u.req) - req->size );
203     sigprocmask( SIG_BLOCK, &block_set, &old_set );
204     send_request( req );
205     wait_reply( req );
206     sigprocmask( SIG_SETMASK, &old_set, NULL );
207     return req->u.reply.reply_header.error;
208 }
209
210
211 /***********************************************************************
212  *           wine_server_send_fd
213  *
214  * Send a file descriptor to the server.
215  */
216 void wine_server_send_fd( int fd )
217 {
218 #ifndef HAVE_MSGHDR_ACCRIGHTS
219     struct cmsg_fd cmsg;
220 #endif
221     struct send_fd data;
222     struct msghdr msghdr;
223     struct iovec vec;
224     int ret;
225
226     vec.iov_base = (void *)&data;
227     vec.iov_len  = sizeof(data);
228
229     msghdr.msg_name    = NULL;
230     msghdr.msg_namelen = 0;
231     msghdr.msg_iov     = &vec;
232     msghdr.msg_iovlen  = 1;
233
234 #ifdef HAVE_MSGHDR_ACCRIGHTS
235     msghdr.msg_accrights    = (void *)&fd;
236     msghdr.msg_accrightslen = sizeof(fd);
237 #else  /* HAVE_MSGHDR_ACCRIGHTS */
238     cmsg.len   = sizeof(cmsg);
239     cmsg.level = SOL_SOCKET;
240     cmsg.type  = SCM_RIGHTS;
241     cmsg.fd    = fd;
242     msghdr.msg_control    = &cmsg;
243     msghdr.msg_controllen = sizeof(cmsg);
244     msghdr.msg_flags      = 0;
245 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
246
247     data.tid = (void *)GetCurrentThreadId();
248     data.fd  = fd;
249
250     for (;;)
251     {
252         if ((ret = sendmsg( fd_socket, &msghdr, 0 )) == sizeof(data)) return;
253         if (ret >= 0) server_protocol_error( "partial write %d\n", ret );
254         if (errno == EINTR) continue;
255         if (errno == EPIPE) SYSDEPS_AbortThread(0);
256         server_protocol_perror( "sendmsg" );
257     }
258 }
259
260
261 /***********************************************************************
262  *           receive_fd
263  *
264  * Receive a file descriptor passed from the server.
265  */
266 static int receive_fd( handle_t *handle )
267 {
268     struct iovec vec;
269     int ret, fd;
270
271 #ifdef HAVE_MSGHDR_ACCRIGHTS
272     struct msghdr msghdr;
273
274     fd = -1;
275     msghdr.msg_accrights    = (void *)&fd;
276     msghdr.msg_accrightslen = sizeof(fd);
277 #else  /* HAVE_MSGHDR_ACCRIGHTS */
278     struct msghdr msghdr;
279     struct cmsg_fd cmsg;
280
281     cmsg.len   = sizeof(cmsg);
282     cmsg.level = SOL_SOCKET;
283     cmsg.type  = SCM_RIGHTS;
284     cmsg.fd    = -1;
285     msghdr.msg_control    = &cmsg;
286     msghdr.msg_controllen = sizeof(cmsg);
287     msghdr.msg_flags      = 0;
288 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
289
290     msghdr.msg_name    = NULL;
291     msghdr.msg_namelen = 0;
292     msghdr.msg_iov     = &vec;
293     msghdr.msg_iovlen  = 1;
294     vec.iov_base = (void *)handle;
295     vec.iov_len  = sizeof(*handle);
296
297     for (;;)
298     {
299         if ((ret = recvmsg( fd_socket, &msghdr, 0 )) > 0)
300         {
301 #ifndef HAVE_MSGHDR_ACCRIGHTS
302             fd = cmsg.fd;
303 #endif
304             if (fd == -1) server_protocol_error( "no fd received for handle %d\n", *handle );
305             fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
306             return fd;
307         }
308         if (!ret) break;
309         if (errno == EINTR) continue;
310         if (errno == EPIPE) break;
311         server_protocol_perror("recvmsg");
312     }
313     /* the server closed the connection; time to die... */
314     SYSDEPS_AbortThread(0);
315 }
316
317
318 /***********************************************************************
319  *           wine_server_recv_fd
320  *
321  * Receive a file descriptor passed from the server.
322  * The file descriptor must not be closed.
323  * Return -2 if a race condition stole our file descriptor.
324  */
325 int wine_server_recv_fd( handle_t handle )
326 {
327     handle_t fd_handle;
328
329     int fd = receive_fd( &fd_handle );
330
331     /* now store it in the server fd cache for this handle */
332
333     SERVER_START_REQ( set_handle_info )
334     {
335         req->handle = fd_handle;
336         req->flags  = 0;
337         req->mask   = 0;
338         req->fd     = fd;
339         if (!wine_server_call( req ))
340         {
341             if (reply->cur_fd != fd)
342             {
343                 /* someone was here before us */
344                 close( fd );
345                 fd = reply->cur_fd;
346             }
347         }
348         else
349         {
350             close( fd );
351             fd = -1;
352         }
353     }
354     SERVER_END_REQ;
355
356     if (handle != fd_handle) fd = -2;  /* not the one we expected */
357     return fd;
358 }
359
360
361 /***********************************************************************
362  *           get_config_dir
363  *
364  * Return the configuration directory ($WINEPREFIX or $HOME/.wine)
365  */
366 const char *get_config_dir(void)
367 {
368     static char *confdir;
369     if (!confdir)
370     {
371         const char *prefix = getenv( "WINEPREFIX" );
372         if (prefix)
373         {
374             int len = strlen(prefix);
375             if (!(confdir = strdup( prefix ))) fatal_error( "out of memory\n" );
376             if (len > 1 && confdir[len-1] == '/') confdir[len-1] = 0;
377         }
378         else
379         {
380             const char *home = getenv( "HOME" );
381             if (!home)
382             {
383                 struct passwd *pwd = getpwuid( getuid() );
384                 if (!pwd) fatal_error( "could not find your home directory\n" );
385                 home = pwd->pw_dir;
386             }
387             if (!(confdir = malloc( strlen(home) + strlen(CONFDIR) + 1 )))
388                 fatal_error( "out of memory\n" );
389             strcpy( confdir, home );
390             strcat( confdir, CONFDIR );
391         }
392     }
393     return confdir;
394 }
395
396
397 /***********************************************************************
398  *           start_server
399  *
400  * Start a new wine server.
401  */
402 static void start_server( const char *oldcwd )
403 {
404     static int started;  /* we only try once */
405     char *path, *p;
406     if (!started)
407     {
408         int status;
409         int pid = fork();
410         if (pid == -1) fatal_perror( "fork" );
411         if (!pid)
412         {
413             /* if server is explicitly specified, use this */
414             if ((p = getenv("WINESERVER")))
415             {
416                 if (p[0] != '/' && oldcwd[0] == '/')  /* make it an absolute path */
417                 {
418                     if (!(path = malloc( strlen(oldcwd) + strlen(p) + 1 )))
419                         fatal_error( "out of memory\n" );
420                     sprintf( path, "%s/%s", oldcwd, p );
421                     p = path;
422                 }
423                 execl( p, "wineserver", NULL );
424                 fatal_perror( "could not exec the server '%s'\n"
425                               "    specified in the WINESERVER environment variable", p );
426             }
427
428             /* first try the installation dir */
429             execl( BINDIR "/wineserver", "wineserver", NULL );
430
431             /* now try the dir we were launched from */
432             if (full_argv0)
433             {
434                 if (!(path = malloc( strlen(full_argv0) + 20 )))
435                     fatal_error( "out of memory\n" );
436                 if ((p = strrchr( strcpy( path, full_argv0 ), '/' )))
437                 {
438                     strcpy( p, "/wineserver" );
439                     execl( path, "wineserver", NULL );
440                     strcpy( p, "/server/wineserver" );
441                     execl( path, "wineserver", NULL );
442                 }
443                 free(path);
444             }
445
446             /* now try the path */
447             execlp( "wineserver", "wineserver", NULL );
448
449             /* and finally the current dir */
450             if (!(path = malloc( strlen(oldcwd) + 20 )))
451                 fatal_error( "out of memory\n" );
452             p = strcpy( path, oldcwd ) + strlen( oldcwd );
453             strcpy( p, "/wineserver" );
454             execl( path, "wineserver", NULL );
455             strcpy( p, "/server/wineserver" );
456             execl( path, "wineserver", NULL );
457             free(path);
458             fatal_error( "could not exec wineserver\n" );
459         }
460         started = 1;
461         waitpid( pid, &status, 0 );
462         status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
463         if (status) exit(status);  /* server failed */
464     }
465 }
466
467 /***********************************************************************
468  *           server_connect
469  *
470  * Attempt to connect to an existing server socket.
471  * We need to be in the server directory already.
472  */
473 static int server_connect( const char *oldcwd, const char *serverdir )
474 {
475     struct sockaddr_un addr;
476     struct stat st;
477     int s, slen, retry;
478
479     /* chdir to the server directory */
480     if (chdir( serverdir ) == -1)
481     {
482         if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
483         start_server( "." );
484         if (chdir( serverdir ) == -1) fatal_perror( "chdir to %s", serverdir );
485     }
486
487     /* make sure we are at the right place */
488     if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
489     if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
490     if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );
491
492     for (retry = 0; retry < 3; retry++)
493     {
494         /* if not the first try, wait a bit to leave the server time to exit */
495         if (retry) usleep( 100000 * retry * retry );
496
497         /* check for an existing socket */
498         if (lstat( SOCKETNAME, &st ) == -1)
499         {
500             if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
501             start_server( oldcwd );
502             if (lstat( SOCKETNAME, &st ) == -1) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
503         }
504
505         /* make sure the socket is sane (ISFIFO needed for Solaris) */
506         if (!S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode))
507             fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
508         if (st.st_uid != getuid())
509             fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
510
511         /* try to connect to it */
512         addr.sun_family = AF_UNIX;
513         strcpy( addr.sun_path, SOCKETNAME );
514         slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
515 #ifdef HAVE_SOCKADDR_SUN_LEN
516         addr.sun_len = slen;
517 #endif
518         if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
519         if (connect( s, (struct sockaddr *)&addr, slen ) != -1)
520         {
521             fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
522             return s;
523         }
524         close( s );
525     }
526     fatal_error( "file '%s/%s' exists,\n"
527                  "   but I cannot connect to it; maybe the wineserver has crashed?\n"
528                  "   If this is the case, you should remove this socket file and try again.\n",
529                  serverdir, SOCKETNAME );
530 }
531
532
533 /***********************************************************************
534  *           CLIENT_InitServer
535  *
536  * Start the server and create the initial socket pair.
537  */
538 void CLIENT_InitServer(void)
539 {
540     int size;
541     char hostname[64];
542     char *oldcwd, *serverdir;
543     const char *configdir;
544     handle_t dummy_handle;
545
546     /* retrieve the current directory */
547     for (size = 512; ; size *= 2)
548     {
549         if (!(oldcwd = malloc( size ))) break;
550         if (getcwd( oldcwd, size )) break;
551         free( oldcwd );
552         if (errno == ERANGE) continue;
553         oldcwd = NULL;
554         break;
555     }
556
557     /* if argv[0] is a relative path, make it absolute */
558     full_argv0 = argv0;
559     if (oldcwd && argv0[0] != '/' && strchr( argv0, '/' ))
560     {
561         char *new_argv0 = malloc( strlen(oldcwd) + strlen(argv0) + 2 );
562         if (new_argv0)
563         {
564             strcpy( new_argv0, oldcwd );
565             strcat( new_argv0, "/" );
566             strcat( new_argv0, argv0 );
567             full_argv0 = new_argv0;
568         }
569     }
570
571     /* get the server directory name */
572     if (gethostname( hostname, sizeof(hostname) ) == -1) fatal_perror( "gethostname" );
573     configdir = get_config_dir();
574     serverdir = malloc( strlen(configdir) + strlen(SERVERDIR) + strlen(hostname) + 1 );
575     if (!serverdir) fatal_error( "out of memory\n" );
576     strcpy( serverdir, configdir );
577     strcat( serverdir, SERVERDIR );
578     strcat( serverdir, hostname );
579
580     /* connect to the server */
581     fd_socket = server_connect( oldcwd, serverdir );
582
583     /* switch back to the starting directory */
584     if (oldcwd)
585     {
586         chdir( oldcwd );
587         free( oldcwd );
588     }
589
590     /* setup the signal mask */
591     sigemptyset( &block_set );
592     sigaddset( &block_set, SIGALRM );
593     sigaddset( &block_set, SIGIO );
594     sigaddset( &block_set, SIGINT );
595     sigaddset( &block_set, SIGHUP );
596
597     /* receive the first thread request fd on the main socket */
598     NtCurrentTeb()->request_fd = receive_fd( &dummy_handle );
599
600     CLIENT_InitThread();
601 }
602
603
604 /***********************************************************************
605  *           CLIENT_InitThread
606  *
607  * Send an init thread request. Return 0 if OK.
608  */
609 void CLIENT_InitThread(void)
610 {
611     TEB *teb = NtCurrentTeb();
612     int version, ret;
613     int reply_pipe[2];
614
615     /* ignore SIGPIPE so that we get a EPIPE error instead  */
616     signal( SIGPIPE, SIG_IGN );
617
618     /* create the server->client communication pipes */
619     if (pipe( reply_pipe ) == -1) server_protocol_perror( "pipe" );
620     if (pipe( teb->wait_fd ) == -1) server_protocol_perror( "pipe" );
621     wine_server_send_fd( reply_pipe[1] );
622     wine_server_send_fd( teb->wait_fd[1] );
623     teb->reply_fd = reply_pipe[0];
624
625     /* set close on exec flag */
626     fcntl( teb->reply_fd, F_SETFD, 1 );
627     fcntl( teb->wait_fd[0], F_SETFD, 1 );
628     fcntl( teb->wait_fd[1], F_SETFD, 1 );
629
630     SERVER_START_REQ( init_thread )
631     {
632         req->unix_pid    = getpid();
633         req->teb         = teb;
634         req->entry       = teb->entry_point;
635         req->reply_fd    = reply_pipe[1];
636         req->wait_fd     = teb->wait_fd[1];
637         ret = wine_server_call( req );
638         teb->pid = reply->pid;
639         teb->tid = reply->tid;
640         version  = reply->version;
641         if (reply->boot) boot_thread_id = teb->tid;
642         else if (boot_thread_id == teb->tid) boot_thread_id = 0;
643         close( reply_pipe[1] );
644     }
645     SERVER_END_REQ;
646
647     if (ret) server_protocol_error( "init_thread failed with status %x\n", ret );
648     if (version != SERVER_PROTOCOL_VERSION)
649         server_protocol_error( "version mismatch %d/%d.\n"
650                                "Your %s binary was not upgraded correctly,\n"
651                                "or you have an older one somewhere in your PATH.\n"
652                                "Or maybe the wrong wineserver is still running?\n",
653                                version, SERVER_PROTOCOL_VERSION,
654                                (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
655 }
656
657
658 /***********************************************************************
659  *           CLIENT_BootDone
660  *
661  * Signal that we have finished booting, and set debug level.
662  */
663 void CLIENT_BootDone( int debug_level )
664 {
665     SERVER_START_REQ( boot_done )
666     {
667         req->debug_level = debug_level;
668         wine_server_call( req );
669     }
670     SERVER_END_REQ;
671 }
672
673
674 /***********************************************************************
675  *           CLIENT_IsBootThread
676  *
677  * Return TRUE if current thread is the boot thread.
678  */
679 int CLIENT_IsBootThread(void)
680 {
681     return (GetCurrentThreadId() == (DWORD)boot_thread_id);
682 }