Revision f07b6003 qemu-char.c
b/qemu-char.c | ||
---|---|---|
1957 | 1957 |
{ |
1958 | 1958 |
CharDriverState *chr = NULL; |
1959 | 1959 |
TCPCharDriver *s = NULL; |
1960 |
int fd = -1, ret, err, val;
|
|
1960 |
int fd = -1, offset = 0;
|
|
1961 | 1961 |
int is_listen = 0; |
1962 | 1962 |
int is_waitconnect = 1; |
1963 | 1963 |
int do_nodelay = 0; |
1964 | 1964 |
const char *ptr; |
1965 |
struct sockaddr_in saddr; |
|
1966 |
#ifndef _WIN32 |
|
1967 |
struct sockaddr_un uaddr; |
|
1968 |
#endif |
|
1969 |
struct sockaddr *addr; |
|
1970 |
socklen_t addrlen; |
|
1971 |
|
|
1972 |
#ifndef _WIN32 |
|
1973 |
if (is_unix) { |
|
1974 |
addr = (struct sockaddr *)&uaddr; |
|
1975 |
addrlen = sizeof(uaddr); |
|
1976 |
if (parse_unix_path(&uaddr, host_str) < 0) |
|
1977 |
goto fail; |
|
1978 |
} else |
|
1979 |
#endif |
|
1980 |
{ |
|
1981 |
addr = (struct sockaddr *)&saddr; |
|
1982 |
addrlen = sizeof(saddr); |
|
1983 |
if (parse_host_port(&saddr, host_str) < 0) |
|
1984 |
goto fail; |
|
1985 |
} |
|
1986 | 1965 |
|
1987 | 1966 |
ptr = host_str; |
1988 | 1967 |
while((ptr = strchr(ptr,','))) { |
... | ... | |
1993 | 1972 |
is_waitconnect = 0; |
1994 | 1973 |
} else if (!strncmp(ptr,"nodelay",6)) { |
1995 | 1974 |
do_nodelay = 1; |
1975 |
} else if (!strncmp(ptr,"to=",3)) { |
|
1976 |
/* nothing, inet_listen() parses this one */; |
|
1996 | 1977 |
} else { |
1997 | 1978 |
printf("Unknown option: %s\n", ptr); |
1998 | 1979 |
goto fail; |
... | ... | |
2008 | 1989 |
if (!s) |
2009 | 1990 |
goto fail; |
2010 | 1991 |
|
2011 |
#ifndef _WIN32 |
|
2012 |
if (is_unix) |
|
2013 |
fd = socket(PF_UNIX, SOCK_STREAM, 0); |
|
2014 |
else |
|
2015 |
#endif |
|
2016 |
fd = socket(PF_INET, SOCK_STREAM, 0); |
|
2017 |
|
|
1992 |
if (is_listen) { |
|
1993 |
chr->filename = qemu_malloc(256); |
|
1994 |
if (is_unix) { |
|
1995 |
strcpy(chr->filename, "unix:"); |
|
1996 |
} else if (is_telnet) { |
|
1997 |
strcpy(chr->filename, "telnet:"); |
|
1998 |
} else { |
|
1999 |
strcpy(chr->filename, "tcp:"); |
|
2000 |
} |
|
2001 |
offset = strlen(chr->filename); |
|
2002 |
} |
|
2003 |
if (is_unix) { |
|
2004 |
if (is_listen) { |
|
2005 |
fd = unix_listen(host_str, chr->filename + offset, 256 - offset); |
|
2006 |
} else { |
|
2007 |
fd = unix_connect(host_str); |
|
2008 |
} |
|
2009 |
} else { |
|
2010 |
if (is_listen) { |
|
2011 |
fd = inet_listen(host_str, chr->filename + offset, 256 - offset, |
|
2012 |
SOCK_STREAM, 0); |
|
2013 |
} else { |
|
2014 |
fd = inet_connect(host_str, SOCK_STREAM); |
|
2015 |
} |
|
2016 |
} |
|
2018 | 2017 |
if (fd < 0) |
2019 | 2018 |
goto fail; |
2020 | 2019 |
|
... | ... | |
2032 | 2031 |
chr->chr_close = tcp_chr_close; |
2033 | 2032 |
|
2034 | 2033 |
if (is_listen) { |
2035 |
/* allow fast reuse */ |
|
2036 |
#ifndef _WIN32 |
|
2037 |
if (is_unix) { |
|
2038 |
char path[109]; |
|
2039 |
pstrcpy(path, sizeof(path), uaddr.sun_path); |
|
2040 |
unlink(path); |
|
2041 |
} else |
|
2042 |
#endif |
|
2043 |
{ |
|
2044 |
val = 1; |
|
2045 |
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); |
|
2046 |
} |
|
2047 |
|
|
2048 |
ret = bind(fd, addr, addrlen); |
|
2049 |
if (ret < 0) |
|
2050 |
goto fail; |
|
2051 |
|
|
2052 |
ret = listen(fd, 0); |
|
2053 |
if (ret < 0) |
|
2054 |
goto fail; |
|
2055 |
|
|
2056 | 2034 |
s->listen_fd = fd; |
2057 | 2035 |
qemu_set_fd_handler(s->listen_fd, tcp_chr_accept, NULL, chr); |
2058 | 2036 |
if (is_telnet) |
2059 | 2037 |
s->do_telnetopt = 1; |
2060 | 2038 |
} else { |
2061 |
for(;;) { |
|
2062 |
ret = connect(fd, addr, addrlen); |
|
2063 |
if (ret < 0) { |
|
2064 |
err = socket_error(); |
|
2065 |
if (err == EINTR || err == EWOULDBLOCK) { |
|
2066 |
} else if (err == EINPROGRESS) { |
|
2067 |
break; |
|
2068 |
#ifdef _WIN32 |
|
2069 |
} else if (err == WSAEALREADY) { |
|
2070 |
break; |
|
2071 |
#endif |
|
2072 |
} else { |
|
2073 |
goto fail; |
|
2074 |
} |
|
2075 |
} else { |
|
2076 |
s->connected = 1; |
|
2077 |
break; |
|
2078 |
} |
|
2079 |
} |
|
2039 |
s->connected = 1; |
|
2080 | 2040 |
s->fd = fd; |
2081 | 2041 |
socket_set_nodelay(fd); |
2082 |
if (s->connected) |
|
2083 |
tcp_chr_connect(chr); |
|
2084 |
else |
|
2085 |
qemu_set_fd_handler(s->fd, NULL, tcp_chr_connect, chr); |
|
2042 |
tcp_chr_connect(chr); |
|
2086 | 2043 |
} |
2087 | 2044 |
|
2088 | 2045 |
if (is_listen && is_waitconnect) { |
2089 |
printf("QEMU waiting for connection on: %s\n", host_str); |
|
2046 |
printf("QEMU waiting for connection on: %s\n", |
|
2047 |
chr->filename ? chr->filename : host_str); |
|
2090 | 2048 |
tcp_chr_accept(chr); |
2091 | 2049 |
socket_set_nonblock(s->listen_fd); |
2092 | 2050 |
} |
Also available in: Unified diff