summaryrefslogtreecommitdiff
path: root/ext/Socket
diff options
context:
space:
mode:
authorLarry Wall <lwall@scalpel.netlabs.com>1995-11-21 10:01:00 +1200
committerLarry <lwall@scalpel.netlabs.com>1995-11-21 10:01:00 +1200
commit4633a7c4bad06b471d9310620b7fe8ddd158cccd (patch)
tree37ebeb26a64f123784fd8fac6243b124767243b0 /ext/Socket
parent8e07c86ebc651fe92eb7e3b25f801f57cfb8dd6f (diff)
downloadperl-4633a7c4bad06b471d9310620b7fe8ddd158cccd.tar.gz
5.002 beta 1
If you're adventurous, have a look at ftp://ftp.sems.com/pub/outgoing/perl5.0/perl5.002beta1.tar.gz Many thanks to Andy for doing the integration. Obviously, if you consult the bugs database, you'll note there are still plenty of buglets that need fixing, and several enhancements that I've intended to put in still haven't made it in (Hi, Tim and Ilya). But I think it'll be pretty stable. And you can start to fiddle around with prototypes (which are, of course, still totally undocumented). Packrats, don't worry too much about readvertising this widely. Nowadays we're on a T1 here, so our bandwidth is okay. Have the appropriate amount of jollity. Larry
Diffstat (limited to 'ext/Socket')
-rw-r--r--ext/Socket/Makefile.PL2
-rw-r--r--ext/Socket/Socket.pm118
-rw-r--r--ext/Socket/Socket.xs56
3 files changed, 147 insertions, 29 deletions
diff --git a/ext/Socket/Makefile.PL b/ext/Socket/Makefile.PL
index 414df14f22..2b3b08305a 100644
--- a/ext/Socket/Makefile.PL
+++ b/ext/Socket/Makefile.PL
@@ -1,2 +1,2 @@
use ExtUtils::MakeMaker;
-WriteMakefile();
+WriteMakefile(VERSION => 1.3);
diff --git a/ext/Socket/Socket.pm b/ext/Socket/Socket.pm
index 5a4b486a22..9c0f04ba0a 100644
--- a/ext/Socket/Socket.pm
+++ b/ext/Socket/Socket.pm
@@ -1,20 +1,39 @@
package Socket;
+$VERSION = 1.3;
=head1 NAME
-Socket - load the C socket.h defines and structure manipulators
+Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C
+ socket.h defines and structure manipulators
=head1 SYNOPSIS
use Socket;
- $proto = (getprotobyname('udp'))[2];
+ $proto = getprotobyname('udp');
socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
- $sockaddr_in = pack_sockaddr_in(AF_INET,7,inet_aton("localhost"));
- $sockaddr_in = pack_sockaddr_in(AF_INET,7,INADDR_LOOPBACK);
- connect(Socket_Handle,$sockaddr_in);
- $peer = inet_ntoa((unpack_sockaddr_in(getpeername(Socket_Handle)))[2]);
-
+ $iaddr = gethostbyname('hishost.com');
+ $port = getservbyname('time', 'udp');
+ $sin = sockaddr_in($port, $iaddr);
+ send(Socket_Handle, 0, 0, $sin);
+
+ $proto = getprotobyname('tcp');
+ socket(Socket_Handle, PF_INET, SOCK_STREAM, $proto);
+ $port = getservbyname('smtp');
+ $sin = sockaddr_in($port,inet_aton("127.1"));
+ $sin = sockaddr_in(7,inet_aton("localhost"));
+ $sin = sockaddr_in(7,INADDR_LOOPBACK);
+ connect(Socket_Handle,$sin);
+
+ ($port, $iaddr) = sockaddr_in(getpeername(Socket_Handle));
+ $peer_host = gethostbyaddr($iaddr, AF_INET);
+ $peer_addr = inet_ntoa($iaddr);
+
+ $proto = getprotobyname('tcp');
+ socket(Socket_Handle, PF_UNIX, SOCK_STREAM, $proto);
+ unlink('/tmp/usock');
+ $sun = sockaddr_un('/tmp/usock');
+ connect(Socket_Handle,$sun);
=head1 DESCRIPTION
@@ -22,7 +41,8 @@ This module is just a translation of the C F<socket.h> file.
Unlike the old mechanism of requiring a translated F<socket.ph>
file, this uses the B<h2xs> program (see the Perl source distribution)
and your native C compiler. This means that it has a
-far more likely chance of getting the numbers right.
+far more likely chance of getting the numbers right. This includes
+all of the commonly used pound-defines like AF_INET, SOCK_STREAM, etc.
In addition, some structure manipulation functions are available:
@@ -42,7 +62,7 @@ readable four dotted number notation for internet addresses).
=item INADDR_ANY
-Note - does not return a number.
+Note: does not return a number, but a packed string.
Returns the 4-byte wildcard ip address which specifies any
of the hosts ip addresses. (A particular machine can have
@@ -65,21 +85,52 @@ Note - does not return a number.
Returns the 4-byte invalid ip address. Normally equivalent
to inet_aton('255.255.255.255').
-=item pack_sockaddr_in FAMILY, PORT, IP_ADDRESS
+=item sockaddr_in PORT, ADDRESS
+
+=item sockaddr_in SOCKADDR_IN
+
+In an array context, unpacks its SOCKADDR_IN argument and returns an array
+consisting of (PORT, ADDRESS). In a scalar context, packs its (PORT,
+ADDRESS) arguments as a SOCKADDR_IN and returns it. If this is confusing,
+use pack_sockaddr_in() and unpack_sockaddr_in() explicitly.
+
+=item pack_sockaddr_in PORT, IP_ADDRESS
-Takes three arguments, an address family (normally AF_INET),
-a port number, and a 4 byte IP_ADDRESS (as returned by
-inet_aton()). Returns the sockaddr_in structure with those
-arguments packed in. For internet domain sockets, this structure
-is normally what you need for the arguments in bind(), connect(),
-and send(), and is also returned by getpeername(), getsockname()
-and recv().
+Takes two arguments, a port number and a 4 byte IP_ADDRESS (as returned by
+inet_aton()). Returns the sockaddr_in structure with those arguments
+packed in with AF_INET filled in. For internet domain sockets, this
+structure is normally what you need for the arguments in bind(),
+connect(), and send(), and is also returned by getpeername(),
+getsockname() and recv().
=item unpack_sockaddr_in SOCKADDR_IN
-Takes a sockaddr_in structure (as returned by pack_sockaddr_in())
-and returns an array of three elements: the address family,
-the port, and the 4-byte ip-address.
+Takes a sockaddr_in structure (as returned by pack_sockaddr_in()) and
+returns an array of two elements: the port and the 4-byte ip-address.
+Will croak if the structure does not have AF_INET in the right place.
+
+=item sockaddr_un PATHNAME
+
+=item sockaddr_un SOCKADDR_UN
+
+In an array context, unpacks its SOCKADDR_UN argument and returns an array
+consisting of (PATHNAME). In a scalar context, packs its PATHANE
+arguments as a SOCKADDR_UN and returns it. If this is confusing, use
+pack_sockaddr_un() and unpack_sockaddr_un() explicitly.
+
+=item pack_sockaddr_un PATH
+
+Takes one argument, a pathname. Returns the sockaddr_un structure with
+that path packed in with AF_UNIX filled in. For unix domain sockets, this
+structure is normally what you need for the arguments in bind(),
+connect(), and send(), and is also returned by getpeername(),
+getsockname() and recv().
+
+=item unpack_sockaddr_un SOCKADDR_UN
+
+Takes a sockaddr_un structure (as returned by pack_sockaddr_un())
+and returns the pathname. Will croak if the structure does not
+have AF_UNIX in the right place.
=cut
@@ -91,6 +142,8 @@ require DynaLoader;
@ISA = qw(Exporter DynaLoader);
@EXPORT = qw(
inet_aton inet_ntoa pack_sockaddr_in unpack_sockaddr_in
+ pack_sockaddr_un unpack_sockaddr_un
+ sockaddr_in sockaddr_un
INADDR_ANY INADDR_LOOPBACK INADDR_NONE
AF_802
AF_APPLETALK
@@ -171,6 +224,31 @@ require DynaLoader;
SO_USELOOPBACK
);
+sub sockaddr_in {
+ if (@_ == 6 && !wantarray) { # perl5.001m compat; use this && die
+ my($af, $port, @quad) = @_;
+ carp "6-ARG sockaddr_in call is deprecated" if $^W;
+ pack_sockaddr_in($port, inet_aton(join('.', @quad)));
+ } elsif (wantarray) {
+ croak "usage: (port,iaddr) = sockaddr_in(sin_sv)" unless @_ == 1;
+ unpack_sockaddr_in(@_);
+ } else {
+ croak "usage: sin_sv = sockaddr_in(port,iaddr))" unless @_ == 2;
+ pack_sockaddr_in(@_);
+ }
+}
+
+sub sockaddr_un {
+ if (wantarray) {
+ croak "usage: (filename) = sockaddr_un(sun_sv)" unless @_ == 1;
+ unpack_sockaddr_un(@_);
+ } else {
+ croak "usage: sun_sv = sockaddr_un(filename))" unless @_ == 1;
+ pack_sockaddr_in(@_);
+ }
+}
+
+
sub AUTOLOAD {
local($constname);
($constname = $AUTOLOAD) =~ s/.*:://;
diff --git a/ext/Socket/Socket.xs b/ext/Socket/Socket.xs
index 1f32dab79c..e799c81e89 100644
--- a/ext/Socket/Socket.xs
+++ b/ext/Socket/Socket.xs
@@ -7,6 +7,7 @@
# include <sys/types.h>
# endif
#include <sys/socket.h>
+#include <sys/un.h>
# ifdef I_NETINET_IN
# include <netinet/in.h>
# endif
@@ -627,8 +628,45 @@ inet_ntoa(ip_address_sv)
}
void
-pack_sockaddr_in(family,port,ip_address)
- short family
+pack_sockaddr_un(pathname)
+ char * pathname
+ CODE:
+ {
+ struct sockaddr_un sun_ad; /* fear using sun */
+ Zero( &sun_ad, sizeof sun_ad, char );
+ sun_ad.sun_family = AF_UNIX;
+ Copy( pathname, sun_ad.sun_path, sizeof sun_ad.sun_path, char );
+ ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
+ }
+
+void
+unpack_sockaddr_un(sun_sv)
+ SV * sun_sv
+ PPCODE:
+ {
+ STRLEN sockaddrlen;
+ struct sockaddr_un addr;
+ char * sun_ad = SvPV(sun_sv,sockaddrlen);
+
+ if (sockaddrlen != sizeof(addr)) {
+ croak("Bad arg length for %s, length is %d, should be %d",
+ "Socket::unpack_sockaddr_un",
+ sockaddrlen, sizeof(addr));
+ }
+
+ Copy( sun_ad, &addr, sizeof addr, char );
+
+ if ( addr.sun_family != AF_UNIX ) {
+ croak("Bad address family for %s, got %d, should be %d",
+ "Socket::unpack_sockaddr_un",
+ addr.sun_family,
+ AF_UNIX);
+ }
+ ST(0) = sv_2mortal(newSVpv(addr.sun_path, strlen(addr.sun_path)));
+ }
+
+void
+pack_sockaddr_in(port,ip_address)
short port
char * ip_address
CODE:
@@ -636,7 +674,7 @@ pack_sockaddr_in(family,port,ip_address)
struct sockaddr_in sin;
Zero( &sin, sizeof sin, char );
- sin.sin_family = family;
+ sin.sin_family = AF_INET;
sin.sin_port = htons(port);
Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
@@ -650,7 +688,6 @@ unpack_sockaddr_in(sin_sv)
{
STRLEN sockaddrlen;
struct sockaddr_in addr;
- short family;
short port;
struct in_addr ip_address;
char * sin = SvPV(sin_sv,sockaddrlen);
@@ -659,14 +696,17 @@ unpack_sockaddr_in(sin_sv)
"Socket::unpack_sockaddr_in",
sockaddrlen, sizeof(addr));
}
-
Copy( sin, &addr,sizeof addr, char );
- family = addr.sin_family;
+ if ( addr.sin_family != AF_INET ) {
+ croak("Bad address family for %s, got %d, should be %d",
+ "Socket::unpack_sockaddr_in",
+ addr.sin_family,
+ AF_INET);
+ }
port = ntohs(addr.sin_port);
ip_address = addr.sin_addr;
- EXTEND(sp, 3);
- PUSHs(sv_2mortal(newSViv(family)));
+ EXTEND(sp, 2);
PUSHs(sv_2mortal(newSViv(port)));
PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
}