summaryrefslogtreecommitdiff
path: root/ext/Socket
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2009-08-25 17:09:53 +0200
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2009-08-26 11:53:01 +0200
commit99f13d4c3419e967e95c5ac6a3af61e9bb0fd3c0 (patch)
tree5fedd2c1612b3a21f5a0945b138998ce73c0d4fc /ext/Socket
parent289d61c2fe0a9a435b7e5828a3fbe9df5967f4d9 (diff)
downloadperl-99f13d4c3419e967e95c5ac6a3af61e9bb0fd3c0.tar.gz
Add support for Abstract namespace sockets
Abstract namespace sockets are Linux-specific socket type that live in AF_UNIX family, slightly abusing it to be able to use arbitrary character arrays as addresses: They start with nul byte and are not terminated by nul byte, but with the length passed to the socket() system call. Added regression test for the correct address length computation. Signed-off-by: Lubomir Rintel <lkundrak@fedoraproject.org>
Diffstat (limited to 'ext/Socket')
-rw-r--r--ext/Socket/Socket.xs13
-rw-r--r--ext/Socket/t/Socket.t20
2 files changed, 27 insertions, 6 deletions
diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 75d0f33870..d46a6b9892 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
diff --git a/ext/Socket/t/Socket.t b/ext/Socket/t/Socket.t
index aeeb2a0352..09d25f9b95 100644
--- a/ext/Socket/t/Socket.t
+++ b/ext/Socket/t/Socket.t
@@ -14,7 +14,7 @@ BEGIN {
use Socket qw(:all);
-print "1..20\n";
+print "1..21\n";
$has_echo = $^O ne 'MSWin32';
$alarmed = 0;
@@ -163,16 +163,26 @@ 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";
}
if($Config{d_inetntop} && $Config{d_inetaton}){
- print ((inet_ntop(AF_INET, inet_pton(AF_INET, "10.20.30.40")) eq "10.20.30.40") ? "ok 18\n" : "not ok 18\n");
- print ((inet_ntop(AF_INET, inet_aton("10.20.30.40")) eq "10.20.30.40") ? "ok 19\n" : "not ok 19\n");
- print (lc(inet_ntop(AF_INET6, inet_pton(AF_INET6, "2001:503:BA3E::2:30")) eq "2001:503:ba3e::2:30") ? "ok 20\n" : "not ok 20\n");
+ print ((inet_ntop(AF_INET, inet_pton(AF_INET, "10.20.30.40")) eq "10.20.30.40") ? "ok 19\n" : "not ok 19\n");
+ print ((inet_ntop(AF_INET, inet_aton("10.20.30.40")) eq "10.20.30.40") ? "ok 20\n" : "not ok 20\n");
+ print (lc(inet_ntop(AF_INET6, inet_pton(AF_INET6, "2001:503:BA3E::2:30")) eq "2001:503:ba3e::2:30") ? "ok 21\n" : "not ok 21\n");
} else {
# no IPv6
- print "ok $_ - skipped on this platform\n" for 18 .. 20;
+ print "ok $_ - skipped on this platform\n" for 19 .. 21;
}