1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
Author: Lubomir Rintel <lkundrak@v3.sk>
Subject: Add support for Abstract namespace sockets.
Bug-Debian: http://bugs.debian.org/490660
Bug-Debian: http://bugs.debian.org/329291
Origin: upstream, http://perl5.git.perl.org/perl.git/commit/99f13d4c3419e967e95c5ac6a3af61e9bb0fd3c0
Origin: upstream, http://perl5.git.perl.org/perl.git/commit/89904c08923161afd23c629d5c2c7472a09c16bb
trivially backported for 5.10.1 by Niko Tyni <ntyni@debian.org>
---
ext/Socket/Socket.xs | 33 ++++++++++++++++++++++++---------
ext/Socket/t/Socket.t | 14 ++++++++++++--
2 files changed, 36 insertions(+), 11 deletions(-)
diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 076297f..3522303 100644
--- a/ext/Socket/Socket.xs
+++ b/ext/Socket/Socket.xs
@@ -303,6 +303,7 @@ pack_sockaddr_un(pathname)
struct sockaddr_un sun_ad; /* fear using sun */
STRLEN len;
char * pathname_pv;
+ int addr_len;
Zero( &sun_ad, sizeof sun_ad, char );
sun_ad.sun_family = AF_UNIX;
@@ -336,7 +337,17 @@ pack_sockaddr_un(pathname)
Copy( pathname_pv, sun_ad.sun_path, len, char );
# endif
if (0) not_here("dummy");
- ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, sizeof sun_ad));
+ if (len > 1 && sun_ad.sun_path[0] == '\0') {
+ /* Linux-style abstract-namespace socket.
+ * The name is not a file name, but an array of arbitrary
+ * character, starting with \0 and possibly including \0s,
+ * therefore the length of the structure must denote the
+ * end of that character array */
+ addr_len = (void *)&sun_ad.sun_path - (void *)&sun_ad + len;
+ } else {
+ addr_len = sizeof sun_ad;
+ }
+ ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, addr_len));
#else
ST(0) = (SV *) not_here("pack_sockaddr_un");
#endif
@@ -352,7 +363,7 @@ unpack_sockaddr_un(sun_sv)
struct sockaddr_un addr;
STRLEN sockaddrlen;
char * sun_ad = SvPVbyte(sun_sv,sockaddrlen);
- char * e;
+ int addr_len;
# ifndef __linux__
/* On Linux sockaddrlen on sockets returned by accept, recvfrom,
getpeername and getsockname is not equal to sizeof(addr). */
@@ -371,13 +382,17 @@ unpack_sockaddr_un(sun_sv)
addr.sun_family,
AF_UNIX);
}
- e = (char*)addr.sun_path;
- /* On Linux, the name of abstract unix domain sockets begins
- * with a '\0', so allow this. */
- while ((*e || (e == addr.sun_path && e[1] && sockaddrlen > 1))
- && e < (char*)addr.sun_path + sizeof addr.sun_path)
- ++e;
- ST(0) = sv_2mortal(newSVpvn(addr.sun_path, e - (char*)addr.sun_path));
+
+ if (addr.sun_path[0] == '\0') {
+ /* Linux-style abstract socket address begins with a nul
+ * and can contain nuls. */
+ addr_len = (void *)&addr - (void *)&addr.sun_path + sockaddrlen;
+ } else {
+ for (addr_len = 0; addr.sun_path[addr_len]
+ && addr_len < sizeof addr.sun_path; addr_len++);
+ }
+
+ ST(0) = sv_2mortal(newSVpvn(addr.sun_path, addr_len));
#else
ST(0) = (SV *) not_here("unpack_sockaddr_un");
#endif
diff --git a/ext/Socket/t/Socket.t b/ext/Socket/t/Socket.t
index f707999..d1e7447 100755
--- a/ext/Socket/t/Socket.t
+++ b/ext/Socket/t/Socket.t
@@ -14,7 +14,7 @@ BEGIN {
use Socket qw(:all);
-print "1..17\n";
+print "1..18\n";
$has_echo = $^O ne 'MSWin32';
$alarmed = 0;
@@ -152,7 +152,7 @@ print (($@ =~ /^Bad arg length for Socket::sockaddr_family, length is 0, should
if ($^O eq 'linux') {
# see if we can handle abstract sockets
- my $test_abstract_socket = chr(0) . '/tmp/test-perl-socket';
+ my $test_abstract_socket = chr(0) . '/org/perl/hello'. chr(0) . 'world';
my $addr = sockaddr_un ($test_abstract_socket);
my ($path) = sockaddr_un ($addr);
if ($test_abstract_socket eq $path) {
@@ -163,7 +163,17 @@ if ($^O eq 'linux') {
print "# got <$path>\n";
print "not ok 17\n";
}
+
+ # see if we calculate the address structure length correctly
+ if (length ($test_abstract_socket) + 2 == length $addr) {
+ print "ok 18\n";
+ } else {
+ print "# got ".(length $addr)."\n";
+ print "not ok 18\n";
+ }
+
} else {
# doesn't have abstract socket support
print "ok 17 - skipped on this platform\n";
+ print "ok 18 - skipped on this platform\n";
}
--
tg: (daf8b46..) fixes/abstract-sockets (depends on: upstream)
|