0 | |
From: Apollon Oikonomopoulos <apoikos@debian.org>
|
1 | |
Date: Wed, 23 Sep 2020 23:33:46 +0300
|
2 | |
Subject: testserv: fix endianness issue
|
3 | |
|
4 | |
Building beanstalkd on big-endian systems (such as s390x, ppc64 and
|
5 | |
spart64) currently fails on the test phase, indicating an error in
|
6 | |
mustforksrv(). Digging a bit deeper, it turns out this is a type-casting
|
7 | |
issue between size_t (unsigned long int) and socklen_t (unsigned int):
|
8 | |
on these systems, size_t is 8 bytes, while socklen_t is only 4. These
|
9 | |
being big-endian systems, actually casting a (size_t *) pointer as
|
10 | |
(socklen_t *) will set the 4 most significant bytes, rather the
|
11 | |
least-significant ones, leading to unexpected results.
|
12 | |
|
13 | |
To better illustrate this, on s390x this code:
|
14 | |
|
15 | |
size_t sz = 0;
|
16 | |
*(socklen_t *)&sz = 4;
|
17 | |
printf("*(socklen_t *)&sz = %d, sz = %ld\n", *(socklen_t *)&sz, sz);
|
18 | |
|
19 | |
produces the following output:
|
20 | |
|
21 | |
*(socklen_t *)&sz = 4, sz = 17179869184
|
22 | |
|
23 | |
where 17179869184 = 4 << 32
|
24 | |
|
25 | |
Fix this by avoiding the cast from size_to to sockaddr_t altogether.
|
26 | |
---
|
27 | |
testserv.c | 4 ++--
|
28 | |
1 file changed, 2 insertions(+), 2 deletions(-)
|
29 | |
|
30 | |
diff --git a/testserv.c b/testserv.c
|
31 | |
index 449345f..911951d 100644
|
32 | |
--- a/testserv.c
|
33 | |
+++ b/testserv.c
|
34 | |
@@ -191,8 +191,8 @@ mustforksrv(void)
|
35 | |
exit(1);
|
36 | |
}
|
37 | |
|
38 | |
- size_t len = sizeof(addr);
|
39 | |
- int r = getsockname(srv.sock.fd, (struct sockaddr *)&addr, (socklen_t *)&len);
|
40 | |
+ socklen_t len = sizeof(addr);
|
41 | |
+ int r = getsockname(srv.sock.fd, (struct sockaddr *)&addr, &len);
|
42 | |
if (r == -1 || len > sizeof(addr)) {
|
43 | |
puts("mustforksrv failed");
|
44 | |
exit(1);
|