request.c 24.9 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * Server-side request handling
 *
 * Copyright (C) 1998 Alexandre Julliard
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22
#include "wine/port.h"
23

24
#include <assert.h>
25 26
#include <errno.h>
#include <fcntl.h>
Steven Edwards's avatar
Steven Edwards committed
27
#ifdef HAVE_PWD_H
28
#include <pwd.h>
Steven Edwards's avatar
Steven Edwards committed
29
#endif
30
#include <signal.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
31 32
#include <stdio.h>
#include <stdlib.h>
33 34
#include <stdarg.h>
#include <string.h>
35
#include <sys/stat.h>
36
#include <sys/time.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
37
#include <sys/types.h>
38 39 40
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
41 42 43
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
Steven Edwards's avatar
Steven Edwards committed
44
#ifdef HAVE_SYS_UIO_H
Alexandre Julliard's avatar
Alexandre Julliard committed
45
#include <sys/uio.h>
Steven Edwards's avatar
Steven Edwards committed
46 47
#endif
#ifdef HAVE_SYS_UN_H
48
#include <sys/un.h>
Steven Edwards's avatar
Steven Edwards committed
49
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
50
#include <unistd.h>
51 52 53
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
54

55 56
#include "ntstatus.h"
#define WIN32_NO_STATUS
57
#include "windef.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
58
#include "winbase.h"
59
#include "wincon.h"
60
#include "winternl.h"
61 62
#include "wine/library.h"

63
#include "file.h"
64
#include "process.h"
65 66
#define WANT_REQUEST_HANDLERS
#include "request.h"
67 68 69 70 71 72

/* Some versions of glibc don't define this */
#ifndef SCM_RIGHTS
#define SCM_RIGHTS 1
#endif

73 74 75
/* path names for server master Unix socket */
static const char * const server_socket_name = "socket";   /* name of the socket file */
static const char * const server_lock_name = "lock";       /* name of the server lock file */
76 77 78

struct master_socket
{
79 80
    struct object        obj;        /* object header */
    struct fd           *fd;         /* file descriptor of the master socket */
81
    struct timeout_user *timeout;    /* timeout on last process exit */
82 83 84
};

static void master_socket_dump( struct object *obj, int verbose );
85
static void master_socket_destroy( struct object *obj );
86
static void master_socket_poll_event( struct fd *fd, int event );
87 88 89 90 91 92 93 94 95

static const struct object_ops master_socket_ops =
{
    sizeof(struct master_socket),  /* size */
    master_socket_dump,            /* dump */
    no_add_queue,                  /* add_queue */
    NULL,                          /* remove_queue */
    NULL,                          /* signaled */
    NULL,                          /* satisfied */
96
    no_signal,                     /* signal */
97
    no_get_fd,                     /* get_fd */
98
    no_map_access,                 /* map_access */
99
    no_lookup_name,                /* lookup_name */
100
    no_close_handle,               /* close_handle */
101
    master_socket_destroy          /* destroy */
102 103 104 105
};

static const struct fd_ops master_socket_fd_ops =
{
106 107 108 109
    NULL,                          /* get_poll_events */
    master_socket_poll_event,      /* poll_event */
    no_flush,                      /* flush */
    no_get_file_info,              /* get_file_info */
110 111
    no_queue_async,                /* queue_async */
    no_cancel_async                /* cancel_async */
112 113 114
};


Alexandre Julliard's avatar
Alexandre Julliard committed
115
struct thread *current = NULL;  /* thread handling the current request */
116
unsigned int global_error = 0;  /* global error code for when no thread is current */
117
struct timeval server_start_time = { 0, 0 };  /* server startup time */
Alexandre Julliard's avatar
Alexandre Julliard committed
118

119
static struct master_socket *master_socket;  /* the master socket object */
120
static int force_shutdown;
121 122 123

/* socket communication static structures */
static struct iovec myiovec;
124
static struct msghdr msghdr;
125
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
126 127
struct cmsg_fd
{
128 129 130 131 132 133 134
    struct
    {
        size_t len;   /* size of structure */
        int    level; /* SOL_SOCKET */
        int    type;  /* SCM_RIGHTS */
    } header;
    int fd;           /* fd to pass */
135
};
136
static struct cmsg_fd cmsg = { { sizeof(cmsg.header) + sizeof(cmsg.fd), SOL_SOCKET, SCM_RIGHTS }, -1 };
137
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
138

Alexandre Julliard's avatar
Alexandre Julliard committed
139
/* complain about a protocol error and terminate the client connection */
140
void fatal_protocol_error( struct thread *thread, const char *err, ... )
Alexandre Julliard's avatar
Alexandre Julliard committed
141
{
142
    va_list args;
Alexandre Julliard's avatar
Alexandre Julliard committed
143

144
    va_start( args, err );
145
    fprintf( stderr, "Protocol error:%04x: ", thread->id );
146 147
    vfprintf( stderr, err, args );
    va_end( args );
148 149
    thread->exit_code = 1;
    kill_thread( thread, 1 );
Alexandre Julliard's avatar
Alexandre Julliard committed
150 151
}

152 153 154 155 156 157
/* complain about a protocol error and terminate the client connection */
void fatal_protocol_perror( struct thread *thread, const char *err, ... )
{
    va_list args;

    va_start( args, err );
158
    fprintf( stderr, "Protocol error:%04x: ", thread->id );
159 160 161 162 163 164 165
    vfprintf( stderr, err, args );
    perror( " " );
    va_end( args );
    thread->exit_code = 1;
    kill_thread( thread, 1 );
}

166
/* die on a fatal error */
167
void fatal_error( const char *err, ... )
168 169 170 171 172 173 174 175 176 177 178
{
    va_list args;

    va_start( args, err );
    fprintf( stderr, "wineserver: " );
    vfprintf( stderr, err, args );
    va_end( args );
    exit(1);
}

/* die on a fatal error */
179
void fatal_perror( const char *err, ... )
180 181 182 183 184 185 186 187 188 189 190
{
    va_list args;

    va_start( args, err );
    fprintf( stderr, "wineserver: " );
    vfprintf( stderr, err, args );
    perror( " " );
    va_end( args );
    exit(1);
}

191
/* allocate the reply data */
192
void *set_reply_data_size( data_size_t size )
Alexandre Julliard's avatar
Alexandre Julliard committed
193
{
194 195 196 197 198
    assert( size <= get_reply_max_size() );
    if (size && !(current->reply_data = mem_alloc( size ))) size = 0;
    current->reply_size = size;
    return current->reply_data;
}
199

200 201 202 203
/* write the remaining part of the reply */
void write_reply( struct thread *thread )
{
    int ret;
204

205
    if ((ret = write( get_unix_fd( thread->reply_fd ),
206 207 208 209 210 211 212 213
                      (char *)thread->reply_data + thread->reply_size - thread->reply_towrite,
                      thread->reply_towrite )) >= 0)
    {
        if (!(thread->reply_towrite -= ret))
        {
            free( thread->reply_data );
            thread->reply_data = NULL;
            /* sent everything, can go back to waiting for requests */
214 215
            set_fd_events( thread->request_fd, POLLIN );
            set_fd_events( thread->reply_fd, 0 );
216 217 218 219 220 221 222 223
        }
        return;
    }
    if (errno == EPIPE)
        kill_thread( thread, 0 );  /* normal death */
    else if (errno != EWOULDBLOCK && errno != EAGAIN)
        fatal_protocol_perror( thread, "reply write" );
}
Alexandre Julliard's avatar
Alexandre Julliard committed
224

225 226 227 228 229 230 231
/* send a reply to the current thread */
static void send_reply( union generic_reply *reply )
{
    int ret;

    if (!current->reply_size)
    {
232 233
        if ((ret = write( get_unix_fd( current->reply_fd ),
                          reply, sizeof(*reply) )) != sizeof(*reply)) goto error;
234 235
    }
    else
236
    {
237 238
        struct iovec vec[2];

239
        vec[0].iov_base = (void *)reply;
240 241 242 243
        vec[0].iov_len  = sizeof(*reply);
        vec[1].iov_base = current->reply_data;
        vec[1].iov_len  = current->reply_size;

244
        if ((ret = writev( get_unix_fd( current->reply_fd ), vec, 2 )) < sizeof(*reply)) goto error;
245 246

        if ((current->reply_towrite = current->reply_size - (ret - sizeof(*reply))))
247
        {
248
            /* couldn't write it all, wait for POLLOUT */
249 250
            set_fd_events( current->reply_fd, POLLOUT );
            set_fd_events( current->request_fd, 0 );
251 252
            return;
        }
253
    }
254 255
    free( current->reply_data );
    current->reply_data = NULL;
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
    return;

 error:
    if (ret >= 0)
        fatal_protocol_error( current, "partial write %d\n", ret );
    else if (errno == EPIPE)
        kill_thread( current, 0 );  /* normal death */
    else
        fatal_protocol_perror( current, "reply write" );
}

/* call a request handler */
static void call_req_handler( struct thread *thread )
{
    union generic_reply reply;
    enum request req = thread->req.request_header.req;

    current = thread;
    current->reply_size = 0;
    clear_error();
    memset( &reply, 0, sizeof(reply) );

    if (debug_level) trace_request();
279 280

    if (req < REQ_NB_REQUESTS)
281
        req_handlers[req]( &current->req, &reply );
282 283 284 285 286 287
    else
        set_error( STATUS_NOT_IMPLEMENTED );

    if (current)
    {
        if (current->reply_fd)
288
        {
289 290 291 292
            reply.reply_header.error = current->error;
            reply.reply_header.reply_size = current->reply_size;
            if (debug_level) trace_reply( req, &reply );
            send_reply( &reply );
293
        }
294 295 296 297 298
        else
        {
            current->exit_code = 1;
            kill_thread( current, 1 );  /* no way to continue without reply fd */
        }
299
    }
300
    current = NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
301 302
}

303 304 305 306 307
/* read a request from a thread */
void read_request( struct thread *thread )
{
    int ret;

308
    if (!thread->req_toread)  /* no pending request */
309
    {
310
        if ((ret = read( get_unix_fd( thread->request_fd ), &thread->req,
311 312 313 314 315 316 317 318
                         sizeof(thread->req) )) != sizeof(thread->req)) goto error;
        if (!(thread->req_toread = thread->req.request_header.request_size))
        {
            /* no data, handle request at once */
            call_req_handler( thread );
            return;
        }
        if (!(thread->req_data = malloc( thread->req_toread )))
319 320 321 322 323
        {
            fatal_protocol_error( thread, "no memory for %u bytes request %d\n",
                                  thread->req_toread, thread->req.request_header.req );
            return;
        }
324
    }
325 326 327 328

    /* read the variable sized data */
    for (;;)
    {
329 330 331
        ret = read( get_unix_fd( thread->request_fd ),
                    (char *)thread->req_data + thread->req.request_header.request_size
                      - thread->req_toread,
332 333 334 335 336 337 338 339 340 341 342 343
                    thread->req_toread );
        if (ret <= 0) break;
        if (!(thread->req_toread -= ret))
        {
            call_req_handler( thread );
            free( thread->req_data );
            thread->req_data = NULL;
            return;
        }
    }

error:
344 345 346 347
    if (!ret)  /* closed pipe */
        kill_thread( thread, 0 );
    else if (ret > 0)
        fatal_protocol_error( thread, "partial read %d\n", ret );
348
    else if (errno != EWOULDBLOCK && errno != EAGAIN)
349 350 351
        fatal_protocol_perror( thread, "read" );
}

352 353
/* receive a file descriptor on the process socket */
int receive_fd( struct process *process )
354
{
355 356
    struct send_fd data;
    int fd, ret;
357

358
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
359
    msghdr.msg_accrightslen = sizeof(int);
360
    msghdr.msg_accrights = (void *)&fd;
361
#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
362
    msghdr.msg_control    = &cmsg;
363
    msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
364
    cmsg.fd = -1;
365
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
366

367
    myiovec.iov_base = (void *)&data;
368
    myiovec.iov_len  = sizeof(data);
369

370
    ret = recvmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
371
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
372
    fd = cmsg.fd;
373 374
#endif

375
    if (ret == sizeof(data))
376
    {
377 378 379
        struct thread *thread;

        if (data.tid) thread = get_thread_from_id( data.tid );
380
        else thread = (struct thread *)grab_object( get_process_first_thread( process ));
381

382
        if (!thread || thread->process != process || thread->state == TERMINATED)
383 384
        {
            if (debug_level)
385 386
                fprintf( stderr, "%04x: *fd* %d <- %d bad thread id\n",
                         data.tid, data.fd, fd );
387 388 389 390 391
            close( fd );
        }
        else
        {
            if (debug_level)
392 393
                fprintf( stderr, "%04x: *fd* %d <- %d\n",
                         thread->id, data.fd, fd );
394 395
            thread_add_inflight_fd( thread, data.fd, fd );
        }
396
        if (thread) release_object( thread );
397 398 399
        return 0;
    }

400 401
    if (!ret)
    {
402
        kill_process( process, 0 );
403 404
    }
    else if (ret > 0)
405
    {
406 407
        fprintf( stderr, "Protocol error: process %04x: partial recvmsg %d for fd\n",
                 process->id, ret );
408
        kill_process( process, 1 );
409
    }
410
    else
411 412 413
    {
        if (errno != EWOULDBLOCK && errno != EAGAIN)
        {
414
            fprintf( stderr, "Protocol error: process %04x: ", process->id );
415
            perror( "recvmsg" );
416
            kill_process( process, 1 );
417 418 419
        }
    }
    return -1;
420 421
}

422
/* send an fd to a client */
423
int send_client_fd( struct process *process, int fd, obj_handle_t handle )
424 425 426
{
    int ret;

427
    if (debug_level)
428 429
        fprintf( stderr, "%04x: *fd* %p -> %d\n",
                 current ? current->id : process->id, handle, fd );
430

431
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
432 433
    msghdr.msg_accrightslen = sizeof(fd);
    msghdr.msg_accrights = (void *)&fd;
434
#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
435
    msghdr.msg_control    = &cmsg;
436
    msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
437
    cmsg.fd = fd;
438
#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
439

440 441
    myiovec.iov_base = (void *)&handle;
    myiovec.iov_len  = sizeof(handle);
442

443
    ret = sendmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
444

445 446 447
    if (ret == sizeof(handle)) return 0;

    if (ret >= 0)
448
    {
449
        fprintf( stderr, "Protocol error: process %04x: partial sendmsg %d\n", process->id, ret );
450
        kill_process( process, 1 );
451
    }
452 453
    else if (errno == EPIPE)
    {
454
        kill_process( process, 0 );
455
    }
456 457
    else
    {
458
        fprintf( stderr, "Protocol error: process %04x: ", process->id );
459
        perror( "sendmsg" );
460
        kill_process( process, 1 );
461 462
    }
    return -1;
463 464
}

465 466 467
/* get current tick count to return to client */
unsigned int get_tick_count(void)
{
468 469
    return ((current_time.tv_sec - server_start_time.tv_sec) * 1000) +
           ((current_time.tv_usec - server_start_time.tv_usec) / 1000);
470 471
}

472 473 474 475
static void master_socket_dump( struct object *obj, int verbose )
{
    struct master_socket *sock = (struct master_socket *)obj;
    assert( obj->ops == &master_socket_ops );
476 477 478 479 480 481 482 483
    fprintf( stderr, "Master socket fd=%p\n", sock->fd );
}

static void master_socket_destroy( struct object *obj )
{
    struct master_socket *sock = (struct master_socket *)obj;
    assert( obj->ops == &master_socket_ops );
    release_object( sock->fd );
484 485 486
}

/* handle a socket event */
487
static void master_socket_poll_event( struct fd *fd, int event )
488
{
489 490
    struct master_socket *sock = get_fd_user( fd );
    assert( master_socket->obj.ops == &master_socket_ops );
491 492 493 494 495 496 497

    assert( sock == master_socket );  /* there is only one master socket */

    if (event & (POLLERR | POLLHUP))
    {
        /* this is not supposed to happen */
        fprintf( stderr, "wineserver: Error on master socket\n" );
498
        set_fd_events( sock->fd, -1 );
499 500 501 502
    }
    else if (event & POLLIN)
    {
        struct sockaddr_un dummy;
503
        unsigned int len = sizeof(dummy);
504
        int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len );
505
        if (client == -1) return;
506 507 508 509 510
        if (sock->timeout)
        {
            remove_timeout_user( sock->timeout );
            sock->timeout = NULL;
        }
511
        fcntl( client, F_SETFL, O_NONBLOCK );
512
        create_process( client, NULL, 0 );
513 514 515 516 517 518
    }
}

/* remove the socket upon exit */
static void socket_cleanup(void)
{
519
    static int do_it_once;
520
    if (!do_it_once++) unlink( server_socket_name );
521 522
}

523 524
/* create a directory and check its permissions */
static void create_dir( const char *name, struct stat *st )
525
{
526
    if (lstat( name, st ) == -1)
527
    {
528
        if (errno != ENOENT) fatal_perror( "lstat %s", name );
529
        if (mkdir( name, 0700 ) == -1 && errno != EEXIST) fatal_perror( "mkdir %s", name );
530
        if (lstat( name, st ) == -1) fatal_perror( "lstat %s", name );
531
    }
532 533 534
    if (!S_ISDIR(st->st_mode)) fatal_error( "%s is not a directory\n", name );
    if (st->st_uid != getuid()) fatal_error( "%s is not owned by you\n", name );
    if (st->st_mode & 077) fatal_error( "%s must not be accessible by other users\n", name );
535 536 537
}

/* create the server directory and chdir to it */
538
static void create_server_dir( const char *dir )
539
{
540 541
    char *p, *server_dir;
    struct stat st, st2;
542

543
    if (!(server_dir = strdup( dir ))) fatal_error( "out of memory\n" );
544

545
    /* first create the base directory if needed */
546

547 548 549
    p = strrchr( server_dir, '/' );
    *p = 0;
    create_dir( server_dir, &st );
550

551
    /* now create the server directory */
552

553 554 555 556 557 558 559 560 561
    *p = '/';
    create_dir( server_dir, &st );

    if (chdir( server_dir ) == -1) fatal_perror( "chdir %s", server_dir );
    if (stat( ".", &st2 ) == -1) fatal_perror( "stat %s", server_dir );
    if (st.st_dev != st2.st_dev || st.st_ino != st2.st_ino)
        fatal_error( "chdir did not end up in %s\n", server_dir );

    free( server_dir );
562 563
}

564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
/* create the lock file and return its file descriptor */
static int create_server_lock(void)
{
    struct stat st;
    int fd;

    if (lstat( server_lock_name, &st ) == -1)
    {
        if (errno != ENOENT)
            fatal_perror( "lstat %s/%s", wine_get_server_dir(), server_lock_name );
    }
    else
    {
        if (!S_ISREG(st.st_mode))
            fatal_error( "%s/%s is not a regular file\n", wine_get_server_dir(), server_lock_name );
    }

    if ((fd = open( server_lock_name, O_CREAT|O_TRUNC|O_WRONLY, 0600 )) == -1)
        fatal_perror( "error creating %s/%s", wine_get_server_dir(), server_lock_name );
    return fd;
}

586 587
/* wait for the server lock */
int wait_for_lock(void)
588
{
589
    const char *server_dir = wine_get_server_dir();
590 591 592
    int fd, r;
    struct flock fl;

593 594 595
    if (!server_dir) return 0;  /* no server dir, so no lock to wait on */

    create_server_dir( server_dir );
596
    fd = create_server_lock();
597 598 599 600 601 602 603 604 605 606 607

    fl.l_type   = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start  = 0;
    fl.l_len    = 1;
    r = fcntl( fd, F_SETLKW, &fl );
    close(fd);

    return r;
}

608 609 610
/* kill the wine server holding the lock */
int kill_lock_owner( int sig )
{
611
    const char *server_dir = wine_get_server_dir();
612 613 614 615
    int fd, i, ret = 0;
    pid_t pid = 0;
    struct flock fl;

616 617 618
    if (!server_dir) return 0;  /* no server dir, nothing to do */

    create_server_dir( server_dir );
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
    fd = create_server_lock();

    for (i = 0; i < 10; i++)
    {
        fl.l_type   = F_WRLCK;
        fl.l_whence = SEEK_SET;
        fl.l_start  = 0;
        fl.l_len    = 1;
        if (fcntl( fd, F_GETLK, &fl ) == -1) goto done;
        if (fl.l_type != F_WRLCK) goto done;  /* the file is not locked */
        if (!pid)  /* first time around */
        {
            if (!(pid = fl.l_pid)) goto done;  /* shouldn't happen */
            if (sig == -1)
            {
                if (kill( pid, SIGINT ) == -1) goto done;
                kill( pid, SIGCONT );
                ret = 1;
            }
            else  /* just send the specified signal and return */
            {
                ret = (kill( pid, sig ) != -1);
                goto done;
            }
        }
        else if (fl.l_pid != pid) goto done;  /* no longer the same process */
        sleep( 1 );
    }
    /* waited long enough, now kill it */
    kill( pid, SIGKILL );

 done:
    close( fd );
    return ret;
}

655 656 657
/* acquire the main server lock */
static void acquire_lock(void)
{
658
    struct sockaddr_un addr;
659 660 661
    struct stat st;
    struct flock fl;
    int fd, slen, got_lock = 0;
662

663
    fd = create_server_lock();
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678

    fl.l_type   = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start  = 0;
    fl.l_len    = 1;
    if (fcntl( fd, F_SETLK, &fl ) != -1)
    {
        /* check for crashed server */
        if (stat( server_socket_name, &st ) != -1 &&   /* there is a leftover socket */
            stat( "core", &st ) != -1 && st.st_size)   /* and there is a non-empty core file */
        {
            fprintf( stderr,
                     "Warning: a previous instance of the wine server seems to have crashed.\n"
                     "Please run 'gdb %s %s/core',\n"
                     "type 'backtrace' at the gdb prompt and report the results. Thanks.\n\n",
679
                     server_argv0, wine_get_server_dir() );
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
        }
        unlink( server_socket_name ); /* we got the lock, we can safely remove the socket */
        got_lock = 1;
        /* in that case we reuse fd without closing it, this ensures
         * that we hold the lock until the process exits */
    }
    else
    {
        switch(errno)
        {
        case ENOLCK:
            break;
        case EACCES:
            /* check whether locks work at all on this file system */
            if (fcntl( fd, F_GETLK, &fl ) == -1) break;
            /* fall through */
        case EAGAIN:
            exit(2); /* we didn't get the lock, exit with special status */
        default:
699
            fatal_perror( "fcntl %s/%s", wine_get_server_dir(), server_lock_name );
700 701 702 703
        }
        /* it seems we can't use locks on this fs, so we will use the socket existence as lock */
        close( fd );
    }
704

705 706
    if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" );
    addr.sun_family = AF_UNIX;
707
    strcpy( addr.sun_path, server_socket_name );
708
    slen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path) + 1;
709
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
710 711 712
    addr.sun_len = slen;
#endif
    if (bind( fd, (struct sockaddr *)&addr, slen ) == -1)
713 714
    {
        if ((errno == EEXIST) || (errno == EADDRINUSE))
715 716 717 718 719 720
        {
            if (got_lock)
                fatal_error( "couldn't bind to the socket even though we hold the lock\n" );
            exit(2); /* we didn't get the lock, exit with special status */
        }
        fatal_perror( "bind" );
721 722
    }
    atexit( socket_cleanup );
723
    chmod( server_socket_name, 0600 );  /* make sure no other user can connect */
724 725
    if (listen( fd, 5 ) == -1) fatal_perror( "listen" );

726
    if (!(master_socket = alloc_object( &master_socket_ops )) ||
727
        !(master_socket->fd = create_anonymous_fd( &master_socket_fd_ops, fd, &master_socket->obj )))
728
        fatal_error( "out of memory\n" );
729
    master_socket->timeout = NULL;
730
    set_fd_events( master_socket->fd, POLLIN );
731
    make_object_static( &master_socket->obj );
732 733 734 735 736
}

/* open the master server socket and start waiting for new clients */
void open_master_socket(void)
{
737
    const char *server_dir = wine_get_server_dir();
738
    int fd, pid, status, sync_pipe[2];
739 740 741 742 743 744
    char dummy;

    /* make sure no request is larger than the maximum size */
    assert( sizeof(union generic_request) == sizeof(struct request_max_size) );
    assert( sizeof(union generic_reply) == sizeof(struct request_max_size) );

745 746
    if (!server_dir) fatal_error( "directory %s cannot be accessed\n", wine_get_config_dir() );
    create_server_dir( server_dir );
747

748
    if (!foreground)
749
    {
750 751 752 753 754 755 756
        if (pipe( sync_pipe ) == -1) fatal_perror( "pipe" );
        pid = fork();
        switch( pid )
        {
        case 0:  /* child */
            setsid();
            close( sync_pipe[0] );
757

758
            acquire_lock();
759

760 761 762 763 764 765 766
            /* close stdin and stdout */
            if ((fd = open( "/dev/null", O_RDWR )) != -1)
            {
                dup2( fd, 0 );
                dup2( fd, 1 );
                close( fd );
            }
767

768
            /* signal parent */
769
            dummy = 0;
770 771 772
            write( sync_pipe[1], &dummy, 1 );
            close( sync_pipe[1] );
            break;
773

774 775 776
        case -1:
            fatal_perror( "fork" );
            break;
777

778 779
        default:  /* parent */
            close( sync_pipe[1] );
780

781 782 783 784 785 786 787 788 789 790 791 792
            /* wait for child to signal us and then exit */
            if (read( sync_pipe[0], &dummy, 1 ) == 1) _exit(0);

            /* child terminated, propagate exit status */
            wait4( pid, &status, 0, NULL );
            if (WIFEXITED(status)) _exit( WEXITSTATUS(status) );
            _exit(1);
        }
    }
    else  /* remain in the foreground */
    {
        acquire_lock();
793
    }
794

795 796 797 798 799 800
    /* setup msghdr structure constant fields */
    msghdr.msg_name    = NULL;
    msghdr.msg_namelen = 0;
    msghdr.msg_iov     = &myiovec;
    msghdr.msg_iovlen  = 1;

801
    /* init startup time */
802
    gettimeofday( &server_start_time, NULL );
803 804
}

805 806
/* master socket timer expiration handler */
static void close_socket_timeout( void *arg )
807
{
808 809 810
    master_socket->timeout = NULL;
    flush_registry();

811
    /* if a new client is waiting, we keep on running */
812
    if (!force_shutdown && check_fd_events( master_socket->fd, POLLIN )) return;
813 814 815 816

    if (debug_level) fprintf( stderr, "wineserver: exiting (pid=%ld)\n", (long) getpid() );

#ifdef DEBUG_OBJECTS
817
    close_objects();  /* shut down everything properly */
818
#endif
819
    exit( force_shutdown );
820 821
}

822 823 824 825 826 827 828
/* close the master socket and stop waiting for new clients */
void close_master_socket(void)
{
    if (master_socket_timeout == -1) return;  /* just keep running forever */

    if (master_socket_timeout)
    {
829
        struct timeval when = current_time;
830 831 832 833 834 835
        add_timeout( &when, master_socket_timeout * 1000 );
        master_socket->timeout = add_timeout_user( &when, close_socket_timeout, NULL );
    }
    else close_socket_timeout( NULL );  /* close it right away */
}

836 837
/* forced shutdown, used for wineserver -k */
void shutdown_master_socket(void)
838
{
839 840 841 842 843 844 845 846
    force_shutdown = 1;
    master_socket_timeout = 0;
    if (master_socket->timeout)
    {
        remove_timeout_user( master_socket->timeout );
        close_socket_timeout( NULL );
    }
    set_fd_events( master_socket->fd, -1 ); /* stop waiting for new clients */
847
}