2 * Server-side request handling
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"
35 #include <sys/types.h>
36 #ifdef HAVE_SYS_SOCKET_H
37 # include <sys/socket.h>
48 #define WANT_REQUEST_HANDLERS
51 /* Some versions of glibc don't define this */
56 /* path names for server master Unix socket */
57 #define CONFDIR "/.wine" /* directory for Wine config relative to $HOME */
58 #define SERVERDIR "wineserver-" /* server socket directory (hostname appended) */
59 #define SOCKETNAME "socket" /* name of the socket file */
63 struct object obj
; /* object header */
64 struct timeout_user
*timeout
; /* timeout on last process exit */
67 static void master_socket_dump( struct object
*obj
, int verbose
);
68 static void master_socket_poll_event( struct object
*obj
, int event
);
70 static const struct object_ops master_socket_ops
=
72 sizeof(struct master_socket
), /* size */
73 master_socket_dump
, /* dump */
74 no_add_queue
, /* add_queue */
75 NULL
, /* remove_queue */
78 NULL
, /* get_poll_events */
79 master_socket_poll_event
, /* poll_event */
80 no_get_fd
, /* get_fd */
82 no_get_file_info
, /* get_file_info */
83 NULL
, /* queue_async */
84 no_destroy
/* destroy */
88 struct thread
*current
= NULL
; /* thread handling the current request */
89 unsigned int global_error
= 0; /* global error code for when no thread is current */
90 unsigned int server_start_ticks
= 0; /* tick count offset from server startup */
92 static struct master_socket
*master_socket
; /* the master socket object */
94 /* socket communication static structures */
95 static struct iovec myiovec
;
96 static struct msghdr msghdr
;
97 #ifndef HAVE_MSGHDR_ACCRIGHTS
100 int len
; /* sizeof structure */
101 int level
; /* SOL_SOCKET */
102 int type
; /* SCM_RIGHTS */
103 int fd
; /* fd to pass */
105 static struct cmsg_fd cmsg
= { sizeof(cmsg
), SOL_SOCKET
, SCM_RIGHTS
, -1 };
106 #endif /* HAVE_MSGHDR_ACCRIGHTS */
108 /* complain about a protocol error and terminate the client connection */
109 void fatal_protocol_error( struct thread
*thread
, const char *err
, ... )
113 va_start( args
, err
);
114 fprintf( stderr
, "Protocol error:%p: ", thread
);
115 vfprintf( stderr
, err
, args
);
117 thread
->exit_code
= 1;
118 kill_thread( thread
, 1 );
121 /* complain about a protocol error and terminate the client connection */
122 void fatal_protocol_perror( struct thread
*thread
, const char *err
, ... )
126 va_start( args
, err
);
127 fprintf( stderr
, "Protocol error:%p: ", thread
);
128 vfprintf( stderr
, err
, args
);
131 thread
->exit_code
= 1;
132 kill_thread( thread
, 1 );
135 /* die on a fatal error */
136 void fatal_error( const char *err
, ... )
140 va_start( args
, err
);
141 fprintf( stderr
, "wineserver: " );
142 vfprintf( stderr
, err
, args
);
147 /* die on a fatal error */
148 void fatal_perror( const char *err
, ... )
152 va_start( args
, err
);
153 fprintf( stderr
, "wineserver: " );
154 vfprintf( stderr
, err
, args
);
160 /* allocate the reply data */
161 void *set_reply_data_size( size_t size
)
163 assert( size
<= get_reply_max_size() );
164 if (size
&& !(current
->reply_data
= mem_alloc( size
))) size
= 0;
165 current
->reply_size
= size
;
166 return current
->reply_data
;
169 /* write the remaining part of the reply */
170 void write_reply( struct thread
*thread
)
174 if ((ret
= write( thread
->reply_fd
,
175 (char *)thread
->reply_data
+ thread
->reply_size
- thread
->reply_towrite
,
176 thread
->reply_towrite
)) >= 0)
178 if (!(thread
->reply_towrite
-= ret
))
180 free( thread
->reply_data
);
181 thread
->reply_data
= NULL
;
182 /* sent everything, can go back to waiting for requests */
183 change_select_fd( &thread
->obj
, thread
->request_fd
, POLLIN
);
188 kill_thread( thread
, 0 ); /* normal death */
189 else if (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)
190 fatal_protocol_perror( thread
, "reply write" );
193 /* send a reply to the current thread */
194 static void send_reply( union generic_reply
*reply
)
198 if (!current
->reply_size
)
200 if ((ret
= write( current
->reply_fd
, reply
, sizeof(*reply
) )) != sizeof(*reply
)) goto error
;
206 vec
[0].iov_base
= (void *)reply
;
207 vec
[0].iov_len
= sizeof(*reply
);
208 vec
[1].iov_base
= current
->reply_data
;
209 vec
[1].iov_len
= current
->reply_size
;
211 if ((ret
= writev( current
->reply_fd
, vec
, 2 )) < sizeof(*reply
)) goto error
;
213 if ((current
->reply_towrite
= current
->reply_size
- (ret
- sizeof(*reply
))))
215 /* couldn't write it all, wait for POLLOUT */
216 change_select_fd( ¤t
->obj
, current
->reply_fd
, POLLOUT
);
220 if (current
->reply_data
)
222 free( current
->reply_data
);
223 current
->reply_data
= NULL
;
229 fatal_protocol_error( current
, "partial write %d\n", ret
);
230 else if (errno
== EPIPE
)
231 kill_thread( current
, 0 ); /* normal death */
233 fatal_protocol_perror( current
, "reply write" );
236 /* call a request handler */
237 static void call_req_handler( struct thread
*thread
)
239 union generic_reply reply
;
240 enum request req
= thread
->req
.request_header
.req
;
243 current
->reply_size
= 0;
245 memset( &reply
, 0, sizeof(reply
) );
247 if (debug_level
) trace_request();
249 if (req
< REQ_NB_REQUESTS
)
251 req_handlers
[req
]( ¤t
->req
, &reply
);
254 reply
.reply_header
.error
= current
->error
;
255 reply
.reply_header
.reply_size
= current
->reply_size
;
256 if (debug_level
) trace_reply( req
, &reply
);
257 send_reply( &reply
);
262 fatal_protocol_error( current
, "bad request %d\n", req
);
265 /* read a request from a thread */
266 void read_request( struct thread
*thread
)
270 if (!thread
->req_toread
) /* no pending request */
272 if ((ret
= read( thread
->obj
.fd
, &thread
->req
,
273 sizeof(thread
->req
) )) != sizeof(thread
->req
)) goto error
;
274 if (!(thread
->req_toread
= thread
->req
.request_header
.request_size
))
276 /* no data, handle request at once */
277 call_req_handler( thread
);
280 if (!(thread
->req_data
= malloc( thread
->req_toread
)))
281 fatal_protocol_error( thread
, "no memory for %d bytes request\n", thread
->req_toread
);
284 /* read the variable sized data */
287 ret
= read( thread
->obj
.fd
, ((char *)thread
->req_data
+
288 thread
->req
.request_header
.request_size
- thread
->req_toread
),
289 thread
->req_toread
);
291 if (!(thread
->req_toread
-= ret
))
293 call_req_handler( thread
);
294 free( thread
->req_data
);
295 thread
->req_data
= NULL
;
301 if (!ret
) /* closed pipe */
302 kill_thread( thread
, 0 );
304 fatal_protocol_error( thread
, "partial read %d\n", ret
);
305 else if (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)
306 fatal_protocol_perror( thread
, "read" );
309 /* receive a file descriptor on the process socket */
310 int receive_fd( struct process
*process
)
315 #ifdef HAVE_MSGHDR_ACCRIGHTS
316 msghdr
.msg_accrightslen
= sizeof(int);
317 msghdr
.msg_accrights
= (void *)&fd
;
318 #else /* HAVE_MSGHDR_ACCRIGHTS */
319 msghdr
.msg_control
= &cmsg
;
320 msghdr
.msg_controllen
= sizeof(cmsg
);
322 #endif /* HAVE_MSGHDR_ACCRIGHTS */
324 myiovec
.iov_base
= (void *)&data
;
325 myiovec
.iov_len
= sizeof(data
);
327 ret
= recvmsg( process
->obj
.fd
, &msghdr
, 0 );
328 #ifndef HAVE_MSGHDR_ACCRIGHTS
332 if (ret
== sizeof(data
))
334 struct thread
*thread
;
336 if (data
.tid
) thread
= get_thread_from_id( data
.tid
);
337 else thread
= (struct thread
*)grab_object( process
->thread_list
);
339 if (!thread
|| thread
->process
!= process
)
342 fprintf( stderr
, "%08x: *fd* %d <- %d bad thread id\n",
343 (unsigned int)data
.tid
, data
.fd
, fd
);
349 fprintf( stderr
, "%08x: *fd* %d <- %d\n",
350 (unsigned int)thread
, data
.fd
, fd
);
351 thread_add_inflight_fd( thread
, data
.fd
, fd
);
353 if (thread
) release_object( thread
);
360 fprintf( stderr
, "Protocol error: process %p: partial recvmsg %d for fd\n",
362 kill_process( process
, NULL
, 1 );
366 if (errno
!= EWOULDBLOCK
&& errno
!= EAGAIN
)
368 fprintf( stderr
, "Protocol error: process %p: ", process
);
370 kill_process( process
, NULL
, 1 );
376 /* send an fd to a client */
377 int send_client_fd( struct process
*process
, int fd
, handle_t handle
)
382 fprintf( stderr
, "%08x: *fd* %d -> %d\n", (unsigned int)current
, handle
, fd
);
384 #ifdef HAVE_MSGHDR_ACCRIGHTS
385 msghdr
.msg_accrightslen
= sizeof(fd
);
386 msghdr
.msg_accrights
= (void *)&fd
;
387 #else /* HAVE_MSGHDR_ACCRIGHTS */
388 msghdr
.msg_control
= &cmsg
;
389 msghdr
.msg_controllen
= sizeof(cmsg
);
391 #endif /* HAVE_MSGHDR_ACCRIGHTS */
393 myiovec
.iov_base
= (void *)&handle
;
394 myiovec
.iov_len
= sizeof(handle
);
396 ret
= sendmsg( process
->obj
.fd
, &msghdr
, 0 );
398 if (ret
== sizeof(handle
)) return 0;
403 fprintf( stderr
, "Protocol error: process %p: partial sendmsg %d\n", process
, ret
);
404 kill_process( process
, NULL
, 1 );
408 fprintf( stderr
, "Protocol error: process %p: ", process
);
410 kill_process( process
, NULL
, 1 );
415 /* get current tick count to return to client */
416 unsigned int get_tick_count(void)
419 gettimeofday( &t
, NULL
);
420 return (t
.tv_sec
* 1000) + (t
.tv_usec
/ 1000) - server_start_ticks
;
423 static void master_socket_dump( struct object
*obj
, int verbose
)
425 struct master_socket
*sock
= (struct master_socket
*)obj
;
426 assert( obj
->ops
== &master_socket_ops
);
427 fprintf( stderr
, "Master socket fd=%d\n", sock
->obj
.fd
);
430 /* handle a socket event */
431 static void master_socket_poll_event( struct object
*obj
, int event
)
433 struct master_socket
*sock
= (struct master_socket
*)obj
;
434 assert( obj
->ops
== &master_socket_ops
);
436 assert( sock
== master_socket
); /* there is only one master socket */
438 if (event
& (POLLERR
| POLLHUP
))
440 /* this is not supposed to happen */
441 fprintf( stderr
, "wineserver: Error on master socket\n" );
442 release_object( obj
);
444 else if (event
& POLLIN
)
446 struct sockaddr_un dummy
;
447 int len
= sizeof(dummy
);
448 int client
= accept( master_socket
->obj
.fd
, (struct sockaddr
*) &dummy
, &len
);
449 if (client
== -1) return;
452 remove_timeout_user( sock
->timeout
);
453 sock
->timeout
= NULL
;
455 fcntl( client
, F_SETFL
, O_NONBLOCK
);
456 create_process( client
);
460 /* remove the socket upon exit */
461 static void socket_cleanup(void)
463 static int do_it_once
;
464 if (!do_it_once
++) unlink( SOCKETNAME
);
467 /* return the configuration directory ($WINEPREFIX or $HOME/.wine) */
468 const char *get_config_dir(void)
470 static char *confdir
;
473 const char *prefix
= getenv( "WINEPREFIX" );
476 int len
= strlen(prefix
);
477 if (!(confdir
= strdup( prefix
))) fatal_error( "out of memory\n" );
478 if (len
> 1 && confdir
[len
-1] == '/') confdir
[len
-1] = 0;
482 const char *home
= getenv( "HOME" );
485 struct passwd
*pwd
= getpwuid( getuid() );
486 if (!pwd
) fatal_error( "could not find your home directory\n" );
489 if (!(confdir
= malloc( strlen(home
) + strlen(CONFDIR
) + 1 )))
490 fatal_error( "out of memory\n" );
491 strcpy( confdir
, home
);
492 strcat( confdir
, CONFDIR
);
498 /* create the server directory and chdir to it */
499 static void create_server_dir(void)
503 const char *confdir
= get_config_dir();
506 if (gethostname( hostname
, sizeof(hostname
) ) == -1) fatal_perror( "gethostname" );
508 if (!(serverdir
= malloc( strlen(SERVERDIR
) + strlen(hostname
) + 1 )))
509 fatal_error( "out of memory\n" );
511 if (chdir( confdir
) == -1) fatal_perror( "chdir %s", confdir
);
513 strcpy( serverdir
, SERVERDIR
);
514 strcat( serverdir
, hostname
);
516 if (chdir( serverdir
) == -1)
518 if (errno
!= ENOENT
) fatal_perror( "chdir %s", serverdir
);
519 if (mkdir( serverdir
, 0700 ) == -1) fatal_perror( "mkdir %s", serverdir
);
520 if (chdir( serverdir
) == -1) fatal_perror( "chdir %s", serverdir
);
522 if (stat( ".", &st
) == -1) fatal_perror( "stat %s", serverdir
);
523 if (!S_ISDIR(st
.st_mode
)) fatal_error( "%s is not a directory\n", serverdir
);
524 if (st
.st_uid
!= getuid()) fatal_error( "%s is not owned by you\n", serverdir
);
525 if (st
.st_mode
& 077) fatal_error( "%s must not be accessible by other users\n", serverdir
);
528 /* open the master server socket and start waiting for new clients */
529 void open_master_socket(void)
531 struct sockaddr_un addr
;
534 /* make sure no request is larger than the maximum size */
535 assert( sizeof(union generic_request
) == sizeof(struct request_max_size
) );
536 assert( sizeof(union generic_reply
) == sizeof(struct request_max_size
) );
539 if ((fd
= socket( AF_UNIX
, SOCK_STREAM
, 0 )) == -1) fatal_perror( "socket" );
540 addr
.sun_family
= AF_UNIX
;
541 strcpy( addr
.sun_path
, SOCKETNAME
);
542 slen
= sizeof(addr
) - sizeof(addr
.sun_path
) + strlen(addr
.sun_path
) + 1;
543 #ifdef HAVE_SOCKADDR_SUN_LEN
546 if (bind( fd
, (struct sockaddr
*)&addr
, slen
) == -1)
548 if ((errno
== EEXIST
) || (errno
== EADDRINUSE
))
549 exit(0); /* pretend we succeeded to start */
551 fatal_perror( "bind" );
553 atexit( socket_cleanup
);
555 chmod( SOCKETNAME
, 0600 ); /* make sure no other user can connect */
556 if (listen( fd
, 5 ) == -1) fatal_perror( "listen" );
558 if (!(master_socket
= alloc_object( &master_socket_ops
, fd
)))
559 fatal_error( "out of memory\n" );
560 master_socket
->timeout
= NULL
;
561 set_select_events( &master_socket
->obj
, POLLIN
);
563 /* setup msghdr structure constant fields */
564 msghdr
.msg_name
= NULL
;
565 msghdr
.msg_namelen
= 0;
566 msghdr
.msg_iov
= &myiovec
;
567 msghdr
.msg_iovlen
= 1;
569 /* init startup ticks */
570 server_start_ticks
= get_tick_count();
572 /* go in the background */
576 fatal_perror( "fork" );
581 _exit(0); /* do not call atexit functions */
585 /* master socket timer expiration handler */
586 static void close_socket_timeout( void *arg
)
588 /* if a new client is waiting, we keep on running */
589 if (!check_select_events( master_socket
->obj
.fd
, POLLIN
))
590 release_object( master_socket
);
593 /* close the master socket and stop waiting for new clients */
594 void close_master_socket(void)
598 if (master_socket_timeout
== -1) return; /* just keep running forever */
600 if (master_socket_timeout
)
602 gettimeofday( &when
, 0 );
603 add_timeout( &when
, master_socket_timeout
* 1000 );
604 master_socket
->timeout
= add_timeout_user( &when
, close_socket_timeout
, NULL
);
606 else close_socket_timeout( NULL
); /* close it right away */
609 /* lock/unlock the master socket to stop accepting new clients */
610 void lock_master_socket( int locked
)
612 set_select_events( &master_socket
->obj
, locked
? 0 : POLLIN
);