示例#1
0
static void net_socket_send(void *opaque)
{
    NetSocketState *s = opaque;
    int size, err;
    unsigned l;
    uint8_t buf1[4096];
    const uint8_t *buf;

    size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);
    if (size < 0) {
        err = socket_error();
        if (err != EWOULDBLOCK)
            goto eoc;
    } else if (size == 0) {
        /* end of connection */
    eoc:
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
        closesocket(s->fd);
        return;
    }
    buf = buf1;
    while (size > 0) {
        /* reassemble a packet from the network */
        switch(s->state) {
        case 0:
            l = 4 - s->index;
            if (l > size)
                l = size;
            memcpy(s->buf + s->index, buf, l);
            buf += l;
            size -= l;
            s->index += l;
            if (s->index == 4) {
                /* got length */
                s->packet_len = ntohl(*(uint32_t *)s->buf);
                s->index = 0;
                s->state = 1;
            }
            break;
        case 1:
            l = s->packet_len - s->index;
            if (l > size)
                l = size;
            if (s->index + l <= sizeof(s->buf)) {
                memcpy(s->buf + s->index, buf, l);
            } else {
                fprintf(stderr, "serious error: oversized packet received,"
                    "connection terminated.\n");
                s->state = 0;
                goto eoc;
            }

            s->index += l;
            buf += l;
            size -= l;
            if (s->index >= s->packet_len) {
                qemu_send_packet(&s->nc, s->buf, s->packet_len);
                s->index = 0;
                s->state = 0;
            }
            break;
        }
    }
}
示例#2
0
CharDriverState *chr_baum_init(void)
{
    BaumDriverState *baum;
    CharDriverState *chr;
    brlapi_handle_t *handle;
#if defined(CONFIG_SDL)
#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
    SDL_SysWMinfo info;
#endif
#endif
    int tty;

    baum = g_malloc0(sizeof(BaumDriverState));
    baum->chr = chr = qemu_chr_alloc();

    chr->opaque = baum;
    chr->chr_write = baum_write;
    chr->chr_accept_input = baum_accept_input;
    chr->chr_close = baum_close;

    handle = g_malloc0(brlapi_getHandleSize());
    baum->brlapi = handle;

    baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
    if (baum->brlapi_fd == -1) {
        brlapi_perror("baum_init: brlapi_openConnection");
        goto fail_handle;
    }

    baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);

    if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
        brlapi_perror("baum_init: brlapi_getDisplaySize");
        goto fail;
    }

#if defined(CONFIG_SDL)
#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
    memset(&info, 0, sizeof(info));
    SDL_VERSION(&info.version);
    if (SDL_GetWMInfo(&info))
        tty = info.info.x11.wmwindow;
    else
#endif
#endif
        tty = BRLAPI_TTY_DEFAULT;

    if (brlapi__enterTtyMode(handle, tty, NULL) == -1) {
        brlapi_perror("baum_init: brlapi_enterTtyMode");
        goto fail;
    }

    qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);

    return chr;

fail:
    timer_free(baum->cellCount_timer);
    brlapi__closeConnection(handle);
fail_handle:
    g_free(handle);
    g_free(chr);
    g_free(baum);
    return NULL;
}
示例#3
0
static void fd_coroutine_enter(void *opaque)
{
    FDYieldUntilData *data = opaque;
    qemu_set_fd_handler(data->fd, NULL, NULL, NULL);
    qemu_coroutine_enter(data->co, NULL);
}
示例#4
0
static void net_socket_cleanup(VLANClientState *nc)
{
    NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
    qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
    close(s->fd);
}
示例#5
0
static void client_handler(void *opaque)
{
    QemuHttpConnection *conn = (QemuHttpConnection *)opaque;

    if (conn->state == NEW_REQUEST) {
        conn->pos = 0;
    }
    if (conn->pos == HEADER_SIZE) {
        conn->pos = 0;
    }

    int read_bytes
        = read(conn->fd, conn->in_buffer + conn->pos, HEADER_SIZE - conn->pos);

    /* connection is closed or invalid */
    if (read_bytes == 0
            || (read_bytes == -1 && (errno != EINTR && errno != EAGAIN)))
    {
        goto end_connection;
    }

    if (conn->state == NEW_REQUEST) {
        conn->state = IN_HEADERS;
    }

    int b = conn->pos;
    int e = conn->pos + read_bytes;
    while (b < e) {
        /* we are at beginning ? */
        if (!conn->page_complete) {
            while (b < e) {
                if (conn->page_pos >= 0 && conn->page[conn->page_pos] == '\r'
                        && conn->in_buffer[b] == '\n')
                {
                    conn->page[++conn->page_pos] = conn->in_buffer[b++];
                    conn->page_complete = 1;
                    break;
                } else {
                    conn->page[++conn->page_pos] = conn->in_buffer[b++];
                }
            }
        } else {
            if (b >= 3) {
                if (conn->in_buffer[b-3] == '\r' && conn->in_buffer[b-2] == '\n'
                        && conn->in_buffer[b-1] == '\r' && conn->in_buffer[b] == '\n')
                {
                    conn->state = NEW_REQUEST;
                    goto process_request;
                }
            }
            b++;
        }
    }
    conn->pos = e;

    if (conn->state == IN_HEADERS) {
        return;
    }

process_request:
    if (parse_page(conn) || process_request(conn)) {
        goto end_connection;
    }

end_connection:
    close(conn->fd);
    conn->open = 0;
    conn->state = NEW_REQUEST;
    ghttp_state->connections--;
    qemu_set_fd_handler(conn->fd, NULL, NULL, NULL);
}
示例#6
0
int event_notifier_set_handler(EventNotifier *e,
                               EventNotifierHandler *handler)
{
    qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e);
    return 0;
}
示例#7
0
CharDriverState *chr_baum_init(QemuOpts *opts)
{
    BaumDriverState *baum;
    CharDriverState *chr;
    brlapi_handle_t *handle;
#ifdef CONFIG_SDL
    SDL_SysWMinfo info;
#endif
    int tty;

    baum = qemu_mallocz(sizeof(BaumDriverState));
    baum->chr = chr = qemu_mallocz(sizeof(CharDriverState));

    chr->opaque = baum;
    chr->chr_write = baum_write;
    chr->chr_send_event = baum_send_event;
    chr->chr_accept_input = baum_accept_input;

    handle = qemu_mallocz(brlapi_getHandleSize());
    baum->brlapi = handle;

    baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
    if (baum->brlapi_fd == -1) {
        brlapi_perror("baum_init: brlapi_openConnection");
        goto fail_handle;
    }

    baum->cellCount_timer = qemu_new_timer(vm_clock, baum_cellCount_timer_cb, baum);

    if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
        brlapi_perror("baum_init: brlapi_getDisplaySize");
        goto fail;
    }

#ifdef CONFIG_SDL
    memset(&info, 0, sizeof(info));
    SDL_VERSION(&info.version);
    if (SDL_GetWMInfo(&info))
        tty = info.info.x11.wmwindow;
    else
#endif
        tty = BRLAPI_TTY_DEFAULT;

    if (brlapi__enterTtyMode(handle, tty, NULL) == -1) {
        brlapi_perror("baum_init: brlapi_enterTtyMode");
        goto fail;
    }

    qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);

    qemu_chr_reset(chr);

    return chr;

fail:
    qemu_free_timer(baum->cellCount_timer);
    brlapi__closeConnection(handle);
fail_handle:
    free(handle);
    free(chr);
    free(baum);
    return NULL;
}
示例#8
0
static int unix_connect_saddr(UnixSocketAddress *saddr,
                              NonBlockingConnectHandler *callback, void *opaque,
                              Error **errp)
{
    struct sockaddr_un un;
    ConnectState *connect_state = NULL;
    int sock, rc;

    if (saddr->path == NULL) {
        error_setg(errp, "unix connect: no path specified");
        return -1;
    }

    sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
    if (sock < 0) {
        error_setg_errno(errp, errno, "Failed to create socket");
        return -1;
    }
    if (callback != NULL) {
        connect_state = g_malloc0(sizeof(*connect_state));
        connect_state->callback = callback;
        connect_state->opaque = opaque;
        qemu_set_nonblock(sock);
    }

    if (strlen(saddr->path) > sizeof(un.sun_path)) {
        error_setg(errp, "UNIX socket path '%s' is too long", saddr->path);
        error_append_hint(errp, "Path must be less than %zu bytes\n",
                          sizeof(un.sun_path));
        goto err;
    }

    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    strncpy(un.sun_path, saddr->path, sizeof(un.sun_path));

    /* connect to peer */
    do {
        rc = 0;
        if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
            rc = -errno;
        }
    } while (rc == -EINTR);

    if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
        connect_state->fd = sock;
        qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
        return sock;
    } else if (rc >= 0) {
        /* non blocking socket immediate success, call callback */
        if (callback != NULL) {
            callback(sock, NULL, opaque);
        }
    }

    if (rc < 0) {
        error_setg_errno(errp, -rc, "Failed to connect socket %s",
                         saddr->path);
        goto err;
    }

    g_free(connect_state);
    return sock;

 err:
    close(sock);
    g_free(connect_state);
    return -1;
}
ClientFramebuffer*
clientfb_create(SockAddress* console_socket,
                const char* protocol,
                QFrameBuffer* fb)
{
    char* connect_message = NULL;
    char switch_cmd[256];

    // Connect to the framebuffer service.
    _client_fb.core_connection = core_connection_create(console_socket);
    if (_client_fb.core_connection == NULL) {
        derror("Framebuffer client is unable to connect to the console: %s\n",
               errno_str);
        return NULL;
    }
    if (core_connection_open(_client_fb.core_connection)) {
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        derror("Framebuffer client is unable to open the console: %s\n",
               errno_str);
        return NULL;
    }
    snprintf(switch_cmd, sizeof(switch_cmd), "framebuffer %s", protocol);
    if (core_connection_switch_stream(_client_fb.core_connection, switch_cmd,
                                      &connect_message)) {
        derror("Unable to attach to the framebuffer %s: %s\n",
               switch_cmd, connect_message ? connect_message : "");
        if (connect_message != NULL) {
            free(connect_message);
        }
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // We expect core framebuffer to return us bits per pixel property in
    // the handshake message.
    _client_fb.bits_per_pixel = 0;
    if (connect_message != NULL) {
        char* bpp = strstr(connect_message, "bitsperpixel=");
        if (bpp != NULL) {
            char* end;
            bpp += strlen("bitsperpixel=");
            end = strchr(bpp, ' ');
            if (end == NULL) {
                end = bpp + strlen(bpp);
            }
            _client_fb.bits_per_pixel = strtol(bpp, &end, 0);
        }
    }

    if (!_client_fb.bits_per_pixel) {
        derror("Unexpected core framebuffer reply: %s\n"
               "Bits per pixel property is not there, or is invalid\n", connect_message);
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // Now that we're connected lets initialize the descriptor.
    _client_fb.fb = fb;
    _client_fb.sock = core_connection_get_socket(_client_fb.core_connection);
    _client_fb.fb_state = WAIT_HEADER;
    _client_fb.reader_buffer = (uint8_t*)&_client_fb.update_header;
    _client_fb.reader_offset = 0;
    _client_fb.reader_bytes = sizeof(FBUpdateMessage);

    if (connect_message != NULL) {
        free(connect_message);
    }

    // At last setup read callback, and start receiving the updates.
    if (qemu_set_fd_handler(_client_fb.sock, _clientfb_read_cb, NULL, &_client_fb)) {
        derror("Unable to set up framebuffer read callback\n");
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }
    {
        // Force the core to send us entire framebuffer now, when we're prepared
        // to receive it.
        FBRequestHeader hd;
        SyncSocket* sk = syncsocket_init(_client_fb.sock);

        hd.request_type = AFB_REQUEST_REFRESH;
        syncsocket_start_write(sk);
        syncsocket_write(sk, &hd, sizeof(hd), 500);
        syncsocket_stop_write(sk);
        syncsocket_free(sk);
    }
    fprintf(stdout, "Framebuffer %s is now attached to the core %s\n",
            protocol, sock_address_to_string(console_socket));

    return &_client_fb;
}
示例#10
0
文件: baum.c 项目: JeremyAgost/qemu
static CharDriverState *chr_baum_init(const char *id,
                                      ChardevBackend *backend,
                                      ChardevReturn *ret,
                                      Error **errp)
{
    ChardevCommon *common = backend->u.braille;
    BaumDriverState *baum;
    CharDriverState *chr;
    brlapi_handle_t *handle;
#if defined(CONFIG_SDL)
#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
    SDL_SysWMinfo info;
#endif
#endif
    int tty;

    chr = qemu_chr_alloc(common, errp);
    if (!chr) {
        return NULL;
    }
    baum = g_malloc0(sizeof(BaumDriverState));
    baum->chr = chr;

    chr->opaque = baum;
    chr->chr_write = baum_write;
    chr->chr_accept_input = baum_accept_input;
    chr->chr_close = baum_close;

    handle = g_malloc0(brlapi_getHandleSize());
    baum->brlapi = handle;

    baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
    if (baum->brlapi_fd == -1) {
        error_setg(errp, "brlapi__openConnection: %s",
                   brlapi_strerror(brlapi_error_location()));
        goto fail_handle;
    }

    baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);

    if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
        error_setg(errp, "brlapi__getDisplaySize: %s",
                   brlapi_strerror(brlapi_error_location()));
        goto fail;
    }

#if defined(CONFIG_SDL)
#if SDL_COMPILEDVERSION < SDL_VERSIONNUM(2, 0, 0)
    memset(&info, 0, sizeof(info));
    SDL_VERSION(&info.version);
    if (SDL_GetWMInfo(&info))
        tty = info.info.x11.wmwindow;
    else
#endif
#endif
        tty = BRLAPI_TTY_DEFAULT;

    if (brlapi__enterTtyMode(handle, tty, NULL) == -1) {
        error_setg(errp, "brlapi__enterTtyMode: %s",
                   brlapi_strerror(brlapi_error_location()));
        goto fail;
    }

    qemu_set_fd_handler(baum->brlapi_fd, baum_chr_read, NULL, baum);

    return chr;

fail:
    timer_free(baum->cellCount_timer);
    brlapi__closeConnection(handle);
fail_handle:
    g_free(handle);
    g_free(chr);
    g_free(baum);
    return NULL;
}
示例#11
0
static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
{
    Error *err = NULL;
    int i;
    Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
    V9fsState *s = &xen_9pdev->state;
    QemuOpts *fsdev;

    if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings",
                             &xen_9pdev->num_rings) == -1 ||
        xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) {
        return -1;
    }

    xen_9pdev->rings = g_new0(Xen9pfsRing, xen_9pdev->num_rings);
    for (i = 0; i < xen_9pdev->num_rings; i++) {
        char *str;
        int ring_order;

        xen_9pdev->rings[i].priv = xen_9pdev;
        xen_9pdev->rings[i].evtchn = -1;
        xen_9pdev->rings[i].local_port = -1;

        str = g_strdup_printf("ring-ref%u", i);
        if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
                                 &xen_9pdev->rings[i].ref) == -1) {
            g_free(str);
            goto out;
        }
        g_free(str);
        str = g_strdup_printf("event-channel-%u", i);
        if (xenstore_read_fe_int(&xen_9pdev->xendev, str,
                                 &xen_9pdev->rings[i].evtchn) == -1) {
            g_free(str);
            goto out;
        }
        g_free(str);

        xen_9pdev->rings[i].intf =
            xen_be_map_grant_ref(&xen_9pdev->xendev,
                                 xen_9pdev->rings[i].ref,
                                 PROT_READ | PROT_WRITE);
        if (!xen_9pdev->rings[i].intf) {
            goto out;
        }
        ring_order = xen_9pdev->rings[i].intf->ring_order;
        if (ring_order > MAX_RING_ORDER) {
            goto out;
        }
        xen_9pdev->rings[i].ring_order = ring_order;
        xen_9pdev->rings[i].data =
            xen_be_map_grant_refs(&xen_9pdev->xendev,
                                  xen_9pdev->rings[i].intf->ref,
                                  (1 << ring_order),
                                  PROT_READ | PROT_WRITE);
        if (!xen_9pdev->rings[i].data) {
            goto out;
        }
        xen_9pdev->rings[i].ring.in = xen_9pdev->rings[i].data;
        xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data +
                                       XEN_FLEX_RING_SIZE(ring_order);

        xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]);
        xen_9pdev->rings[i].out_cons = 0;
        xen_9pdev->rings[i].out_size = 0;
        xen_9pdev->rings[i].inprogress = false;


        xen_9pdev->rings[i].evtchndev = xenevtchn_open(NULL, 0);
        if (xen_9pdev->rings[i].evtchndev == NULL) {
            goto out;
        }
        qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev));
        xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain
                                            (xen_9pdev->rings[i].evtchndev,
                                             xendev->dom,
                                             xen_9pdev->rings[i].evtchn);
        if (xen_9pdev->rings[i].local_port == -1) {
            xen_pv_printf(xendev, 0,
                          "xenevtchn_bind_interdomain failed port=%d\n",
                          xen_9pdev->rings[i].evtchn);
            goto out;
        }
        xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
        qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev),
                xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings[i]);
    }

    xen_9pdev->security_model = xenstore_read_be_str(xendev, "security_model");
    xen_9pdev->path = xenstore_read_be_str(xendev, "path");
    xen_9pdev->id = s->fsconf.fsdev_id =
        g_strdup_printf("xen9p%d", xendev->dev);
    xen_9pdev->tag = s->fsconf.tag = xenstore_read_fe_str(xendev, "tag");
    fsdev = qemu_opts_create(qemu_find_opts("fsdev"),
            s->fsconf.tag,
            1, NULL);
    qemu_opt_set(fsdev, "fsdriver", "local", NULL);
    qemu_opt_set(fsdev, "path", xen_9pdev->path, NULL);
    qemu_opt_set(fsdev, "security_model", xen_9pdev->security_model, NULL);
    qemu_opts_set_id(fsdev, s->fsconf.fsdev_id);
    qemu_fsdev_add(fsdev, &err);
    if (err) {
        error_report_err(err);
    }
    v9fs_device_realize_common(s, &xen_9p_transport, NULL);

    return 0;

out:
    xen_9pfs_free(xendev);
    return -1;
}
示例#12
0
文件: vde.c 项目: 01org/KVMGT-qemu
static void vde_cleanup(NetClientState *nc)
{
    VDEState *s = DO_UPCAST(VDEState, nc, nc);
    qemu_set_fd_handler(vde_datafd(s->vde), NULL, NULL, NULL);
    vde_close(s->vde);
}
static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
{
    int fd = -1, ret;
    USBHostDevice *dev = NULL;
    struct usbdevfs_connectinfo ci;
    char buf[1024];

    dev = qemu_mallocz(sizeof(USBHostDevice));
    if (!dev)
        goto fail;

    dev->bus_num = bus_num;
    dev->addr = addr;

    printf("husb: open device %d.%d\n", bus_num, addr);

    if (!usb_host_device_path) {
        perror("husb: USB Host Device Path not set");
        goto fail;
    }
    snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
             bus_num, addr);
    fd = open(buf, O_RDWR | O_NONBLOCK);
    if (fd < 0) {
        perror(buf);
        goto fail;
    }
    dprintf("husb: opened %s\n", buf);

    /* read the device description */
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
    if (dev->descr_len <= 0) {
        perror("husb: reading device data failed");
        goto fail;
    }

#ifdef DEBUG
    {
        int x;
        printf("=== begin dumping device descriptor data ===\n");
        for (x = 0; x < dev->descr_len; x++)
            printf("%02x ", dev->descr[x]);
        printf("\n=== end dumping device descriptor data ===\n");
    }
#endif

    dev->fd = fd;

    /* 
     * Initial configuration is -1 which makes us claim first 
     * available config. We used to start with 1, which does not
     * always work. I've seen devices where first config starts 
     * with 2.
     */
    if (!usb_host_claim_interfaces(dev, -1))
        goto fail;

    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
    if (ret < 0) {
        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
        goto fail;
    }

    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);

    ret = usb_linux_update_endp_table(dev);
    if (ret)
        goto fail;

    if (ci.slow)
        dev->dev.speed = USB_SPEED_LOW;
    else
        dev->dev.speed = USB_SPEED_HIGH;

    dev->dev.handle_packet  = usb_host_handle_packet;
    dev->dev.handle_reset   = usb_host_handle_reset;
    dev->dev.handle_destroy = usb_host_handle_destroy;

    if (!prod_name || prod_name[0] == '\0')
        snprintf(dev->dev.devname, sizeof(dev->dev.devname),
                 "host:%d.%d", bus_num, addr);
    else
        pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
                prod_name);

    /* USB devio uses 'write' flag to check for async completions */
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);

    hostdev_link(dev);

    return (USBDevice *) dev;

fail:
    if (dev)
        qemu_free(dev);

    close(fd);
    return NULL;
}
示例#14
0
static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
                                                const char *model,
                                                const char *name,
                                                int fd, int is_connected)
{
    struct sockaddr_in saddr;
    int newfd;
    socklen_t saddr_len;
    NetClientState *nc;
    NetSocketState *s;

    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it
     * Because this may be "shared" socket from a "master" process, datagrams would be recv()
     * by ONLY ONE process: we must "clone" this dgram socket --jjo
     */

    if (is_connected) {
        if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
            /* must be bound */
            if (saddr.sin_addr.s_addr == 0) {
                fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, "
                        "cannot setup multicast dst addr\n", fd);
                goto err;
            }
            /* clone dgram socket */
            newfd = net_socket_mcast_create(&saddr, NULL);
            if (newfd < 0) {
                /* error already reported by net_socket_mcast_create() */
                goto err;
            }
            /* clone newfd to fd, close newfd */
            dup2(newfd, fd);
            close(newfd);

        } else {
            fprintf(stderr,
                    "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",
                    fd, strerror(errno));
            goto err;
        }
    }

    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);

    snprintf(nc->info_str, sizeof(nc->info_str),
            "socket: fd=%d (%s mcast=%s:%d)",
            fd, is_connected ? "cloned" : "",
            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    s = DO_UPCAST(NetSocketState, nc, nc);

    s->fd = fd;
    s->listen_fd = -1;

    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);

    /* mcast: save bound address as dst */
    if (is_connected) {
        s->dgram_dst = saddr;
    }

    return s;

err:
    closesocket(fd);
    return NULL;
}
void  sys_channel_close( SysChannel  channel )
{
    qemu_set_fd_handler( channel->fd, NULL, NULL, NULL );
    sys_channel_free( channel );
}
示例#16
0
static void net_socket_connect(void *opaque)
{
    NetSocketState *s = opaque;
    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
}
示例#17
0
文件: cmd.c 项目: breuerr/qemu
void command_loop(void)
{
    int c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
    char *input;
    char **v;
    const cmdinfo_t *ct;

    for (i = 0; !done && i < ncmdline; i++) {
        input = strdup(cmdline[i]);
        if (!input) {
            fprintf(stderr, _("cannot strdup command '%s': %s\n"),
                    cmdline[i], strerror(errno));
            exit(1);
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                if (ct->flags & CMD_FLAG_GLOBAL) {
                    done = command(ct, c, v);
                } else {
                    j = 0;
                    while (!done && (j = args_command(j))) {
                        done = command(ct, c, v);
                    }
                }
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
	}
        doneline(input, v);
    }
    if (cmdline) {
        g_free(cmdline);
        return;
    }

    while (!done) {
        if (!prompted) {
            printf("%s", get_prompt());
            fflush(stdout);
            qemu_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, &fetchable);
            prompted = 1;
        }

        main_loop_wait(false);

        if (!fetchable) {
            continue;
        }
        input = fetchline();
        if (input == NULL) {
            break;
        }
        v = breakline(input, &c);
        if (c) {
            ct = find_command(v[0]);
            if (ct) {
                done = command(ct, c, v);
            } else {
                fprintf(stderr, _("command \"%s\" not found\n"), v[0]);
            }
        }
        doneline(input, v);

        prompted = 0;
        fetchable = 0;
    }
    qemu_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL);
}