Store process file name in startup info.
[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
9 #include <assert.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <pwd.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <sys/types.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
19 #endif
20 #ifdef HAVE_SYS_WAIT_H
21 #include <sys/wait.h>
22 #endif
23 #include <sys/un.h>
24 #ifdef HAVE_SYS_MMAN_H
25 #include <sys/mman.h>
26 #endif
27 #include <sys/stat.h>
28 #include <sys/uio.h>
29 #include <unistd.h>
30 #include <stdarg.h>
31
32 #include "process.h"
33 #include "thread.h"
34 #include "server.h"
35 #include "winerror.h"
36 #include "options.h"
37
38 /* Some versions of glibc don't define this */
39 #ifndef SCM_RIGHTS
40 #define SCM_RIGHTS 1
41 #endif
42
43 #define CONFDIR    "/.wine"        /* directory for Wine config relative to $HOME */
44 #define SERVERDIR  "/wineserver-"  /* server socket directory (hostname appended) */
45 #define SOCKETNAME "socket"        /* name of the socket file */
46
47 /* data structure used to pass an fd with sendmsg/recvmsg */
48 struct cmsg_fd
49 {
50     int len;   /* sizeof structure */
51     int level; /* SOL_SOCKET */
52     int type;  /* SCM_RIGHTS */
53     int fd;    /* fd to pass */
54 };
55
56 static void *boot_thread_id;
57
58
59 /* die on a fatal error; use only during initialization */
60 static void fatal_error( const char *err, ... ) WINE_NORETURN;
61 static void fatal_error( const char *err, ... )
62 {
63     va_list args;
64
65     va_start( args, err );
66     fprintf( stderr, "wine: " );
67     vfprintf( stderr, err, args );
68     va_end( args );
69     exit(1);
70 }
71
72 /* die on a fatal error; use only during initialization */
73 static void fatal_perror( const char *err, ... ) WINE_NORETURN;
74 static void fatal_perror( const char *err, ... )
75 {
76     va_list args;
77
78     va_start( args, err );
79     fprintf( stderr, "wine: " );
80     vfprintf( stderr, err, args );
81     perror( " " );
82     va_end( args );
83     exit(1);
84 }
85
86 /***********************************************************************
87  *           server_protocol_error
88  */
89 void server_protocol_error( const char *err, ... )
90 {
91     va_list args;
92
93     va_start( args, err );
94     fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
95     vfprintf( stderr, err, args );
96     va_end( args );
97     SYSDEPS_ExitThread(1);
98 }
99
100
101 /***********************************************************************
102  *           server_perror
103  */
104 static void server_perror( const char *err )
105 {
106     fprintf( stderr, "Client protocol error:%p: ", NtCurrentTeb()->tid );
107     perror( err );
108     SYSDEPS_ExitThread(1);
109 }
110
111
112 /***********************************************************************
113  *           send_request
114  *
115  * Send a request to the server.
116  */
117 static void send_request( enum request req )
118 {
119     int ret;
120     if ((ret = write( NtCurrentTeb()->socket, &req, sizeof(req) )) == sizeof(req))
121         return;
122     if (ret == -1)
123     {
124         if (errno == EPIPE) SYSDEPS_ExitThread(0);
125         server_perror( "sendmsg" );
126     }
127     server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
128 }
129
130 /***********************************************************************
131  *           send_request_fd
132  *
133  * Send a request to the server, passing a file descriptor.
134  */
135 static void send_request_fd( enum request req, int fd )
136 {
137     int ret;
138 #ifndef HAVE_MSGHDR_ACCRIGHTS
139     struct cmsg_fd cmsg;
140 #endif
141     struct msghdr msghdr;
142     struct iovec vec;
143
144     vec.iov_base = (void *)&req;
145     vec.iov_len  = sizeof(req);
146
147     msghdr.msg_name    = NULL;
148     msghdr.msg_namelen = 0;
149     msghdr.msg_iov     = &vec;
150     msghdr.msg_iovlen  = 1;
151
152 #ifdef HAVE_MSGHDR_ACCRIGHTS
153     msghdr.msg_accrights    = (void *)&fd;
154     msghdr.msg_accrightslen = sizeof(fd);
155 #else  /* HAVE_MSGHDR_ACCRIGHTS */
156     cmsg.len   = sizeof(cmsg);
157     cmsg.level = SOL_SOCKET;
158     cmsg.type  = SCM_RIGHTS;
159     cmsg.fd    = fd;
160     msghdr.msg_control    = &cmsg;
161     msghdr.msg_controllen = sizeof(cmsg);
162     msghdr.msg_flags      = 0;
163 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
164
165     if ((ret = sendmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(req)) return;
166     if (ret == -1)
167     {
168         if (errno == EPIPE) SYSDEPS_ExitThread(0);
169         server_perror( "sendmsg" );
170     }
171     server_protocol_error( "partial msg sent %d/%d\n", ret, sizeof(req) );
172 }
173
174 /***********************************************************************
175  *           wait_reply
176  *
177  * Wait for a reply from the server.
178  */
179 static unsigned int wait_reply(void)
180 {
181     int ret;
182     unsigned int res;
183
184     for (;;)
185     {
186         if ((ret = read( NtCurrentTeb()->socket, &res, sizeof(res) )) == sizeof(res))
187             return res;
188         if (!ret) break;
189         if (ret == -1)
190         {
191             if (errno == EINTR) continue;
192             if (errno == EPIPE) break;
193             server_perror("read");
194         }
195         server_protocol_error( "partial msg received %d/%d\n", ret, sizeof(res) );
196     }
197     /* the server closed the connection; time to die... */
198     SYSDEPS_ExitThread(0);
199 }
200
201
202 /***********************************************************************
203  *           wait_reply_fd
204  *
205  * Wait for a reply from the server, when a file descriptor is passed.
206  */
207 static unsigned int wait_reply_fd( int *fd )
208 {
209     struct iovec vec;
210     int ret;
211     unsigned int res;
212
213 #ifdef HAVE_MSGHDR_ACCRIGHTS
214     struct msghdr msghdr;
215
216     *fd = -1;
217     msghdr.msg_accrights    = (void *)fd;
218     msghdr.msg_accrightslen = sizeof(*fd);
219 #else  /* HAVE_MSGHDR_ACCRIGHTS */
220     struct msghdr msghdr;
221     struct cmsg_fd cmsg;
222
223     cmsg.len   = sizeof(cmsg);
224     cmsg.level = SOL_SOCKET;
225     cmsg.type  = SCM_RIGHTS;
226     cmsg.fd    = -1;
227     msghdr.msg_control    = &cmsg;
228     msghdr.msg_controllen = sizeof(cmsg);
229     msghdr.msg_flags      = 0;
230 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
231
232     msghdr.msg_name    = NULL;
233     msghdr.msg_namelen = 0;
234     msghdr.msg_iov     = &vec;
235     msghdr.msg_iovlen  = 1;
236     vec.iov_base = (void *)&res;
237     vec.iov_len  = sizeof(res);
238
239     for (;;)
240     {
241         if ((ret = recvmsg( NtCurrentTeb()->socket, &msghdr, 0 )) == sizeof(res))
242         {
243 #ifndef HAVE_MSGHDR_ACCRIGHTS
244             *fd = cmsg.fd;
245 #endif
246             return res;
247         }
248         if (!ret) break;
249         if (ret == -1)
250         {
251             if (errno == EINTR) continue;
252             if (errno == EPIPE) break;
253             server_perror("recvmsg");
254         }
255         server_protocol_error( "partial seq received %d/%d\n", ret, sizeof(res) );
256     }
257     /* the server closed the connection; time to die... */
258     SYSDEPS_ExitThread(0);
259 }
260
261
262 /***********************************************************************
263  *           server_call_noerr
264  *
265  * Perform a server call.
266  */
267 unsigned int server_call_noerr( enum request req )
268 {
269     send_request( req );
270     return wait_reply();
271 }
272
273
274 /***********************************************************************
275  *           server_call_fd
276  *
277  * Perform a server call, passing a file descriptor.
278  * If *fd is != -1, it will be passed to the server.
279  * If the server passes an fd, it will be stored into *fd.
280  */
281 unsigned int server_call_fd( enum request req, int fd_out, int *fd_in )
282 {
283     unsigned int res;
284
285     if (fd_out == -1) send_request( req );
286     else send_request_fd( req, fd_out );
287
288     if (fd_in) res = wait_reply_fd( fd_in );
289     else res = wait_reply();
290     if (res) SetLastError( RtlNtStatusToDosError(res) );
291     return res;  /* error code */
292 }
293
294
295 /***********************************************************************
296  *           get_config_dir
297  *
298  * Return the configuration directory ($WINEPREFIX or $HOME/.wine)
299  */
300 const char *get_config_dir(void)
301 {
302     static char *confdir;
303     if (!confdir)
304     {
305         const char *prefix = getenv( "WINEPREFIX" );
306         if (prefix)
307         {
308             int len = strlen(prefix);
309             if (!(confdir = strdup( prefix ))) fatal_error( "out of memory\n" );
310             if (len > 1 && confdir[len-1] == '/') confdir[len-1] = 0;
311         }
312         else
313         {
314             const char *home = getenv( "HOME" );
315             if (!home)
316             {
317                 struct passwd *pwd = getpwuid( getuid() );
318                 if (!pwd) fatal_error( "could not find your home directory\n" );
319                 home = pwd->pw_dir;
320             }
321             if (!(confdir = malloc( strlen(home) + strlen(CONFDIR) + 1 )))
322                 fatal_error( "out of memory\n" );
323             strcpy( confdir, home );
324             strcat( confdir, CONFDIR );
325         }
326         mkdir( confdir, 0755 );  /* just in case */
327     }
328     return confdir;
329 }
330
331
332 /***********************************************************************
333  *           start_server
334  *
335  * Start a new wine server.
336  */
337 static void start_server( const char *oldcwd )
338 {
339     static int started;  /* we only try once */
340     if (!started)
341     {
342         int status;
343         int pid = fork();
344         if (pid == -1) fatal_perror( "fork" );
345         if (!pid)
346         {
347             char *path, *p;
348             /* first try the installation dir */
349             execl( BINDIR "/wineserver", "wineserver", NULL );
350             if (oldcwd) chdir( oldcwd );
351             /* now try the dir we were launched from */
352             if (!(path = malloc( strlen(argv0) + 20 )))
353                 fatal_error( "out of memory\n" );
354             if ((p = strrchr( strcpy( path, argv0 ), '/' )))
355             {
356                 strcpy( p, "/wineserver" );
357                 execl( path, "wineserver", NULL );
358                 strcpy( p, "/server/wineserver" );
359                 execl( path, "wineserver", NULL );
360             }
361             /* now try the path */
362             execlp( "wineserver", "wineserver", NULL );
363             /* and finally the current dir */
364             execl( "./server/wineserver", "wineserver", NULL );
365             fatal_error( "could not exec wineserver\n" );
366         }
367         started = 1;
368         waitpid( pid, &status, 0 );
369         status = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
370         if (status) exit(status);  /* server failed */
371     }
372 }
373
374 /***********************************************************************
375  *           server_connect
376  *
377  * Attempt to connect to an existing server socket.
378  * We need to be in the server directory already.
379  */
380 static int server_connect( const char *oldcwd, const char *serverdir )
381 {
382     struct sockaddr_un addr;
383     struct stat st;
384     int s, slen;
385
386     /* chdir to the server directory */
387     if (chdir( serverdir ) == -1)
388     {
389         if (errno != ENOENT) fatal_perror( "chdir to %s", serverdir );
390         start_server( NULL );
391         if (chdir( serverdir ) == -1) fatal_perror( "chdir to %s", serverdir );
392     }
393
394     /* make sure we are at the right place */
395     if (stat( ".", &st ) == -1) fatal_perror( "stat %s", serverdir );
396     if (st.st_uid != getuid()) fatal_error( "'%s' is not owned by you\n", serverdir );
397     if (st.st_mode & 077) fatal_error( "'%s' must not be accessible by other users\n", serverdir );
398
399     /* check for an existing socket */
400     if (lstat( SOCKETNAME, &st ) == -1)
401     {
402         if (errno != ENOENT) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
403         start_server( oldcwd );
404         if (lstat( SOCKETNAME, &st ) == -1) fatal_perror( "lstat %s/%s", serverdir, SOCKETNAME );
405     }
406
407     /* make sure the socket is sane */
408     if (!S_ISSOCK(st.st_mode))
409         fatal_error( "'%s/%s' is not a socket\n", serverdir, SOCKETNAME );
410     if (st.st_uid != getuid())
411         fatal_error( "'%s/%s' is not owned by you\n", serverdir, SOCKETNAME );
412
413     /* try to connect to it */
414     if ((s = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
415     addr.sun_family = AF_UNIX;
416     strcpy( addr.sun_path, SOCKETNAME );
417     slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
418 #ifdef HAVE_SOCKADDR_SUN_LEN
419     addr.sun_len = slen;
420 #endif
421     if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
422     {
423         usleep( 50000 );  /* in case the server was starting right now */
424         if (connect( s, (struct sockaddr *)&addr, slen ) == -1)
425             fatal_error( "'%s/%s' exists,\n"
426                          "   but I cannot connect to it; maybe the server has crashed?\n"
427                          "   If this is the case, you should remove the socket file and try again.\n",
428                          serverdir, SOCKETNAME );
429     }
430     fcntl( s, F_SETFD, 1 ); /* set close on exec flag */
431     return s;
432 }
433
434
435 /***********************************************************************
436  *           CLIENT_InitServer
437  *
438  * Start the server and create the initial socket pair.
439  */
440 int CLIENT_InitServer(void)
441 {
442     int fd, size;
443     const char *env_fd;
444     char hostname[64];
445     char *oldcwd, *serverdir;
446     const char *configdir;
447
448     /* first check if we inherited the socket fd */
449     if ((env_fd = getenv( "__WINE_FD" )) && isdigit(env_fd[0]))
450     {
451         fd = atoi( env_fd );
452         if (fcntl( fd, F_SETFD, 1 ) != -1) return fd; /* set close on exec flag */
453     }
454
455     /* retrieve the current directory */
456     for (size = 512; ; size *= 2)
457     {
458         if (!(oldcwd = malloc( size ))) break;
459         if (getcwd( oldcwd, size )) break;
460         free( oldcwd );
461         if (errno == ERANGE) continue;
462         oldcwd = NULL;
463         break;
464     }
465
466     /* get the server directory name */
467     if (gethostname( hostname, sizeof(hostname) ) == -1) fatal_perror( "gethostname" );
468     configdir = get_config_dir();
469     serverdir = malloc( strlen(configdir) + strlen(SERVERDIR) + strlen(hostname) + 1 );
470     if (!serverdir) fatal_error( "out of memory\n" );
471     strcpy( serverdir, configdir );
472     strcat( serverdir, SERVERDIR );
473     strcat( serverdir, hostname );
474
475     /* connect to the server */
476     fd = server_connect( oldcwd, serverdir );
477
478     /* switch back to the starting directory */
479     if (oldcwd)
480     {
481         chdir( oldcwd );
482         free( oldcwd );
483     }
484     return fd;
485 }
486
487
488 /***********************************************************************
489  *           CLIENT_InitThread
490  *
491  * Send an init thread request. Return 0 if OK.
492  */
493 int CLIENT_InitThread(void)
494 {
495     struct get_thread_buffer_request *first_req;
496     struct init_thread_request *req;
497     TEB *teb = NtCurrentTeb();
498     int fd;
499
500     if (wait_reply_fd( &fd ) || (fd == -1))
501         server_protocol_error( "no fd passed on first request\n" );
502     if ((teb->buffer_size = lseek( fd, 0, SEEK_END )) == -1) server_perror( "lseek" );
503     teb->buffer = mmap( 0, teb->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
504     close( fd );
505     if (teb->buffer == (void*)-1) server_perror( "mmap" );
506     first_req = teb->buffer;
507     teb->process->server_pid = first_req->pid;
508     teb->pid = first_req->pid;
509     teb->tid = first_req->tid;
510     if (first_req->version != SERVER_PROTOCOL_VERSION)
511         server_protocol_error( "version mismatch %d/%d.\n"
512                                "Your %s binary was not upgraded correctly,\n"
513                                "or you have an older one somewhere in your PATH.\n",
514                                first_req->version, SERVER_PROTOCOL_VERSION,
515                                (first_req->version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" );
516     if (first_req->boot) boot_thread_id = teb->tid;
517     else if (boot_thread_id == teb->tid) boot_thread_id = 0;
518
519     req = teb->buffer;
520     req->unix_pid = getpid();
521     req->teb      = teb;
522     req->entry    = teb->entry_point;
523     return server_call_noerr( REQ_INIT_THREAD );
524 }
525
526 /***********************************************************************
527  *           CLIENT_BootDone
528  *
529  * Signal that we have finished booting, and set debug level.
530  */
531 int CLIENT_BootDone( int debug_level )
532 {
533     struct boot_done_request *req = get_req_buffer();
534     req->debug_level = debug_level;
535     return server_call( REQ_BOOT_DONE );
536 }
537
538
539 /***********************************************************************
540  *           CLIENT_IsBootThread
541  *
542  * Return TRUE if current thread is the boot thread.
543  */
544 int CLIENT_IsBootThread(void)
545 {
546     return (GetCurrentThreadId() == (DWORD)boot_thread_id);
547 }