Added support for system-wide hooks.
[wine] / server / request.c
1 /*
2  * Server-side request handling
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <assert.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <pwd.h>
28 #include <signal.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <sys/types.h>
36 #ifdef HAVE_SYS_SOCKET_H
37 # include <sys/socket.h>
38 #endif
39 #ifdef HAVE_SYS_WAIT_H
40 # include <sys/wait.h>
41 #endif
42 #include <sys/uio.h>
43 #include <sys/un.h>
44 #include <unistd.h>
45
46 #include "winnt.h"
47 #include "winbase.h"
48 #include "wincon.h"
49 #include "wine/library.h"
50
51 #include "handle.h"
52 #include "thread.h"
53 #include "process.h"
54 #include "user.h"
55 #define WANT_REQUEST_HANDLERS
56 #include "request.h"
57
58 /* Some versions of glibc don't define this */
59 #ifndef SCM_RIGHTS
60 #define SCM_RIGHTS 1
61 #endif
62
63 /* path names for server master Unix socket */
64 static const char * const server_socket_name = "socket";   /* name of the socket file */
65 static const char * const server_lock_name = "lock";       /* name of the server lock file */
66
67 struct master_socket
68 {
69     struct object        obj;         /* object header */
70     struct timeout_user *timeout;    /* timeout on last process exit */
71 };
72
73 static void master_socket_dump( struct object *obj, int verbose );
74 static void master_socket_poll_event( struct object *obj, int event );
75
76 static const struct object_ops master_socket_ops =
77 {
78     sizeof(struct master_socket),  /* size */
79     master_socket_dump,            /* dump */
80     no_add_queue,                  /* add_queue */
81     NULL,                          /* remove_queue */
82     NULL,                          /* signaled */
83     NULL,                          /* satisfied */
84     NULL,                          /* get_poll_events */
85     master_socket_poll_event,      /* poll_event */
86     no_get_fd,                     /* get_fd */
87     no_flush,                      /* flush */
88     no_get_file_info,              /* get_file_info */
89     NULL,                          /* queue_async */
90     no_destroy                     /* destroy */
91 };
92
93
94 struct thread *current = NULL;  /* thread handling the current request */
95 unsigned int global_error = 0;  /* global error code for when no thread is current */
96 unsigned int server_start_ticks = 0;  /* tick count offset from server startup */
97
98 static struct master_socket *master_socket;  /* the master socket object */
99
100 /* socket communication static structures */
101 static struct iovec myiovec;
102 static struct msghdr msghdr;
103 #ifndef HAVE_MSGHDR_ACCRIGHTS
104 struct cmsg_fd
105 {
106     int len;   /* sizeof structure */
107     int level; /* SOL_SOCKET */
108     int type;  /* SCM_RIGHTS */
109     int fd;    /* fd to pass */
110 };
111 static struct cmsg_fd cmsg = { sizeof(cmsg), SOL_SOCKET, SCM_RIGHTS, -1 };
112 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
113
114 /* complain about a protocol error and terminate the client connection */
115 void fatal_protocol_error( struct thread *thread, const char *err, ... )
116 {
117     va_list args;
118
119     va_start( args, err );
120     fprintf( stderr, "Protocol error:%p: ", thread );
121     vfprintf( stderr, err, args );
122     va_end( args );
123     thread->exit_code = 1;
124     kill_thread( thread, 1 );
125 }
126
127 /* complain about a protocol error and terminate the client connection */
128 void fatal_protocol_perror( struct thread *thread, const char *err, ... )
129 {
130     va_list args;
131
132     va_start( args, err );
133     fprintf( stderr, "Protocol error:%p: ", thread );
134     vfprintf( stderr, err, args );
135     perror( " " );
136     va_end( args );
137     thread->exit_code = 1;
138     kill_thread( thread, 1 );
139 }
140
141 /* die on a fatal error */
142 void fatal_error( const char *err, ... )
143 {
144     va_list args;
145
146     va_start( args, err );
147     fprintf( stderr, "wineserver: " );
148     vfprintf( stderr, err, args );
149     va_end( args );
150     exit(1);
151 }
152
153 /* die on a fatal error */
154 void fatal_perror( const char *err, ... )
155 {
156     va_list args;
157
158     va_start( args, err );
159     fprintf( stderr, "wineserver: " );
160     vfprintf( stderr, err, args );
161     perror( " " );
162     va_end( args );
163     exit(1);
164 }
165
166 /* allocate the reply data */
167 void *set_reply_data_size( size_t size )
168 {
169     assert( size <= get_reply_max_size() );
170     if (size && !(current->reply_data = mem_alloc( size ))) size = 0;
171     current->reply_size = size;
172     return current->reply_data;
173 }
174
175 /* write the remaining part of the reply */
176 void write_reply( struct thread *thread )
177 {
178     int ret;
179
180     if ((ret = write( thread->reply_fd,
181                       (char *)thread->reply_data + thread->reply_size - thread->reply_towrite,
182                       thread->reply_towrite )) >= 0)
183     {
184         if (!(thread->reply_towrite -= ret))
185         {
186             free( thread->reply_data );
187             thread->reply_data = NULL;
188             /* sent everything, can go back to waiting for requests */
189             change_select_fd( &thread->obj, thread->request_fd, POLLIN );
190         }
191         return;
192     }
193     if (errno == EPIPE)
194         kill_thread( thread, 0 );  /* normal death */
195     else if (errno != EWOULDBLOCK && errno != EAGAIN)
196         fatal_protocol_perror( thread, "reply write" );
197 }
198
199 /* send a reply to the current thread */
200 static void send_reply( union generic_reply *reply )
201 {
202     int ret;
203
204     if (!current->reply_size)
205     {
206         if ((ret = write( current->reply_fd, reply, sizeof(*reply) )) != sizeof(*reply)) goto error;
207     }
208     else
209     {
210         struct iovec vec[2];
211
212         vec[0].iov_base = (void *)reply;
213         vec[0].iov_len  = sizeof(*reply);
214         vec[1].iov_base = current->reply_data;
215         vec[1].iov_len  = current->reply_size;
216
217         if ((ret = writev( current->reply_fd, vec, 2 )) < sizeof(*reply)) goto error;
218
219         if ((current->reply_towrite = current->reply_size - (ret - sizeof(*reply))))
220         {
221             /* couldn't write it all, wait for POLLOUT */
222             change_select_fd( &current->obj, current->reply_fd, POLLOUT );
223             return;
224         }
225     }
226     if (current->reply_data)
227     {
228         free( current->reply_data );
229         current->reply_data = NULL;
230     }
231     return;
232
233  error:
234     if (ret >= 0)
235         fatal_protocol_error( current, "partial write %d\n", ret );
236     else if (errno == EPIPE)
237         kill_thread( current, 0 );  /* normal death */
238     else
239         fatal_protocol_perror( current, "reply write" );
240 }
241
242 /* call a request handler */
243 static void call_req_handler( struct thread *thread )
244 {
245     union generic_reply reply;
246     enum request req = thread->req.request_header.req;
247
248     current = thread;
249     current->reply_size = 0;
250     clear_error();
251     memset( &reply, 0, sizeof(reply) );
252
253     if (debug_level) trace_request();
254
255     if (req < REQ_NB_REQUESTS)
256     {
257         req_handlers[req]( &current->req, &reply );
258         if (current)
259         {
260             reply.reply_header.error = current->error;
261             reply.reply_header.reply_size = current->reply_size;
262             if (debug_level) trace_reply( req, &reply );
263             send_reply( &reply );
264         }
265         current = NULL;
266         return;
267     }
268     fatal_protocol_error( current, "bad request %d\n", req );
269 }
270
271 /* read a request from a thread */
272 void read_request( struct thread *thread )
273 {
274     int ret;
275
276     if (!thread->req_toread)  /* no pending request */
277     {
278         if ((ret = read( thread->obj.fd, &thread->req,
279                          sizeof(thread->req) )) != sizeof(thread->req)) goto error;
280         if (!(thread->req_toread = thread->req.request_header.request_size))
281         {
282             /* no data, handle request at once */
283             call_req_handler( thread );
284             return;
285         }
286         if (!(thread->req_data = malloc( thread->req_toread )))
287             fatal_protocol_error( thread, "no memory for %d bytes request\n", thread->req_toread );
288     }
289
290     /* read the variable sized data */
291     for (;;)
292     {
293         ret = read( thread->obj.fd, ((char *)thread->req_data +
294                                      thread->req.request_header.request_size - thread->req_toread),
295                     thread->req_toread );
296         if (ret <= 0) break;
297         if (!(thread->req_toread -= ret))
298         {
299             call_req_handler( thread );
300             free( thread->req_data );
301             thread->req_data = NULL;
302             return;
303         }
304     }
305
306 error:
307     if (!ret)  /* closed pipe */
308         kill_thread( thread, 0 );
309     else if (ret > 0)
310         fatal_protocol_error( thread, "partial read %d\n", ret );
311     else if (errno != EWOULDBLOCK && errno != EAGAIN)
312         fatal_protocol_perror( thread, "read" );
313 }
314
315 /* receive a file descriptor on the process socket */
316 int receive_fd( struct process *process )
317 {
318     struct send_fd data;
319     int fd, ret;
320
321 #ifdef HAVE_MSGHDR_ACCRIGHTS
322     msghdr.msg_accrightslen = sizeof(int);
323     msghdr.msg_accrights = (void *)&fd;
324 #else  /* HAVE_MSGHDR_ACCRIGHTS */
325     msghdr.msg_control    = &cmsg;
326     msghdr.msg_controllen = sizeof(cmsg);
327     cmsg.fd = -1;
328 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
329
330     myiovec.iov_base = (void *)&data;
331     myiovec.iov_len  = sizeof(data);
332
333     ret = recvmsg( process->obj.fd, &msghdr, 0 );
334 #ifndef HAVE_MSGHDR_ACCRIGHTS
335     fd = cmsg.fd;
336 #endif
337
338     if (ret == sizeof(data))
339     {
340         struct thread *thread;
341
342         if (data.tid) thread = get_thread_from_id( data.tid );
343         else thread = (struct thread *)grab_object( process->thread_list );
344
345         if (!thread || thread->process != process || thread->state == TERMINATED)
346         {
347             if (debug_level)
348                 fprintf( stderr, "%08x: *fd* %d <- %d bad thread id\n",
349                          (unsigned int)data.tid, data.fd, fd );
350             close( fd );
351         }
352         else
353         {
354             if (debug_level)
355                 fprintf( stderr, "%08x: *fd* %d <- %d\n",
356                          (unsigned int)thread, data.fd, fd );
357             thread_add_inflight_fd( thread, data.fd, fd );
358         }
359         if (thread) release_object( thread );
360         return 0;
361     }
362
363     if (ret >= 0)
364     {
365         if (ret > 0)
366             fprintf( stderr, "Protocol error: process %p: partial recvmsg %d for fd\n",
367                      process, ret );
368         kill_process( process, NULL, 1 );
369     }
370     else
371     {
372         if (errno != EWOULDBLOCK && errno != EAGAIN)
373         {
374             fprintf( stderr, "Protocol error: process %p: ", process );
375             perror( "recvmsg" );
376             kill_process( process, NULL, 1 );
377         }
378     }
379     return -1;
380 }
381
382 /* send an fd to a client */
383 int send_client_fd( struct process *process, int fd, obj_handle_t handle )
384 {
385     int ret;
386
387     if (debug_level)
388         fprintf( stderr, "%08x: *fd* %p -> %d\n", (unsigned int)current, handle, fd );
389
390 #ifdef HAVE_MSGHDR_ACCRIGHTS
391     msghdr.msg_accrightslen = sizeof(fd);
392     msghdr.msg_accrights = (void *)&fd;
393 #else  /* HAVE_MSGHDR_ACCRIGHTS */
394     msghdr.msg_control    = &cmsg;
395     msghdr.msg_controllen = sizeof(cmsg);
396     cmsg.fd = fd;
397 #endif  /* HAVE_MSGHDR_ACCRIGHTS */
398
399     myiovec.iov_base = (void *)&handle;
400     myiovec.iov_len  = sizeof(handle);
401
402     ret = sendmsg( process->obj.fd, &msghdr, 0 );
403
404     if (ret == sizeof(handle)) return 0;
405
406     if (ret >= 0)
407     {
408         fprintf( stderr, "Protocol error: process %p: partial sendmsg %d\n", process, ret );
409         kill_process( process, NULL, 1 );
410     }
411     else if (errno == EPIPE)
412     {
413         kill_process( process, NULL, 0 );
414     }
415     else
416     {
417         fprintf( stderr, "Protocol error: process %p: ", process );
418         perror( "sendmsg" );
419         kill_process( process, NULL, 1 );
420     }
421     return -1;
422 }
423
424 /* get current tick count to return to client */
425 unsigned int get_tick_count(void)
426 {
427     struct timeval t;
428     gettimeofday( &t, NULL );
429     return (t.tv_sec * 1000) + (t.tv_usec / 1000) - server_start_ticks;
430 }
431
432 static void master_socket_dump( struct object *obj, int verbose )
433 {
434     struct master_socket *sock = (struct master_socket *)obj;
435     assert( obj->ops == &master_socket_ops );
436     fprintf( stderr, "Master socket fd=%d\n", sock->obj.fd );
437 }
438
439 /* handle a socket event */
440 static void master_socket_poll_event( struct object *obj, int event )
441 {
442     struct master_socket *sock = (struct master_socket *)obj;
443     assert( obj->ops == &master_socket_ops );
444
445     assert( sock == master_socket );  /* there is only one master socket */
446
447     if (event & (POLLERR | POLLHUP))
448     {
449         /* this is not supposed to happen */
450         fprintf( stderr, "wineserver: Error on master socket\n" );
451         release_object( obj );
452     }
453     else if (event & POLLIN)
454     {
455         struct sockaddr_un dummy;
456         int len = sizeof(dummy);
457         int client = accept( master_socket->obj.fd, (struct sockaddr *) &dummy, &len );
458         if (client == -1) return;
459         if (sock->timeout)
460         {
461             remove_timeout_user( sock->timeout );
462             sock->timeout = NULL;
463         }
464         fcntl( client, F_SETFL, O_NONBLOCK );
465         create_process( client );
466     }
467 }
468
469 /* remove the socket upon exit */
470 static void socket_cleanup(void)
471 {
472     static int do_it_once;
473     if (!do_it_once++) unlink( server_socket_name );
474 }
475
476 /* create a directory and check its permissions */
477 static void create_dir( const char *name, struct stat *st )
478 {
479     if (lstat( name, st ) == -1)
480     {
481         if (errno != ENOENT) fatal_perror( "lstat %s", name );
482         if (mkdir( name, 0700 ) == -1) fatal_perror( "mkdir %s", name );
483         if (lstat( name, st ) == -1) fatal_perror( "lstat %s", name );
484     }
485     if (!S_ISDIR(st->st_mode)) fatal_error( "%s is not a directory\n", name );
486     if (st->st_uid != getuid()) fatal_error( "%s is not owned by you\n", name );
487     if (st->st_mode & 077) fatal_error( "%s must not be accessible by other users\n", name );
488 }
489
490 /* create the server directory and chdir to it */
491 static void create_server_dir(void)
492 {
493     char *p, *server_dir;
494     struct stat st, st2;
495
496     if (!(server_dir = strdup( wine_get_server_dir() ))) fatal_error( "out of memory\n" );
497
498     /* first create the base directory if needed */
499
500     p = strrchr( server_dir, '/' );
501     *p = 0;
502     create_dir( server_dir, &st );
503
504     /* now create the server directory */
505
506     *p = '/';
507     create_dir( server_dir, &st );
508
509     if (chdir( server_dir ) == -1) fatal_perror( "chdir %s", server_dir );
510     if (stat( ".", &st2 ) == -1) fatal_perror( "stat %s", server_dir );
511     if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino)
512         fatal_error( "chdir did not end up in %s\n", server_dir );
513
514     free( server_dir );
515 }
516
517 /* create the lock file and return its file descriptor */
518 static int create_server_lock(void)
519 {
520     struct stat st;
521     int fd;
522
523     if (lstat( server_lock_name, &st ) == -1)
524     {
525         if (errno != ENOENT)
526             fatal_perror( "lstat %s/%s", wine_get_server_dir(), server_lock_name );
527     }
528     else
529     {
530         if (!S_ISREG(st.st_mode))
531             fatal_error( "%s/%s is not a regular file\n", wine_get_server_dir(), server_lock_name );
532     }
533
534     if ((fd = open( server_lock_name, O_CREAT|O_TRUNC|O_WRONLY, 0600 )) == -1)
535         fatal_perror( "error creating %s/%s", wine_get_server_dir(), server_lock_name );
536     return fd;
537 }
538
539 /* wait for the server lock */
540 int wait_for_lock(void)
541 {
542     int fd, r;
543     struct flock fl;
544
545     create_server_dir();
546     fd = create_server_lock();
547
548     fl.l_type   = F_WRLCK;
549     fl.l_whence = SEEK_SET;
550     fl.l_start  = 0;
551     fl.l_len    = 1;
552     r = fcntl( fd, F_SETLKW, &fl );
553     close(fd);
554
555     return r;
556 }
557
558 /* kill the wine server holding the lock */
559 int kill_lock_owner( int sig )
560 {
561     int fd, i, ret = 0;
562     pid_t pid = 0;
563     struct flock fl;
564
565     create_server_dir();
566     fd = create_server_lock();
567
568     for (i = 0; i < 10; i++)
569     {
570         fl.l_type   = F_WRLCK;
571         fl.l_whence = SEEK_SET;
572         fl.l_start  = 0;
573         fl.l_len    = 1;
574         if (fcntl( fd, F_GETLK, &fl ) == -1) goto done;
575         if (fl.l_type != F_WRLCK) goto done;  /* the file is not locked */
576         if (!pid)  /* first time around */
577         {
578             if (!(pid = fl.l_pid)) goto done;  /* shouldn't happen */
579             if (sig == -1)
580             {
581                 if (kill( pid, SIGINT ) == -1) goto done;
582                 kill( pid, SIGCONT );
583                 ret = 1;
584             }
585             else  /* just send the specified signal and return */
586             {
587                 ret = (kill( pid, sig ) != -1);
588                 goto done;
589             }
590         }
591         else if (fl.l_pid != pid) goto done;  /* no longer the same process */
592         sleep( 1 );
593     }
594     /* waited long enough, now kill it */
595     kill( pid, SIGKILL );
596
597  done:
598     close( fd );
599     return ret;
600 }
601
602 /* acquire the main server lock */
603 static void acquire_lock(void)
604 {
605     struct sockaddr_un addr;
606     struct stat st;
607     struct flock fl;
608     int fd, slen, got_lock = 0;
609
610     fd = create_server_lock();
611
612     fl.l_type   = F_WRLCK;
613     fl.l_whence = SEEK_SET;
614     fl.l_start  = 0;
615     fl.l_len    = 1;
616     if (fcntl( fd, F_SETLK, &fl ) != -1)
617     {
618         /* check for crashed server */
619         if (stat( server_socket_name, &st ) != -1 &&   /* there is a leftover socket */
620             stat( "core", &st ) != -1 && st.st_size)   /* and there is a non-empty core file */
621         {
622             fprintf( stderr,
623                      "Warning: a previous instance of the wine server seems to have crashed.\n"
624                      "Please run 'gdb %s %s/core',\n"
625                      "type 'backtrace' at the gdb prompt and report the results. Thanks.\n\n",
626                      server_argv0, wine_get_server_dir() );
627         }
628         unlink( server_socket_name ); /* we got the lock, we can safely remove the socket */
629         got_lock = 1;
630         /* in that case we reuse fd without closing it, this ensures
631          * that we hold the lock until the process exits */
632     }
633     else
634     {
635         switch(errno)
636         {
637         case ENOLCK:
638             break;
639         case EACCES:
640             /* check whether locks work at all on this file system */
641             if (fcntl( fd, F_GETLK, &fl ) == -1) break;
642             /* fall through */
643         case EAGAIN:
644             exit(2); /* we didn't get the lock, exit with special status */
645         default:
646             fatal_perror( "fcntl %s/%s", wine_get_server_dir(), server_lock_name );
647         }
648         /* it seems we can't use locks on this fs, so we will use the socket existence as lock */
649         close( fd );
650     }
651
652     if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
653     addr.sun_family = AF_UNIX;
654     strcpy( addr.sun_path, server_socket_name );
655     slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
656 #ifdef HAVE_SOCKADDR_SUN_LEN
657     addr.sun_len = slen;
658 #endif
659     if (bind( fd, (struct sockaddr *)&addr, slen ) == -1)
660     {
661         if ((errno == EEXIST) || (errno == EADDRINUSE))
662         {
663             if (got_lock)
664                 fatal_error( "couldn't bind to the socket even though we hold the lock\n" );
665             exit(2); /* we didn't get the lock, exit with special status */
666         }
667         fatal_perror( "bind" );
668     }
669     atexit( socket_cleanup );
670     chmod( server_socket_name, 0600 );  /* make sure no other user can connect */
671     if (listen( fd, 5 ) == -1) fatal_perror( "listen" );
672
673     if (!(master_socket = alloc_object( &master_socket_ops, fd )))
674         fatal_error( "out of memory\n" );
675     master_socket->timeout = NULL;
676     set_select_events( &master_socket->obj, POLLIN );
677 }
678
679 /* open the master server socket and start waiting for new clients */
680 void open_master_socket(void)
681 {
682     int pid, status, sync_pipe[2];
683     char dummy;
684
685     /* make sure no request is larger than the maximum size */
686     assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
687     assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );
688
689     create_server_dir();
690     if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
691
692     pid = fork();
693     switch( pid )
694     {
695     case 0:  /* child */
696         setsid();
697         close( sync_pipe[0] );
698
699         acquire_lock();
700
701         /* signal parent */
702         write( sync_pipe[1], &dummy, 1 );
703         close( sync_pipe[1] );
704         break;
705
706     case -1:
707         fatal_perror( "fork" );
708         break;
709
710     default:  /* parent */
711         close( sync_pipe[1] );
712
713         /* wait for child to signal us and then exit */
714         if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);
715
716         /* child terminated, propagate exit status */
717         wait4( pid, &status, 0, NULL );
718         if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
719         _exit(1);
720     }
721
722     /* setup msghdr structure constant fields */
723     msghdr.msg_name    = NULL;
724     msghdr.msg_namelen = 0;
725     msghdr.msg_iov     = &myiovec;
726     msghdr.msg_iovlen  = 1;
727
728     /* init startup ticks */
729     server_start_ticks = get_tick_count();
730 }
731
732 /* master socket timer expiration handler */
733 static void close_socket_timeout( void *arg )
734 {
735     master_socket->timeout = NULL;
736     flush_registry();
737
738     /* if a new client is waiting, we keep on running */
739     if (check_select_events( master_socket->obj.fd, POLLIN )) return;
740
741     if (debug_level) fprintf( stderr, "wineserver: exiting (pid=%ld)\n", (long) getpid() );
742
743 #ifdef DEBUG_OBJECTS
744     /* shut down everything properly */
745     release_object( master_socket );
746     close_global_hooks();
747     close_global_handles();
748     close_registry();
749     close_atom_table();
750 #else
751     exit(0);
752 #endif
753 }
754
755 /* close the master socket and stop waiting for new clients */
756 void close_master_socket(void)
757 {
758     struct timeval when;
759
760     if (master_socket_timeout == -1) return;  /* just keep running forever */
761
762     if (master_socket_timeout)
763     {
764         gettimeofday( &when, 0 );
765         add_timeout( &when, master_socket_timeout * 1000 );
766         master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL );
767     }
768     else close_socket_timeout( NULL );  /* close it right away */
769 }
770
771 /* lock/unlock the master socket to stop accepting new clients */
772 void lock_master_socket( int locked )
773 {
774     set_select_events( &master_socket->obj, locked ? 0 : POLLIN );
775 }