Example #1
0
static int sock_get_poll_events( struct fd *fd )
{
    struct sock *sock = get_fd_user( fd );
    unsigned int mask = sock->mask & ~sock->hmask;
    unsigned int smask = sock->state & mask;
    int ev = 0;

    assert( sock->obj.ops == &sock_ops );

    if (sock->state & FD_CONNECT)
        /* connecting, wait for writable */
        return POLLOUT;

    if ( async_queued( sock->read_q ) )
    {
        if ( async_waiting( sock->read_q ) ) ev |= POLLIN | POLLPRI;
    }
    else if (smask & FD_READ || (sock->state & FD_WINE_LISTENING && mask & FD_ACCEPT))
        ev |= POLLIN | POLLPRI;
    /* We use POLLIN with 0 bytes recv() as FD_CLOSE indication for stream sockets. */
    else if ( sock->type == SOCK_STREAM && sock->state & FD_READ && mask & FD_CLOSE &&
              !(sock->hmask & FD_READ) )
        ev |= POLLIN;

    if ( async_queued( sock->write_q ) )
    {
        if ( async_waiting( sock->write_q ) ) ev |= POLLOUT;
    }
    else if (smask & FD_WRITE)
        ev |= POLLOUT;

    return ev;
}
Example #2
0
/* handle a socket event */
static void master_socket_poll_event( struct fd *fd, int event )
{
    struct master_socket *sock = get_fd_user( fd );
    assert( master_socket->obj.ops == &master_socket_ops );

    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" );
        release_object( sock );
    }
    else if (event & POLLIN)
    {
        struct sockaddr_un dummy;
        unsigned int len = sizeof(dummy);
        int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len );
        if (client == -1) return;
        if (sock->timeout)
        {
            remove_timeout_user( sock->timeout );
            sock->timeout = NULL;
        }
        fcntl( client, F_SETFL, O_NONBLOCK );
        create_process( client, NULL, 0 );
    }
}
Example #3
0
static int file_get_info( struct fd *fd )
{
    struct file *file = get_fd_user( fd );

    if (is_overlapped( file )) return FD_FLAG_OVERLAPPED;
    else return 0;
}
Example #4
0
File: file.c Project: ccpgames/wine
static enum server_fd_type file_get_fd_type( struct fd *fd )
{
    struct file *file = get_fd_user( fd );

    if (S_ISREG(file->mode) || S_ISBLK(file->mode)) return FD_TYPE_FILE;
    if (S_ISDIR(file->mode)) return FD_TYPE_DIR;
    return FD_TYPE_CHAR;
}
Example #5
0
File: file.c Project: ccpgames/wine
static int file_get_poll_events( struct fd *fd )
{
    struct file *file = get_fd_user( fd );
    int events = 0;
    assert( file->obj.ops == &file_ops );
    if (file->access & FILE_UNIX_READ_ACCESS) events |= POLLIN;
    if (file->access & FILE_UNIX_WRITE_ACCESS) events |= POLLOUT;
    return events;
}
Example #6
0
static void sock_cancel_async( struct fd *fd, struct process *process, struct thread *thread, client_ptr_t iosb )
{
    struct sock *sock = get_fd_user( fd );
    int n = 0;
    assert( sock->obj.ops == &sock_ops );

    n += async_wake_up_by( sock->read_q, process, thread, iosb, STATUS_CANCELLED );
    n += async_wake_up_by( sock->write_q, process, thread, iosb, STATUS_CANCELLED );
    if (!n && iosb)
        set_error( STATUS_NOT_FOUND );
}
Example #7
0
static obj_handle_t device_file_flush( struct fd *fd, const async_data_t *async_data, int blocking )
{
    struct device_file *file = get_fd_user( fd );
    struct irp_call *irp;
    obj_handle_t handle;
    irp_params_t params;

    memset( &params, 0, sizeof(params) );
    params.flush.major = IRP_MJ_FLUSH_BUFFERS;
    params.flush.file  = file->user_ptr;

    irp = create_irp( file, &params, NULL, 0, 0 );
    if (!irp) return 0;

    handle = queue_irp( file, irp, async_data, blocking );
    release_object( irp );
    return handle;
}
Example #8
0
static void handler_poll_event( struct fd *fd, int event )
{
    struct handler *handler = get_fd_user( fd );

    if (event & (POLLERR | POLLHUP))
    {
        /* this is not supposed to happen */
        fprintf( stderr, "wineserver: Error on signal handler pipe\n" );
        release_object( handler );
    }
    else if (event & POLLIN)
    {
        char dummy;

        handler->pending = 0;
        read( get_unix_fd( handler->fd ), &dummy, 1 );
        handler->callback();
    }
}
Example #9
0
static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
                                       int blocking )
{
    struct device_file *file = get_fd_user( fd );
    struct irp_call *irp;
    obj_handle_t handle;
    irp_params_t params;

    memset( &params, 0, sizeof(params) );
    params.ioctl.major = IRP_MJ_DEVICE_CONTROL;
    params.ioctl.code  = code;
    params.ioctl.file = file->user_ptr;

    irp = create_irp( file, &params, get_req_data(), get_req_data_size(),
                      get_reply_max_size() );
    if (!irp) return 0;

    handle = queue_irp( file, irp, async_data, blocking );
    release_object( irp );
    return handle;
}
Example #10
0
static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_data, int blocking,
                                       file_pos_t pos, data_size_t *written )
{
    struct device_file *file = get_fd_user( fd );
    struct irp_call *irp;
    obj_handle_t handle;
    irp_params_t params;

    memset( &params, 0, sizeof(params) );
    params.write.major = IRP_MJ_WRITE;
    params.write.key   = 0;
    params.write.pos   = pos;
    params.write.file  = file->user_ptr;

    irp = create_irp( file, &params, get_req_data(), get_req_data_size(), 0 );
    if (!irp) return 0;

    handle = queue_irp( file, irp, async_data, blocking );
    release_object( irp );
    return handle;
}
Example #11
0
static obj_handle_t device_file_read( struct fd *fd, const async_data_t *async_data, int blocking,
                                      file_pos_t pos )
{
    struct device_file *file = get_fd_user( fd );
    struct irp_call *irp;
    obj_handle_t handle;
    irp_params_t params;

    memset( &params, 0, sizeof(params) );
    params.read.major = IRP_MJ_READ;
    params.read.key   = 0;
    params.read.pos   = pos;
    params.read.file  = file->user_ptr;

    irp = create_irp( file, &params, NULL, 0, get_reply_max_size() );
    if (!irp) return 0;

    handle = queue_irp( file, irp, async_data, blocking );
    release_object( irp );
    return handle;
}
Example #12
0
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
                                  int blocking, const void *data, data_size_t size )
{
    struct device *device = get_fd_user( fd );
    struct ioctl_call *ioctl;
    obj_handle_t handle;

    if (!device->manager)  /* it has been deleted */
    {
        set_error( STATUS_FILE_DELETED );
        return 0;
    }

    if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() )))
        return 0;

    ioctl->thread   = (struct thread *)grab_object( current );
    ioctl->user_arg = async_data->arg;

    if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 )))
    {
        release_object( ioctl );
        return 0;
    }

    if (!(ioctl->async = fd_queue_async( device->fd, async_data, ASYNC_TYPE_WAIT )))
    {
        close_handle( current->process, handle );
        release_object( ioctl );
        return 0;
    }
    list_add_tail( &device->requests, &ioctl->dev_entry );
    list_add_tail( &device->manager->requests, &ioctl->mgr_entry );
    if (list_head( &device->manager->requests ) == &ioctl->mgr_entry)  /* first one */
        wake_up( &device->manager->obj, 0 );
    /* don't release ioctl since it is now queued in the device */
    set_error( STATUS_PENDING );
    return handle;
}
Example #13
0
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
{
    struct sock *sock = get_fd_user( fd );
    struct async *async;
    struct async_queue *queue;

    assert( sock->obj.ops == &sock_ops );

    switch (type)
    {
    case ASYNC_TYPE_READ:
        if (!sock->read_q && !(sock->read_q = create_async_queue( sock->fd ))) return;
        queue = sock->read_q;
        break;
    case ASYNC_TYPE_WRITE:
        if (!sock->write_q && !(sock->write_q = create_async_queue( sock->fd ))) return;
        queue = sock->write_q;
        break;
    default:
        set_error( STATUS_INVALID_PARAMETER );
        return;
    }

    if ( ( !( sock->state & (FD_READ|FD_CONNECT|FD_WINE_LISTENING) ) && type == ASYNC_TYPE_READ  ) ||
         ( !( sock->state & (FD_WRITE|FD_CONNECT) ) && type == ASYNC_TYPE_WRITE ) )
    {
        set_error( STATUS_PIPE_DISCONNECTED );
        return;
    }

    if (!(async = create_async( current, queue, data ))) return;
    release_object( async );

    sock_reselect( sock );

    set_error( STATUS_PENDING );
}
Example #14
0
static void sock_reselect_async( struct fd *fd, struct async_queue *queue )
{
    struct sock *sock = get_fd_user( fd );
    sock_reselect( sock );
}
Example #15
0
static void sock_poll_event( struct fd *fd, int event )
{
    struct sock *sock = get_fd_user( fd );
    int hangup_seen = 0;
    int prevstate = sock->state;
    int error = 0;

    assert( sock->obj.ops == &sock_ops );
    if (debug_level)
        fprintf(stderr, "socket %p select event: %x\n", sock, event);

    /* we may change event later, remove from loop here */
    if (event & (POLLERR|POLLHUP)) set_fd_events( sock->fd, -1 );

    if (sock->state & FD_CONNECT)
    {
        if (event & (POLLERR|POLLHUP))
        {
            /* we didn't get connected? */
            sock->state &= ~FD_CONNECT;
            event &= ~POLLOUT;
            error = sock_error( fd );
        }
        else if (event & POLLOUT)
        {
            /* we got connected */
            sock->state |= FD_WINE_CONNECTED|FD_READ|FD_WRITE;
            sock->state &= ~FD_CONNECT;
        }
    }
    else if (sock->state & FD_WINE_LISTENING)
    {
        /* listening */
        if (event & (POLLERR|POLLHUP))
            error = sock_error( fd );
    }
    else
    {
        /* normal data flow */
        if ( sock->type == SOCK_STREAM && ( event & POLLIN ) )
        {
            char dummy;
            int nr;

            /* Linux 2.4 doesn't report POLLHUP if only one side of the socket
             * has been closed, so we need to check for it explicitly here */
            nr  = recv( get_unix_fd( fd ), &dummy, 1, MSG_PEEK );
            if ( nr == 0 )
            {
                hangup_seen = 1;
                event &= ~POLLIN;
            }
            else if ( nr < 0 )
            {
                event &= ~POLLIN;
                /* EAGAIN can happen if an async recv() falls between the server's poll()
                   call and the invocation of this routine */
                if ( errno != EAGAIN )
                {
                    error = errno;
                    event |= POLLERR;
                    if ( debug_level )
                        fprintf( stderr, "recv error on socket %p: %d\n", sock, errno );
                }
            }
        }

        if ( (hangup_seen || event & (POLLHUP|POLLERR)) && (sock->state & (FD_READ|FD_WRITE)) )
        {
            error = error ? error : sock_error( fd );
            if ( (event & POLLERR) || ( sock_shutdown_type == SOCK_SHUTDOWN_EOF && (event & POLLHUP) ))
                sock->state &= ~FD_WRITE;
            sock->state &= ~FD_READ;

            if (debug_level)
                fprintf(stderr, "socket %p aborted by error %d, event: %x\n", sock, error, event);
        }

        if (hangup_seen)
            event |= POLLHUP;
    }

    event = sock_dispatch_asyncs( sock, event, error );
    sock_dispatch_events( sock, prevstate, event, error );

    /* if anyone is stupid enough to wait on the socket object itself,
     * maybe we should wake them up too, just in case? */
    wake_up( &sock->obj, 0 );

    sock_reselect( sock );
}