[PULL 1/1] slirp: Allow non-local DNS address when restrict is off

2019-10-06 Thread Samuel Thibault
This can be used to set a DNS server to be used by the guest which is
different from the one configured on the host.

Buglink: https://bugs.launchpad.net/qemu/+bug/1010484
Signed-off-by: Samuel Thibault 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Thomas Huth 
---
 net/slirp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index f42f496641..c4334ee876 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -456,7 +456,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+if (restricted && (dns.s_addr & mask.s_addr) != net.s_addr) {
 error_setg(errp, "DNS doesn't belong to network");
 return -1;
 }
@@ -522,7 +522,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse IPv6 DNS");
 return -1;
 }
-if (!in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) {
+if (restricted && !in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) 
{
 error_setg(errp, "IPv6 DNS doesn't belong to network");
 return -1;
 }
-- 
2.23.0




[PATCHv2] slirp: Allow non-local DNS address when restrict is off

2019-10-01 Thread Samuel Thibault
This can be used to set a DNS server to be used by the guest which is
different from the one configured on the host.

Buglink: https://bugs.launchpad.net/qemu/+bug/1010484
Signed-off-by: Samuel Thibault 
---
Difference from first version:
- handle DNS IPv6 as well
- reference bug with Buglink

 net/slirp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index f42f496641..c4334ee876 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -456,7 +456,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+if (restricted && (dns.s_addr & mask.s_addr) != net.s_addr) {
 error_setg(errp, "DNS doesn't belong to network");
 return -1;
 }
@@ -522,7 +522,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse IPv6 DNS");
 return -1;
 }
-if (!in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) {
+if (restricted && !in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) 
{
 error_setg(errp, "IPv6 DNS doesn't belong to network");
 return -1;
 }
-- 
2.23.0




[PATCH] slirp: Allow non-local DNS address when restrict is off

2019-10-01 Thread Samuel Thibault
This can be used to set a DNS server to be used by the guest which is
different from the one configured on the host.

Buglink: https://bugs.launchpad.net/qemu/+bug/1010484
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index f42f496641..c4334ee876 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -456,7 +456,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+if (restricted && (dns.s_addr & mask.s_addr) != net.s_addr) {
 error_setg(errp, "DNS doesn't belong to network");
 return -1;
 }
@@ -522,7 +522,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse IPv6 DNS");
 return -1;
 }
-if (!in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) {
+if (restricted && !in6_equal_net(&ip6_prefix, &ip6_dns, vprefix6_len)) 
{
 error_setg(errp, "IPv6 DNS doesn't belong to network");
 return -1;
 }
-- 
2.23.0




[PATCH] slirp: Allow non-local DNS address when restrict is off

2019-09-29 Thread Samuel Thibault
This can be used to set a DNS server to be used by the guest which is
different from the one configured on the host.

This fixes LP 1010484.

Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/slirp.c b/net/slirp.c
index f42f496641..4d158b0542 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -456,7 +456,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+if (restricted && (dns.s_addr & mask.s_addr) != net.s_addr) {
 error_setg(errp, "DNS doesn't belong to network");
 return -1;
 }
-- 
2.23.0




Re: [Qemu-devel] slirp, incoming packets get truncated

2019-09-09 Thread Samuel Thibault
Hello,

Philippe Mathieu-Daudé, le lun. 09 sept. 2019 12:51:23 +0200, a ecrit:
> Anyhow, if you plan to properly (with your S-o-b) commit your patch to
> the libslirp repository,

Actually the libslirp repository already has something there. Since
IPv4/6 have a maximum of 64KB packets, it just allocates that size
on the stack, whîch is simpler in the end. Also it makes mru/mtu
configurable, we will be able to plug that into qemu once released.

Samuel



Re: [Qemu-devel] slirp, incoming packets get truncated

2019-09-07 Thread Samuel Thibault
Hello,

As usual, several things here.

Chris Heinze, le mar. 03 sept. 2019 17:02:15 +0200, a ecrit:
> root@guest:~# tcpdump -ni eth0 port 19003
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
> 16:49:39.430959 IP 10.0.2.2.33294 > 10.0.2.15.19003: UDP, bad length 9000 > 
> 1472

tcpdump seems to be showing dumb output here. The packet is fragmented
by slirp, which makes tcpdump confused and show only the first
fragment. If you let tcpdump print everything, you will see the other
fragments. In reality, everything is going fine here.

> i tried to change slirp/src/if.h to: 
> 
> #define IF_MTU 9000
> #define IF_MRU 9000
> 
> but the resulting qemu-system-x86_64 binary did not behave differently.

Did you explicitly remove the qemu-system-x86_64 binary? As mentioned
previously on the list, there seems to be a missing Makefile dependency.

Now, with MTU set to 9000, the packets just don't go at all. Could you
try the attached patch? The lowest layer of slirp was indeed limited to
1600-byte frames for no good reason. With this and the virtio driver, I
could exchange 9000-byte packets.

Samuel
diff --git a/src/slirp.c b/src/slirp.c
index b0194cb..3fd6f68 100644
--- a/src/slirp.c
+++ b/src/slirp.c
@@ -890,20 +890,22 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, 
struct ethhdr *eh,
  */
 int if_encap(Slirp *slirp, struct mbuf *ifm)
 {
-uint8_t buf[1600];
-struct ethhdr *eh = (struct ethhdr *)buf;
+uint8_t *buf;
+struct ethhdr *eh;
 uint8_t ethaddr[ETH_ALEN];
 const struct ip *iph = (const struct ip *)ifm->m_data;
 int ret;
 
-if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
-return 1;
-}
+buf = g_malloc(ifm->m_len + ETH_HLEN);
+if (!buf)
+return 0;
+eh = (struct ethhdr *)buf;
 
 switch (iph->ip_v) {
 case IPVERSION:
 ret = if_encap4(slirp, ifm, eh, ethaddr);
 if (ret < 2) {
+g_free(buf);
 return ret;
 }
 break;
@@ -911,6 +913,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 case IP6VERSION:
 ret = if_encap6(slirp, ifm, eh, ethaddr);
 if (ret < 2) {
+g_free(buf);
 return ret;
 }
 break;
@@ -929,6 +932,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
   eh->h_dest[5]);
 memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
 slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN);
+g_free(buf);
 return 1;
 }
 


Re: [Qemu-devel] slirp, incoming packets get truncated

2019-09-06 Thread Samuel Thibault
Chris Heinze, le ven. 06 sept. 2019 12:54:24 +0200, a ecrit:
> i'm not aware of any (canonical) parameters to set a max size for received 
> packets

Ah, right.

> i found no way to configure slirp (in qemu) itself except for the DEFINEs in 
> the if.h.

Yes, that's where it is to be configured atm. IF_MRU is however only
used for setting the TCP mss, there is no code that is supposed to
truncate packets etc., that's why I'm really surprised that there is
such truncation happening.

Samuel



Re: [Qemu-devel] slirp, incoming packets get truncated

2019-09-06 Thread Samuel Thibault
Hello,

Chris Heinze, le mar. 03 sept. 2019 17:02:15 +0200, a ecrit:
> on the guest:
> root@guest:~# tcpdump -ni eth0 port 19003
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
> 16:49:39.430959 IP 10.0.2.2.33294 > 10.0.2.15.19003: UDP, bad length 9000 > 
> 1472

Just to be sure: did you configure your guest mru to 9000 ? Does the
emulated network hardware card support jumbo frames?

Samuel



[Qemu-devel] [Bug 1837094] Re: UndefinedBehaviorSanitizer crash around slirp::ip_reass()

2019-08-29 Thread Samuel thibault
And

https://gitlab.freedesktop.org/slirp/libslirp/commit/d203c81b

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1837094

Title:
  UndefinedBehaviorSanitizer crash around slirp::ip_reass()

Status in QEMU:
  New

Bug description:
  tag: v4.1.0-rc1

  ./configure --enable-sanitizers --extra-cflags=-O1

  ==26130==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 
0x0008 (pc 0x561ad346d588 bp 0x7fff6ee9f940 sp 0x7fff6ee9f8e8 
T26130)
  ==26130==The signal is caused by a WRITE memory access.
  ==26130==Hint: address points to the zero page.
  #0 0x561ad346d587 in ip_deq() at slirp/src/ip_input.c:411:55
  #1 0x561ad346cffb in ip_reass() at slirp/src/ip_input.c:304:9
  #2 0x561ad346cb6f in ip_input() at slirp/src/ip_input.c:184:18

  I only had access to the last packet which isn't the culprit, I'm now
  seeing how to log the network traffic of the guest to provide more
  useful information.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1837094/+subscriptions



Re: [Qemu-devel] [Slirp] [PATCH 1/2] Do not reassemble fragments pointing outside of the original payload

2019-08-25 Thread Samuel Thibault
Hello,

Philippe Mathieu-Daudé, le ven. 23 août 2019 17:15:32 +0200, a ecrit:
> > Did you make your test with commit 126c04acbabd ("Fix heap overflow in
> > ip_reass on big packet input") applied?
> 
> Yes, unfortunately it doesn't fix the issue.

Ok.

Could you try the attached patch?  There was a use-after-free.  Without
it, I can indeed crash qemu with the given exploit.  With it I don't
seem to be able to crash it (trying in a loop for several minutes).

Samuel
diff --git a/src/ip_input.c b/src/ip_input.c
index 7364ce0..aa514ae 100644
--- a/src/ip_input.c
+++ b/src/ip_input.c
@@ -292,6 +292,7 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, 
struct ipq *fp)
  */
 while (q != (struct ipasfrag *)&fp->frag_link &&
ip->ip_off + ip->ip_len > q->ipf_off) {
+struct ipasfrag *prev;
 i = (ip->ip_off + ip->ip_len) - q->ipf_off;
 if (i < q->ipf_len) {
 q->ipf_len -= i;
@@ -299,9 +300,10 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, 
struct ipq *fp)
 m_adj(dtom(slirp, q), i);
 break;
 }
+prev = q;
 q = q->ipf_next;
-m_free(dtom(slirp, q->ipf_prev));
-ip_deq(q->ipf_prev);
+ip_deq(prev);
+m_free(dtom(slirp, prev));
 }
 
 insert:


Re: [Qemu-devel] [Slirp] [PATCH 1/2] Do not reassemble fragments pointing outside of the original payload

2019-08-22 Thread Samuel Thibault
Hello,

Philippe Mathieu-Daudé, le jeu. 22 août 2019 16:41:33 +0200, a ecrit:
>   Later the newly calculated pointer q is converted into ip structure
>   and values are modified, Due to the wrong calculation of the delta,
>   ip will be pointing to incorrect location and ip_src and ip_dst can
>   be used to write controlled data onto the calculated location. This
>   may also crash qemu if the calculated ip is located in unmaped area.

That does not seem to be related to this:

> Do not queue fragments pointing out of the original payload to avoid
> to calculate the variable delta.

I don't understand the relation with having to calculate delta.

> diff --git a/src/ip_input.c b/src/ip_input.c
> index 7364ce0..ee52085 100644
> --- a/src/ip_input.c
> +++ b/src/ip_input.c
> @@ -304,6 +304,19 @@ static struct ip *ip_reass(Slirp *slirp, struct ip *ip, 
> struct ipq *fp)
>  ip_deq(q->ipf_prev);
>  }
>  
> +/*
> + * If we received the first fragment, we know the original
> + * payload size.

? We only know the total payload size when receiving the last fragment
(payload = offset*8 + size).

> Verify fragments are within our payload.

By construction of the protocol, fragments can only be within the
payload, since it's the last fragment which provides the payload size.

> +for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link;
> +q = q->ipf_next) {
> +if (!q->ipf_off && q->ipf_len) {
> +if (ip->ip_off + ip->ip_len >= q->ipf_len) {
> +goto dropfrag;
> +}
> +}
> +}

Fragments are kept in order, there is no need to go around the list to
find the fragment with offset zero, if it is there it is the first one.

Did you make your test with commit 126c04acbabd ("Fix heap overflow in
ip_reass on big packet input") applied?

Samuel



Re: [Qemu-devel] [ANNOUNCE] QEMU 4.1.0-rc3 is now available

2019-08-02 Thread Samuel Thibault
Marc-André Lureau, le ven. 02 août 2019 15:07:46 +0400, a ecrit:
> And Samuel probably thought the same, since he didn't update the submodule.

I'm rather mostly buried under piles of things to do...

> According to MAINTAINERS, this is for Samuel to take care of. But I'll
> do it if he ask me.

Please do.

Samuel



Re: [Qemu-devel] [PATCH] ui/curses: Fix build with -m32

2019-05-27 Thread Samuel Thibault
Max Reitz, le lun. 27 mai 2019 16:25:40 +0200, a ecrit:
> wchar_t may resolve to be an unsigned long on 32-bit architectures.
> Using the %x conversion specifier will then give a compiler warning:
> 
> ui/curses.c: In function ‘get_ucs’:
> ui/curses.c:492:49: error: format ‘%x’ expects argument of type ‘unsigned 
> int’, but argument 3 has type ‘wchar_t’ {aka ‘long int’} [-Werror=format=]
>   492 | fprintf(stderr, "Could not convert 0x%04x "
>   |  ~~~^
>   | |
>   | unsigned int
>   |  %04lx
>   493 | "from wchar_t to a multibyte character: %s\n",
>   494 | wch, strerror(errno));
>   | ~~~
>   | |
>   | wchar_t {aka long int}
> ui/curses.c:504:49: error: format ‘%x’ expects argument of type ‘unsigned 
> int’, but argument 3 has type ‘wchar_t’ {aka ‘long int’} [-Werror=format=]
>   504 | fprintf(stderr, "Could not convert 0x%04x "
>   |  ~~~^
>   | |
>   | unsigned int
>   |  %04lx
>   505 | "from a multibyte character to UCS-2 : %s\n",
>   506 | wch, strerror(errno));
>   | ~~~
>   | |
>   | wchar_t {aka long int}
> 
> Fix this by casting the wchar_t value to an unsigned long and using %lx
> as the conversion specifier.
> 
> Fixes: b7b664a4fe9a955338f2e11a0f7433b29c8cbad0
> Signed-off-by: Max Reitz 

Reviewed-by: Samuel Thibault 

> ---
>  ui/curses.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/ui/curses.c b/ui/curses.c
> index 1f3fcabb00..e9319eb8ae 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -489,9 +489,9 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
>  memset(&ps, 0, sizeof(ps));
>  ret = wcrtomb(mbch, wch, &ps);
>  if (ret == -1) {
> -fprintf(stderr, "Could not convert 0x%04x "
> +fprintf(stderr, "Could not convert 0x%04lx "
>  "from wchar_t to a multibyte character: %s\n",
> -wch, strerror(errno));
> +(unsigned long)wch, strerror(errno));
>  return 0xFFFD;
>  }
>  
> @@ -501,9 +501,9 @@ static uint16_t get_ucs(wchar_t wch, iconv_t conv)
>  such = sizeof(uch);
>  
>  if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
> -fprintf(stderr, "Could not convert 0x%04x "
> +fprintf(stderr, "Could not convert 0x%04lx "
>  "from a multibyte character to UCS-2 : %s\n",
> -wch, strerror(errno));
> +(unsigned long)wch, strerror(errno));
>  return 0xFFFD;
>  }
>  
> -- 
> 2.21.0
> 
> 

-- 
Samuel
/*
 * [...] Note that 120 sec is defined in the protocol as the maximum
 * possible RTT.  I guess we'll have to use something other than TCP
 * to talk to the University of Mars.
 * PAWS allows us longer timeouts and large windows, so once implemented
 * ftp to mars will work nicely.
 */
(from /usr/src/linux/net/inet/tcp.c, concerning RTT [retransmission timeout])



[Qemu-devel] [PULL 0/1] Update upstream slirp

2019-05-09 Thread Samuel Thibault
The following changes since commit 30302acee710881cb248ec3391adcd54dcf52396:

  Update upstream slirp (2019-05-09 09:58:57 +0200)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 30302acee710881cb248ec3391adcd54dcf52396:

  Update upstream slirp (2019-05-09 09:58:57 +0200)


Update slirp submodule

Samuel Thibault (1):
  Update upstream slirp
  Adds gitignore, README file, and fixes ident protocol parsing.





[Qemu-devel] [PULL 1/1] Update upstream slirp

2019-05-09 Thread Samuel Thibault
Adds gitignore, README file, and fixes ident protocol parsing.

Signed-off-by: Samuel Thibault 
---
 slirp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp b/slirp
index 0e79ba4856..f0da672620 16
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit 0e79ba48567ccfb3cc2cf2e98cce8811eee7e455
+Subproject commit f0da6726207b740f6101028b2992f918477a4b08
-- 
2.20.1




[Qemu-devel] [PULL 1/1] Update slirp submodule

2019-05-04 Thread Samuel Thibault
To fix Windows on ARM.
---
 slirp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp b/slirp
index 59a1b1f165..0e79ba4856 16
--- a/slirp
+++ b/slirp
@@ -1 +1 @@
-Subproject commit 59a1b1f165458c2acb7ff0525b543945f7416225
+Subproject commit 0e79ba48567ccfb3cc2cf2e98cce8811eee7e455
-- 
2.20.1




[Qemu-devel] [PULL 0/1] Update slirp submodule

2019-05-04 Thread Samuel Thibault
The following changes since commit 52ec9dcc1ed5609674e7b52198c18207bb193548:

  Update slirp submodule (2019-05-04 14:38:05 +0200)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 52ec9dcc1ed5609674e7b52198c18207bb193548:

  Update slirp submodule (2019-05-04 14:38:05 +0200)


Update slirp submodule

To fix Windows on ARM.





Re: [Qemu-devel] [PATCH v2 1/4] Initial Windows on ARM (AArch64 64-Bit) host support

2019-05-04 Thread Samuel Thibault
Hello,

Cao Jiaxi, le mer. 01 mai 2019 02:10:09 +0800, a ecrit:
> This series of patches is for initial support of Windows 10 on ARM as a QEMU 
> host.
> Currently only TCG intepreter is working correctly, it crashes when TCG JIT 
> is enabled.
> For now we assume it is built using the clang aarch64-w64-mingw32 toolchain, 
> you can get a prebuilt toolchain at https://github.com/mstorsjo/llvm-mingw.
> 
> QEMU_PACKED: Remove gcc_struct attribute in Windows non x86 targets
> This attribute is for x86 only, and it generates an warning on ARM64 
> Clang/MinGW targets.

I have applied it to the libslirp repo, thanks!

I'll submit a pull request to get it updated on qemu.

Samuel



[Qemu-devel] [PULL 0/2] slirp: move slirp as git submodule project

2019-05-02 Thread Samuel Thibault
The following changes since commit 8482ff2eb3bb95020eb2f370a9b3ea26511e41df:

  Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into 
staging (2019-05-02 12:04:51 +0100)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 7c57bdd82026ba03f3158bbcd841afde7c2dc43a:

  build-sys: move slirp as git submodule project (2019-05-03 00:15:37 +0200)


slirp: move slirp as git submodule project

Marc-André Lureau (2):
  build-sys: pass CFLAGS & LDFLAGS to subdir-slirp
  build-sys: move slirp as git submodule project


Marc-André Lureau (2):
  build-sys: pass CFLAGS & LDFLAGS to subdir-slirp
  build-sys: move slirp as git submodule project

 .gitmodules   |3 +
 Makefile  |2 +-
 configure |   11 +-
 scripts/archive-source.sh |2 +-
 slirp |1 +
 slirp/COPYRIGHT   |   62 --
 slirp/Makefile|   47 --
 slirp/src/arp_table.c |   92 ---
 slirp/src/bootp.c |  371 ---
 slirp/src/bootp.h |  129 
 slirp/src/cksum.c |  161 -
 slirp/src/debug.h |   46 --
 slirp/src/dhcpv6.c|  224 ---
 slirp/src/dhcpv6.h|   53 --
 slirp/src/dnssearch.c |  311 -
 slirp/src/if.c|  218 ---
 slirp/src/if.h|   21 -
 slirp/src/ip.h|  242 ---
 slirp/src/ip6.h   |  160 -
 slirp/src/ip6_icmp.c  |  438 -
 slirp/src/ip6_icmp.h  |  232 ---
 slirp/src/ip6_input.c |   78 ---
 slirp/src/ip6_output.c|   39 --
 slirp/src/ip_icmp.c   |  470 --
 slirp/src/ip_icmp.h   |  166 -
 slirp/src/ip_input.c  |  469 --
 slirp/src/ip_output.c |  170 -
 slirp/src/libslirp.h  |  118 
 slirp/src/main.h  |   16 -
 slirp/src/mbuf.c  |  235 ---
 slirp/src/mbuf.h  |  127 
 slirp/src/misc.c  |  321 --
 slirp/src/misc.h  |   66 --
 slirp/src/ncsi-pkt.h  |  445 -
 slirp/src/ncsi.c  |  194 --
 slirp/src/ndp_table.c |   87 ---
 slirp/src/qtailq.h|  194 --
 slirp/src/sbuf.c  |  186 --
 slirp/src/sbuf.h  |   27 -
 slirp/src/slirp.c | 1118 
 slirp/src/slirp.h |  275 
 slirp/src/socket.c|  945 ---
 slirp/src/socket.h|  160 -
 slirp/src/state.c |  388 ---
 slirp/src/stream.c|  120 
 slirp/src/stream.h|   35 -
 slirp/src/tcp.h   |  181 --
 slirp/src/tcp_input.c | 1554 -
 slirp/src/tcp_output.c|  522 ---
 slirp/src/tcp_subr.c  |  987 
 slirp/src/tcp_timer.c |  294 -
 slirp/src/tcp_timer.h |  128 
 slirp/src/tcp_var.h   |  162 -
 slirp/src/tcpip.h |  102 ---
 slirp/src/tftp.c  |  463 --
 slirp/src/tftp.h  |   52 --
 slirp/src/udp.c   |  363 ---
 slirp/src/udp.h   |   92 ---
 slirp/src/udp6.c  |  173 -
 slirp/src/util.c  |  368 ---
 slirp/src/util.h  |  175 -
 slirp/src/vmstate.c   |  441 -
 slirp/src/vmstate.h   |  409 
 63 files changed, 15 insertions(+), 15726 deletions(-)
 create mode 16 slirp
 delete mode 100644 slirp/COPYRIGHT
 delete mode 100644 slirp/Makefile
 delete mode 100644 slirp/src/arp_table.c
 delete mode 100644 slirp/src/bootp.c
 delete mode 100644 slirp/src/bootp.h
 delete mode 100644 slirp/src/cksum.c
 delete mode 100644 slirp/src/debug.h
 delete mode 100644 slirp/src/dhcpv6.c
 delete mode 100644 slirp/src/dhcpv6.h
 delete mode 100644 slirp/src/dnssearch.c
 delete mode 100644 slirp/src/if.c
 delete mode 100644 slirp/src/if.h
 delete mode 100644 slirp/src/ip.h
 delete mode 100644 slirp/src/ip6.h
 delete mode 100644 slirp/src/ip6_icmp.c
 delete mode 100644 slirp/src/ip6_icmp.h
 delete mode 100644 slirp/src/ip6_input.c
 delete mode 100644 slirp/src/ip6_output.c
 delete mode 100644 slirp/src/ip_icmp.c
 delete mode 100644 slirp/src/ip_icmp.h
 delete mode 100644 slirp/src/ip_input.c
 delete mode 100644 slirp/src/ip_output.c
 delete mode 100644 slirp/src/libslirp.h
 delete mode 100644 slirp/src/main.h
 delete mode 100644 slirp/src/mbuf.c
 delete mode 100644 slirp/src/mbuf.h
 delete mode 100644 slirp/src/misc.c
 delete mode 100644 slirp/src/misc.h
 delete mode 100644 slirp/src/ncsi-pkt.h
 delete mode 100644 slirp/src/ncsi.c
 delete mode 100644 slirp/src/ndp_table.c
 delete mode 100644 slirp/src/qtailq.h
 delete mode 100644 slirp/src/sbuf.c
 delete mode 100644 slirp/src/sbuf.h
 delete

[Qemu-devel] [PULL 1/2] build-sys: pass CFLAGS & LDFLAGS to subdir-slirp

2019-05-02 Thread Samuel Thibault
From: Marc-André Lureau 

CFLAGS/LDFLAGS have debug and sanitizers flags, which should be passed
to slirp compilation.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190424110041.8175-2-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 1211e78c91..d372493042 100644
--- a/Makefile
+++ b/Makefile
@@ -480,7 +480,7 @@ subdir-capstone: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no 
BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) 
$(BUILD_DIR)/capstone/$(LIBCAPSTONE))
 
 subdir-slirp: .git-submodule-status
-   $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp 
BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS)")
+   $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp 
BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS) $(CFLAGS)" LDFLAGS="$(LDFLAGS)")
 
 $(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
$(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
-- 
2.20.1




[Qemu-devel] [PATCHv4 2/2] ui/curses: manipulate cchar_t with standard curses functions

2019-04-27 Thread Samuel Thibault
The chars/attr fields are curses internals, setcchar and getcchar have
to be used instead.

Signed-off-by: Samuel Thibault 
Tested-by: Kamil Rytarowski 
---
 ui/curses.c | 43 +--
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index 81d419879e..1f3fcabb00 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -66,20 +66,22 @@ static void curses_update(DisplayChangeListener *dcl,
 {
 console_ch_t *line;
 cchar_t curses_line[width];
+wchar_t wch[CCHARW_MAX];
+attr_t attrs;
+short colors;
+int ret;
 
 line = screen + y * width;
 for (h += y; y < h; y ++, line += width) {
 for (x = 0; x < width; x++) {
 chtype ch = line[x] & 0xff;
 chtype at = line[x] & ~0xff;
-if (vga_to_curses[ch].chars[0]) {
-curses_line[x] = vga_to_curses[ch];
-} else {
-curses_line[x] = (cchar_t) {
-.chars[0] = ch,
-};
+ret = getcchar(&vga_to_curses[ch], wch, &attrs, &colors, NULL);
+if (ret == ERR || wch[0] == 0) {
+wch[0] = ch;
+wch[1] = 0;
 }
-curses_line[x].attr |= at;
+setcchar(&curses_line[x], wch, at, 0, NULL);
 }
 mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
 }
@@ -412,7 +414,7 @@ static void curses_atexit(void)
 static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
 char mbch[MB_LEN_MAX];
-wchar_t wch;
+wchar_t wch[2];
 char *puch, *pmbch;
 size_t such, smbch;
 mbstate_t ps;
@@ -430,20 +432,22 @@ static void convert_ucs(unsigned char fch, uint16_t uch, 
iconv_t conv)
 }
 
 memset(&ps, 0, sizeof(ps));
-if (mbrtowc(&wch, mbch, sizeof(mbch) - smbch, &ps) == -1) {
+if (mbrtowc(&wch[0], mbch, sizeof(mbch) - smbch, &ps) == -1) {
 fprintf(stderr, "Could not convert 0x%04x "
 "from a multibyte character to wchar_t: %s\n",
 uch, strerror(errno));
 return;
 }
-vga_to_curses[fch].chars[0] = wch;
+
+wch[1] = 0;
+setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
 }
 
 /* Setup wchar glyph for one font character */
 static void convert_font(unsigned char fch, iconv_t conv)
 {
 char mbch[MB_LEN_MAX];
-wchar_t wch;
+wchar_t wch[2];
 char *pfch, *pmbch;
 size_t sfch, smbch;
 mbstate_t ps;
@@ -461,13 +465,15 @@ static void convert_font(unsigned char fch, iconv_t conv)
 }
 
 memset(&ps, 0, sizeof(ps));
-if (mbrtowc(&wch, mbch, sizeof(mbch) - smbch, &ps) == -1) {
+if (mbrtowc(&wch[0], mbch, sizeof(mbch) - smbch, &ps) == -1) {
 fprintf(stderr, "Could not convert font glyph 0x%02x "
 "from a multibyte character to wchar_t: %s\n",
 fch, strerror(errno));
 return;
 }
-vga_to_curses[fch].chars[0] = wch;
+
+wch[1] = 0;
+setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
 }
 
 /* Convert one wchar to UCS-2 */
@@ -592,7 +598,16 @@ static void font_setup(void)
 if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
 /* Non-Unicode capable, use termcap equivalents for those available */
 for (i = 0; i <= 0xFF; i++) {
-switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) 
{
+wchar_t wch[CCHARW_MAX];
+attr_t attr;
+short color;
+int ret;
+
+ret = getcchar(&vga_to_curses[i], wch, &attr, &color, NULL);
+if (ret == ERR)
+continue;
+
+switch (get_ucs(wch[0], nativecharset_to_ucs2)) {
 case 0x00a3:
 vga_to_curses[i] = *WACS_STERLING;
 break;
-- 
2.20.1




[Qemu-devel] [PATCHv4 0/2] ui/curses: BSD portability fixes

2019-04-27 Thread Samuel Thibault
BSD needs a few fixes for wide character manipulations.

Difference with v1:
- Fix unitialized value in error message

Difference with v2:
- Add cchar_t manipulation fix

Difference with v3:
- use mbrtowc/wcrtomb instead of mbtowc/wctomb
- use MB_LEN_MAX instead of MB_CUR_MAX to avoid using a VLA.

Samuel Thibault (2):
  ui/curses: do not assume wchar_t contains unicode
  ui/curses: manipulate cchar_t with standard curses functions

 ui/curses.c | 194 ++--
 1 file changed, 126 insertions(+), 68 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCHv4 1/2] ui/curses: do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
E.g. BSD and Solaris even use locale-specific encoding there.

We thus have to go through the native multibyte representation and use
mbrtowc/wcrtomb to make a proper conversion.

Signed-off-by: Samuel Thibault 
Tested-by: Kamil Rytarowski 
---
 ui/curses.c | 157 +---
 1 file changed, 100 insertions(+), 57 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..81d419879e 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,108 @@ static void curses_atexit(void)
 endwin();
 }
 
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
 /* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
+char mbch[MB_LEN_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *puch, *pmbch;
+size_t such, smbch;
+mbstate_t ps;
+
+puch = (char *) &uch;
+pmbch = (char *) mbch;
+such = sizeof(uch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from UCS-2 to a multibyte character: %s\n",
+uch, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
-ch, strerror(errno));
-} else {
-vga_to_curses[glyph].chars[0] = wch;
+memset(&ps, 0, sizeof(ps));
+if (mbrtowc(&wch, mbch, sizeof(mbch) - smbch, &ps) == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to wchar_t: %s\n",
+uch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
 {
+char mbch[MB_LEN_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *pfch, *pmbch;
+size_t sfch, smbch;
+mbstate_t ps;
+
+pfch = (char *) &fch;
+pmbch = (char *) &mbch;
+sfch = sizeof(fch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from %s to a multibyte character: %s\n",
+fch, font_charset, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
-ch, font_charset, strerror(errno));
-} else {
-vga_to_curses[ch].chars[0] = wch;
+memset(&ps, 0, sizeof(ps));
+if (mbrtowc(&wch, mbch, sizeof(mbch) - smbch, &ps) == -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from a multibyte character to wchar_t: %s\n",
+fch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Convert one wchar to UCS-2 */
 static uint16_t get_ucs(wchar_t wch, iconv_t conv)
 {
-uint16_t ch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
-
-if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
%s\n",
-(unsigned long)wch, strerror(errno));
+char mbch[MB_LEN_MAX];
+uint16_t uch;
+char *pmbch, *puch;
+size_t smbch, such;
+mbstate_t ps;
+int ret;
+
+memset(&ps, 0, sizeof(ps));
+ret = wcrtomb(mbch, wch, &ps);
+if (ret == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from wchar_t to a multibyte character: %s\n",
+wch, strerror(errno));
+return 0xFFFD;
+}
+
+pmbch = (char *) mbch;
+puch = (char *) &uch;
+smbch = ret;
+such = sizeof(uch);
+
+if (iconv(conv, &pmbch, &smbch, &puch, &such) == 

Re: [Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
Kamil Rytarowski, le sam. 27 avril 2019 19:36:40 +0200, a ecrit:
> On 27.04.2019 18:30, Samuel Thibault wrote:
> > E.g. BSD and Solaris even use locale-specific encoding there.
> > 
> > We thus have to go through the native multibyte representation and use
> > mbtowc/wctomb to make a proper conversion.
> > 
> > Signed-off-by: Samuel Thibault 
> 
> Both patches work for me on NetBSD/amd64 8.99.37 for qemu-system-x86_64.
> Borders are printed correctly.
> 
> Regarding the patch I'm not sure whether to use MB_LEN_MAX or MB_CUR_MAX?

I don't know if qemu can afford VLA?

> I'm also unsure whether to reset conversion state between a multibyte
> character and wide character, with: `mbtowc(NULL, 0, 0);`. It's
> recommended to use in code examples examples. I think it doesn't make
> any harm to use it.

Mmm, better yet, we should actually use mbrtowc and wcrtomb. I have
fixed this in my tree.

> I'm not sure if this is related, but "qemu-system-hppa -curses" is
> broken for me. I didn't use it in the past as it just recently acquired
> NetBSD guest support.
> 
> (lldb) bt
> libcurses.so.7`mvwadd_wchnstr(win=0x, y=,
> x=, wchstr=0x7f7fe020, n=0) at add_wchstr.c:123
>   * frame #2: 0x0078629e
> qemu-system-hppa`curses_update(dcl=0x7f7ff7bd8bc0, x=0, y=0, w=79,
> h=24) at curses.c:86:9
> frame #3: 0x00753dae
> qemu-system-hppa`dpy_text_update(con=0x7f7ff7bae580, x=0, y=0, w=79,

> (lldb) p screenpad
> (WINDOW *) $2 = 0x

I don't think this is related at all, screenpad management is another
matter.

Samuel



[Qemu-devel] [PATCHv3 0/2] ui/curses: BSD portability fixes

2019-04-27 Thread Samuel Thibault
BSD needs a few fixes for wide character manipulations.

Difference with v1:
- Fix unitialized value in error message

Difference with v2:
- Add cchar_t manipulation fix

Samuel Thibault (2):
  ui/curses: do not assume wchar_t contains unicode
  ui/curses: manipulate cchar_t with standard curses functions

 ui/curses.c | 188 +---
 1 file changed, 120 insertions(+), 68 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCHv3 2/2] ui/curses: manipulate cchar_t with standard curses functions

2019-04-27 Thread Samuel Thibault
The chars/attr fields are curses internals, setcchar and getcchar have
to be used instead.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 43 +--
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index 395f9545e9..bc0d77a2a8 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -66,20 +66,22 @@ static void curses_update(DisplayChangeListener *dcl,
 {
 console_ch_t *line;
 cchar_t curses_line[width];
+wchar_t wch[CCHARW_MAX];
+attr_t attrs;
+short colors;
+int ret;
 
 line = screen + y * width;
 for (h += y; y < h; y ++, line += width) {
 for (x = 0; x < width; x++) {
 chtype ch = line[x] & 0xff;
 chtype at = line[x] & ~0xff;
-if (vga_to_curses[ch].chars[0]) {
-curses_line[x] = vga_to_curses[ch];
-} else {
-curses_line[x] = (cchar_t) {
-.chars[0] = ch,
-};
+ret = getcchar(&vga_to_curses[ch], wch, &attrs, &colors, NULL);
+if (ret == ERR || wch[0] == 0) {
+wch[0] = ch;
+wch[1] = 0;
 }
-curses_line[x].attr |= at;
+setcchar(&curses_line[x], wch, at, 0, NULL);
 }
 mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
 }
@@ -412,7 +414,7 @@ static void curses_atexit(void)
 static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
 char mbch[MB_CUR_MAX];
-wchar_t wch;
+wchar_t wch[2];
 char *puch, *pmbch;
 size_t such, smbch;
 
@@ -428,20 +430,22 @@ static void convert_ucs(unsigned char fch, uint16_t uch, 
iconv_t conv)
 return;
 }
 
-if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
 fprintf(stderr, "Could not convert 0x%04x "
 "from a multibyte character to wchar_t: %s\n",
 uch, strerror(errno));
 return;
 }
-vga_to_curses[fch].chars[0] = wch;
+
+wch[1] = 0;
+setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
 }
 
 /* Setup wchar glyph for one font character */
 static void convert_font(unsigned char fch, iconv_t conv)
 {
 char mbch[MB_CUR_MAX];
-wchar_t wch;
+wchar_t wch[2];
 char *pfch, *pmbch;
 size_t sfch, smbch;
 
@@ -457,13 +461,15 @@ static void convert_font(unsigned char fch, iconv_t conv)
 return;
 }
 
-if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+if (mbtowc(&wch[0], mbch, sizeof(mbch) - smbch) == -1) {
 fprintf(stderr, "Could not convert font glyph 0x%02x "
 "from a multibyte character to wchar_t: %s\n",
 fch, strerror(errno));
 return;
 }
-vga_to_curses[fch].chars[0] = wch;
+
+wch[1] = 0;
+setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
 }
 
 /* Convert one wchar to UCS-2 */
@@ -586,7 +592,16 @@ static void font_setup(void)
 if (strcmp(nl_langinfo(CODESET), "UTF-8")) {
 /* Non-Unicode capable, use termcap equivalents for those available */
 for (i = 0; i <= 0xFF; i++) {
-switch (get_ucs(vga_to_curses[i].chars[0], nativecharset_to_ucs2)) 
{
+wchar_t wch[CCHARW_MAX];
+attr_t attr;
+short color;
+int ret;
+
+ret = getcchar(&vga_to_curses[i], wch, &attr, &color, NULL);
+if (ret == ERR)
+continue;
+
+switch (get_ucs(wch[0], nativecharset_to_ucs2)) {
 case 0x00a3:
 vga_to_curses[i] = *WACS_STERLING;
 break;
-- 
2.20.1




[Qemu-devel] [PATCHv3 1/2] ui/curses: Do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
E.g. BSD and Solaris even use locale-specific encoding there.

We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 151 
 1 file changed, 94 insertions(+), 57 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
 endwin();
 }
 
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
 /* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *puch, *pmbch;
+size_t such, smbch;
+
+puch = (char *) &uch;
+pmbch = (char *) mbch;
+such = sizeof(uch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from UCS-2 to a multibyte character: %s\n",
+uch, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
-ch, strerror(errno));
-} else {
-vga_to_curses[glyph].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to wchar_t: %s\n",
+uch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *pfch, *pmbch;
+size_t sfch, smbch;
+
+pfch = (char *) &fch;
+pmbch = (char *) &mbch;
+sfch = sizeof(fch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from %s to a multibyte character: %s\n",
+fch, font_charset, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
-ch, font_charset, strerror(errno));
-} else {
-vga_to_curses[ch].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from a multibyte character to wchar_t: %s\n",
+fch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Convert one wchar to UCS-2 */
 static uint16_t get_ucs(wchar_t wch, iconv_t conv)
 {
-uint16_t ch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
-
-if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
%s\n",
-(unsigned long)wch, strerror(errno));
+char mbch[MB_CUR_MAX];
+uint16_t uch;
+char *pmbch, *puch;
+size_t smbch, such;
+int ret;
+
+ret = wctomb(mbch, wch);
+if (ret == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from wchar_t to a multibyte character: %s\n",
+wch, strerror(errno));
+return 0xFFFD;
+}
+
+pmbch = (char *) mbch;
+puch = (char *) &uch;
+smbch = ret;
+such = sizeof(uch);
+
+if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to UCS-2 : %s\n",
+wch, strerror(errno));
 return 0xFFFD;

[Qemu-devel] [PATCH] curses: do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
E.g. BSD and Solaris even use locale-specific encoding there.

We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 151 
 1 file changed, 94 insertions(+), 57 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
 endwin();
 }
 
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
 /* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *puch, *pmbch;
+size_t such, smbch;
+
+puch = (char *) &uch;
+pmbch = (char *) mbch;
+such = sizeof(uch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from UCS-2 to a multibyte character: %s\n",
+uch, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
-ch, strerror(errno));
-} else {
-vga_to_curses[glyph].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to wchar_t: %s\n",
+uch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *pfch, *pmbch;
+size_t sfch, smbch;
+
+pfch = (char *) &fch;
+pmbch = (char *) &mbch;
+sfch = sizeof(fch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from %s to a multibyte character: %s\n",
+fch, font_charset, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
-ch, font_charset, strerror(errno));
-} else {
-vga_to_curses[ch].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from a multibyte character to wchar_t: %s\n",
+fch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Convert one wchar to UCS-2 */
 static uint16_t get_ucs(wchar_t wch, iconv_t conv)
 {
-uint16_t ch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
-
-if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
%s\n",
-(unsigned long)wch, strerror(errno));
+char mbch[MB_CUR_MAX];
+uint16_t uch;
+char *pmbch, *puch;
+size_t smbch, such;
+int ret;
+
+ret = wctomb(mbch, wch);
+if (ret == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from wchar_t to a multibyte character: %s\n",
+wch, strerror(errno));
+return 0xFFFD;
+}
+
+pmbch = (char *) mbch;
+puch = (char *) &uch;
+smbch = ret;
+such = sizeof(uch);
+
+if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to UCS-2 : %s\n",
+wch, strerror(errno));
 return 0xFFFD;

[Qemu-devel] [PATCH] curses: Do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
E.g. BSD and Solaris even use locale-specific encoding there.

We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 151 
 1 file changed, 94 insertions(+), 57 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..395f9545e9 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
 endwin();
 }
 
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
 /* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *puch, *pmbch;
+size_t such, smbch;
+
+puch = (char *) &uch;
+pmbch = (char *) mbch;
+such = sizeof(uch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from UCS-2 to a multibyte character: %s\n",
+uch, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
-ch, strerror(errno));
-} else {
-vga_to_curses[glyph].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to wchar_t: %s\n",
+uch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *pfch, *pmbch;
+size_t sfch, smbch;
+
+pfch = (char *) &fch;
+pmbch = (char *) &mbch;
+sfch = sizeof(fch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from %s to a multibyte character: %s\n",
+fch, font_charset, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
-ch, font_charset, strerror(errno));
-} else {
-vga_to_curses[ch].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from a multibyte character to wchar_t: %s\n",
+fch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Convert one wchar to UCS-2 */
 static uint16_t get_ucs(wchar_t wch, iconv_t conv)
 {
-uint16_t ch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
-
-if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
%s\n",
-(unsigned long)wch, strerror(errno));
+char mbch[MB_CUR_MAX];
+uint16_t uch;
+char *pmbch, *puch;
+size_t smbch, such;
+int ret;
+
+ret = wctomb(mbch, wch);
+if (ret == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from wchar_t to a multibyte character: %s\n",
+wch, strerror(errno));
+return 0xFFFD;
+}
+
+pmbch = (char *) mbch;
+puch = (char *) &uch;
+smbch = ret;
+such = sizeof(uch);
+
+if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to UCS-2 : %s\n",
+wch, strerror(errno));
 return 0xFFFD;

Re: [Qemu-devel] [PATCH] curses: Do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
Ah, sorry, I missed putting v2 above and the change summary: I fixed an
uninitalized value in an error message.

Samuel

Samuel Thibault, le sam. 27 avril 2019 17:58:07 +0200, a ecrit:
> E.g. BSD and Solaris even use locale-specific encoding there.
> 
> We thus have to go through the native multibyte representation and use
> mbtowc/wctomb to make a proper conversion.
> 
> Signed-off-by: Samuel Thibault 
> ---
>  ui/curses.c | 151 
>  1 file changed, 94 insertions(+), 57 deletions(-)
> 
> diff --git a/ui/curses.c b/ui/curses.c
> index fb63945188..395f9545e9 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -400,65 +400,102 @@ static void curses_atexit(void)
>  endwin();
>  }
>  
> +/*
> + * In the following:
> + * - fch is the font glyph number
> + * - uch is the unicode value
> + * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
> + * - mbch is the native local-dependent multibyte representation
> + */
> +
>  /* Setup wchar glyph for one UCS-2 char */
> -static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
> +static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
>  {
> +char mbch[MB_CUR_MAX];
>  wchar_t wch;
> -char *pch, *pwch;
> -size_t sch, swch;
> -
> -pch = (char *) &ch;
> -pwch = (char *) &wch;
> -sch = sizeof(ch);
> -swch = sizeof(wch);
> +char *puch, *pmbch;
> +size_t such, smbch;
> +
> +puch = (char *) &uch;
> +pmbch = (char *) mbch;
> +such = sizeof(uch);
> +smbch = sizeof(mbch);
> +
> +if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
> +fprintf(stderr, "Could not convert 0x%04x "
> +"from UCS-2 to a multibyte character: %s\n",
> +uch, strerror(errno));
> +return;
> +}
>  
> -if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> -fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: 
> %s\n",
> -ch, strerror(errno));
> -} else {
> -vga_to_curses[glyph].chars[0] = wch;
> +if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> +fprintf(stderr, "Could not convert 0x%04x "
> +"from a multibyte character to wchar_t: %s\n",
> +uch, strerror(errno));
> +return;
>  }
> +vga_to_curses[fch].chars[0] = wch;
>  }
>  
>  /* Setup wchar glyph for one font character */
> -static void convert_font(unsigned char ch, iconv_t conv)
> +static void convert_font(unsigned char fch, iconv_t conv)
>  {
> +char mbch[MB_CUR_MAX];
>  wchar_t wch;
> -char *pch, *pwch;
> -size_t sch, swch;
> -
> -pch = (char *) &ch;
> -pwch = (char *) &wch;
> -sch = sizeof(ch);
> -swch = sizeof(wch);
> +char *pfch, *pmbch;
> +size_t sfch, smbch;
> +
> +pfch = (char *) &fch;
> +pmbch = (char *) &mbch;
> +sfch = sizeof(fch);
> +smbch = sizeof(mbch);
> +
> +if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
> +fprintf(stderr, "Could not convert font glyph 0x%02x "
> +"from %s to a multibyte character: %s\n",
> +fch, font_charset, strerror(errno));
> +return;
> +}
>  
> -if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
> -fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
> -ch, font_charset, strerror(errno));
> -} else {
> -vga_to_curses[ch].chars[0] = wch;
> +if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
> +fprintf(stderr, "Could not convert font glyph 0x%02x "
> +"from a multibyte character to wchar_t: %s\n",
> +fch, strerror(errno));
> +return;
>  }
> +vga_to_curses[fch].chars[0] = wch;
>  }
>  
>  /* Convert one wchar to UCS-2 */
>  static uint16_t get_ucs(wchar_t wch, iconv_t conv)
>  {
> -uint16_t ch;
> -char *pch, *pwch;
> -size_t sch, swch;
> -
> -pch = (char *) &ch;
> -pwch = (char *) &wch;
> -sch = sizeof(ch);
> -swch = sizeof(wch);
> -
> -if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
> -fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
> %s\n",
> -   

[Qemu-devel] [PATCH] curses: Do not assume wchar_t contains unicode

2019-04-27 Thread Samuel Thibault
E.g. BSD and Solaris even use locale-specific encoding there.

We thus have to go through the native multibyte representation and use
mbtowc/wctomb to make a proper conversion.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 151 
 1 file changed, 94 insertions(+), 57 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index fb63945188..4414399e73 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -400,65 +400,102 @@ static void curses_atexit(void)
 endwin();
 }
 
+/*
+ * In the following:
+ * - fch is the font glyph number
+ * - uch is the unicode value
+ * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
+ * - mbch is the native local-dependent multibyte representation
+ */
+
 /* Setup wchar glyph for one UCS-2 char */
-static void convert_ucs(int glyph, uint16_t ch, iconv_t conv)
+static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *puch, *pmbch;
+size_t such, smbch;
+
+puch = (char *) &uch;
+pmbch = (char *) mbch;
+such = sizeof(uch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from UCS-2 to a multibyte character: %s\n",
+uch, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%04x from UCS-2 to WCHAR_T: %s\n",
-ch, strerror(errno));
-} else {
-vga_to_curses[glyph].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to wchar_t: %s\n",
+uch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Setup wchar glyph for one font character */
-static void convert_font(unsigned char ch, iconv_t conv)
+static void convert_font(unsigned char fch, iconv_t conv)
 {
+char mbch[MB_CUR_MAX];
 wchar_t wch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
+char *pfch, *pmbch;
+size_t sfch, smbch;
+
+pfch = (char *) &fch;
+pmbch = (char *) &mbch;
+sfch = sizeof(fch);
+smbch = sizeof(mbch);
+
+if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from %s to a multibyte character: %s\n",
+fch, font_charset, strerror(errno));
+return;
+}
 
-if (iconv(conv, &pch, &sch, &pwch, &swch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02x from %s to WCHAR_T: %s\n",
-ch, font_charset, strerror(errno));
-} else {
-vga_to_curses[ch].chars[0] = wch;
+if (mbtowc(&wch, mbch, sizeof(mbch) - smbch) == -1) {
+fprintf(stderr, "Could not convert font glyph 0x%02x "
+"from a multibyte character to wchar_t: %s\n",
+fch, strerror(errno));
+return;
 }
+vga_to_curses[fch].chars[0] = wch;
 }
 
 /* Convert one wchar to UCS-2 */
 static uint16_t get_ucs(wchar_t wch, iconv_t conv)
 {
-uint16_t ch;
-char *pch, *pwch;
-size_t sch, swch;
-
-pch = (char *) &ch;
-pwch = (char *) &wch;
-sch = sizeof(ch);
-swch = sizeof(wch);
-
-if (iconv(conv, &pwch, &swch, &pch, &sch) == (size_t) -1) {
-fprintf(stderr, "Could not convert 0x%02lx from WCHAR_T to UCS-2: 
%s\n",
-(unsigned long)wch, strerror(errno));
+char mbch[MB_CUR_MAX];
+uint16_t uch;
+char *pmbch, *puch;
+size_t smbch, such;
+int ret;
+
+ret = wctomb(mbch, wch);
+if (ret == -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from wchar_t to a multibyte character: %s\n",
+uch, strerror(errno));
+return 0xFFFD;
+}
+
+pmbch = (char *) mbch;
+puch = (char *) &uch;
+smbch = ret;
+such = sizeof(uch);
+
+if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
+fprintf(stderr, "Could not convert 0x%04x "
+"from a multibyte character to UCS-2 : %s\n",
+uch, strerror(errno));
 return 0xFFFD;

[Qemu-devel] [PULL 1/1] slirp: Gcc 9 -O3 fix

2019-04-15 Thread Samuel Thibault
From: "Dr. David Alan Gilbert" 

Gcc 9 needs some convincing that sopreprbuf really is going to fill
in iov in the call from soreadbuf, even though the failure case
shouldn't happen.

Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20190415121740.9881-1-dgilb...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/src/socket.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/slirp/src/socket.c b/slirp/src/socket.c
index 4a3c935e25..bb752fdcae 100644
--- a/slirp/src/socket.c
+++ b/slirp/src/socket.c
@@ -171,6 +171,7 @@ int
 soread(struct socket *so)
 {
int n, nn;
+   size_t buf_len;
struct sbuf *sb = &so->so_snd;
struct iovec iov[2];
 
@@ -181,7 +182,8 @@ soread(struct socket *so)
 * No need to check if there's enough room to read.
 * soread wouldn't have been called if there weren't
 */
-   sopreprbuf(so, iov, &n);
+   buf_len = sopreprbuf(so, iov, &n);
+   assert(buf_len != 0);
 
nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
if (nn <= 0) {
@@ -257,6 +259,7 @@ int soreadbuf(struct socket *so, const char *buf, int size)
 * No need to check if there's enough room to read.
 * soread wouldn't have been called if there weren't
 */
+   assert(size > 0);
if (sopreprbuf(so, iov, &n) < size)
 goto err;
 
-- 
2.20.1




Re: [Qemu-devel] [PATCH v3] slirp: Gcc 9 -O3 fix

2019-04-15 Thread Samuel Thibault
Dr. David Alan Gilbert (git), le lun. 15 avril 2019 13:17:40 +0100, a ecrit:
> From: "Dr. David Alan Gilbert" 
> 
> Gcc 9 needs some convincing that sopreprbuf really is going to fill
> in iov in the call from soreadbuf, even though the failure case
> shouldn't happen.
> 
> Signed-off-by: Dr. David Alan Gilbert 

Applied to my tree, thanks!

Samuel



[Qemu-devel] [PULL 0/1] slirp gcc9 build fix

2019-04-15 Thread Samuel Thibault
The following changes since commit afccfc0c4c6134a7bc9da6375996b3b91d291de4:

  Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging 
(2019-04-12 17:06:49 +0100)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 6fabae61a9393fd2bc703837e464b9c34ec5ef25:

  slirp: Gcc 9 -O3 fix (2019-04-15 20:01:18 +0200)


Slirp updates

Dr. David Alan Gilbert (1):
  slirp: Gcc 9 -O3 fix


Dr. David Alan Gilbert (1):
  slirp: Gcc 9 -O3 fix

 slirp/src/socket.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)



Re: [Qemu-devel] [PATCH v2] slirp: Gcc 9 -O3 fix

2019-04-15 Thread Samuel Thibault
Dr. David Alan Gilbert (git), le lun. 15 avril 2019 13:02:05 +0100, a ecrit:
> From: "Dr. David Alan Gilbert" 
> 
> Gcc 9 needs some convincing that sopreprbuf really is going to fill
> in iov in the call from soreadbuf, even though the failure case
> shouldn't happen.
> 
> Signed-off-by: Dr. David Alan Gilbert 
> ---
>  slirp/src/socket.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/slirp/src/socket.c b/slirp/src/socket.c
> index 4a3c935e25..beb8517f1c 100644
> --- a/slirp/src/socket.c
> +++ b/slirp/src/socket.c
> @@ -181,7 +181,7 @@ soread(struct socket *so)
>* No need to check if there's enough room to read.
>* soread wouldn't have been called if there weren't
>*/
> - sopreprbuf(so, iov, &n);
> + assert(sopreprbuf(so, iov, &n) != 0);

Please make this through a variable, otherwise anybody building with
-DNDEBUG will get sopreprbuf not being called.

>   nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
>   if (nn <= 0) {
> @@ -257,6 +257,7 @@ int soreadbuf(struct socket *so, const char *buf, int 
> size)
>* No need to check if there's enough room to read.
>* soread wouldn't have been called if there weren't
>*/
> + assert(size > 0);
>   if (sopreprbuf(so, iov, &n) < size)
>  goto err;
>  
> -- 
> 2.21.0
> 



Re: [Qemu-devel] [PATCH] vl: set LC_MESSAGES and LC_CTYPE in main for all code

2019-04-15 Thread Samuel Thibault
Daniel P. Berrangé, le lun. 15 avril 2019 12:34:31 +0100, a ecrit:
> Hardcoding LC_CTYPE to C.UTF-8 is a partial regression vs the above
> curses commit, since it will break the curses wide character handling
> for non-UTF-8 locales but this is unavoidable until QEMU is cleaned up
> to cope with non-UTF-8 locales fully.
> 
> Signed-off-by: Daniel P. Berrangé 

Non-utf-8 environments should be rare enough that it will not be a real
concern.

Acked-by: Samuel Thibault 



Re: [Qemu-devel] [PATCH] slirp: Gcc 9 -O3 fix

2019-04-12 Thread Samuel Thibault
Dr. David Alan Gilbert, le ven. 12 avril 2019 16:49:42 +0100, a ecrit:
> * Samuel Thibault (samuel.thiba...@gnu.org) wrote:
> > Hello,
> > 
> > Dr. David Alan Gilbert, le lun. 08 avril 2019 09:46:53 +0100, a ecrit:
> > > 'soread' has the comment:
> > > 
> > > /*
> > >  * No need to check if there's enough room to read.
> > >  * soread wouldn't have been called if there weren't
> > >  */
> > > sopreprbuf(so, iov, &n);
> > > 
> > > the compiler doesn't realise that, and is moaning about the case
> > > where the if (len <=0) return happens and the following 
> > > code tries to use iov.
> > 
> > I see. Perhaps we should make this an assert then? In case this isn't
> > true, i.e. soread() is called even if no room is available, returning 0
> > would probably just let the caller just try again, and we should rather
> > just plainly crash than hang?
> 
> Adding the assert in soread sorts that case out:
>   assert(sopreprbuf(so, iov, &n) != 0);
> 
> however, I also need to fix soreadbuf;  is it legal to call that with
> a 0 size?

It does not really make sense to, so an assert >0 should be fine.

Samuel



Re: [Qemu-devel] [PATCH] slirp: Gcc 9 -O3 fix

2019-04-11 Thread Samuel Thibault
Hello,

Dr. David Alan Gilbert, le lun. 08 avril 2019 09:46:53 +0100, a ecrit:
> 'soread' has the comment:
> 
> /*
>  * No need to check if there's enough room to read.
>  * soread wouldn't have been called if there weren't
>  */
> sopreprbuf(so, iov, &n);
> 
> the compiler doesn't realise that, and is moaning about the case
> where the if (len <=0) return happens and the following 
> code tries to use iov.

I see. Perhaps we should make this an assert then? In case this isn't
true, i.e. soread() is called even if no room is available, returning 0
would probably just let the caller just try again, and we should rather
just plainly crash than hang?

Samuel



Re: [Qemu-devel] [PATCH] slirp: Gcc 9 -O3 fix

2019-04-05 Thread Samuel Thibault
Hello,

Dr. David Alan Gilbert (git), le ven. 05 avril 2019 19:46:48 +0100, a ecrit:
> From: "Dr. David Alan Gilbert" 
> 
> Gcc 9 needs some convincing that sopreprbuf really is going to fill
> in iov in the call from soreadbuf, even though the failure case
> shouldn't happen; so swing the check around initialising the fields.

While I can understand that setting iov[0].iov_len may help a compiler,
I don't see why moving if (len <= 0) return 0; down?

> Signed-off-by: Dr. David Alan Gilbert 
> ---
>  slirp/src/socket.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/slirp/src/socket.c b/slirp/src/socket.c
> index 4a3c935e25..4aa95f 100644
> --- a/slirp/src/socket.c
> +++ b/slirp/src/socket.c
> @@ -113,12 +113,14 @@ size_t sopreprbuf(struct socket *so, struct iovec *iov, 
> int *np)
>   DEBUG_CALL("sopreprbuf");
>   DEBUG_ARG("so = %p", so);
>  
> - if (len <= 0)
> - return 0;
> -
>   iov[0].iov_base = sb->sb_wptr;
> +iov[0].iov_len = 0;
>  iov[1].iov_base = NULL;
>  iov[1].iov_len = 0;
> +
> + if (len <= 0)
> + return 0;
> +
>   if (sb->sb_wptr < sb->sb_rptr) {
>   iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
>   /* Should never succeed, but... */
> -- 
> 2.21.0
> 

-- 
Samuel
 FYLG> Tiens, vlà une URL qui va bien :
 FYLG> ftp://127.0.0.1/WaReZ/NiouZeS/WinDoZe/NeWSMoNGeR/SuPeR
 c'est gentil sauf que l'adresse ne fonctionne pas sa me fais une erreur
 -+- Furtif in Guide du Neuneu Usenet :  -+-



Re: [Qemu-devel] [PATCH v4 0/8] slirp: clarify license of slirp as BSD-3

2019-03-22 Thread Samuel Thibault
Marc-André Lureau, le ven. 22 mars 2019 17:46:12 +0100, a ecrit:
> On Fri, Mar 22, 2019 at 5:43 PM Marc-André Lureau
>  wrote:
> >
> > Hi,
> >
> > In order to make slirp a standalone project, the project must have a
> > clear license, and be compatible with the GPL or LGPL.
> >
> > Since commit 2f5f89963186d42a7ded253bc6cf5b32abb45cec ("Remove the
> > advertising clause from the slirp license"), slirp is BSD-3. But new
> > files have been added under slirp/ with QEMU GPL license since then.
> >
> > v4:
> >  - update SPDX-patches commit titles to differentiate them, as
> >suggested by Eric
> >  - add a-b & r-b tags
> >
> 
> This version should be queue-able, hopefully. Samuel, I am not sure if
> you are willing to do it.
> 
> If no objections, I can also send a pullreq to Peter?

I don't see a use for going through my tree :)

Samuel



Re: [Qemu-devel] [PATCH v3 0/8] slirp: clarify license of slirp as BSD-3

2019-03-16 Thread Samuel Thibault
Eric Blake, le jeu. 14 mars 2019 08:44:06 -0500, a ecrit:
> However, while it does not affect compilation, it DOES have legal
> ramification; I'd feel a lot better about having R-b on every patch,

Sure, I was just asking for the git commit path :) I don't think it's
useful to make it go through my tree.

Samuel



Re: [Qemu-devel] [PATCH] curses ui: always initialize all curses_line fields

2019-03-15 Thread Samuel Thibault
Peter Maydell, le ven. 15 mars 2019 10:06:48 +, a ecrit:
> > +curses_line[x] = (cchar_t) {};
> >  curses_line[x].chars[0] = ch;
> > -curses_line[x].chars[1] = 0;
> > -curses_line[x].attr = 0;
> >  }
> >  curses_line[x].attr |= at;
> 
> Does this really need the cast ?

Yes, otherwise it is refused by the compiler.

> {} is supposed to be a universal initializer.

When used as initialized (cchar_t foo = {}), yes.  But when used in
assignations, no, one has to cast it.

Samuel



Re: [Qemu-devel] [PATCH] curses ui: always initialize all curses_line fields

2019-03-15 Thread Samuel Thibault
Eric Blake, le ven. 15 mars 2019 08:02:29 -0500, a ecrit:
> On 3/15/19 5:06 AM, Peter Maydell wrote:
> > On Fri, 15 Mar 2019 at 08:37, Samuel Thibault
> >  wrote:
> >>
> >> cchar_t can contain not only attr and chars fields, but also ext_color.
> >> Initialize the whole structure to zero instead of enumerating fields.
> >>
> >> Spotted by Coverity: CID 1399711
> >>
> >> Signed-off-by: Samuel Thibault 
> >> ---
> >>  ui/curses.c | 3 +--
> >>  1 file changed, 1 insertion(+), 2 deletions(-)
> >>
> >> diff --git a/ui/curses.c b/ui/curses.c
> >> index d29098db9f..e99fbe3e24 100644
> >> --- a/ui/curses.c
> >> +++ b/ui/curses.c
> >> @@ -75,9 +75,8 @@ static void curses_update(DisplayChangeListener *dcl,
> >>  if (vga_to_curses[ch].chars[0]) {
> >>  curses_line[x] = vga_to_curses[ch];
> >>  } else {
> >> +curses_line[x] = (cchar_t) {};
> >>  curses_line[x].chars[0] = ch;
> >> -curses_line[x].chars[1] = 0;
> >> -curses_line[x].attr = 0;
> >>  }
> >>  curses_line[x].attr |= at;
> > 
> > Does this really need the cast ? {} is supposed to be a
> > universal initializer.
> 
> Or is it worth using:
> 
> curses_line[x] = (cchar_t) {
>   .chars[0] = ch,
> };
> 
> so that all other fields not mentioned are zero-initialized, without
> relying on the {} extension?

Right, it's no less readable :) I have sent an updated patch.

Samuel



[Qemu-devel] [PATCHv2] curses ui: always initialize all curses_line fields

2019-03-15 Thread Samuel Thibault
cchar_t can contain not only attr and chars fields, but also ext_color.
Initialize the whole structure to zero instead of enumerating fields.

Spotted by Coverity: CID 1399711

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index d29098db9f..cc6d6da684 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -75,9 +75,9 @@ static void curses_update(DisplayChangeListener *dcl,
 if (vga_to_curses[ch].chars[0]) {
 curses_line[x] = vga_to_curses[ch];
 } else {
-curses_line[x].chars[0] = ch;
-curses_line[x].chars[1] = 0;
-curses_line[x].attr = 0;
+curses_line[x] = (cchar_t) {
+.chars[0] = ch,
+};
 }
 curses_line[x].attr |= at;
 }
-- 
2.20.1




[Qemu-devel] [PATCH] curses ui: always initialize all curses_line fields

2019-03-15 Thread Samuel Thibault
cchar_t can contain not only attr and chars fields, but also ext_color.
Initialize the whole structure to zero instead of enumerating fields.

Spotted by Coverity: CID 1399711

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index d29098db9f..e99fbe3e24 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -75,9 +75,8 @@ static void curses_update(DisplayChangeListener *dcl,
 if (vga_to_curses[ch].chars[0]) {
 curses_line[x] = vga_to_curses[ch];
 } else {
+curses_line[x] = (cchar_t) {};
 curses_line[x].chars[0] = ch;
-curses_line[x].chars[1] = 0;
-curses_line[x].attr = 0;
 }
 curses_line[x].attr |= at;
 }
-- 
2.20.1




Re: [Qemu-devel] [PATCH] curses ui: add missing iconv_close

2019-03-14 Thread Samuel Thibault
Peter Maydell, le jeu. 14 mars 2019 17:21:54 +, a ecrit:
> On Thu, 14 Mar 2019 at 17:20, Samuel Thibault
>  wrote:
> >
> > Signed-off-by: Samuel Thibault 
> > ---
> >  ui/curses.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/ui/curses.c b/ui/curses.c
> > index 3a7e8649f3..1f83a15a1c 100644
> > --- a/ui/curses.c
> > +++ b/ui/curses.c
> > @@ -646,6 +646,7 @@ static void font_setup(void)
> >  }
> >  }
> >  }
> > +iconv_close(ucs_to_wchar_conv);
> >  }
> 
> Don't you need to iconv_close() font_conv and
> wchar_to_ucs_conv as well ?

Right, sorry, since I didn't have coverity access I didn't realize there
were three leaks.

Samuel



[Qemu-devel] [PATCHv2] curses ui: add missing iconv_close calls

2019-03-14 Thread Samuel Thibault
The iconv_t are opened but never closed.

Spotted by Coverity: CID 1399708
Spotted by Coverity: CID 1399709
Spotted by Coverity: CID 1399713

Signed-off-by: Samuel Thibault 
---

Change since previous version: close all iconv_t, not only
ucs_to_wchar_conv.

 ui/curses.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/ui/curses.c b/ui/curses.c
index 3a7e8649f3..d29098db9f 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -519,6 +519,7 @@ static void font_setup(void)
 
 wchar_to_ucs_conv = iconv_open("UCS-2", "WCHAR_T");
 if (wchar_to_ucs_conv == (iconv_t) -1) {
+iconv_close(ucs_to_wchar_conv);
 fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
 strerror(errno));
 exit(1);
@@ -526,6 +527,8 @@ static void font_setup(void)
 
 font_conv = iconv_open("WCHAR_T", font_charset);
 if (font_conv == (iconv_t) -1) {
+iconv_close(ucs_to_wchar_conv);
+iconv_close(wchar_to_ucs_conv);
 fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
 font_charset, strerror(errno));
 exit(1);
@@ -646,6 +649,9 @@ static void font_setup(void)
 }
 }
 }
+iconv_close(ucs_to_wchar_conv);
+iconv_close(wchar_to_ucs_conv);
+iconv_close(font_conv);
 }
 
 static void curses_setup(void)
-- 
2.20.1




[Qemu-devel] [PATCH] curses ui: add missing iconv_close

2019-03-14 Thread Samuel Thibault
The iconv_t is opened but never closed.

Spotted by Coverity: CID 1399708
Spotted by Coverity: CID 1399709
Spotted by Coverity: CID 1399713

Signed-off-by: Samuel Thibault 
---
 ui/curses.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ui/curses.c b/ui/curses.c
index 3a7e8649f3..1f83a15a1c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -646,6 +646,7 @@ static void font_setup(void)
 }
 }
 }
+iconv_close(ucs_to_wchar_conv);
 }
 
 static void curses_setup(void)
-- 
2.20.1




Re: [Qemu-devel] [PATCH v3 0/8] slirp: clarify license of slirp as BSD-3

2019-03-14 Thread Samuel Thibault
Hello,

Should this go through my tree, or perhaps it can be directly pushed to
master by Peter since it's no-code-only-copyright changes?

Samuel

Marc-André Lureau, le jeu. 14 mars 2019 14:10:41 +0100, a ecrit:
> In order to make slirp a standalone project, the project must have a
> clear license, and be compatible with the GPL or LGPL.
> 
> Since commit 2f5f89963186d42a7ded253bc6cf5b32abb45cec ("Remove the
> advertising clause from the slirp license"), slirp is BSD-3. But new
> files have been added under slirp/ with QEMU GPL license since then.
> 
> v3:
>  - add preliminary "slirp: update COPYRIGHT to use full 3-Clause BSD
>License"
>  - split "slirp: clarify license of slirp files using SPDX" patch,
>  - fix SPDX for files with MIT license header
>  - add r-b tags, wording/spelling changes
> 
> v2:
>  - split the initial patch to add BSD-3 header & then SPDX lines
>  - do not modify existing copyright headers without copyright holder
>authorization
>  - drop the weak/ambiguous notice to the COPYRIGHT file
>  - added a RFC patch to remove Kelly Price from the maintainer duties
> 
> Marc-André Lureau (8):
>   slirp: update COPYRIGHT to use full 3-Clause BSD License
>   slirp: relicense GPL files to BSD-3
>   slirp: clarify license of slirp files using SPDX
>   slirp: clarify license of slirp files using SPDX
>   slirp: clarify license of slirp files using SPDX
>   slirp: clarify license of slirp files using SPDX
>   slirp: remove reference to COPYRIGHT file
>   slirp: is not maintained by Kelly Price for a long time
> 
>  slirp/src/bootp.h  |  1 +
>  slirp/src/debug.h  |  4 +---
>  slirp/src/dhcpv6.h | 32 +--
>  slirp/src/if.h |  4 +---
>  slirp/src/ip.h |  1 +
>  slirp/src/ip6.h|  1 +
>  slirp/src/ip6_icmp.h   |  1 +
>  slirp/src/ip_icmp.h|  1 +
>  slirp/src/libslirp.h   |  1 +
>  slirp/src/main.h   |  4 +---
>  slirp/src/mbuf.h   |  1 +
>  slirp/src/misc.h   |  4 +---
>  slirp/src/ncsi-pkt.h   | 34 +
>  slirp/src/qtailq.h |  1 +
>  slirp/src/sbuf.h   |  4 +---
>  slirp/src/slirp.h  |  1 +
>  slirp/src/socket.h |  4 +---
>  slirp/src/stream.h |  1 +
>  slirp/src/tcp.h|  1 +
>  slirp/src/tcp_timer.h  |  1 +
>  slirp/src/tcp_var.h|  1 +
>  slirp/src/tcpip.h  |  1 +
>  slirp/src/tftp.h   |  1 +
>  slirp/src/udp.h|  1 +
>  slirp/src/util.h   |  1 +
>  slirp/src/vmstate.h| 43 +++---
>  slirp/src/arp_table.c  |  1 +
>  slirp/src/bootp.c  |  1 +
>  slirp/src/cksum.c  |  1 +
>  slirp/src/dhcpv6.c | 38 +++--
>  slirp/src/dnssearch.c  |  1 +
>  slirp/src/if.c |  4 +---
>  slirp/src/ip6_icmp.c   |  1 +
>  slirp/src/ip6_input.c  |  1 +
>  slirp/src/ip6_output.c |  1 +
>  slirp/src/ip_icmp.c|  1 +
>  slirp/src/ip_input.c   |  4 +---
>  slirp/src/ip_output.c  |  4 +---
>  slirp/src/mbuf.c   |  4 +---
>  slirp/src/misc.c   |  4 +---
>  slirp/src/ncsi.c   | 32 +--
>  slirp/src/ndp_table.c  |  1 +
>  slirp/src/sbuf.c   |  4 +---
>  slirp/src/slirp.c  |  1 +
>  slirp/src/socket.c |  4 +---
>  slirp/src/state.c  |  1 +
>  slirp/src/stream.c |  1 +
>  slirp/src/tcp_input.c  |  4 +---
>  slirp/src/tcp_output.c |  4 +---
>  slirp/src/tcp_subr.c   |  4 +---
>  slirp/src/tcp_timer.c  |  1 +
>  slirp/src/tftp.c   |  1 +
>  slirp/src/udp.c|  1 +
>  slirp/src/udp6.c   |  1 +
>  slirp/src/util.c   |  1 +
>  slirp/src/vmstate.c| 32 +--
>  slirp/COPYRIGHT|  5 +++--
>  57 files changed, 229 insertions(+), 85 deletions(-)
> 
> -- 
> 2.21.0.4.g36eb1cb9cf
> 

-- 
Samuel
As usual, this being a 1.3.x release, I haven't even compiled this
kernel yet.  So if it works, you should be doubly impressed.
(Linus Torvalds, announcing kernel 1.3.3 on the linux-kernel mailing list.)



Re: [Qemu-devel] [PULL 0/2] Ui 20190313 patches

2019-03-13 Thread Samuel Thibault
Peter Maydell, le mer. 13 mars 2019 22:20:03 +, a ecrit:
> On Wed, 13 Mar 2019 at 07:41, Gerd Hoffmann  wrote:
> >
> > The following changes since commit 377b155bde451d5ac545fbdcdfbf6ca17a4228f5:
> >
> >   Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into 
> > staging (2019-03-11 18:26:37 +)
> >
> > are available in the Git repository at:
> >
> >   git://git.kraxel.org/qemu tags/ui-20190313-pull-request
> >
> > for you to fetch changes up to 2f8b7cd587558944532f587abb5203ce54badba9:
> >
> >   curses: add option to specify VGA font encoding (2019-03-13 08:29:06 
> > +0100)
> >
> > 
> > ui: better unicode support for curses, v2.
> >
> > 
> 
> Applied, thanks.
> 
> Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
> for any user-visible changes.

Done so, thanks for the merge!

Samuel



Re: [Qemu-devel] [PATCH v2 1/4] slirp: relicense GPL files to BSD-3

2019-03-13 Thread Samuel Thibault
Hello,

Marc-André Lureau, le mer. 13 mars 2019 18:35:09 +0100, a ecrit:
> On Wed, Mar 13, 2019 at 6:32 PM Eric Blake  wrote:
> >
> > On 3/13/19 11:42 AM, Marc-André Lureau wrote:
> > > In order to make slirp a standalone project, the project must have a
> > > clear license, and be compatible with the GPL or LGPL.
> > >
> > > Since commit 2f5f89963186d42a7ded253bc6cf5b32abb45cec ("Remove the
> > > advertising clause from the slirp license"), slirp is BSD-3. But new
> > > files have been added under slirp/ with QEMU GPL license since then.
> > >
> > > The copyright holders have been asked to relicense files to BSD-3 and
> > > gave their permission:
> >
> > Reviewed-by: Eric Blake 
> >
> >
> > >
> > > Signed-off-by: Marc-André Lureau 
> > > ---
> > >  slirp/src/dhcpv6.h   | 31 +--
> > >  slirp/src/ncsi-pkt.h | 33 +
> > >  slirp/src/vmstate.h  | 42 +++---
> > >  slirp/src/dhcpv6.c   | 37 +++--
> > >  slirp/src/ncsi.c | 31 +--
> > >  slirp/src/vmstate.c  | 31 +--
> > >  6 files changed, 170 insertions(+), 35 deletions(-)
> >
> > Are we trying to split slirp off in time for 4.0, or are we at the point
> > where it remains embedded until 4.1?
> 
> I don't know what Samuel, Peter and others think about it.

I'd say since the source seems ready we can try for 4.0, but I let
general qemu maintainers consider what they prefer.

> If we don't have code change, but only move slirp/ to a submodule, is
> that acceptable during soft-freeze?
> 
> Fwiw, we are mostly ready to do that, we mostly need the repo creation
> now (https://gitlab.freedesktop.org/freedesktop/freedesktop/issues/119)



[Qemu-devel] [PULL 2/2] configure: remove slirp submodule support that doesn't exist yet

2019-03-13 Thread Samuel Thibault
From: Daniel P. Berrangé 

The slirp code is not yet split off into a separate repository, so
configuring QEMU to use slirp as a submodule is premature. This
causes the non-existant "slirp" to be requested from git when syncing
submodules. This in turn appears to be cause of non-deterministic
failures some developers are seeing with QEMU's submodule sync process.

Signed-off-by: Daniel P. Berrangé 
Message-Id: <20190313173157.30504-1-berra...@redhat.com>
Reviewed-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 configure | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index cab830a4c9..355eebfc5d 100755
--- a/configure
+++ b/configure
@@ -1109,8 +1109,6 @@ for opt do
   ;;
   --disable-slirp) slirp="no"
   ;;
-  --enable-slirp=git) slirp="git"
-  ;;
   --enable-slirp=system) slirp="system"
   ;;
   --disable-vde) vde="no"
@@ -5780,8 +5778,6 @@ case "$slirp" in
   "" | yes)
 if $pkg_config slirp; then
   slirp=system
-elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
-  slirp=git
 elif test -e "${source_path}/slirp/Makefile" ; then
   slirp=internal
 elif test -z "$slirp" ; then
@@ -5799,10 +5795,7 @@ case "$slirp" in
 esac
 
 case "$slirp" in
-  git | internal)
-if test "$slirp" = git; then
-  git_submodules="${git_submodules} slirp"
-fi
+  internal)
 mkdir -p slirp
 slirp_cflags="-I\$(SRC_PATH)/slirp/src -I\$(BUILD_DIR)/slirp/src"
 slirp_libs="-L\$(BUILD_DIR)/slirp -lslirp"
@@ -6464,7 +6457,7 @@ if test "$slirp" != "no"; then
   echo "SLIRP_CFLAGS=$slirp_cflags" >> $config_host_mak
   echo "SLIRP_LIBS=$slirp_libs" >> $config_host_mak
 fi
-if [ "$slirp" = "git" -o "$slirp" = "internal" ]; then
+if [ "$slirp" = "internal" ]; then
 echo "config-host.h: subdir-slirp" >> $config_host_mak
 fi
 if test "$vde" = "yes" ; then
-- 
2.20.1




[Qemu-devel] [PULL 1/1] configure: remove slirp submodule support that doesn't exist yet

2019-03-13 Thread Samuel Thibault
From: Daniel P. Berrangé 

The slirp code is not yet split off into a separate repository, so
configuring QEMU to use slirp as a submodule is premature. This
causes the non-existant "slirp" to be requested from git when syncing
submodules. This in turn appears to be cause of non-deterministic
failures some developers are seeing with QEMU's submodule sync process.

Signed-off-by: Daniel P. Berrangé 
Message-Id: <20190313173157.30504-1-berra...@redhat.com>
Reviewed-by: Marc-André Lureau 
Signed-off-by: Samuel Thibault 
---
 configure | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/configure b/configure
index cab830a4c9..355eebfc5d 100755
--- a/configure
+++ b/configure
@@ -1109,8 +1109,6 @@ for opt do
   ;;
   --disable-slirp) slirp="no"
   ;;
-  --enable-slirp=git) slirp="git"
-  ;;
   --enable-slirp=system) slirp="system"
   ;;
   --disable-vde) vde="no"
@@ -5780,8 +5778,6 @@ case "$slirp" in
   "" | yes)
 if $pkg_config slirp; then
   slirp=system
-elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
-  slirp=git
 elif test -e "${source_path}/slirp/Makefile" ; then
   slirp=internal
 elif test -z "$slirp" ; then
@@ -5799,10 +5795,7 @@ case "$slirp" in
 esac
 
 case "$slirp" in
-  git | internal)
-if test "$slirp" = git; then
-  git_submodules="${git_submodules} slirp"
-fi
+  internal)
 mkdir -p slirp
 slirp_cflags="-I\$(SRC_PATH)/slirp/src -I\$(BUILD_DIR)/slirp/src"
 slirp_libs="-L\$(BUILD_DIR)/slirp -lslirp"
@@ -6464,7 +6457,7 @@ if test "$slirp" != "no"; then
   echo "SLIRP_CFLAGS=$slirp_cflags" >> $config_host_mak
   echo "SLIRP_LIBS=$slirp_libs" >> $config_host_mak
 fi
-if [ "$slirp" = "git" -o "$slirp" = "internal" ]; then
+if [ "$slirp" = "internal" ]; then
 echo "config-host.h: subdir-slirp" >> $config_host_mak
 fi
 if test "$vde" = "yes" ; then
-- 
2.20.1




[Qemu-devel] [PULL 1/2] slirp: remove empty state.h

2019-03-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Message-Id: <20190313173949.2369-1-marcandre.lur...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/src/state.c | 1 -
 slirp/src/state.h | 0
 2 files changed, 1 deletion(-)
 delete mode 100644 slirp/src/state.h

diff --git a/slirp/src/state.c b/slirp/src/state.c
index f5dd80cdc8..c3e3f0b671 100644
--- a/slirp/src/state.c
+++ b/slirp/src/state.c
@@ -23,7 +23,6 @@
  */
 #include "slirp.h"
 #include "vmstate.h"
-#include "state.h"
 #include "stream.h"
 
 static int slirp_tcp_post_load(void *opaque, int version)
diff --git a/slirp/src/state.h b/slirp/src/state.h
deleted file mode 100644
index e69de29bb2..00
-- 
2.20.1




Re: [Qemu-devel] [PATCH] slirp: remove empty state.h

2019-03-13 Thread Samuel Thibault
Eric Blake, le mer. 13 mars 2019 13:21:23 -0500, a ecrit:
> On 3/13/19 12:39 PM, Marc-André Lureau wrote:
> > Signed-off-by: Marc-André Lureau 
> > ---
> >  slirp/src/state.h | 0
> >  slirp/src/state.c | 1 -
> >  2 files changed, 1 deletion(-)
> >  delete mode 100644 slirp/src/state.h
> 
> Made empty in commit d890344, before moving to its current location in
> c2d63650.
> 
> Reviewed-by: Eric Blake 

Applied and sent pull request, thanks!



[Qemu-devel] [PULL 0/2] Slirp updates

2019-03-13 Thread Samuel Thibault
The following changes since commit cd82b1e170019c4b722ed53116ee9346315d7791:

  slirp: remove empty state.h (2019-03-13 22:12:23 +0100)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to 1f773d9dd3187281b29ceae38541fa2d945b1d0f:

  configure: remove slirp submodule support that doesn't exist yet (2019-03-13 
22:15:30 +0100)


Slirp updates

Daniel P. Berrangé (1):
  configure: remove slirp submodule support that doesn't exist yet

Marc-André Lureau (1):
  slirp: remove empty state.h


Daniel P. Berrangé (1):
  configure: remove slirp submodule support that doesn't exist yet

 configure | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)



[Qemu-devel] [PULL 0/1] slirp update

2019-03-13 Thread Samuel Thibault
The following changes since commit cd82b1e170019c4b722ed53116ee9346315d7791:

  slirp: remove empty state.h (2019-03-13 22:12:23 +0100)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to cd82b1e170019c4b722ed53116ee9346315d7791:

  slirp: remove empty state.h (2019-03-13 22:12:23 +0100)


Slirp updates

Marc-André Lureau (1):
  slirp: remove empty state.h





Re: [Qemu-devel] [PULL 0/1] slirp update

2019-03-13 Thread Samuel Thibault
Samuel Thibault, le mer. 13 mars 2019 22:14:42 +0100, a ecrit:
> The following changes since commit cd82b1e170019c4b722ed53116ee9346315d7791:
> 
>   slirp: remove empty state.h (2019-03-13 22:12:23 +0100)

Oops, sorry, there was another patch to commit, you can ignore this pull
request.

Samuel



[Qemu-devel] [PULL 1/1] slirp: remove empty state.h

2019-03-13 Thread Samuel Thibault
From: Marc-André Lureau 

Signed-off-by: Marc-André Lureau 
Message-Id: <20190313173949.2369-1-marcandre.lur...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Samuel Thibault 
---
 slirp/src/state.c | 1 -
 slirp/src/state.h | 0
 2 files changed, 1 deletion(-)
 delete mode 100644 slirp/src/state.h

diff --git a/slirp/src/state.c b/slirp/src/state.c
index f5dd80cdc8..c3e3f0b671 100644
--- a/slirp/src/state.c
+++ b/slirp/src/state.c
@@ -23,7 +23,6 @@
  */
 #include "slirp.h"
 #include "vmstate.h"
-#include "state.h"
 #include "stream.h"
 
 static int slirp_tcp_post_load(void *opaque, int version)
diff --git a/slirp/src/state.h b/slirp/src/state.h
deleted file mode 100644
index e69de29bb2..00
-- 
2.20.1




Re: [Qemu-devel] [PULL 3/5] contrib: gitdm: add more individual contributors

2019-03-12 Thread Samuel Thibault
Alex Bennée, le mar. 12 mars 2019 19:34:56 +, a ecrit:
> I know Richard's is right because I asked him in the pub. I'm guessing
> Fredrik's based on the fact I vaguely remember an Atari demo. The
> others I attributed to academic institutions last time I posted so
> have moved them to individuals as requested.
> 
> Cc: Fredrik Noring 
> Cc: Samuel Thibault 
> Cc: Aurelien Jarno 
> Cc: BALATON Zoltan 
> Signed-off-by: Alex Bennée 
> Acked-by: Richard Henderson 

Acked-by: Samuel Thibault 

Thanks!
> 
> diff --git a/contrib/gitdm/group-map-individuals 
> b/contrib/gitdm/group-map-individuals
> index afdbe7d460..05e355d30e 100644
> --- a/contrib/gitdm/group-map-individuals
> +++ b/contrib/gitdm/group-map-individuals
> @@ -8,3 +8,8 @@
>  f4...@amsat.org
>  m...@tls.msk.ru
>  mark.cave-ayl...@ilande.co.uk
> +r...@twiddle.net
> +nor...@nocrew.org
> +samuel.thiba...@ens-lyon.org
> +aurel...@aurel32.net
> +bala...@eik.bme.hu
> -- 
> 2.20.1
> 

-- 
Samuel
"...[Linux's] capacity to talk via any medium except smoke signals."
(By Dr. Greg Wettstein, Roger Maris Cancer Center)



Re: [Qemu-devel] [libvirt] [PULL 0/5] Ui 20190311 v2 patches

2019-03-11 Thread Samuel Thibault
Samuel Thibault, le lun. 11 mars 2019 15:08:16 +0100, a ecrit:
> Daniel P. Berrangé, le lun. 11 mars 2019 13:51:16 +, a ecrit:
> > On Mon, Mar 11, 2019 at 01:45:13PM +, Peter Maydell wrote:
> > > On Mon, 11 Mar 2019 at 08:40, Gerd Hoffmann  wrote:
> > > >
> > > > The following changes since commit 
> > > > e2a18635a400b0e68679614132e9ef6316105590:
> > > >
> > > >   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-03-08' 
> > > > into staging (2019-03-09 20:55:44 +)
> > > >
> > > > are available in the Git repository at:
> > > >
> > > >   git://git.kraxel.org/qemu tags/ui-20190311-v2-pull-request
> > > >
> > > > for you to fetch changes up to 0143840771548e8ffece831398d745880ddfa080:
> > > >
> > > >   monitor: deprecate acl_show, acl_reset, acl_policy, acl_add, 
> > > > acl_remove (2019-03-11 08:39:02 +0100)
> > > >
> > > > 
> > > > curses: wide char input support.
> > > > vnc: acl update, stall fix.
> > > >
> > > > 
> > > 
> > > Applied, thanks.
> > > 
> > > Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
> > > for any user-visible changes.
> > 
> > Gerd, I'll take care of updating the changelog for the auth / acl
> > related parts of the pull request
> 
> I wanted to do the same for the curses part but I don't seem to have a
> wiki account, could somebody create one for me?

Done so, and thus Gerd: done so :)

Samuel



Re: [Qemu-devel] [libvirt] [PULL 0/5] Ui 20190311 v2 patches

2019-03-11 Thread Samuel Thibault
Daniel P. Berrangé, le lun. 11 mars 2019 13:51:16 +, a ecrit:
> On Mon, Mar 11, 2019 at 01:45:13PM +, Peter Maydell wrote:
> > On Mon, 11 Mar 2019 at 08:40, Gerd Hoffmann  wrote:
> > >
> > > The following changes since commit 
> > > e2a18635a400b0e68679614132e9ef6316105590:
> > >
> > >   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-03-08' 
> > > into staging (2019-03-09 20:55:44 +)
> > >
> > > are available in the Git repository at:
> > >
> > >   git://git.kraxel.org/qemu tags/ui-20190311-v2-pull-request
> > >
> > > for you to fetch changes up to 0143840771548e8ffece831398d745880ddfa080:
> > >
> > >   monitor: deprecate acl_show, acl_reset, acl_policy, acl_add, acl_remove 
> > > (2019-03-11 08:39:02 +0100)
> > >
> > > 
> > > curses: wide char input support.
> > > vnc: acl update, stall fix.
> > >
> > > 
> > 
> > Applied, thanks.
> > 
> > Please update the changelog at https://wiki.qemu.org/ChangeLog/4.0
> > for any user-visible changes.
> 
> Gerd, I'll take care of updating the changelog for the auth / acl
> related parts of the pull request

I wanted to do the same for the curses part but I don't seem to have a
wiki account, could somebody create one for me?

Samuel



[Qemu-devel] [PATCHv3 0/2] curses: Add support for wide output

2019-03-11 Thread Samuel Thibault
Hello,

This adds support for wide output in the curses frontend

Difference with previous version:
- detect iconv from /usr/local before from /usr, in case a libiconv
  version is there in addition to the system-provided in /usr

Samuel Thibault (2):
  iconv: detect and make curses depend on it
  curses: add option to specify VGA font encoding

 configure|  60 -
 qapi/ui.json |  14 +++
 qemu-options.hx  |   5 +-
 ui/Makefile.objs |   4 +-
 ui/curses.c  | 315 ---
 vl.c |   2 +-
 6 files changed, 348 insertions(+), 52 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCHv3 2/2] curses: add option to specify VGA font encoding

2019-03-11 Thread Samuel Thibault
This uses iconv to convert glyphs from the specified VGA font encoding to
unicode, and makes use of cchar_t instead of chtype when using ncursesw,
which allows to store all wide char as well as the WACS values. The default
charset is made CP437 since that is the charset of the hardware default VGA
font. This also makes the curses backend set the LC_CTYPE locale to "" to
allow curses to emit wide characters.

Signed-off-by: Samuel Thibault 
Cc: Eddie Kohler 
Acked-by: Markus Armbruster 
---
 configure   |   5 +-
 qapi/ui.json|  14 +++
 qemu-options.hx |   5 +-
 ui/curses.c | 315 
 4 files changed, 290 insertions(+), 49 deletions(-)

diff --git a/configure b/configure
index c97c78a6a4..efe39f2e08 100755
--- a/configure
+++ b/configure
@@ -3462,14 +3462,17 @@ if test "$curses" != "no" ; then
 #include 
 #include 
 #include 
+#include 
 int main(void) {
+  const char *codeset;
   wchar_t wch = L'w';
   setlocale(LC_ALL, "");
   resize_term(0, 0);
   addwstr(L"wide chars\n");
   addnwstr(&wch, 1);
   add_wch(WACS_DEGREE);
-  return 0;
+  codeset = nl_langinfo(CODESET);
+  return codeset != 0;
 }
 EOF
   IFS=:
diff --git a/qapi/ui.json b/qapi/ui.json
index c5d1d7f099..59e412139a 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1080,6 +1080,19 @@
  { 'enum': 'DisplayGLMode',
'data': [ 'off', 'on', 'core', 'es' ] }
 
+##
+# @DisplayCurses:
+#
+# Curses display options.
+#
+# @charset:   Font charset used by guest (default: CP437).
+#
+# Since: 4.0
+#
+##
+{ 'struct'  : 'DisplayCurses',
+  'data': { '*charset'   : 'str' } }
+
 ##
 # @DisplayType:
 #
@@ -1142,6 +1155,7 @@
 '*gl': 'DisplayGLMode' },
   'discriminator' : 'type',
   'data': { 'gtk': 'DisplayGTK',
+'curses' : 'DisplayCurses',
 'egl-headless'   : 'DisplayEGLHeadless'} }
 
 ##
diff --git a/qemu-options.hx b/qemu-options.hx
index 1cf9aac1fe..4bc4e736bb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1216,7 +1216,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
 "[,window_close=on|off][,gl=on|core|es|off]\n"
 "-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
 "-display vnc=[,]\n"
-"-display curses\n"
+"-display curses[,charset=]\n"
 "-display none\n"
 "-display egl-headless[,rendernode=]"
 "select display type\n"
@@ -1248,6 +1248,9 @@ support a text mode, QEMU can display this output using a
 curses/ncurses interface. Nothing is displayed when the graphics
 device is in graphical mode or if the graphics device does not support
 a text mode. Generally only the VGA device models support text mode.
+The font charset used by the guest can be specified with the
+@code{charset} option, for example @code{charset=CP850} for IBM CP850
+encoding. The default is @code{CP437}.
 @item none
 Do not display video output. The guest will still see an emulated
 graphics card, but its output will not be displayed to the QEMU
diff --git a/ui/curses.c b/ui/curses.c
index 6861539b20..99eb026a9a 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -27,6 +27,10 @@
 #include 
 #include 
 #endif
+#include 
+#include 
+#include 
+#include 
 
 #include "qapi/error.h"
 #include "qemu-common.h"
@@ -54,25 +58,30 @@ static WINDOW *screenpad = NULL;
 static int width, height, gwidth, gheight, invalidate;
 static int px, py, sminx, sminy, smaxx, smaxy;
 
-static chtype vga_to_curses[256];
+static const char *font_charset = "CP437";
+static cchar_t vga_to_curses[256];
 
 static void curses_update(DisplayChangeListener *dcl,
   int x, int y, int w, int h)
 {
 console_ch_t *line;
-chtype curses_line[width];
+cchar_t curses_line[width];
 
 line = screen + y * width;
 for (h += y; y < h; y ++, line += width) {
 for (x = 0; x < width; x++) {
 chtype ch = line[x] & 0xff;
 chtype at = line[x] & ~0xff;
-if (vga_to_curses[ch]) {
-ch = vga_to_curses[ch];
+if (vga_to_curses[ch].chars[0]) {
+curses_line[x] = vga_to_curses[ch];
+} else {
+curses_line[x].chars[0] = ch;
+curses_line[x].chars[1] = 0;
+curses_line[x].attr = 0;
 }
-curses_line[x] = ch | at;
+curses_line[x].attr |= at;
 }
-mvwaddchnstr(screenpad, y, 0, curses_line, width);
+mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
 }
 
 pnoutre

[Qemu-devel] [PATCHv3 1/2] iconv: detect and make curses depend on it

2019-03-11 Thread Samuel Thibault
curses will use it for proper wide output support.

Signed-off-by: Samuel Thibault 
---
 configure| 55 
 ui/Makefile.objs |  4 ++--
 vl.c |  2 +-
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/configure b/configure
index 540bee19ba..c97c78a6a4 100755
--- a/configure
+++ b/configure
@@ -1217,6 +1217,10 @@ for opt do
   ;;
   --enable-curses) curses="yes"
   ;;
+  --disable-iconv) iconv="no"
+  ;;
+  --enable-iconv) iconv="yes"
+  ;;
   --disable-curl) curl="no"
   ;;
   --enable-curl) curl="yes"
@@ -1718,6 +1722,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   gtk gtk UI
   vte vte support for the gtk UI
   curses  curses UI
+  iconv   font glyph conversion support
   vnc VNC UI support
   vnc-saslSASL encryption for VNC server
   vnc-jpegJPEG lossy compression for VNC server
@@ -3398,8 +3403,52 @@ EOF
   fi
 fi
 
+##
+# iconv probe
+if test "$iconv" != "no" ; then
+  cat > $TMPC << EOF
+#include 
+int main(void) {
+  iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
+  return conv != (iconv_t) -1;
+}
+EOF
+  iconv_prefix_list="/usr/local:/usr"
+  iconv_lib_list=":-liconv"
+  IFS=:
+  for iconv_prefix in $iconv_prefix_list; do
+IFS=:
+iconv_cflags="-I$iconv_prefix/include"
+iconv_ldflags="-L$iconv_prefix/lib"
+for iconv_link in $iconv_lib_list; do
+  unset IFS
+  iconv_lib="$iconv_ldflags $iconv_link"
+  echo "looking at iconv in '$iconv_cflags' '$iconv_lib'" >> config.log
+  if compile_prog "$iconv_cflags" "$iconv_lib" ; then
+iconv_found=yes
+break
+  fi
+done
+if test "$iconv_found" = yes ; then
+  break
+fi
+  done
+  if test "$iconv_found" = "yes" ; then
+iconv=yes
+  else
+if test "$iconv" = "yes" ; then
+  feature_not_found "iconv" "Install iconv devel"
+fi
+iconv=no
+  fi
+fi
+
 ##
 # curses probe
+if test "$iconv" = "no" ; then
+  # curses will need iconv
+  curses=no
+fi
 if test "$curses" != "no" ; then
   if test "$mingw32" = "yes" ; then
 curses_inc_list="$($pkg_config --cflags ncurses 2>/dev/null):"
@@ -6111,6 +6160,7 @@ echo "libgcrypt $gcrypt"
 echo "nettle$nettle $(echo_version $nettle $nettle_version)"
 echo "libtasn1  $tasn1"
 echo "PAM   $auth_pam"
+echo "iconv support $iconv"
 echo "curses support$curses"
 echo "virgl support $virglrenderer $(echo_version $virglrenderer 
$virgl_version)"
 echo "curl support  $curl"
@@ -6435,6 +6485,11 @@ fi
 if test "$cocoa" = "yes" ; then
   echo "CONFIG_COCOA=y" >> $config_host_mak
 fi
+if test "$iconv" = "yes" ; then
+  echo "CONFIG_ICONV=y" >> $config_host_mak
+  echo "ICONV_CFLAGS=$iconv_cflags" >> $config_host_mak
+  echo "ICONV_LIBS=$iconv_lib" >> $config_host_mak
+fi
 if test "$curses" = "yes" ; then
   echo "CONFIG_CURSES=m" >> $config_host_mak
   echo "CURSES_CFLAGS=$curses_inc" >> $config_host_mak
diff --git a/ui/Makefile.objs b/ui/Makefile.objs
index fe1a7aed97..cc2bf5b180 100644
--- a/ui/Makefile.objs
+++ b/ui/Makefile.objs
@@ -46,8 +46,8 @@ endif
 
 common-obj-$(CONFIG_CURSES) += curses.mo
 curses.mo-objs := curses.o
-curses.mo-cflags := $(CURSES_CFLAGS)
-curses.mo-libs := $(CURSES_LIBS)
+curses.mo-cflags := $(CURSES_CFLAGS) $(ICONV_CFLAGS)
+curses.mo-libs := $(CURSES_LIBS) $(ICONV_LIBS)
 
 common-obj-$(call land,$(CONFIG_SPICE),$(CONFIG_GIO)) += spice-app.mo
 spice-app.mo-objs := spice-app.o
diff --git a/vl.c b/vl.c
index 502857a176..c8594fc6d5 100644
--- a/vl.c
+++ b/vl.c
@@ -3171,7 +3171,7 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_CURSES
 dpy.type = DISPLAY_TYPE_CURSES;
 #else
-error_report("curses support is disabled");
+error_report("curses or iconv support is disabled");
 exit(1);
 #endif
 break;
-- 
2.20.1




Re: [Qemu-devel] [PULL 0/7] Ui 20190307 patches

2019-03-11 Thread Samuel Thibault
Gerd Hoffmann, le lun. 11 mars 2019 09:33:40 +0100, a ecrit:
> > > curses: better wide char support.
> > > vnc: acl update, stall fix.
> 
> > Hi; this fails to build on FreeBSD; linking the qemu-system-*
> > binaries fails with:
> > 
> > /usr/bin/ld: undefined reference to symbol `libiconv_open' (try adding 
> > -liconv)
> > //usr/local/lib/libiconv.so.2: could not read symbols: Bad value
> > c++: error: linker command failed with exit code 1 (use -v to see 
> > invocation)
> 
> > (This is with the FreeBSD test setup from tests/vm/freebsd).
> 
> Hmm, not obvious why configure finds iconv but the build doesn't.
> Samuel, can you check please?

Mmm, that's because on the freebsd vm there is a libiconv installed
in /usr/local, and that path gets pulled in include flags after the
system's iconv is detected not to need -liconv.

In PATCHv3 I have added detection in /usr/local before /usr

Samuel



Re: [Qemu-devel] [PATCHv2 0/2] curses: Add support for wide output

2019-03-07 Thread Samuel Thibault
Gerd Hoffmann, le jeu. 07 mars 2019 14:21:12 +0100, a ecrit:
> On Mon, Mar 04, 2019 at 10:02:15PM +0100, Samuel Thibault wrote:
> > This adds support for wide output in the curses frontend
> > 
> > Difference with previous version:
> > - Add more rationale in commit message
> > - Move charset option to curses-only section.
> 
> Added to UI patch queue (the other curses patches too).

Thanks!

Samuel



Re: [Qemu-devel] [PULL 00/12] slirp updates

2019-03-07 Thread Samuel Thibault
Peter Maydell, le jeu. 07 mars 2019 11:27:38 +, a ecrit:
> Hi; this fails to build on FreeBSD, I'm afraid:
> 
> /var/tmp/qemu-test.Sn5gQz/slirp/src/libslirp.h:29:19: warning: type
> specifier missing, defaults to 'int' [-Wimplicit-int]
> typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
>   ^

> I think this is a missing #include of  which is where
> ssize_t comes from -- on the other OSes it likely gets dragged in
> by default.

That's probably it indeed. I have resubmitted the series with it.

Samuel



[Qemu-devel] [PULLv2 07/12] slirp: use libslirp migration code

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

slirp migration code uses QEMU vmstate so far, when building WITH_QEMU.

Introduce slirp_state_{load,save,version}() functions to move the
state saving handling to libslirp side.

So far, the bitstream compatibility should remain equal with current
QEMU, as this is effectively using the same code, with the same format
etc. When libslirp is made standalone, we will need some mechanism to
ensure bitstream compatibility regardless of the libslirp version
installed. See the FIXME note in the code.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-3-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 include/migration/qemu-file-types.h |  2 ++
 migration/qemu-file.h   |  1 -
 net/slirp.c | 55 +
 slirp/libslirp.h|  8 +
 slirp/slirp.c   |  9 -
 slirp/state.c   | 52 ---
 slirp/state.h   |  9 -
 7 files changed, 88 insertions(+), 48 deletions(-)

diff --git a/include/migration/qemu-file-types.h 
b/include/migration/qemu-file-types.h
index bd6d7dd7f9..bbe04d4484 100644
--- a/include/migration/qemu-file-types.h
+++ b/include/migration/qemu-file-types.h
@@ -25,6 +25,8 @@
 #ifndef QEMU_FILE_H
 #define QEMU_FILE_H
 
+int qemu_file_get_error(QEMUFile *f);
+
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size);
 void qemu_put_byte(QEMUFile *f, int v);
 
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index 2ccfcfb2a8..13baf896bd 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -149,7 +149,6 @@ void qemu_update_position(QEMUFile *f, size_t size);
 void qemu_file_reset_rate_limit(QEMUFile *f);
 void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
 int64_t qemu_file_get_rate_limit(QEMUFile *f);
-int qemu_file_get_error(QEMUFile *f);
 void qemu_file_set_error(QEMUFile *f, int ret);
 int qemu_file_shutdown(QEMUFile *f);
 QEMUFile *qemu_file_get_return_path(QEMUFile *f);
diff --git a/net/slirp.c b/net/slirp.c
index a8fd9e6364..059b2d9b08 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -44,6 +44,8 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "util.h"
+#include "migration/register.h"
+#include "migration/qemu-file-types.h"
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
 {
@@ -146,6 +148,7 @@ static void net_slirp_cleanup(NetClientState *nc)
 
 g_slist_free_full(s->fwd, slirp_free_fwd);
 main_loop_poll_remove_notifier(&s->poll_notifier);
+unregister_savevm(NULL, "slirp", s->slirp);
 slirp_cleanup(s->slirp);
 if (s->exit_notifier.notify) {
 qemu_remove_exit_notifier(&s->exit_notifier);
@@ -303,6 +306,46 @@ static void net_slirp_poll_notify(Notifier *notifier, void 
*data)
 }
 }
 
+static ssize_t
+net_slirp_stream_read(void *buf, size_t size, void *opaque)
+{
+QEMUFile *f = opaque;
+
+return qemu_get_buffer(f, buf, size);
+}
+
+static ssize_t
+net_slirp_stream_write(const void *buf, size_t size, void *opaque)
+{
+QEMUFile *f = opaque;
+
+qemu_put_buffer(f, buf, size);
+if (qemu_file_get_error(f)) {
+return -1;
+}
+
+return size;
+}
+
+static int net_slirp_state_load(QEMUFile *f, void *opaque, int version_id)
+{
+Slirp *slirp = opaque;
+
+return slirp_state_load(slirp, version_id, net_slirp_stream_read, f);
+}
+
+static void net_slirp_state_save(QEMUFile *f, void *opaque)
+{
+Slirp *slirp = opaque;
+
+slirp_state_save(slirp, net_slirp_stream_write, f);
+}
+
+static SaveVMHandlers savevm_slirp_state = {
+.save_state = net_slirp_state_save,
+.load_state = net_slirp_state_load,
+};
+
 static int net_slirp_init(NetClientState *peer, const char *model,
   const char *name, int restricted,
   bool ipv4, const char *vnetwork, const char *vhost,
@@ -523,6 +566,18 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   &slirp_cb, s);
 QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
 
+/*
+ * Make sure the current bitstream version of slirp is 4, to avoid
+ * QEMU migration incompatibilities, if upstream slirp bumped the
+ * version.
+ *
+ * FIXME: use bitfields of features? teach libslirp to save with
+ * specific version?
+ */
+g_assert(slirp_state_version() == 4);
+register_savevm_live(NULL, "slirp", 0, slirp_state_version(),
+ &savevm_slirp_state, s->slirp);
+
 s->poll_notifier.notify = net_slirp_poll_notify;
 main_loop_poll_add_notifier(&s->poll_notifier);
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 57bd6f597c..2d13950065 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -102,6 +102,14 @@ void slirp_socke

[Qemu-devel] [PULLv2 10/12] slirp: add a standalone Makefile

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

Add a simple Makefile to build libslirp.a, a static library version of
libslirp, to be used by QEMU during a transition period, until a
shared library is available.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-6-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile | 47 +++
 1 file changed, 47 insertions(+)
 create mode 100644 slirp/Makefile

diff --git a/slirp/Makefile b/slirp/Makefile
new file mode 100644
index 00..6d48f626ba
--- /dev/null
+++ b/slirp/Makefile
@@ -0,0 +1,47 @@
+ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST
+BUILD_DIR ?= .
+
+LIBSLIRP = $(BUILD_DIR)/libslirp.a
+
+all: $(LIBSLIRP)
+
+SRCS := $(wildcard src/*.c)
+OBJS := $(SRCS:%.c=$(BUILD_DIR)/%.o)
+DEPS := $(OBJS:%.o=%.d)
+
+INC_DIRS := $(BUILD_DIR)/src
+INC_FLAGS := $(addprefix -I,$(INC_DIRS))
+
+override CFLAGS += \
+   -DG_LOG_DOMAIN='"Slirp"'\
+   $(shell $(PKG_CONFIG) --cflags glib-2.0)\
+   $(INC_FLAGS)\
+   -MMD -MP
+override LDFLAGS += $(shell $(PKG_CONFIG) --libs glib-2.0)
+
+$(LIBSLIRP): $(OBJS)
+
+.PHONY: clean
+
+clean:
+   rm -r $(OBJS) $(DEPS) $(LIBSLIRP)
+
+$(BUILD_DIR)/src/%.o: $(ROOT_DIR)/src/%.c
+   @$(MKDIR_P) $(dir $@)
+   $(call quiet-command,$(CC) $(CFLAGS) -c -o $@ $<,"CC","$@")
+
+%.a:
+   $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"AR","$@")
+
+PKG_CONFIG ?= pkg-config
+MKDIR_P ?= mkdir -p
+quiet-command-run = $(if $(V),,$(if $2,printf "  %-7s %s\n" $2 $3 && ))$1
+quiet-@ = $(if $(V),,@)
+quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
+
+print-%:
+   @echo '$*=$($*)'
+
+.SUFFIXES:
+
+-include $(DEPS)
-- 
2.20.1




[Qemu-devel] [PULLv2 05/12] slirp: Mark pieces missing IPv6 support

2019-03-07 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
---
 net/slirp.c   | 1 +
 slirp/misc.c  | 3 +++
 slirp/slirp.c | 5 +
 slirp/socket.c| 1 +
 slirp/tcp_input.c | 2 ++
 slirp/tcp_subr.c  | 2 ++
 slirp/udp.c   | 1 +
 7 files changed, 15 insertions(+)

diff --git a/net/slirp.c b/net/slirp.c
index 4ec989b592..a8fd9e6364 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -885,6 +885,7 @@ static ssize_t guestfwd_write(const void *buf, size_t len, 
void *chr)
 
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 {
+/* TODO: IPv6 */
 struct in_addr server = { .s_addr = 0 };
 struct GuestFwd *fwd;
 const char *p;
diff --git a/slirp/misc.c b/slirp/misc.c
index d9fc586a24..937a418d4e 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -28,6 +28,7 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
+/* TODO: IPv6 */
 struct gfwd_list *
 add_guestfwd(struct gfwd_list **ex_ptr,
  SlirpWriteCb write_cb, void *opaque,
@@ -254,6 +255,8 @@ char *slirp_connection_info(Slirp *slirp)
 "  Protocol[State]FD  Source Address  Port   "
 "Dest. Address  Port RecvQ SendQ\n");
 
+/* TODO: IPv6 */
+
 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
 if (so->so_state & SS_HOSTFWD) {
 state = "HOST_FORWARD";
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 55591430dc..cbdf9f778d 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -729,6 +729,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
 ah->ar_tip == slirp->vhost_addr.s_addr)
 goto arp_ok;
+/* TODO: IPv6 */
 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = 
ex_ptr->ex_next) {
 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
 goto arp_ok;
@@ -945,6 +946,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 }
 
 /* Drop host forwarding rule, return 0 if found. */
+/* TODO: IPv6 */
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  int host_port)
 {
@@ -970,6 +972,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return -1;
 }
 
+/* TODO: IPv6 */
 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
   int host_port, struct in_addr guest_addr, int guest_port)
 {
@@ -988,6 +991,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
+/* TODO: IPv6 */
 static bool
 check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
 {
@@ -1065,6 +1069,7 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr 
guest_addr, int guest_port)
 {
 struct socket *so;
 
+/* TODO: IPv6 */
 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
 if (so->so_faddr.s_addr == guest_addr.s_addr &&
 htons(so->so_fport) == guest_port) {
diff --git a/slirp/socket.c b/slirp/socket.c
index 4dc5e2907d..f2428a3ae8 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -687,6 +687,7 @@ struct socket *
 tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
unsigned lport, int flags)
 {
+/* TODO: IPv6 */
struct sockaddr_in addr;
struct socket *so;
int s, opt = 1;
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 6749b32f5d..b10477fc57 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -388,6 +388,7 @@ findso:
 * as if it was LISTENING, and continue...
 */
 if (so == NULL) {
+  /* TODO: IPv6 */
   if (slirp->restricted) {
 /* Any hostfwds will have an existing socket, so we only get here
  * for non-hostfwd connections. These should be dropped, unless it
@@ -609,6 +610,7 @@ findso:
   * If this is destined for the control address, then flag to
   * tcp_ctl once connected, otherwise connect
   */
+  /* TODO: IPv6 */
  if (af == AF_INET &&
 (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 slirp->vnetwork_addr.s_addr) {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 1d7e72dca7..1db59caa89 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -626,6 +626,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
switch(so->so_emu) {
int x, i;
 
+/* TODO: IPv6 */
 case EMU_IDENT:
/*
 * Identification protocol as per rfc-1413
@@ -964,6 +965,7 @@ int tcp_ctl(struct socket *so)
 DEBUG_CALL("tcp_ctl");
 DEBUG_ARG("so = %p", so);
 
+/* TODO: IPv6 */
 if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
 /* Check if it's pty_exec */
 fo

[Qemu-devel] [PULLv2 06/12] slirp: adapt a subset of QEMU vmstate code

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

Add vmstate serialization code adapted from QEMU.

Keep only the bits that are required for libslirp.

Introduce a IStream/OStream interface to replace QEMU QFile
abstraction.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-2-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   2 +
 slirp/libslirp.h|   2 +
 slirp/stream.c  | 119 +
 slirp/stream.h  |  34 
 slirp/vmstate.c | 413 
 slirp/vmstate.h | 396 ++
 6 files changed, 966 insertions(+)
 create mode 100644 slirp/stream.c
 create mode 100644 slirp/stream.h
 create mode 100644 slirp/vmstate.c
 create mode 100644 slirp/vmstate.h

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 88340a583b..69e140f965 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -21,6 +21,7 @@ slirp.mo-objs = \
slirp.o \
socket.o \
state.o \
+   stream.o \
tcp_input.o \
tcp_output.o \
tcp_subr.o \
@@ -29,6 +30,7 @@ slirp.mo-objs = \
udp.o \
udp6.o \
util.o \
+   vmstate.o \
$(NULL)
 
 slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index fccab42518..57bd6f597c 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -3,6 +3,7 @@
 
 #include 
 #include 
+#include 
 
 #ifdef _WIN32
 #include 
@@ -26,6 +27,7 @@ enum {
 SLIRP_POLL_HUP = 1 << 4,
 };
 
+typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
diff --git a/slirp/stream.c b/slirp/stream.c
new file mode 100644
index 00..d114dde334
--- /dev/null
+++ b/slirp/stream.c
@@ -0,0 +1,119 @@
+/*
+ * libslirp io streams
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "stream.h"
+#include 
+
+bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size)
+{
+return f->read_cb(buf, size, f->opaque) == size;
+}
+
+bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size)
+{
+return f->write_cb(buf, size, f->opaque) == size;
+}
+
+uint8_t slirp_istream_read_u8(SlirpIStream *f)
+{
+uint8_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return b;
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b)
+{
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint16_t slirp_istream_read_u16(SlirpIStream *f)
+{
+uint16_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GUINT16_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b)
+{
+b =  GUINT16_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint32_t slirp_istream_read_u32(SlirpIStream *f)
+{
+uint32_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GUINT32_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b)
+{
+b = GUINT32_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int16_t slirp_istream_read_i16(SlirpIStream *f)
+{
+int16_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GINT16_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b)
+{
+b = GINT16_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int32_t slirp_istream_read_i32(SlirpIStream *f)
+{
+int32_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GINT32_FROM_BE(b);
+}
+
+return 0;
+}

[Qemu-devel] [PULLv2 09/12] slirp: move sources to src/ subdirectory

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

Prepare for making slirp/ a standalone project.

Remove some useless includes while at it.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-5-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  2 +-
 slirp/Makefile.objs  | 60 ++--
 slirp/{ => src}/arp_table.c  |  0
 slirp/{ => src}/bootp.c  |  0
 slirp/{ => src}/bootp.h  |  0
 slirp/{ => src}/cksum.c  |  0
 slirp/{ => src}/debug.h  |  0
 slirp/{ => src}/dhcpv6.c |  0
 slirp/{ => src}/dhcpv6.h |  0
 slirp/{ => src}/dnssearch.c  |  0
 slirp/{ => src}/if.c |  0
 slirp/{ => src}/if.h |  0
 slirp/{ => src}/ip.h |  0
 slirp/{ => src}/ip6.h|  0
 slirp/{ => src}/ip6_icmp.c   |  0
 slirp/{ => src}/ip6_icmp.h   |  0
 slirp/{ => src}/ip6_input.c  |  0
 slirp/{ => src}/ip6_output.c |  0
 slirp/{ => src}/ip_icmp.c|  0
 slirp/{ => src}/ip_icmp.h|  0
 slirp/{ => src}/ip_input.c   |  0
 slirp/{ => src}/ip_output.c  |  0
 slirp/{ => src}/libslirp.h   |  0
 slirp/{ => src}/main.h   |  0
 slirp/{ => src}/mbuf.c   |  0
 slirp/{ => src}/mbuf.h   |  0
 slirp/{ => src}/misc.c   |  0
 slirp/{ => src}/misc.h   |  0
 slirp/{ => src}/ncsi-pkt.h   |  0
 slirp/{ => src}/ncsi.c   |  0
 slirp/{ => src}/ndp_table.c  |  0
 slirp/{ => src}/qtailq.h |  0
 slirp/{ => src}/sbuf.c   |  0
 slirp/{ => src}/sbuf.h   |  0
 slirp/{ => src}/slirp.c  |  0
 slirp/{ => src}/slirp.h  |  0
 slirp/{ => src}/socket.c |  0
 slirp/{ => src}/socket.h |  0
 slirp/{ => src}/state.c  |  0
 slirp/{ => src}/state.h  |  0
 slirp/{ => src}/stream.c |  0
 slirp/{ => src}/stream.h |  0
 slirp/{ => src}/tcp.h|  0
 slirp/{ => src}/tcp_input.c  |  0
 slirp/{ => src}/tcp_output.c |  0
 slirp/{ => src}/tcp_subr.c   |  0
 slirp/{ => src}/tcp_timer.c  |  0
 slirp/{ => src}/tcp_timer.h  |  0
 slirp/{ => src}/tcp_var.h|  0
 slirp/{ => src}/tcpip.h  |  0
 slirp/{ => src}/tftp.c   |  0
 slirp/{ => src}/tftp.h   |  0
 slirp/{ => src}/udp.c|  0
 slirp/{ => src}/udp.h|  0
 slirp/{ => src}/udp6.c   |  0
 slirp/{ => src}/util.c   |  0
 slirp/{ => src}/util.h   |  0
 slirp/{ => src}/vmstate.c|  0
 slirp/{ => src}/vmstate.h|  0
 util/main-loop.c |  2 --
 vl.c |  3 --
 61 files changed, 31 insertions(+), 36 deletions(-)
 rename slirp/{ => src}/arp_table.c (100%)
 rename slirp/{ => src}/bootp.c (100%)
 rename slirp/{ => src}/bootp.h (100%)
 rename slirp/{ => src}/cksum.c (100%)
 rename slirp/{ => src}/debug.h (100%)
 rename slirp/{ => src}/dhcpv6.c (100%)
 rename slirp/{ => src}/dhcpv6.h (100%)
 rename slirp/{ => src}/dnssearch.c (100%)
 rename slirp/{ => src}/if.c (100%)
 rename slirp/{ => src}/if.h (100%)
 rename slirp/{ => src}/ip.h (100%)
 rename slirp/{ => src}/ip6.h (100%)
 rename slirp/{ => src}/ip6_icmp.c (100%)
 rename slirp/{ => src}/ip6_icmp.h (100%)
 rename slirp/{ => src}/ip6_input.c (100%)
 rename slirp/{ => src}/ip6_output.c (100%)
 rename slirp/{ => src}/ip_icmp.c (100%)
 rename slirp/{ => src}/ip_icmp.h (100%)
 rename slirp/{ => src}/ip_input.c (100%)
 rename slirp/{ => src}/ip_output.c (100%)
 rename slirp/{ => src}/libslirp.h (100%)
 rename slirp/{ => src}/main.h (100%)
 rename slirp/{ => src}/mbuf.c (100%)
 rename slirp/{ => src}/mbuf.h (100%)
 rename slirp/{ => src}/misc.c (100%)
 rename slirp/{ => src}/misc.h (100%)
 rename slirp/{ => src}/ncsi-pkt.h (100%)
 rename slirp/{ => src}/ncsi.c (100%)
 rename slirp/{ => src}/ndp_table.c (100%)
 rename slirp/{ => src}/qtailq.h (100%)
 rename slirp/{ => src}/sbuf.c (100%)
 rename slirp/{ => src}/sbuf.h (100%)
 rename slirp/{ => src}/slirp.c (100%)
 rename slirp/{ => src}/slirp.h (100%)
 rename slirp/{ => src}/socket.c (100%)
 rename slirp/{ => src}/socket.h (100%)
 rename slirp/{ => src}/state.c (100%)
 rename slirp/{ => src}/state.h (100%)
 rename slirp/{ => src}/stream.c (100%)
 rename slirp/{ => src}/stream.h (100%)
 rename slirp/{ => src}/tcp.h (100%)
 rename slirp/{ => src}/tcp_input.c (100%)
 rename slirp/{ => src}/tcp_output.c (100%)
 rename slirp/{ => src}/tcp_subr.c (100%)
 rename slirp/{ => src}/tcp_timer.c (100%)
 rename slirp/{ => src}/tcp_timer.h (100%)
 rename slirp/{ => src}/tcp_var.h (100%)
 rename slirp/{ => src}/tcpip.h (100%)
 rename slirp/{ => src}/tftp.c (100%)
 rename slirp/{ => src}/tftp.h (100%)
 rename slirp/{ => src}/udp.c (100%)
 rename slirp/{ => src}/udp.h (100%)
 rename slirp/{ => src}/udp6.c (100%)
 rename slirp/{ => src}/util.c (100%)
 rename slirp/{ 

[Qemu-devel] [PULLv2 03/12] slirp: check sscanf result when emulating ident

2019-03-07 Thread Samuel Thibault
From: William Bowling 

When emulating ident in tcp_emu, if the strchr checks passed but the
sscanf check failed, two uninitialized variables would be copied and
sent in the reply, so move this code inside the if(sscanf()) clause.

Signed-off-by: William Bowling 
Cc: qemu-sta...@nongnu.org
Cc: secal...@redhat.com
Message-Id: <1551476756-25749-1-git-send-email-w...@wbowling.info>
Signed-off-by: Samuel Thibault 
Reviewed-by: Philippe Mathieu-Daudé 
---
 slirp/tcp_subr.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 262a42d6c8..ef9d99c154 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -664,12 +664,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
break;
}
}
+   so_rcv->sb_cc = 
snprintf(so_rcv->sb_data,
+
so_rcv->sb_datalen,
+"%d,%d\r\n", 
n1, n2);
+   so_rcv->sb_rptr = so_rcv->sb_data;
+   so_rcv->sb_wptr = so_rcv->sb_data + 
so_rcv->sb_cc;
}
-so_rcv->sb_cc = snprintf(so_rcv->sb_data,
- so_rcv->sb_datalen,
- "%d,%d\r\n", n1, n2);
-   so_rcv->sb_rptr = so_rcv->sb_data;
-   so_rcv->sb_wptr = so_rcv->sb_data + 
so_rcv->sb_cc;
}
m_free(m);
return 0;
-- 
2.20.1




[Qemu-devel] [PULLv2 11/12] build-sys: link with slirp as an external project

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

Use the "system" libslirp if its present or requested.

Else build with a static libslirp.a if slirp/ is checked
out ("internal") or a submodule ("git").

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-7-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 Makefile   |  8 +++---
 Makefile.objs  |  1 -
 Makefile.target|  5 +---
 configure  | 65 +++---
 net/Makefile.objs  |  2 ++
 net/slirp.c|  2 +-
 util/Makefile.objs |  1 +
 7 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile
index 2208bde419..a99acda9d9 100644
--- a/Makefile
+++ b/Makefile
@@ -383,8 +383,7 @@ dummy := $(call unnest-vars,, \
 ui-obj-m \
 audio-obj-y \
 audio-obj-m \
-trace-obj-y \
-slirp-obj-y)
+trace-obj-y)
 
 include $(SRC_PATH)/tests/Makefile.include
 
@@ -458,7 +457,10 @@ CAP_CFLAGS += -DCAPSTONE_HAS_X86
 subdir-capstone: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no 
BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) 
$(BUILD_DIR)/capstone/$(LIBCAPSTONE))
 
-$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) $(slirp-obj-y) 
\
+subdir-slirp: .git-submodule-status
+   $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp 
BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS)")
+
+$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
$(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
diff --git a/Makefile.objs b/Makefile.objs
index 6e91ee5674..ef65a6c12e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -4,7 +4,6 @@ stub-obj-y = stubs/ util/ crypto/
 util-obj-y = util/ qobject/ qapi/
 
 chardev-obj-y = chardev/
-slirp-obj-$(CONFIG_SLIRP) = slirp/
 
 ###
 # authz-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/Makefile.target b/Makefile.target
index 3b79e7074c..bd773da756 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -174,7 +174,6 @@ target-obj-y :=
 block-obj-y :=
 common-obj-y :=
 chardev-obj-y :=
-slirp-obj-y :=
 include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,,target-obj-y)
 target-obj-y-save := $(target-obj-y)
@@ -188,8 +187,7 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m \
-   slirp-obj-y)
+   common-obj-m)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -199,7 +197,6 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
-all-obj-$(CONFIG_SOFTMMU) += $(slirp-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/configure b/configure
index cefeb8fcce..ec43207c18 100755
--- a/configure
+++ b/configure
@@ -406,7 +406,7 @@ includedir="\${prefix}/include"
 sysconfdir="\${prefix}/etc"
 local_statedir="\${prefix}/var"
 confsuffix="/qemu"
-slirp="yes"
+slirp=""
 oss_lib=""
 bsd="no"
 linux="no"
@@ -1105,6 +1105,10 @@ for opt do
   ;;
   --disable-slirp) slirp="no"
   ;;
+  --enable-slirp=git) slirp="git"
+  ;;
+  --enable-slirp=system) slirp="system"
+  ;;
   --disable-vde) vde="no"
   ;;
   --enable-vde) vde="yes"
@@ -5754,6 +5758,55 @@ if test "$libpmem" != "no"; then
fi
 fi
 
+##
+# check for slirp
+
+case "$slirp" in
+  "" | yes)
+if $pkg_config slirp; then
+  slirp=system
+elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
+  slirp=git
+elif test -e "${source_path}/slirp/Makefile" ; then
+  slirp=internal
+elif test -z "$slirp" ; then
+  slirp=no
+else
+  feature_not_found "slirp" "Install slirp devel or git submodule"
+fi
+;;
+
+  system)
+if ! $pkg_config slirp; then
+  feature_not_found "slirp" "Install slirp devel"
+fi
+;;
+esac
+
+case "$slirp" in
+  git | internal)
+if test "$slirp" = git; then
+  git_submodules="${git_submodules} s

[Qemu-devel] [PULLv2 12/12] slirp: remove QEMU Makefile.objs

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU no longer includes it, and treats slirp/ as a separate project.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-8-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 36 
 1 file changed, 36 deletions(-)
 delete mode 100644 slirp/Makefile.objs

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
deleted file mode 100644
index 0250229dfa..00
--- a/slirp/Makefile.objs
+++ /dev/null
@@ -1,36 +0,0 @@
-slirp-obj-y = slirp.mo
-
-slirp.mo-objs = \
-   src/arp_table.o \
-   src/bootp.o \
-   src/cksum.o \
-   src/dhcpv6.o \
-   src/dnssearch.o \
-   src/if.o \
-   src/ip6_icmp.o \
-   src/ip6_input.o \
-   src/ip6_output.o \
-   src/ip_icmp.o \
-   src/ip_input.o \
-   src/ip_output.o \
-   src/mbuf.o \
-   src/misc.o \
-   src/ncsi.o \
-   src/ndp_table.o \
-   src/sbuf.o \
-   src/slirp.o \
-   src/socket.o \
-   src/state.o \
-   src/stream.o \
-   src/tcp_input.o \
-   src/tcp_output.o \
-   src/tcp_subr.o \
-   src/tcp_timer.o \
-   src/tftp.o \
-   src/udp.o \
-   src/udp6.o \
-   src/util.o \
-   src/vmstate.o \
-   $(NULL)
-
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
-- 
2.20.1




[Qemu-devel] [PULLv2 00/12] slirp updates

2019-03-07 Thread Samuel Thibault
The following changes since commit 32694e98b8d7a246345448a8f707d2e11d6c65e2:

  Merge remote-tracking branch 
'remotes/ehabkost/tags/machine-next-pull-request' into staging (2019-03-06 
18:52:19 +)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to be1911ff7504be95d5cf2c18bc99ce07246a91e5:

  slirp: remove QEMU Makefile.objs (2019-03-07 12:46:31 +0100)


Slirp updates

Greg Kurz (1):
  slirp: Fix build with gcc 9

Marc-André Lureau (7):
  slirp: adapt a subset of QEMU vmstate code
  slirp: use libslirp migration code
  slirp: use "slirp_" prefix for inet_aton() win32 implementation
  slirp: move sources to src/ subdirectory
  slirp: add a standalone Makefile
  build-sys: link with slirp as an external project
  slirp: remove QEMU Makefile.objs

Samuel Thibault (2):
  slirp: fix big/little endian conversion in ident protocol
  slirp: Mark pieces missing IPv6 support

Vic Lee (1):
  slirp: check for ioctlsocket error and 0-length udp payload.

William Bowling (1):
  slirp: check sscanf result when emulating ident


Greg Kurz (1):
  slirp: Fix build with gcc 9

Marc-André Lureau (7):
  slirp: adapt a subset of QEMU vmstate code
  slirp: use libslirp migration code
  slirp: use "slirp_" prefix for inet_aton() win32 implementation
  slirp: move sources to src/ subdirectory
  slirp: add a standalone Makefile
  build-sys: link with slirp as an external project
  slirp: remove QEMU Makefile.objs

Samuel Thibault (2):
  slirp: fix big/little endian conversion in ident protocol
  slirp: Mark pieces missing IPv6 support

Vic Lee (1):
  slirp: check for ioctlsocket error and 0-length udp payload.

William Bowling (1):
  slirp: check sscanf result when emulating ident

 Makefile|   8 +-
 Makefile.objs   |   1 -
 Makefile.target |   5 +-
 configure   |  65 +-
 include/migration/qemu-file-types.h |   2 +
 migration/qemu-file.h   |   1 -
 net/Makefile.objs   |   2 +
 net/slirp.c |  58 -
 slirp/Makefile  |  47 
 slirp/Makefile.objs |  34 ---
 slirp/{ => src}/arp_table.c |   0
 slirp/{ => src}/bootp.c |   0
 slirp/{ => src}/bootp.h |   0
 slirp/{ => src}/cksum.c |   0
 slirp/{ => src}/debug.h |   0
 slirp/{ => src}/dhcpv6.c|   0
 slirp/{ => src}/dhcpv6.h|   0
 slirp/{ => src}/dnssearch.c |   0
 slirp/{ => src}/if.c|   0
 slirp/{ => src}/if.h|   0
 slirp/{ => src}/ip.h|   0
 slirp/{ => src}/ip6.h   |   0
 slirp/{ => src}/ip6_icmp.c  |   0
 slirp/{ => src}/ip6_icmp.h  |   0
 slirp/{ => src}/ip6_input.c |   0
 slirp/{ => src}/ip6_output.c|   0
 slirp/{ => src}/ip_icmp.c   |   0
 slirp/{ => src}/ip_icmp.h   |   0
 slirp/{ => src}/ip_input.c  |   0
 slirp/{ => src}/ip_output.c |   0
 slirp/{ => src}/libslirp.h  |  10 +
 slirp/{ => src}/main.h  |   0
 slirp/{ => src}/mbuf.c  |   0
 slirp/{ => src}/mbuf.h  |   0
 slirp/{ => src}/misc.c  |   3 +
 slirp/{ => src}/misc.h  |   0
 slirp/{ => src}/ncsi-pkt.h  |   0
 slirp/{ => src}/ncsi.c  |   0
 slirp/{ => src}/ndp_table.c |   0
 slirp/{ => src}/qtailq.h|   0
 slirp/{ => src}/sbuf.c  |   0
 slirp/{ => src}/sbuf.h  |   0
 slirp/{ => src}/slirp.c |  14 +-
 slirp/{ => src}/slirp.h |   2 +-
 slirp/{ => src}/socket.c|  11 +-
 slirp/{ => src}/socket.h|   0
 slirp/{ => src}/state.c |  52 ++---
 slirp/src/state.h   |   0
 slirp/src/stream.c  | 119 +++
 slirp/src/stream.h  |  34 +++
 slirp/{ => src}/tcp.h   |   0
 slirp/{ => src}/tcp_input.c |   2 +
 slirp/{ => src}/tcp_output.c|   0
 slirp/{ => src}/tcp_subr.c  |  16 +-
 slirp/{ => src}/tcp_timer.c |   0
 slirp/{ => src}/tcp_timer.h |   0
 slirp/{ => src}/tcp_var.h   |   0
 slirp/{ => src}/tcpip.h |   0
 slirp/{ => src}/tftp.c  |   0
 slirp/{ => src}/tftp.h  |   0
 slirp/{ => src}/udp.c   |   1 +
 slirp/{ => src}/udp.h   |   0
 slirp/{ => src}/udp6.c  |   0
 slirp/{ => src}/util.c

[Qemu-devel] [PULLv2 01/12] slirp: Fix build with gcc 9

2019-03-07 Thread Samuel Thibault
From: Greg Kurz 

Build fails with gcc 9:

  CC  slirp/ndp_table.o
slirp/ndp_table.c: In function ‘ndp_table_add’:
slirp/ndp_table.c:31:23: error: taking address of packed member of ‘struct 
ndpentry’ may result in an unaligned pointer value 
[-Werror=address-of-packed-member]
   31 | if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  |   ^~~~
slirp/ndp_table.c: In function ‘ndp_table_search’:
slirp/ndp_table.c:75:23: error: taking address of packed member of ‘struct 
ndpentry’ may result in an unaligned pointer value 
[-Werror=address-of-packed-member]
   75 | if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  |   ^~~~
cc1: all warnings being treated as errors

The ndpentry structure isn't used to model on-the-wire data or anything
else that would care for the struct layout. It doesn't need to be packed
actually. Just drop SLIRP_PACKED.

Signed-off-by: Greg Kurz 
Message-Id: <155143315831.102868.17515265400523392682.st...@bahia.lan>
Reviewed-by: Peter Maydell 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 752a4cd8c8..8068ba1d1e 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -106,7 +106,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
 struct ndpentry {
 unsigned char   eth_addr[ETH_ALEN]; /* sender hardware address */
 struct in6_addr ip_addr;/* sender IP address   */
-} SLIRP_PACKED;
+};
 
 #define NDP_TABLE_SIZE 16
 
-- 
2.20.1




[Qemu-devel] [PULLv2 08/12] slirp: use "slirp_" prefix for inet_aton() win32 implementation

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

To avoid conflict with QEMU inet_aton() implementation, let's use the
"slirp_" prefix. This allows to drop the WITH_QEMU, thus the source
won't make a distinction when building with QEMU or not.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-4-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 2 +-
 slirp/util.c| 4 ++--
 slirp/util.h| 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 69e140f965..e91daf0e91 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -33,4 +33,4 @@ slirp.mo-objs = \
vmstate.o \
$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
diff --git a/slirp/util.c b/slirp/util.c
index 1cbaa26b60..5ec2fa87ab 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -31,8 +31,8 @@
 #include 
 #include 
 
-#if defined(_WIN32) && !defined(WITH_QEMU)
-int inet_aton(const char *cp, struct in_addr *ia)
+#if defined(_WIN32)
+int slirp_inet_aton(const char *cp, struct in_addr *ia)
 {
 uint32_t addr = inet_addr(cp);
 if (addr == 0x) {
diff --git a/slirp/util.h b/slirp/util.h
index c4207a49d6..e94ee4e7f1 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -138,8 +138,8 @@ int slirp_getsockopt_wrap(int sockfd, int level, int 
optname,
 #define setsockopt slirp_setsockopt_wrap
 int slirp_setsockopt_wrap(int sockfd, int level, int optname,
   const void *optval, int optlen);
-
-int inet_aton(const char *cp, struct in_addr *ia);
+#define inet_aton slirp_inet_aton
+int slirp_inet_aton(const char *cp, struct in_addr *ia);
 #else
 #define closesocket(s) close(s)
 #define ioctlsocket(s, r, v) ioctl(s, r, v)
-- 
2.20.1




[Qemu-devel] [PULLv2 1/1] slirp: remove QEMU Makefile.objs

2019-03-07 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU no longer includes it, and treats slirp/ as a separate project.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-8-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 36 
 1 file changed, 36 deletions(-)
 delete mode 100644 slirp/Makefile.objs

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
deleted file mode 100644
index 0250229dfa..00
--- a/slirp/Makefile.objs
+++ /dev/null
@@ -1,36 +0,0 @@
-slirp-obj-y = slirp.mo
-
-slirp.mo-objs = \
-   src/arp_table.o \
-   src/bootp.o \
-   src/cksum.o \
-   src/dhcpv6.o \
-   src/dnssearch.o \
-   src/if.o \
-   src/ip6_icmp.o \
-   src/ip6_input.o \
-   src/ip6_output.o \
-   src/ip_icmp.o \
-   src/ip_input.o \
-   src/ip_output.o \
-   src/mbuf.o \
-   src/misc.o \
-   src/ncsi.o \
-   src/ndp_table.o \
-   src/sbuf.o \
-   src/slirp.o \
-   src/socket.o \
-   src/state.o \
-   src/stream.o \
-   src/tcp_input.o \
-   src/tcp_output.o \
-   src/tcp_subr.o \
-   src/tcp_timer.o \
-   src/tftp.o \
-   src/udp.o \
-   src/udp6.o \
-   src/util.o \
-   src/vmstate.o \
-   $(NULL)
-
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
-- 
2.20.1




[Qemu-devel] [PULLv2 04/12] slirp: fix big/little endian conversion in ident protocol

2019-03-07 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
Reviewed-by: Philippe Mathieu-Daudé 

---
Based-on: <1551476756-25749-1-git-send-email-w...@wbowling.info>
---
 slirp/tcp_subr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index ef9d99c154..1d7e72dca7 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -660,10 +660,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
tmpso->so_fport == n1) {
if 
(getsockname(tmpso->s,
(struct 
sockaddr *)&addr, &addrlen) == 0)
-  n2 = 
ntohs(addr.sin_port);
+  n2 = addr.sin_port;
break;
}
}
+   NTOHS(n1);
+   NTOHS(n2);
so_rcv->sb_cc = 
snprintf(so_rcv->sb_data,
 
so_rcv->sb_datalen,
 "%d,%d\r\n", 
n1, n2);
-- 
2.20.1




[Qemu-devel] [PULLv2 02/12] slirp: check for ioctlsocket error and 0-length udp payload.

2019-03-07 Thread Samuel Thibault
From: Vic Lee 

Sometimes sorecvfrom() is called from slirp.c because revents == G_IO_IN,
but there is 0 bytes available and recvfrom could be blocking indefinitely.
This is likely due to 0-length udp payload. This also adds an error
checking for ioctlsocket.

Signed-off-by: Vic Lee 
Message-Id: <20190301064809.3074-1-llyzs@gmail.com>
Signed-off-by: Samuel Thibault 
---
 slirp/socket.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/slirp/socket.c b/slirp/socket.c
index 4876ea3f31..4dc5e2907d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -529,6 +529,15 @@ sorecvfrom(struct socket *so)
   int n;
 #endif
 
+ if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
+ DEBUG_MISC(" ioctlsocket errno = %d-%s\n",
+errno,strerror(errno));
+ return;
+ }
+ if (n == 0) {
+ return;
+ }
+
  m = m_get(so->slirp);
  if (!m) {
  return;
@@ -552,7 +561,6 @@ sorecvfrom(struct socket *so)
   */
  len = M_FREEROOM(m);
  /* if (so->so_fport != htons(53)) { */
- ioctlsocket(so->s, FIONREAD, &n);
 
  if (n > len) {
n = (m->m_data - m->m_dat) + m->m_len + n + 1;
-- 
2.20.1




[Qemu-devel] [PULL 07/12] slirp: use libslirp migration code

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

slirp migration code uses QEMU vmstate so far, when building WITH_QEMU.

Introduce slirp_state_{load,save,version}() functions to move the
state saving handling to libslirp side.

So far, the bitstream compatibility should remain equal with current
QEMU, as this is effectively using the same code, with the same format
etc. When libslirp is made standalone, we will need some mechanism to
ensure bitstream compatibility regardless of the libslirp version
installed. See the FIXME note in the code.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-3-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 include/migration/qemu-file-types.h |  2 ++
 migration/qemu-file.h   |  1 -
 net/slirp.c | 55 +
 slirp/libslirp.h|  8 +
 slirp/slirp.c   |  9 -
 slirp/state.c   | 52 ---
 slirp/state.h   |  9 -
 7 files changed, 88 insertions(+), 48 deletions(-)

diff --git a/include/migration/qemu-file-types.h 
b/include/migration/qemu-file-types.h
index bd6d7dd7f9..bbe04d4484 100644
--- a/include/migration/qemu-file-types.h
+++ b/include/migration/qemu-file-types.h
@@ -25,6 +25,8 @@
 #ifndef QEMU_FILE_H
 #define QEMU_FILE_H
 
+int qemu_file_get_error(QEMUFile *f);
+
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size);
 void qemu_put_byte(QEMUFile *f, int v);
 
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index 2ccfcfb2a8..13baf896bd 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -149,7 +149,6 @@ void qemu_update_position(QEMUFile *f, size_t size);
 void qemu_file_reset_rate_limit(QEMUFile *f);
 void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate);
 int64_t qemu_file_get_rate_limit(QEMUFile *f);
-int qemu_file_get_error(QEMUFile *f);
 void qemu_file_set_error(QEMUFile *f, int ret);
 int qemu_file_shutdown(QEMUFile *f);
 QEMUFile *qemu_file_get_return_path(QEMUFile *f);
diff --git a/net/slirp.c b/net/slirp.c
index a8fd9e6364..059b2d9b08 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -44,6 +44,8 @@
 #include "qapi/error.h"
 #include "qapi/qmp/qdict.h"
 #include "util.h"
+#include "migration/register.h"
+#include "migration/qemu-file-types.h"
 
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
 {
@@ -146,6 +148,7 @@ static void net_slirp_cleanup(NetClientState *nc)
 
 g_slist_free_full(s->fwd, slirp_free_fwd);
 main_loop_poll_remove_notifier(&s->poll_notifier);
+unregister_savevm(NULL, "slirp", s->slirp);
 slirp_cleanup(s->slirp);
 if (s->exit_notifier.notify) {
 qemu_remove_exit_notifier(&s->exit_notifier);
@@ -303,6 +306,46 @@ static void net_slirp_poll_notify(Notifier *notifier, void 
*data)
 }
 }
 
+static ssize_t
+net_slirp_stream_read(void *buf, size_t size, void *opaque)
+{
+QEMUFile *f = opaque;
+
+return qemu_get_buffer(f, buf, size);
+}
+
+static ssize_t
+net_slirp_stream_write(const void *buf, size_t size, void *opaque)
+{
+QEMUFile *f = opaque;
+
+qemu_put_buffer(f, buf, size);
+if (qemu_file_get_error(f)) {
+return -1;
+}
+
+return size;
+}
+
+static int net_slirp_state_load(QEMUFile *f, void *opaque, int version_id)
+{
+Slirp *slirp = opaque;
+
+return slirp_state_load(slirp, version_id, net_slirp_stream_read, f);
+}
+
+static void net_slirp_state_save(QEMUFile *f, void *opaque)
+{
+Slirp *slirp = opaque;
+
+slirp_state_save(slirp, net_slirp_stream_write, f);
+}
+
+static SaveVMHandlers savevm_slirp_state = {
+.save_state = net_slirp_state_save,
+.load_state = net_slirp_state_load,
+};
+
 static int net_slirp_init(NetClientState *peer, const char *model,
   const char *name, int restricted,
   bool ipv4, const char *vnetwork, const char *vhost,
@@ -523,6 +566,18 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   &slirp_cb, s);
 QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
 
+/*
+ * Make sure the current bitstream version of slirp is 4, to avoid
+ * QEMU migration incompatibilities, if upstream slirp bumped the
+ * version.
+ *
+ * FIXME: use bitfields of features? teach libslirp to save with
+ * specific version?
+ */
+g_assert(slirp_state_version() == 4);
+register_savevm_live(NULL, "slirp", 0, slirp_state_version(),
+ &savevm_slirp_state, s->slirp);
+
 s->poll_notifier.notify = net_slirp_poll_notify;
 main_loop_poll_add_notifier(&s->poll_notifier);
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 18c50bd7ba..7ce1e4d0d4 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -101,6 +101,14 @@ void slirp_socke

[Qemu-devel] [PULL 09/12] slirp: move sources to src/ subdirectory

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

Prepare for making slirp/ a standalone project.

Remove some useless includes while at it.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-5-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 net/slirp.c  |  2 +-
 slirp/Makefile.objs  | 60 ++--
 slirp/{ => src}/arp_table.c  |  0
 slirp/{ => src}/bootp.c  |  0
 slirp/{ => src}/bootp.h  |  0
 slirp/{ => src}/cksum.c  |  0
 slirp/{ => src}/debug.h  |  0
 slirp/{ => src}/dhcpv6.c |  0
 slirp/{ => src}/dhcpv6.h |  0
 slirp/{ => src}/dnssearch.c  |  0
 slirp/{ => src}/if.c |  0
 slirp/{ => src}/if.h |  0
 slirp/{ => src}/ip.h |  0
 slirp/{ => src}/ip6.h|  0
 slirp/{ => src}/ip6_icmp.c   |  0
 slirp/{ => src}/ip6_icmp.h   |  0
 slirp/{ => src}/ip6_input.c  |  0
 slirp/{ => src}/ip6_output.c |  0
 slirp/{ => src}/ip_icmp.c|  0
 slirp/{ => src}/ip_icmp.h|  0
 slirp/{ => src}/ip_input.c   |  0
 slirp/{ => src}/ip_output.c  |  0
 slirp/{ => src}/libslirp.h   |  0
 slirp/{ => src}/main.h   |  0
 slirp/{ => src}/mbuf.c   |  0
 slirp/{ => src}/mbuf.h   |  0
 slirp/{ => src}/misc.c   |  0
 slirp/{ => src}/misc.h   |  0
 slirp/{ => src}/ncsi-pkt.h   |  0
 slirp/{ => src}/ncsi.c   |  0
 slirp/{ => src}/ndp_table.c  |  0
 slirp/{ => src}/qtailq.h |  0
 slirp/{ => src}/sbuf.c   |  0
 slirp/{ => src}/sbuf.h   |  0
 slirp/{ => src}/slirp.c  |  0
 slirp/{ => src}/slirp.h  |  0
 slirp/{ => src}/socket.c |  0
 slirp/{ => src}/socket.h |  0
 slirp/{ => src}/state.c  |  0
 slirp/{ => src}/state.h  |  0
 slirp/{ => src}/stream.c |  0
 slirp/{ => src}/stream.h |  0
 slirp/{ => src}/tcp.h|  0
 slirp/{ => src}/tcp_input.c  |  0
 slirp/{ => src}/tcp_output.c |  0
 slirp/{ => src}/tcp_subr.c   |  0
 slirp/{ => src}/tcp_timer.c  |  0
 slirp/{ => src}/tcp_timer.h  |  0
 slirp/{ => src}/tcp_var.h|  0
 slirp/{ => src}/tcpip.h  |  0
 slirp/{ => src}/tftp.c   |  0
 slirp/{ => src}/tftp.h   |  0
 slirp/{ => src}/udp.c|  0
 slirp/{ => src}/udp.h|  0
 slirp/{ => src}/udp6.c   |  0
 slirp/{ => src}/util.c   |  0
 slirp/{ => src}/util.h   |  0
 slirp/{ => src}/vmstate.c|  0
 slirp/{ => src}/vmstate.h|  0
 util/main-loop.c |  2 --
 vl.c |  3 --
 61 files changed, 31 insertions(+), 36 deletions(-)
 rename slirp/{ => src}/arp_table.c (100%)
 rename slirp/{ => src}/bootp.c (100%)
 rename slirp/{ => src}/bootp.h (100%)
 rename slirp/{ => src}/cksum.c (100%)
 rename slirp/{ => src}/debug.h (100%)
 rename slirp/{ => src}/dhcpv6.c (100%)
 rename slirp/{ => src}/dhcpv6.h (100%)
 rename slirp/{ => src}/dnssearch.c (100%)
 rename slirp/{ => src}/if.c (100%)
 rename slirp/{ => src}/if.h (100%)
 rename slirp/{ => src}/ip.h (100%)
 rename slirp/{ => src}/ip6.h (100%)
 rename slirp/{ => src}/ip6_icmp.c (100%)
 rename slirp/{ => src}/ip6_icmp.h (100%)
 rename slirp/{ => src}/ip6_input.c (100%)
 rename slirp/{ => src}/ip6_output.c (100%)
 rename slirp/{ => src}/ip_icmp.c (100%)
 rename slirp/{ => src}/ip_icmp.h (100%)
 rename slirp/{ => src}/ip_input.c (100%)
 rename slirp/{ => src}/ip_output.c (100%)
 rename slirp/{ => src}/libslirp.h (100%)
 rename slirp/{ => src}/main.h (100%)
 rename slirp/{ => src}/mbuf.c (100%)
 rename slirp/{ => src}/mbuf.h (100%)
 rename slirp/{ => src}/misc.c (100%)
 rename slirp/{ => src}/misc.h (100%)
 rename slirp/{ => src}/ncsi-pkt.h (100%)
 rename slirp/{ => src}/ncsi.c (100%)
 rename slirp/{ => src}/ndp_table.c (100%)
 rename slirp/{ => src}/qtailq.h (100%)
 rename slirp/{ => src}/sbuf.c (100%)
 rename slirp/{ => src}/sbuf.h (100%)
 rename slirp/{ => src}/slirp.c (100%)
 rename slirp/{ => src}/slirp.h (100%)
 rename slirp/{ => src}/socket.c (100%)
 rename slirp/{ => src}/socket.h (100%)
 rename slirp/{ => src}/state.c (100%)
 rename slirp/{ => src}/state.h (100%)
 rename slirp/{ => src}/stream.c (100%)
 rename slirp/{ => src}/stream.h (100%)
 rename slirp/{ => src}/tcp.h (100%)
 rename slirp/{ => src}/tcp_input.c (100%)
 rename slirp/{ => src}/tcp_output.c (100%)
 rename slirp/{ => src}/tcp_subr.c (100%)
 rename slirp/{ => src}/tcp_timer.c (100%)
 rename slirp/{ => src}/tcp_timer.h (100%)
 rename slirp/{ => src}/tcp_var.h (100%)
 rename slirp/{ => src}/tcpip.h (100%)
 rename slirp/{ => src}/tftp.c (100%)
 rename slirp/{ => src}/tftp.h (100%)
 rename slirp/{ => src}/udp.c (100%)
 rename slirp/{ => src}/udp.h (100%)
 rename slirp/{ => src}/udp6.c (100%)
 rename slirp/{ => src}/util.c (100%)
 rename slirp/{ 

[Qemu-devel] [PULL 11/12] build-sys: link with slirp as an external project

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

Use the "system" libslirp if its present or requested.

Else build with a static libslirp.a if slirp/ is checked
out ("internal") or a submodule ("git").

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-7-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 Makefile   |  8 +++---
 Makefile.objs  |  1 -
 Makefile.target|  5 +---
 configure  | 65 +++---
 net/Makefile.objs  |  2 ++
 net/slirp.c|  2 +-
 util/Makefile.objs |  1 +
 7 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile
index 2208bde419..a99acda9d9 100644
--- a/Makefile
+++ b/Makefile
@@ -383,8 +383,7 @@ dummy := $(call unnest-vars,, \
 ui-obj-m \
 audio-obj-y \
 audio-obj-m \
-trace-obj-y \
-slirp-obj-y)
+trace-obj-y)
 
 include $(SRC_PATH)/tests/Makefile.include
 
@@ -458,7 +457,10 @@ CAP_CFLAGS += -DCAPSTONE_HAS_X86
 subdir-capstone: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no 
BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) 
$(BUILD_DIR)/capstone/$(LIBCAPSTONE))
 
-$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) $(slirp-obj-y) 
\
+subdir-slirp: .git-submodule-status
+   $(call quiet-command,$(MAKE) -C $(SRC_PATH)/slirp 
BUILD_DIR="$(BUILD_DIR)/slirp" CC="$(CC)" AR="$(AR)" LD="$(LD)" 
RANLIB="$(RANLIB)" CFLAGS="$(QEMU_CFLAGS)")
+
+$(SUBDIR_RULES): libqemuutil.a $(common-obj-y) $(chardev-obj-y) \
$(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
 
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
diff --git a/Makefile.objs b/Makefile.objs
index 6e91ee5674..ef65a6c12e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -4,7 +4,6 @@ stub-obj-y = stubs/ util/ crypto/
 util-obj-y = util/ qobject/ qapi/
 
 chardev-obj-y = chardev/
-slirp-obj-$(CONFIG_SLIRP) = slirp/
 
 ###
 # authz-obj-y is code used by both qemu system emulation and qemu-img
diff --git a/Makefile.target b/Makefile.target
index 3b79e7074c..bd773da756 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -174,7 +174,6 @@ target-obj-y :=
 block-obj-y :=
 common-obj-y :=
 chardev-obj-y :=
-slirp-obj-y :=
 include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,,target-obj-y)
 target-obj-y-save := $(target-obj-y)
@@ -188,8 +187,7 @@ dummy := $(call unnest-vars,.., \
qom-obj-y \
io-obj-y \
common-obj-y \
-   common-obj-m \
-   slirp-obj-y)
+   common-obj-m)
 target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
@@ -199,7 +197,6 @@ all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
-all-obj-$(CONFIG_SOFTMMU) += $(slirp-obj-y)
 
 $(QEMU_PROG_BUILD): config-devices.mak
 
diff --git a/configure b/configure
index cefeb8fcce..ec43207c18 100755
--- a/configure
+++ b/configure
@@ -406,7 +406,7 @@ includedir="\${prefix}/include"
 sysconfdir="\${prefix}/etc"
 local_statedir="\${prefix}/var"
 confsuffix="/qemu"
-slirp="yes"
+slirp=""
 oss_lib=""
 bsd="no"
 linux="no"
@@ -1105,6 +1105,10 @@ for opt do
   ;;
   --disable-slirp) slirp="no"
   ;;
+  --enable-slirp=git) slirp="git"
+  ;;
+  --enable-slirp=system) slirp="system"
+  ;;
   --disable-vde) vde="no"
   ;;
   --enable-vde) vde="yes"
@@ -5754,6 +5758,55 @@ if test "$libpmem" != "no"; then
fi
 fi
 
+##
+# check for slirp
+
+case "$slirp" in
+  "" | yes)
+if $pkg_config slirp; then
+  slirp=system
+elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
+  slirp=git
+elif test -e "${source_path}/slirp/Makefile" ; then
+  slirp=internal
+elif test -z "$slirp" ; then
+  slirp=no
+else
+  feature_not_found "slirp" "Install slirp devel or git submodule"
+fi
+;;
+
+  system)
+if ! $pkg_config slirp; then
+  feature_not_found "slirp" "Install slirp devel"
+fi
+;;
+esac
+
+case "$slirp" in
+  git | internal)
+if test "$slirp" = git; then
+  git_submodules="${git_submodules} s

[Qemu-devel] [PULL 12/12] slirp: remove QEMU Makefile.objs

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

QEMU no longer includes it, and treats slirp/ as a separate project.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-8-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 36 
 1 file changed, 36 deletions(-)
 delete mode 100644 slirp/Makefile.objs

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
deleted file mode 100644
index 0250229dfa..00
--- a/slirp/Makefile.objs
+++ /dev/null
@@ -1,36 +0,0 @@
-slirp-obj-y = slirp.mo
-
-slirp.mo-objs = \
-   src/arp_table.o \
-   src/bootp.o \
-   src/cksum.o \
-   src/dhcpv6.o \
-   src/dnssearch.o \
-   src/if.o \
-   src/ip6_icmp.o \
-   src/ip6_input.o \
-   src/ip6_output.o \
-   src/ip_icmp.o \
-   src/ip_input.o \
-   src/ip_output.o \
-   src/mbuf.o \
-   src/misc.o \
-   src/ncsi.o \
-   src/ndp_table.o \
-   src/sbuf.o \
-   src/slirp.o \
-   src/socket.o \
-   src/state.o \
-   src/stream.o \
-   src/tcp_input.o \
-   src/tcp_output.o \
-   src/tcp_subr.o \
-   src/tcp_timer.o \
-   src/tftp.o \
-   src/udp.o \
-   src/udp6.o \
-   src/util.o \
-   src/vmstate.o \
-   $(NULL)
-
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
-- 
2.20.1




[Qemu-devel] [PULL 10/12] slirp: add a standalone Makefile

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

Add a simple Makefile to build libslirp.a, a static library version of
libslirp, to be used by QEMU during a transition period, until a
shared library is available.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-6-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile | 47 +++
 1 file changed, 47 insertions(+)
 create mode 100644 slirp/Makefile

diff --git a/slirp/Makefile b/slirp/Makefile
new file mode 100644
index 00..6d48f626ba
--- /dev/null
+++ b/slirp/Makefile
@@ -0,0 +1,47 @@
+ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST
+BUILD_DIR ?= .
+
+LIBSLIRP = $(BUILD_DIR)/libslirp.a
+
+all: $(LIBSLIRP)
+
+SRCS := $(wildcard src/*.c)
+OBJS := $(SRCS:%.c=$(BUILD_DIR)/%.o)
+DEPS := $(OBJS:%.o=%.d)
+
+INC_DIRS := $(BUILD_DIR)/src
+INC_FLAGS := $(addprefix -I,$(INC_DIRS))
+
+override CFLAGS += \
+   -DG_LOG_DOMAIN='"Slirp"'\
+   $(shell $(PKG_CONFIG) --cflags glib-2.0)\
+   $(INC_FLAGS)\
+   -MMD -MP
+override LDFLAGS += $(shell $(PKG_CONFIG) --libs glib-2.0)
+
+$(LIBSLIRP): $(OBJS)
+
+.PHONY: clean
+
+clean:
+   rm -r $(OBJS) $(DEPS) $(LIBSLIRP)
+
+$(BUILD_DIR)/src/%.o: $(ROOT_DIR)/src/%.c
+   @$(MKDIR_P) $(dir $@)
+   $(call quiet-command,$(CC) $(CFLAGS) -c -o $@ $<,"CC","$@")
+
+%.a:
+   $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"AR","$@")
+
+PKG_CONFIG ?= pkg-config
+MKDIR_P ?= mkdir -p
+quiet-command-run = $(if $(V),,$(if $2,printf "  %-7s %s\n" $2 $3 && ))$1
+quiet-@ = $(if $(V),,@)
+quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
+
+print-%:
+   @echo '$*=$($*)'
+
+.SUFFIXES:
+
+-include $(DEPS)
-- 
2.20.1




[Qemu-devel] [PULL 06/12] slirp: adapt a subset of QEMU vmstate code

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

Add vmstate serialization code adapted from QEMU.

Keep only the bits that are required for libslirp.

Introduce a IStream/OStream interface to replace QEMU QFile
abstraction.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-2-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs |   2 +
 slirp/libslirp.h|   1 +
 slirp/stream.c  | 119 +
 slirp/stream.h  |  34 
 slirp/vmstate.c | 413 
 slirp/vmstate.h | 396 ++
 6 files changed, 965 insertions(+)
 create mode 100644 slirp/stream.c
 create mode 100644 slirp/stream.h
 create mode 100644 slirp/vmstate.c
 create mode 100644 slirp/vmstate.h

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 88340a583b..69e140f965 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -21,6 +21,7 @@ slirp.mo-objs = \
slirp.o \
socket.o \
state.o \
+   stream.o \
tcp_input.o \
tcp_output.o \
tcp_subr.o \
@@ -29,6 +30,7 @@ slirp.mo-objs = \
udp.o \
udp6.o \
util.o \
+   vmstate.o \
$(NULL)
 
 slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index fccab42518..18c50bd7ba 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -26,6 +26,7 @@ enum {
 SLIRP_POLL_HUP = 1 << 4,
 };
 
+typedef ssize_t (*SlirpReadCb)(void *buf, size_t len, void *opaque);
 typedef ssize_t (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
 typedef void (*SlirpTimerCb)(void *opaque);
 typedef int (*SlirpAddPollCb)(int fd, int events, void *opaque);
diff --git a/slirp/stream.c b/slirp/stream.c
new file mode 100644
index 00..d114dde334
--- /dev/null
+++ b/slirp/stream.c
@@ -0,0 +1,119 @@
+/*
+ * libslirp io streams
+ *
+ * Copyright (c) 2018 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "stream.h"
+#include 
+
+bool slirp_istream_read(SlirpIStream *f, void *buf, size_t size)
+{
+return f->read_cb(buf, size, f->opaque) == size;
+}
+
+bool slirp_ostream_write(SlirpOStream *f, const void *buf, size_t size)
+{
+return f->write_cb(buf, size, f->opaque) == size;
+}
+
+uint8_t slirp_istream_read_u8(SlirpIStream *f)
+{
+uint8_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return b;
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u8(SlirpOStream *f, uint8_t b)
+{
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint16_t slirp_istream_read_u16(SlirpIStream *f)
+{
+uint16_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GUINT16_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u16(SlirpOStream *f, uint16_t b)
+{
+b =  GUINT16_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+uint32_t slirp_istream_read_u32(SlirpIStream *f)
+{
+uint32_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GUINT32_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_u32(SlirpOStream *f, uint32_t b)
+{
+b = GUINT32_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int16_t slirp_istream_read_i16(SlirpIStream *f)
+{
+int16_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GINT16_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_i16(SlirpOStream *f, int16_t b)
+{
+b = GINT16_TO_BE(b);
+return slirp_ostream_write(f, &b, sizeof(b));
+}
+
+int32_t slirp_istream_read_i32(SlirpIStream *f)
+{
+int32_t b;
+
+if (slirp_istream_read(f, &b, sizeof(b))) {
+return GINT32_FROM_BE(b);
+}
+
+return 0;
+}
+
+bool slirp_ostream_write_i32(SlirpOStream *f, int32_t b)
+{
+b = GINT32_TO_BE(b);
+ 

[Qemu-devel] [PULL 03/12] slirp: check sscanf result when emulating ident

2019-03-06 Thread Samuel Thibault
From: William Bowling 

When emulating ident in tcp_emu, if the strchr checks passed but the
sscanf check failed, two uninitialized variables would be copied and
sent in the reply, so move this code inside the if(sscanf()) clause.

Signed-off-by: William Bowling 
Cc: qemu-sta...@nongnu.org
Cc: secal...@redhat.com
Message-Id: <1551476756-25749-1-git-send-email-w...@wbowling.info>
Signed-off-by: Samuel Thibault 
Reviewed-by: Philippe Mathieu-Daudé 
---
 slirp/tcp_subr.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 262a42d6c8..ef9d99c154 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -664,12 +664,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
break;
}
}
+   so_rcv->sb_cc = 
snprintf(so_rcv->sb_data,
+
so_rcv->sb_datalen,
+"%d,%d\r\n", 
n1, n2);
+   so_rcv->sb_rptr = so_rcv->sb_data;
+   so_rcv->sb_wptr = so_rcv->sb_data + 
so_rcv->sb_cc;
}
-so_rcv->sb_cc = snprintf(so_rcv->sb_data,
- so_rcv->sb_datalen,
- "%d,%d\r\n", n1, n2);
-   so_rcv->sb_rptr = so_rcv->sb_data;
-   so_rcv->sb_wptr = so_rcv->sb_data + 
so_rcv->sb_cc;
}
m_free(m);
return 0;
-- 
2.20.1




[Qemu-devel] [PULL 00/12] slirp updates

2019-03-06 Thread Samuel Thibault
The following changes since commit 32694e98b8d7a246345448a8f707d2e11d6c65e2:

  Merge remote-tracking branch 
'remotes/ehabkost/tags/machine-next-pull-request' into staging (2019-03-06 
18:52:19 +)

are available in the Git repository at:

  https://people.debian.org/~sthibault/qemu.git tags/samuel-thibault

for you to fetch changes up to dd9eff6c839db3996c157f0a6a4e18f95683e58c:

  slirp: remove QEMU Makefile.objs (2019-03-07 00:12:34 +0100)


Slirp updates

Greg Kurz (1):
  slirp: Fix build with gcc 9

Marc-André Lureau (7):
  slirp: adapt a subset of QEMU vmstate code
  slirp: use libslirp migration code
  slirp: use "slirp_" prefix for inet_aton() win32 implementation
  slirp: move sources to src/ subdirectory
  slirp: add a standalone Makefile
  build-sys: link with slirp as an external project
  slirp: remove QEMU Makefile.objs

Samuel Thibault (2):
  slirp: fix big/little endian conversion in ident protocol
  slirp: Mark pieces missing IPv6 support

Vic Lee (1):
  slirp: check for ioctlsocket error and 0-length udp payload.

William Bowling (1):
  slirp: check sscanf result when emulating ident


Greg Kurz (1):
  slirp: Fix build with gcc 9

Marc-André Lureau (7):
  slirp: adapt a subset of QEMU vmstate code
  slirp: use libslirp migration code
  slirp: use "slirp_" prefix for inet_aton() win32 implementation
  slirp: move sources to src/ subdirectory
  slirp: add a standalone Makefile
  build-sys: link with slirp as an external project
  slirp: remove QEMU Makefile.objs

Samuel Thibault (2):
  slirp: fix big/little endian conversion in ident protocol
  slirp: Mark pieces missing IPv6 support

Vic Lee (1):
  slirp: check for ioctlsocket error and 0-length udp payload.

William Bowling (1):
  slirp: check sscanf result when emulating ident

 Makefile|   8 +-
 Makefile.objs   |   1 -
 Makefile.target |   5 +-
 configure   |  65 +-
 include/migration/qemu-file-types.h |   2 +
 migration/qemu-file.h   |   1 -
 net/Makefile.objs   |   2 +
 net/slirp.c |  58 -
 slirp/Makefile  |  47 
 slirp/Makefile.objs |  34 ---
 slirp/{ => src}/arp_table.c |   0
 slirp/{ => src}/bootp.c |   0
 slirp/{ => src}/bootp.h |   0
 slirp/{ => src}/cksum.c |   0
 slirp/{ => src}/debug.h |   0
 slirp/{ => src}/dhcpv6.c|   0
 slirp/{ => src}/dhcpv6.h|   0
 slirp/{ => src}/dnssearch.c |   0
 slirp/{ => src}/if.c|   0
 slirp/{ => src}/if.h|   0
 slirp/{ => src}/ip.h|   0
 slirp/{ => src}/ip6.h   |   0
 slirp/{ => src}/ip6_icmp.c  |   0
 slirp/{ => src}/ip6_icmp.h  |   0
 slirp/{ => src}/ip6_input.c |   0
 slirp/{ => src}/ip6_output.c|   0
 slirp/{ => src}/ip_icmp.c   |   0
 slirp/{ => src}/ip_icmp.h   |   0
 slirp/{ => src}/ip_input.c  |   0
 slirp/{ => src}/ip_output.c |   0
 slirp/{ => src}/libslirp.h  |   9 +
 slirp/{ => src}/main.h  |   0
 slirp/{ => src}/mbuf.c  |   0
 slirp/{ => src}/mbuf.h  |   0
 slirp/{ => src}/misc.c  |   3 +
 slirp/{ => src}/misc.h  |   0
 slirp/{ => src}/ncsi-pkt.h  |   0
 slirp/{ => src}/ncsi.c  |   0
 slirp/{ => src}/ndp_table.c |   0
 slirp/{ => src}/qtailq.h|   0
 slirp/{ => src}/sbuf.c  |   0
 slirp/{ => src}/sbuf.h  |   0
 slirp/{ => src}/slirp.c |  14 +-
 slirp/{ => src}/slirp.h |   2 +-
 slirp/{ => src}/socket.c|  11 +-
 slirp/{ => src}/socket.h|   0
 slirp/{ => src}/state.c |  52 ++---
 slirp/src/state.h   |   0
 slirp/src/stream.c  | 119 +++
 slirp/src/stream.h  |  34 +++
 slirp/{ => src}/tcp.h   |   0
 slirp/{ => src}/tcp_input.c |   2 +
 slirp/{ => src}/tcp_output.c|   0
 slirp/{ => src}/tcp_subr.c  |  16 +-
 slirp/{ => src}/tcp_timer.c |   0
 slirp/{ => src}/tcp_timer.h |   0
 slirp/{ => src}/tcp_var.h   |   0
 slirp/{ => src}/tcpip.h |   0
 slirp/{ => src}/tftp.c  |   0
 slirp/{ => src}/tftp.h  |   0
 slirp/{ => src}/udp.c   |   1 +
 slirp/{ => src}/udp.h   |   0
 slirp/{ => src}/udp6.c  |   0
 slirp/{ => src}/util.c

[Qemu-devel] [PULL 05/12] slirp: Mark pieces missing IPv6 support

2019-03-06 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
---
 net/slirp.c   | 1 +
 slirp/misc.c  | 3 +++
 slirp/slirp.c | 5 +
 slirp/socket.c| 1 +
 slirp/tcp_input.c | 2 ++
 slirp/tcp_subr.c  | 2 ++
 slirp/udp.c   | 1 +
 7 files changed, 15 insertions(+)

diff --git a/net/slirp.c b/net/slirp.c
index 4ec989b592..a8fd9e6364 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -885,6 +885,7 @@ static ssize_t guestfwd_write(const void *buf, size_t len, 
void *chr)
 
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
 {
+/* TODO: IPv6 */
 struct in_addr server = { .s_addr = 0 };
 struct GuestFwd *fwd;
 const char *p;
diff --git a/slirp/misc.c b/slirp/misc.c
index d9fc586a24..937a418d4e 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -28,6 +28,7 @@ remque(void *a)
   element->qh_rlink = NULL;
 }
 
+/* TODO: IPv6 */
 struct gfwd_list *
 add_guestfwd(struct gfwd_list **ex_ptr,
  SlirpWriteCb write_cb, void *opaque,
@@ -254,6 +255,8 @@ char *slirp_connection_info(Slirp *slirp)
 "  Protocol[State]FD  Source Address  Port   "
 "Dest. Address  Port RecvQ SendQ\n");
 
+/* TODO: IPv6 */
+
 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
 if (so->so_state & SS_HOSTFWD) {
 state = "HOST_FORWARD";
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 55591430dc..cbdf9f778d 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -729,6 +729,7 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int 
pkt_len)
 if (ah->ar_tip == slirp->vnameserver_addr.s_addr ||
 ah->ar_tip == slirp->vhost_addr.s_addr)
 goto arp_ok;
+/* TODO: IPv6 */
 for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = 
ex_ptr->ex_next) {
 if (ex_ptr->ex_addr.s_addr == ah->ar_tip)
 goto arp_ok;
@@ -945,6 +946,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
 }
 
 /* Drop host forwarding rule, return 0 if found. */
+/* TODO: IPv6 */
 int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
  int host_port)
 {
@@ -970,6 +972,7 @@ int slirp_remove_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return -1;
 }
 
+/* TODO: IPv6 */
 int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct in_addr host_addr,
   int host_port, struct in_addr guest_addr, int guest_port)
 {
@@ -988,6 +991,7 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp, struct 
in_addr host_addr,
 return 0;
 }
 
+/* TODO: IPv6 */
 static bool
 check_guestfwd(Slirp *slirp, struct in_addr *guest_addr, int guest_port)
 {
@@ -1065,6 +1069,7 @@ slirp_find_ctl_socket(Slirp *slirp, struct in_addr 
guest_addr, int guest_port)
 {
 struct socket *so;
 
+/* TODO: IPv6 */
 for (so = slirp->tcb.so_next; so != &slirp->tcb; so = so->so_next) {
 if (so->so_faddr.s_addr == guest_addr.s_addr &&
 htons(so->so_fport) == guest_port) {
diff --git a/slirp/socket.c b/slirp/socket.c
index 4dc5e2907d..f2428a3ae8 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -687,6 +687,7 @@ struct socket *
 tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
unsigned lport, int flags)
 {
+/* TODO: IPv6 */
struct sockaddr_in addr;
struct socket *so;
int s, opt = 1;
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 6749b32f5d..b10477fc57 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -388,6 +388,7 @@ findso:
 * as if it was LISTENING, and continue...
 */
 if (so == NULL) {
+  /* TODO: IPv6 */
   if (slirp->restricted) {
 /* Any hostfwds will have an existing socket, so we only get here
  * for non-hostfwd connections. These should be dropped, unless it
@@ -609,6 +610,7 @@ findso:
   * If this is destined for the control address, then flag to
   * tcp_ctl once connected, otherwise connect
   */
+  /* TODO: IPv6 */
  if (af == AF_INET &&
 (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 slirp->vnetwork_addr.s_addr) {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 1d7e72dca7..1db59caa89 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -626,6 +626,7 @@ tcp_emu(struct socket *so, struct mbuf *m)
switch(so->so_emu) {
int x, i;
 
+/* TODO: IPv6 */
 case EMU_IDENT:
/*
 * Identification protocol as per rfc-1413
@@ -964,6 +965,7 @@ int tcp_ctl(struct socket *so)
 DEBUG_CALL("tcp_ctl");
 DEBUG_ARG("so = %p", so);
 
+/* TODO: IPv6 */
 if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
 /* Check if it's pty_exec */
 fo

[Qemu-devel] [PULL 02/12] slirp: check for ioctlsocket error and 0-length udp payload.

2019-03-06 Thread Samuel Thibault
From: Vic Lee 

Sometimes sorecvfrom() is called from slirp.c because revents == G_IO_IN,
but there is 0 bytes available and recvfrom could be blocking indefinitely.
This is likely due to 0-length udp payload. This also adds an error
checking for ioctlsocket.

Signed-off-by: Vic Lee 
Message-Id: <20190301064809.3074-1-llyzs@gmail.com>
Signed-off-by: Samuel Thibault 
---
 slirp/socket.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/slirp/socket.c b/slirp/socket.c
index 4876ea3f31..4dc5e2907d 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -529,6 +529,15 @@ sorecvfrom(struct socket *so)
   int n;
 #endif
 
+ if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
+ DEBUG_MISC(" ioctlsocket errno = %d-%s\n",
+errno,strerror(errno));
+ return;
+ }
+ if (n == 0) {
+ return;
+ }
+
  m = m_get(so->slirp);
  if (!m) {
  return;
@@ -552,7 +561,6 @@ sorecvfrom(struct socket *so)
   */
  len = M_FREEROOM(m);
  /* if (so->so_fport != htons(53)) { */
- ioctlsocket(so->s, FIONREAD, &n);
 
  if (n > len) {
n = (m->m_data - m->m_dat) + m->m_len + n + 1;
-- 
2.20.1




[Qemu-devel] [PULL 08/12] slirp: use "slirp_" prefix for inet_aton() win32 implementation

2019-03-06 Thread Samuel Thibault
From: Marc-André Lureau 

To avoid conflict with QEMU inet_aton() implementation, let's use the
"slirp_" prefix. This allows to drop the WITH_QEMU, thus the source
won't make a distinction when building with QEMU or not.

Signed-off-by: Marc-André Lureau 
Message-Id: <20190212162524.31504-4-marcandre.lur...@redhat.com>
Signed-off-by: Samuel Thibault 
---
 slirp/Makefile.objs | 2 +-
 slirp/util.c| 4 ++--
 slirp/util.h| 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 69e140f965..e91daf0e91 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -33,4 +33,4 @@ slirp.mo-objs = \
vmstate.o \
$(NULL)
 
-slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\" -DWITH_QEMU
+slirp.mo-cflags = -DG_LOG_DOMAIN=\"Slirp\"
diff --git a/slirp/util.c b/slirp/util.c
index 1cbaa26b60..5ec2fa87ab 100644
--- a/slirp/util.c
+++ b/slirp/util.c
@@ -31,8 +31,8 @@
 #include 
 #include 
 
-#if defined(_WIN32) && !defined(WITH_QEMU)
-int inet_aton(const char *cp, struct in_addr *ia)
+#if defined(_WIN32)
+int slirp_inet_aton(const char *cp, struct in_addr *ia)
 {
 uint32_t addr = inet_addr(cp);
 if (addr == 0x) {
diff --git a/slirp/util.h b/slirp/util.h
index c4207a49d6..e94ee4e7f1 100644
--- a/slirp/util.h
+++ b/slirp/util.h
@@ -138,8 +138,8 @@ int slirp_getsockopt_wrap(int sockfd, int level, int 
optname,
 #define setsockopt slirp_setsockopt_wrap
 int slirp_setsockopt_wrap(int sockfd, int level, int optname,
   const void *optval, int optlen);
-
-int inet_aton(const char *cp, struct in_addr *ia);
+#define inet_aton slirp_inet_aton
+int slirp_inet_aton(const char *cp, struct in_addr *ia);
 #else
 #define closesocket(s) close(s)
 #define ioctlsocket(s, r, v) ioctl(s, r, v)
-- 
2.20.1




[Qemu-devel] [PULL 04/12] slirp: fix big/little endian conversion in ident protocol

2019-03-06 Thread Samuel Thibault
Signed-off-by: Samuel Thibault 
Reviewed-by: Philippe Mathieu-Daudé 

---
Based-on: <1551476756-25749-1-git-send-email-w...@wbowling.info>
---
 slirp/tcp_subr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index ef9d99c154..1d7e72dca7 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -660,10 +660,12 @@ tcp_emu(struct socket *so, struct mbuf *m)
tmpso->so_fport == n1) {
if 
(getsockname(tmpso->s,
(struct 
sockaddr *)&addr, &addrlen) == 0)
-  n2 = 
ntohs(addr.sin_port);
+  n2 = addr.sin_port;
break;
}
}
+   NTOHS(n1);
+   NTOHS(n2);
so_rcv->sb_cc = 
snprintf(so_rcv->sb_data,
 
so_rcv->sb_datalen,
 "%d,%d\r\n", 
n1, n2);
-- 
2.20.1




[Qemu-devel] [PULL 01/12] slirp: Fix build with gcc 9

2019-03-06 Thread Samuel Thibault
From: Greg Kurz 

Build fails with gcc 9:

  CC  slirp/ndp_table.o
slirp/ndp_table.c: In function ‘ndp_table_add’:
slirp/ndp_table.c:31:23: error: taking address of packed member of ‘struct 
ndpentry’ may result in an unaligned pointer value 
[-Werror=address-of-packed-member]
   31 | if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  |   ^~~~
slirp/ndp_table.c: In function ‘ndp_table_search’:
slirp/ndp_table.c:75:23: error: taking address of packed member of ‘struct 
ndpentry’ may result in an unaligned pointer value 
[-Werror=address-of-packed-member]
   75 | if (in6_equal(&ndp_table->table[i].ip_addr, &ip_addr)) {
  |   ^~~~
cc1: all warnings being treated as errors

The ndpentry structure isn't used to model on-the-wire data or anything
else that would care for the struct layout. It doesn't need to be packed
actually. Just drop SLIRP_PACKED.

Signed-off-by: Greg Kurz 
Message-Id: <155143315831.102868.17515265400523392682.st...@bahia.lan>
Reviewed-by: Peter Maydell 
Signed-off-by: Samuel Thibault 
---
 slirp/slirp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/slirp/slirp.h b/slirp/slirp.h
index 752a4cd8c8..8068ba1d1e 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -106,7 +106,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
 struct ndpentry {
 unsigned char   eth_addr[ETH_ALEN]; /* sender hardware address */
 struct in6_addr ip_addr;/* sender IP address   */
-} SLIRP_PACKED;
+};
 
 #define NDP_TABLE_SIZE 16
 
-- 
2.20.1




Re: [Qemu-devel] [PATCH 0/7] slirp: make it a standalone project

2019-03-06 Thread Samuel Thibault
Applied to my tree, thanks!



[Qemu-devel] [PATCHv2 2/2] curses: add option to specify VGA font encoding

2019-03-04 Thread Samuel Thibault
This uses iconv to convert glyphs from the specified VGA font encoding to
unicode, and makes use of cchar_t instead of chtype when using ncursesw,
which allows to store all wide char as well as the WACS values. The default
charset is made CP437 since that is the charset of the hardware default VGA
font. This also makes the curses backend set the LC_CTYPE locale to "" to
allow curses to emit wide characters.

Signed-off-by: Samuel Thibault 
Cc: Eddie Kohler 
---
 configure   |   5 +-
 qapi/ui.json|  14 +++
 qemu-options.hx |   5 +-
 ui/curses.c | 315 
 4 files changed, 290 insertions(+), 49 deletions(-)

diff --git a/configure b/configure
index 9979ca708d..1270dc8dc0 100755
--- a/configure
+++ b/configure
@@ -3449,14 +3449,17 @@ if test "$curses" != "no" ; then
 #include 
 #include 
 #include 
+#include 
 int main(void) {
+  const char *codeset;
   wchar_t wch = L'w';
   setlocale(LC_ALL, "");
   resize_term(0, 0);
   addwstr(L"wide chars\n");
   addnwstr(&wch, 1);
   add_wch(WACS_DEGREE);
-  return 0;
+  codeset = nl_langinfo(CODESET);
+  return codeset != 0;
 }
 EOF
   IFS=:
diff --git a/qapi/ui.json b/qapi/ui.json
index c5d1d7f099..59e412139a 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1080,6 +1080,19 @@
  { 'enum': 'DisplayGLMode',
'data': [ 'off', 'on', 'core', 'es' ] }
 
+##
+# @DisplayCurses:
+#
+# Curses display options.
+#
+# @charset:   Font charset used by guest (default: CP437).
+#
+# Since: 4.0
+#
+##
+{ 'struct'  : 'DisplayCurses',
+  'data': { '*charset'   : 'str' } }
+
 ##
 # @DisplayType:
 #
@@ -1142,6 +1155,7 @@
 '*gl': 'DisplayGLMode' },
   'discriminator' : 'type',
   'data': { 'gtk': 'DisplayGTK',
+'curses' : 'DisplayCurses',
 'egl-headless'   : 'DisplayEGLHeadless'} }
 
 ##
diff --git a/qemu-options.hx b/qemu-options.hx
index 1cf9aac1fe..4bc4e736bb 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1216,7 +1216,7 @@ DEF("display", HAS_ARG, QEMU_OPTION_display,
 "[,window_close=on|off][,gl=on|core|es|off]\n"
 "-display gtk[,grab_on_hover=on|off][,gl=on|off]|\n"
 "-display vnc=[,]\n"
-"-display curses\n"
+"-display curses[,charset=]\n"
 "-display none\n"
 "-display egl-headless[,rendernode=]"
 "select display type\n"
@@ -1248,6 +1248,9 @@ support a text mode, QEMU can display this output using a
 curses/ncurses interface. Nothing is displayed when the graphics
 device is in graphical mode or if the graphics device does not support
 a text mode. Generally only the VGA device models support text mode.
+The font charset used by the guest can be specified with the
+@code{charset} option, for example @code{charset=CP850} for IBM CP850
+encoding. The default is @code{CP437}.
 @item none
 Do not display video output. The guest will still see an emulated
 graphics card, but its output will not be displayed to the QEMU
diff --git a/ui/curses.c b/ui/curses.c
index 6861539b20..99eb026a9a 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -27,6 +27,10 @@
 #include 
 #include 
 #endif
+#include 
+#include 
+#include 
+#include 
 
 #include "qapi/error.h"
 #include "qemu-common.h"
@@ -54,25 +58,30 @@ static WINDOW *screenpad = NULL;
 static int width, height, gwidth, gheight, invalidate;
 static int px, py, sminx, sminy, smaxx, smaxy;
 
-static chtype vga_to_curses[256];
+static const char *font_charset = "CP437";
+static cchar_t vga_to_curses[256];
 
 static void curses_update(DisplayChangeListener *dcl,
   int x, int y, int w, int h)
 {
 console_ch_t *line;
-chtype curses_line[width];
+cchar_t curses_line[width];
 
 line = screen + y * width;
 for (h += y; y < h; y ++, line += width) {
 for (x = 0; x < width; x++) {
 chtype ch = line[x] & 0xff;
 chtype at = line[x] & ~0xff;
-if (vga_to_curses[ch]) {
-ch = vga_to_curses[ch];
+if (vga_to_curses[ch].chars[0]) {
+curses_line[x] = vga_to_curses[ch];
+} else {
+curses_line[x].chars[0] = ch;
+curses_line[x].chars[1] = 0;
+curses_line[x].attr = 0;
 }
-curses_line[x] = ch | at;
+curses_line[x].attr |= at;
 }
-mvwaddchnstr(screenpad, y, 0, curses_line, width);
+mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
 }
 
 pnoutrefresh(screenpad, py, px,

[Qemu-devel] [PATCHv2 0/2] curses: Add support for wide output

2019-03-04 Thread Samuel Thibault
Hello,

This adds support for wide output in the curses frontend

Difference with previous version:
- Add more rationale in commit message
- Move charset option to curses-only section.

Samuel Thibault (2):
  iconv: detect and make curses depend on it
  curses: add option to specify VGA font encoding

 configure   |  45 ++-
 qapi/ui.json|  14 +++
 qemu-options.hx |   5 +-
 ui/curses.c | 315 
 vl.c|   2 +-
 5 files changed, 331 insertions(+), 50 deletions(-)

-- 
2.20.1




[Qemu-devel] [PATCHv2 1/2] iconv: detect and make curses depend on it

2019-03-04 Thread Samuel Thibault
curses will use it for proper wide output support.

Signed-off-by: Samuel Thibault 
---
 configure | 40 
 vl.c  |  2 +-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 540bee19ba..9979ca708d 100755
--- a/configure
+++ b/configure
@@ -1217,6 +1217,10 @@ for opt do
   ;;
   --enable-curses) curses="yes"
   ;;
+  --disable-iconv) iconv="no"
+  ;;
+  --enable-iconv) iconv="yes"
+  ;;
   --disable-curl) curl="no"
   ;;
   --enable-curl) curl="yes"
@@ -1718,6 +1722,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   gtk gtk UI
   vte vte support for the gtk UI
   curses  curses UI
+  iconv   font glyph conversion support
   vnc VNC UI support
   vnc-saslSASL encryption for VNC server
   vnc-jpegJPEG lossy compression for VNC server
@@ -3398,8 +3403,39 @@ EOF
   fi
 fi
 
+##
+# iconv probe
+if test "$iconv" != "no" ; then
+  cat > $TMPC << EOF
+#include 
+int main(void) {
+  iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
+  return conv != (iconv_t) -1;
+}
+EOF
+  for iconv_lib in '' -liconv; do
+if compile_prog "" "$iconv_lib" ; then
+  iconv_found=yes
+  libs_softmmu="$iconv_lib $libs_softmmu"
+  break
+fi
+  done
+  if test "$iconv_found" = "yes" ; then
+iconv=yes
+  else
+if test "$iconv" = "yes" ; then
+  feature_not_found "iconv" "Install iconv devel"
+fi
+iconv=no
+  fi
+fi
+
 ##
 # curses probe
+if test "$iconv" = "no" ; then
+  # curses will need iconv
+  curses=no
+fi
 if test "$curses" != "no" ; then
   if test "$mingw32" = "yes" ; then
 curses_inc_list="$($pkg_config --cflags ncurses 2>/dev/null):"
@@ -6111,6 +6147,7 @@ echo "libgcrypt $gcrypt"
 echo "nettle$nettle $(echo_version $nettle $nettle_version)"
 echo "libtasn1  $tasn1"
 echo "PAM   $auth_pam"
+echo "iconv support $iconv"
 echo "curses support$curses"
 echo "virgl support $virglrenderer $(echo_version $virglrenderer 
$virgl_version)"
 echo "curl support  $curl"
@@ -6435,6 +6472,9 @@ fi
 if test "$cocoa" = "yes" ; then
   echo "CONFIG_COCOA=y" >> $config_host_mak
 fi
+if test "$iconv" = "yes" ; then
+  echo "CONFIG_ICONV=y" >> $config_host_mak
+fi
 if test "$curses" = "yes" ; then
   echo "CONFIG_CURSES=m" >> $config_host_mak
   echo "CURSES_CFLAGS=$curses_inc" >> $config_host_mak
diff --git a/vl.c b/vl.c
index 502857a176..c8594fc6d5 100644
--- a/vl.c
+++ b/vl.c
@@ -3171,7 +3171,7 @@ int main(int argc, char **argv, char **envp)
 #ifdef CONFIG_CURSES
 dpy.type = DISPLAY_TYPE_CURSES;
 #else
-error_report("curses support is disabled");
+error_report("curses or iconv support is disabled");
 exit(1);
 #endif
 break;
-- 
2.20.1




[Qemu-devel] [PATCH] curses: support wide input

2019-03-04 Thread Samuel Thibault
This makes use of wide curses functions instead of 8bit functions. This
allows to type e.g. accented letters.

Unfortunately, key codes are then returned with values that could be
confused with wide characters by ncurses, so we need to add a maybe_keycode
variable to know whether the returned value is a key code or a character
(curses with wide support), or possibly both (curses without wide support).

The translation tables thus also need to be separated into key code
translation and character translation.  The curses2foo helper makes it easier
to use them.

Signed-off-by: Samuel Thibault 
---
 ui/curses.c  |  76 +--
 ui/curses_keys.h | 113 +++
 2 files changed, 127 insertions(+), 62 deletions(-)

diff --git a/ui/curses.c b/ui/curses.c
index 6e0091c3b2..6861539b20 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -42,6 +42,12 @@
 #define FONT_HEIGHT 16
 #define FONT_WIDTH 8
 
+enum maybe_keycode {
+CURSES_KEYCODE,
+CURSES_CHAR,
+CURSES_CHAR_OR_KEYCODE,
+};
+
 static DisplayChangeListener *dcl;
 static console_ch_t screen[160 * 100];
 static WINDOW *screenpad = NULL;
@@ -194,9 +200,54 @@ static void curses_cursor_position(DisplayChangeListener 
*dcl,
 
 static kbd_layout_t *kbd_layout = NULL;
 
+static wint_t console_getch(enum maybe_keycode *maybe_keycode)
+{
+wint_t ret;
+switch (get_wch(&ret)) {
+case KEY_CODE_YES:
+*maybe_keycode = CURSES_KEYCODE;
+break;
+case OK:
+*maybe_keycode = CURSES_CHAR;
+break;
+case ERR:
+ret = -1;
+break;
+}
+return ret;
+}
+
+static int curses2foo(const int _curses2foo[], const int _curseskey2foo[],
+  int chr, enum maybe_keycode maybe_keycode)
+{
+int ret = -1;
+if (maybe_keycode == CURSES_CHAR) {
+if (chr < CURSES_CHARS) {
+ret = _curses2foo[chr];
+}
+} else {
+if (chr < CURSES_KEYS) {
+ret = _curseskey2foo[chr];
+}
+if (ret == -1 && maybe_keycode == CURSES_CHAR_OR_KEYCODE &&
+chr < CURSES_CHARS) {
+ret = _curses2foo[chr];
+}
+}
+return ret;
+}
+
+#define curses2keycode(chr, maybe_keycode) \
+curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
+#define curses2keysym(chr, maybe_keycode) \
+curses2foo(_curses2keysym, _curseskey2keysym, chr, maybe_keycode)
+#define curses2qemu(chr, maybe_keycode) \
+curses2foo(_curses2qemu, _curseskey2qemu, chr, maybe_keycode)
+
 static void curses_refresh(DisplayChangeListener *dcl)
 {
 int chr, keysym, keycode, keycode_alt;
+enum maybe_keycode maybe_keycode;
 
 curses_winch_check();
 
@@ -212,14 +263,14 @@ static void curses_refresh(DisplayChangeListener *dcl)
 
 while (1) {
 /* while there are any pending key strokes to process */
-chr = getch();
+chr = console_getch(&maybe_keycode);
 
-if (chr == ERR)
+if (chr == -1)
 break;
 
 #ifdef KEY_RESIZE
 /* this shouldn't occur when we use a custom SIGWINCH handler */
-if (chr == KEY_RESIZE) {
+if (maybe_keycode != CURSES_CHAR && chr == KEY_RESIZE) {
 clear();
 refresh();
 curses_calc_pad();
@@ -228,17 +279,19 @@ static void curses_refresh(DisplayChangeListener *dcl)
 }
 #endif
 
-keycode = curses2keycode[chr];
+keycode = curses2keycode(chr, maybe_keycode);
 keycode_alt = 0;
 
 /* alt key */
 if (keycode == 1) {
-int nextchr = getch();
+enum maybe_keycode next_maybe_keycode;
+int nextchr = console_getch(&next_maybe_keycode);
 
-if (nextchr != ERR) {
+if (nextchr != -1) {
 chr = nextchr;
+maybe_keycode = next_maybe_keycode;
 keycode_alt = ALT;
-keycode = curses2keycode[chr];
+keycode = curses2keycode(chr, maybe_keycode);
 
 if (keycode != -1) {
 keycode |= ALT;
@@ -258,9 +311,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
 }
 
 if (kbd_layout) {
-keysym = -1;
-if (chr < CURSES_KEYS)
-keysym = curses2keysym[chr];
+keysym = curses2keysym(chr, maybe_keycode);
 
 if (keysym == -1) {
 if (chr < ' ') {
@@ -326,10 +377,7 @@ static void curses_refresh(DisplayChangeListener *dcl)
 qemu_input_event_send_key_delay(0);
 }
 } else {
-keysym = -1;
-if (chr < CURSES_KEYS) {
-keysym = curses2qemu[chr];
-}
+keysym = curses2qemu(chr, maybe_keycode);
 if (keysym == -1)
 keysym = chr;
 
diff --git a/ui/curses_keys.h b/ui/curses_keys.h
index e9195a

<    1   2   3   4   5   6   7   8   9   10   >