⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vl.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
    }        snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |                              PIPE_WAIT,                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);    if (s->hcom == INVALID_HANDLE_VALUE) {        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());        s->hcom = NULL;        goto fail;    }    ZeroMemory(&ov, sizeof(ov));    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    ret = ConnectNamedPipe(s->hcom, &ov);    if (ret) {        fprintf(stderr, "Failed ConnectNamedPipe\n");        goto fail;    }    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);    if (!ret) {        fprintf(stderr, "Failed GetOverlappedResult\n");        if (ov.hEvent) {            CloseHandle(ov.hEvent);            ov.hEvent = NULL;        }        goto fail;    }    if (ov.hEvent) {        CloseHandle(ov.hEvent);        ov.hEvent = NULL;    }    qemu_add_polling_cb(win_chr_pipe_poll, s);    return 0; fail:    win_chr_close2(s);    return -1;}static CharDriverState *qemu_chr_open_win_pipe(const char *filename){    CharDriverState *chr;    WinCharState *s;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    s = qemu_mallocz(sizeof(WinCharState));    if (!s) {        free(chr);        return NULL;    }    chr->opaque = s;    chr->chr_write = win_chr_write;    chr->chr_close = win_chr_close;        if (win_chr_pipe_init(s, filename) < 0) {        free(s);        free(chr);        return NULL;    }    qemu_chr_reset(chr);    return chr;}static CharDriverState *qemu_chr_open_win_file(HANDLE fd_out){    CharDriverState *chr;    WinCharState *s;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        return NULL;    s = qemu_mallocz(sizeof(WinCharState));    if (!s) {        free(chr);        return NULL;    }    s->hcom = fd_out;    chr->opaque = s;    chr->chr_write = win_chr_write;    qemu_chr_reset(chr);    return chr;}    static CharDriverState *qemu_chr_open_win_file_out(const char *file_out){    HANDLE fd_out;        fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);    if (fd_out == INVALID_HANDLE_VALUE)        return NULL;    return qemu_chr_open_win_file(fd_out);}#endif/***********************************************************//* UDP Net console */typedef struct {    int fd;    struct sockaddr_in daddr;    char buf[1024];    int bufcnt;    int bufptr;    int max_size;} NetCharDriver;static int udp_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    NetCharDriver *s = chr->opaque;    return sendto(s->fd, buf, len, 0,                  (struct sockaddr *)&s->daddr, sizeof(struct sockaddr_in));}static int udp_chr_read_poll(void *opaque){    CharDriverState *chr = opaque;    NetCharDriver *s = chr->opaque;    s->max_size = qemu_chr_can_read(chr);    /* If there were any stray characters in the queue process them     * first     */    while (s->max_size > 0 && s->bufptr < s->bufcnt) {        qemu_chr_read(chr, &s->buf[s->bufptr], 1);        s->bufptr++;        s->max_size = qemu_chr_can_read(chr);    }    return s->max_size;}static void udp_chr_read(void *opaque){    CharDriverState *chr = opaque;    NetCharDriver *s = chr->opaque;    if (s->max_size == 0)        return;    s->bufcnt = recv(s->fd, s->buf, sizeof(s->buf), 0);    s->bufptr = s->bufcnt;    if (s->bufcnt <= 0)        return;    s->bufptr = 0;    while (s->max_size > 0 && s->bufptr < s->bufcnt) {        qemu_chr_read(chr, &s->buf[s->bufptr], 1);        s->bufptr++;        s->max_size = qemu_chr_can_read(chr);    }}static void udp_chr_update_read_handler(CharDriverState *chr){    NetCharDriver *s = chr->opaque;    if (s->fd >= 0) {        qemu_set_fd_handler2(s->fd, udp_chr_read_poll,                             udp_chr_read, NULL, chr);    }}int parse_host_port(struct sockaddr_in *saddr, const char *str);#ifndef _WIN32static int parse_unix_path(struct sockaddr_un *uaddr, const char *str);#endifint parse_host_src_port(struct sockaddr_in *haddr,                        struct sockaddr_in *saddr,                        const char *str);static CharDriverState *qemu_chr_open_udp(const char *def){    CharDriverState *chr = NULL;    NetCharDriver *s = NULL;    int fd = -1;    struct sockaddr_in saddr;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        goto return_err;    s = qemu_mallocz(sizeof(NetCharDriver));    if (!s)        goto return_err;    fd = socket(PF_INET, SOCK_DGRAM, 0);    if (fd < 0) {        perror("socket(PF_INET, SOCK_DGRAM)");        goto return_err;    }    if (parse_host_src_port(&s->daddr, &saddr, def) < 0) {        printf("Could not parse: %s\n", def);        goto return_err;    }    if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)    {        perror("bind");        goto return_err;    }    s->fd = fd;    s->bufcnt = 0;    s->bufptr = 0;    chr->opaque = s;    chr->chr_write = udp_chr_write;    chr->chr_update_read_handler = udp_chr_update_read_handler;    return chr;return_err:    if (chr)        free(chr);    if (s)        free(s);    if (fd >= 0)        closesocket(fd);    return NULL;}/***********************************************************//* TCP Net console */typedef struct {    int fd, listen_fd;    int connected;    int max_size;    int do_telnetopt;    int do_nodelay;    int is_unix;} TCPCharDriver;static void tcp_chr_accept(void *opaque);static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len){    TCPCharDriver *s = chr->opaque;    if (s->connected) {        return send_all(s->fd, buf, len);    } else {        /* XXX: indicate an error ? */        return len;    }}static int tcp_chr_read_poll(void *opaque){    CharDriverState *chr = opaque;    TCPCharDriver *s = chr->opaque;    if (!s->connected)        return 0;    s->max_size = qemu_chr_can_read(chr);    return s->max_size;}#define IAC 255#define IAC_BREAK 243static void tcp_chr_process_IAC_bytes(CharDriverState *chr,                                      TCPCharDriver *s,                                      char *buf, int *size){    /* Handle any telnet client's basic IAC options to satisfy char by     * char mode with no echo.  All IAC options will be removed from     * the buf and the do_telnetopt variable will be used to track the     * state of the width of the IAC information.     *     * IAC commands come in sets of 3 bytes with the exception of the     * "IAC BREAK" command and the double IAC.     */    int i;    int j = 0;    for (i = 0; i < *size; i++) {        if (s->do_telnetopt > 1) {            if ((unsigned char)buf[i] == IAC && s->do_telnetopt == 2) {                /* Double IAC means send an IAC */                if (j != i)                    buf[j] = buf[i];                j++;                s->do_telnetopt = 1;            } else {                if ((unsigned char)buf[i] == IAC_BREAK && s->do_telnetopt == 2) {                    /* Handle IAC break commands by sending a serial break */                    qemu_chr_event(chr, CHR_EVENT_BREAK);                    s->do_telnetopt++;                }                s->do_telnetopt++;            }            if (s->do_telnetopt >= 4) {                s->do_telnetopt = 1;            }        } else {            if ((unsigned char)buf[i] == IAC) {                s->do_telnetopt = 2;            } else {                if (j != i)                    buf[j] = buf[i];                j++;            }        }    }    *size = j;}static void tcp_chr_read(void *opaque){    CharDriverState *chr = opaque;    TCPCharDriver *s = chr->opaque;    uint8_t buf[1024];    int len, size;    if (!s->connected || s->max_size <= 0)        return;    len = sizeof(buf);    if (len > s->max_size)        len = s->max_size;    size = recv(s->fd, buf, len, 0);    if (size == 0) {        /* connection closed */        s->connected = 0;        if (s->listen_fd >= 0) {            qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr);        }        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);        closesocket(s->fd);        s->fd = -1;    } else if (size > 0) {        if (s->do_telnetopt)            tcp_chr_process_IAC_bytes(chr, s, buf, &size);        if (size > 0)            qemu_chr_read(chr, buf, size);    }}static void tcp_chr_connect(void *opaque){    CharDriverState *chr = opaque;    TCPCharDriver *s = chr->opaque;    s->connected = 1;    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,                         tcp_chr_read, NULL, chr);    qemu_chr_reset(chr);}#define IACSET(x,a,b,c) x[0] = a; x[1] = b; x[2] = c;static void tcp_chr_telnet_init(int fd){    char buf[3];    /* Send the telnet negotion to put telnet in binary, no echo, single char mode */    IACSET(buf, 0xff, 0xfb, 0x01);  /* IAC WILL ECHO */    send(fd, (char *)buf, 3, 0);    IACSET(buf, 0xff, 0xfb, 0x03);  /* IAC WILL Suppress go ahead */    send(fd, (char *)buf, 3, 0);    IACSET(buf, 0xff, 0xfb, 0x00);  /* IAC WILL Binary */    send(fd, (char *)buf, 3, 0);    IACSET(buf, 0xff, 0xfd, 0x00);  /* IAC DO Binary */    send(fd, (char *)buf, 3, 0);}static void socket_set_nodelay(int fd){    int val = 1;    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));}static void tcp_chr_accept(void *opaque){    CharDriverState *chr = opaque;    TCPCharDriver *s = chr->opaque;    struct sockaddr_in saddr;#ifndef _WIN32    struct sockaddr_un uaddr;#endif    struct sockaddr *addr;    socklen_t len;    int fd;    for(;;) {#ifndef _WIN32	if (s->is_unix) {	    len = sizeof(uaddr);	    addr = (struct sockaddr *)&uaddr;	} else#endif	{	    len = sizeof(saddr);	    addr = (struct sockaddr *)&saddr;	}        fd = accept(s->listen_fd, addr, &len);        if (fd < 0 && errno != EINTR) {            return;        } else if (fd >= 0) {            if (s->do_telnetopt)                tcp_chr_telnet_init(fd);            break;        }    }    socket_set_nonblock(fd);    if (s->do_nodelay)        socket_set_nodelay(fd);    s->fd = fd;    qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);    tcp_chr_connect(chr);}static void tcp_chr_close(CharDriverState *chr){    TCPCharDriver *s = chr->opaque;    if (s->fd >= 0)        closesocket(s->fd);    if (s->listen_fd >= 0)        closesocket(s->listen_fd);    qemu_free(s);}static CharDriverState *qemu_chr_open_tcp(const char *host_str,                                           int is_telnet,					  int is_unix){    CharDriverState *chr = NULL;    TCPCharDriver *s = NULL;    int fd = -1, ret, err, val;    int is_listen = 0;    int is_waitconnect = 1;    int do_nodelay = 0;    const char *ptr;    struct sockaddr_in saddr;#ifndef _WIN32    struct sockaddr_un uaddr;#endif    struct sockaddr *addr;    socklen_t addrlen;#ifndef _WIN32    if (is_unix) {	addr = (struct sockaddr *)&uaddr;	addrlen = sizeof(uaddr);	if (parse_unix_path(&uaddr, host_str) < 0)	    goto fail;    } else#endif    {	addr = (struct sockaddr *)&saddr;	addrlen = sizeof(saddr);	if (parse_host_port(&saddr, host_str) < 0)	    goto fail;    }    ptr = host_str;    while((ptr = strchr(ptr,','))) {        ptr++;        if (!strncmp(ptr,"server",6)) {            is_listen = 1;        } else if (!strncmp(ptr,"nowait",6)) {            is_waitconnect = 0;        } else if (!strncmp(ptr,"nodelay",6)) {            do_nodelay = 1;        } else {            printf("Unknown option: %s\n", ptr);            goto fail;        }    }    if (!is_listen)        is_waitconnect = 0;    chr = qemu_mallocz(sizeof(CharDriverState));    if (!chr)        goto fail;    s = qemu_mallocz(sizeof(TCPCharDriver));    if (!s)        goto fail;#ifndef _WIN32    if (is_unix)	fd = socket(PF_UNIX, SOCK_STREAM, 0);    else#endif	fd = socket(PF_INET, SOCK_STREAM, 0);	    if (fd < 0)         goto fail;    if (!is_waitconnect)        socket_set_nonblock(fd);    s->connected = 0;    s->fd = -1;    s->listen_fd = -1;    s->is_unix = is_unix;    s->do_nodelay = do_nodelay && !is_unix;    chr->opaque = s;    chr->chr_write = tcp_chr_write;    chr->chr_close = tcp_chr_close;    if (is_listen) {        /* allow fast reuse */#ifndef _WIN32	if (is_unix) {	    char path[109];	    strncpy(path, uaddr.sun_path, 108);	    path[108] = 0;	    unlink(path);	} else#endif	{	    val = 1;	    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));	}                ret = bind(fd, addr, addrlen);        if (ret < 0)            goto fail;        ret = listen(fd, 0);        if (ret < 0)            goto fail;        s->listen_fd = fd;        qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -