diff --git a/examples/io/httpd.pir b/examples/io/httpd.pir index 3970d37..2def929 100644 --- a/examples/io/httpd.pir +++ b/examples/io/httpd.pir @@ -93,6 +93,7 @@ The code was heavily hacked by bernhard and leo. .include "stat.pasm" .include 'except_types.pasm' +.include 'socket.pasm' .sub main :main .local pmc listener, work, fp @@ -112,7 +113,7 @@ The code was heavily hacked by bernhard and leo. # TODO provide sys/socket constants listener = new 'Socket' - listener.'socket'(2, 1, 6) # PF_INET, SOCK_STREAM, tcp + listener.'socket'(.PIO_PF_INET, .PIO_SOCK_STREAM, .PIO_PROTO_TCP) # PF_INET, SOCK_STREAM, tcp unless listener goto ERR_NO_SOCKET # Pack a sockaddr_in structure with IP and port diff --git a/include/parrot/io.h b/include/parrot/io.h index 54fcaaf..03facfb 100644 --- a/include/parrot/io.h +++ b/include/parrot/io.h @@ -905,7 +905,35 @@ extern INTVAL PIO_stdio_getblksize(PIOHANDLE fd); #define PIOCTL_LINEBUF 1 #define PIOCTL_BLKBUF 2 +/* + * Enum definition of constants for Socket.socket. + * Happens to be same for corresponding values on Linux. Other implementations + * of socket API may have to map this values to system specific. + */ +/* &gen_from_enum(socket.pasm) */ +typedef enum { + PIO_PF_LOCAL = 0, + PIO_PF_UNIX = 1, + PIO_PF_INET = 2, + PIO_PF_INET6 = 3, + PIO_PF_MAX = 4 /* last elem */ +} Socket_Protocol_Family; + +typedef enum { + PIO_SOCK_STREAM = 1, + PIO_SOCK_DGRAM = 2, + PIO_SOCK_RAW = 3, + PIO_SOCK_RDM = 4, + PIO_SOCK_SEQPACKET = 5, + PIO_SOCK_PACKET = 10, +} Socket_Socket_Type; + +typedef enum { + PIO_PROTO_TCP = 6, + PIO_PROTO_UDP = 17, +} Socket_Protocol; +/* &end_gen */ #endif /* PARROT_IO_H_GUARD */ diff --git a/src/io/socket_unix.c b/src/io/socket_unix.c index 59f021f..b444e0c 100644 --- a/src/io/socket_unix.c +++ b/src/io/socket_unix.c @@ -114,6 +114,19 @@ Parrot_io_sockaddr_in(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port) # if PARROT_NET_DEVEL /* + * Mappping between PIO_PF_* constants and system-specific PF_* constants. + * + * Uses -1 for unsupported protocols. + */ + +static int pio_pf[PIO_PF_MAX+1] = { + PF_LOCAL, /* PIO_PF_LOCAL */ + PF_UNIX, /* PIO_PF_UNIX */ + PF_INET, /* PIO_PF_INET */ + PF_INET6, /* PIO_PF_INET6 */ +}; + +/* =item C @@ -131,6 +144,13 @@ Parrot_io_socket_unix(PARROT_INTERP, ARGIN(PMC *s), int fam, int type, int proto { ASSERT_ARGS(Parrot_io_socket_unix) int i = 1; + /* convert Parrot's family to system family */ + if (fam < 0 || fam >= PIO_PF_MAX) + return -1; + fam = pio_pf[fam]; + if (fam < 0) + return -1; + const int sock = socket(fam, type, proto); if (sock >= 0) { setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); diff --git a/src/io/socket_win32.c b/src/io/socket_win32.c index 6b1b13a..d93b7f3 100644 --- a/src/io/socket_win32.c +++ b/src/io/socket_win32.c @@ -60,6 +60,19 @@ static void get_sockaddr_in(PARROT_INTERP, PARROT_SOCKET((p))->remote)) /* + * Mappping between PIO_PF_* constants and system-specific PF_* constants. + * + * Uses -1 for unsupported protocols. + */ + +static int pio_pf[PIO_PF_MAX+1] = { + PF_LOCAL, /* PIO_PF_LOCAL */ + PF_UNIX, /* PIO_PF_UNIX */ + PF_INET, /* PIO_PF_INET */ + PF_INET6, /* PIO_PF_INET6 */ +}; + +/* =item C @@ -77,6 +90,13 @@ Parrot_io_socket_win32(PARROT_INTERP, ARGIN(PMC * s), int fam, int type, int pro { ASSERT_ARGS(Parrot_io_socket_win32) int i = 1; + /* convert Parrot's family to system family */ + if (fam < 0 || fam >= PIO_PF_MAX) + return -1; + fam = pio_pf[fam]; + if (fam < 0) + return -1; + const int sock = socket(fam, type, proto); if (sock >= 0) { setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&i, sizeof (i));