commit 722d303fdc139f1275b68102250d583b955eef24 Author: Mark Glines Date: Fri Mar 27 08:53:02 2009 -0700 Stop using the "socket" opcode; add some inithash handling to the Socket PMC instead. diff --git a/examples/io/httpd.pir b/examples/io/httpd.pir index fe6a1c1..fbbb89d 100644 --- a/examples/io/httpd.pir +++ b/examples/io/httpd.pir @@ -98,7 +98,7 @@ The code was heavily hacked by bernhard and leo. .local pmc listener, work, fp .local pmc fp # read requested files from disk .local int port - .local pmc address + .local pmc address, socket_init_hash .local string host .local string buf, req, rep, temp .local string meth, url, file_content @@ -110,8 +110,13 @@ The code was heavily hacked by bernhard and leo. host = "localhost" port = 1234 + socket_init_hash = new 'Hash' # TODO provide sys/socket constants - listener = socket 2, 1, 6 # PF_INET, SOCK_STREAM, tcp + # PF_INET, SOCK_STREAM, tcp + socket_init_hash['family'] = 2 + socket_init_hash['type'] = 1 + socket_init_hash['protocol'] = 6 + listener = new 'Socket', socket_init_hash 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 88953ab..f736b9e 100644 --- a/include/parrot/io.h +++ b/include/parrot/io.h @@ -829,7 +829,10 @@ INTVAL Parrot_io_send(PARROT_INTERP, ARGMOD(PMC *pmc), ARGMOD(STRING *buf)) PARROT_EXPORT PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL -PMC * Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) +INTVAL Parrot_io_socket(PARROT_INTERP, + INTVAL fam, + INTVAL type, + INTVAL proto) __attribute__nonnull__(1); PARROT_EXPORT diff --git a/include/parrot/io_portable.h b/include/parrot/io_portable.h index f2c0808..2ab5cdf 100644 --- a/include/parrot/io_portable.h +++ b/include/parrot/io_portable.h @@ -152,6 +152,8 @@ size_t Parrot_io_write_portable(PARROT_INTERP, #define PIO_FLUSH(interp, pmc) Parrot_io_flush_portable((interp), (pmc)) #define PIO_GETBLKSIZE(handle) Parrot_io_getblksize_portable((handle)) +#define PIO_INVALID_HANDLE_VALUE NULL + #endif /* PARROT_IO_PORTABLE_H_GUARD */ /* diff --git a/include/parrot/io_unix.h b/include/parrot/io_unix.h index 4dd53cb..a00f578 100644 --- a/include/parrot/io_unix.h +++ b/include/parrot/io_unix.h @@ -220,7 +220,7 @@ PMC * Parrot_io_sockaddr_in(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port) PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL -PMC * Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) +INTVAL Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) __attribute__nonnull__(1); #define ASSERT_ARGS_Parrot_io_accept_unix __attribute__unused__ int _ASSERT_ARGS_CHECK = \ @@ -290,6 +290,8 @@ PMC * Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) #define PIO_ACCEPT(interp, pmc) \ Parrot_io_accept_unix((interp), (pmc)) +#define PIO_INVALID_HANDLE_VALUE -1 + #endif /* PARROT_IO_UNIX_H_GUARD */ /* diff --git a/include/parrot/io_win32.h b/include/parrot/io_win32.h index 96f943f..ad91773 100644 --- a/include/parrot/io_win32.h +++ b/include/parrot/io_win32.h @@ -199,7 +199,7 @@ PMC * Parrot_io_sockaddr_in(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port) PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL -PMC * Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) +INTVAL Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) __attribute__nonnull__(1); #define ASSERT_ARGS_Parrot_io_accept_win32 __attribute__unused__ int _ASSERT_ARGS_CHECK = \ @@ -267,6 +267,8 @@ PMC * Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) #define PIO_ACCEPT(interp, pmc) \ Parrot_io_accept_win32((interp), (pmc)) +#define PIO_INVALID_HANDLE_VALUE INVALID_HANDLE_VALUE + #endif /* PARROT_IO_WIN32_H_GUARD */ /* diff --git a/src/io/socket_api.c b/src/io/socket_api.c index fe25f94..1ab180f 100644 --- a/src/io/socket_api.c +++ b/src/io/socket_api.c @@ -69,7 +69,7 @@ Parrot_io_poll(PARROT_INTERP, ARGMOD(PMC *pmc), INTVAL which, INTVAL sec, INTVAL /* -=item C +=item C Creates and returns a socket using the specified address family, socket type, and protocol number. Check the returned PMC with a boolean test to see whether @@ -82,7 +82,7 @@ the socket was successfully created. PARROT_EXPORT PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL -PMC * +INTVAL Parrot_io_socket(PARROT_INTERP, INTVAL fam, INTVAL type, INTVAL proto) { ASSERT_ARGS(Parrot_io_socket) diff --git a/src/io/socket_unix.c b/src/io/socket_unix.c index db52817..41b993b 100644 --- a/src/io/socket_unix.c +++ b/src/io/socket_unix.c @@ -115,7 +115,7 @@ Parrot_io_sockaddr_in(PARROT_INTERP, ARGIN(STRING *addr), INTVAL port) /* -=item C +=item C Uses C to create a socket with the specified address family, socket type and protocol number. @@ -126,20 +126,17 @@ socket type and protocol number. PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL -PMC * +INTVAL Parrot_io_socket_unix(PARROT_INTERP, int fam, int type, int proto) { ASSERT_ARGS(Parrot_io_socket_unix) - int i; const int sock = socket(fam, type, proto); if (sock >= 0) { - PMC * io = Parrot_io_new_socket_pmc(interp, PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); - PARROT_SOCKET(io)->os_handle = sock; - setsockopt(PARROT_SOCKET(io)->os_handle, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); - SOCKADDR_REMOTE(io)->sin_family = fam; - return io; + int i = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); + return sock; } - return PMCNULL; + return PIO_INVALID_HANDLE_VALUE; } /* diff --git a/src/io/socket_win32.c b/src/io/socket_win32.c index 1f07d5b..b56c5a6 100644 --- a/src/io/socket_win32.c +++ b/src/io/socket_win32.c @@ -61,7 +61,7 @@ static void get_sockaddr_in(PARROT_INTERP, /* -=item C +=item C Uses C to create a socket with the specified address family, socket type and protocol number. @@ -72,20 +72,17 @@ socket type and protocol number. PARROT_WARN_UNUSED_RESULT PARROT_CAN_RETURN_NULL -PMC * +INTVAL Parrot_io_socket_win32(PARROT_INTERP, int fam, int type, int proto) { ASSERT_ARGS(Parrot_io_socket_win32) - int i; const int sock = socket(fam, type, proto); if (sock >= 0) { - PMC * io = Parrot_io_new_socket_pmc(interp, PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); - PARROT_SOCKET(io)->os_handle = (void*)sock; - setsockopt((int)PARROT_SOCKET(io)->os_handle, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); - SOCKADDR_REMOTE(io)->sin_family = fam; - return io; + int i = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof (i)); + return sock; } - return PMCNULL; + return PIO_INVALID_HANDLE_VALUE; } /* diff --git a/src/pmc/socket.pmc b/src/pmc/socket.pmc index 9f71c17..865945d 100644 --- a/src/pmc/socket.pmc +++ b/src/pmc/socket.pmc @@ -44,17 +44,71 @@ Initializes a newly created Socket object. data_struct->remote = PMCNULL; /* Initialize the os_handle to the platform-specific value for closed. */ -#ifdef PIO_OS_WIN32 - data_struct->os_handle = (PIOHANDLE)INVALID_HANDLE_VALUE; -#endif -#ifdef PIO_OS_UNIX - data_struct->os_handle = (PIOHANDLE)-1; -#endif -#ifdef PIO_OS_STDIO - data_struct->os_handle = (PIOHANDLE)NULL; -#endif + data_struct->os_handle = (PIOHANDLE)PIO_INVALID_HANDLE_VALUE; PObj_custom_mark_destroy_SETALL(SELF); + Parrot_io_set_flags(interp, SELF, PIO_F_SOCKET|PIO_F_READ|PIO_F_WRITE); + } + + +/* + +=item C + +Initializes a newly created Socket object with the specified parameters. + +=cut + +*/ + + VTABLE void init_pmc(PMC *initializer) { + const INTVAL arg_type = VTABLE_type(interp, initializer); + int domain = -1, type = -1, protocol = -1; + PMC *temp_value; + + SELF.init(); + switch (arg_type) { + case enum_class_FixedFloatArray: + case enum_class_ResizableFloatArray: + case enum_class_FixedIntegerArray: + case enum_class_ResizableIntegerArray: + if(VTABLE_get_integer(interp, initializer) >= 1) + domain = VTABLE_get_integer_keyed_int(interp, initializer, 0); + if(VTABLE_get_integer(interp, initializer) >= 2) + type = VTABLE_get_integer_keyed_int(interp, initializer, 1); + if(VTABLE_get_integer(interp, initializer) >= 3) + protocol = VTABLE_get_integer_keyed_int(interp, initializer, 2); + break; + + case enum_class_Hash: + /* "family" and "domain" are both common names for the first argument. */ + /* accept either one. */ + temp_value = VTABLE_get_pmc_keyed_str(interp, initializer, + string_from_literal(interp, "domain")); + if(!PMC_IS_NULL(temp_value)) + domain = VTABLE_get_integer(interp, temp_value); + temp_value = VTABLE_get_pmc_keyed_str(interp, initializer, + string_from_literal(interp, "family")); + if(!PMC_IS_NULL(temp_value)) + domain = VTABLE_get_integer(interp, temp_value); + + temp_value = VTABLE_get_pmc_keyed_str(interp, initializer, + string_from_literal(interp, "type")); + if(!PMC_IS_NULL(temp_value)) + type = VTABLE_get_integer(interp, temp_value); + + temp_value = VTABLE_get_pmc_keyed_str(interp, initializer, + string_from_literal(interp, "protocol")); + if(!PMC_IS_NULL(temp_value)) + protocol = VTABLE_get_integer(interp, temp_value); + break; + + default: + Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, + "Cannot parse arguments to Socket initializer."); + } + + PCCINVOKE(INTERP, SELF, "socket", INTVAL domain, INTVAL type, INTVAL protocol); } /* @@ -117,7 +171,10 @@ Free structures. METHOD close() { INTVAL status = 0; - close(PARROT_SOCKET(SELF)->os_handle); + if(PARROT_SOCKET(SELF)->os_handle != PIO_INVALID_HANDLE_VALUE) { + close(PARROT_SOCKET(SELF)->os_handle); + PARROT_SOCKET(SELF)->os_handle = PIO_INVALID_HANDLE_VALUE; + } RETURN(INTVAL status); } @@ -130,6 +187,21 @@ Free structures. =over 4 +=item C + +Create a socket with the specified parameters. + +=cut + +*/ + + METHOD socket(int domain, int type, int protocol) { + int sock = Parrot_io_socket(interp, domain, type, protocol); + PARROT_SOCKET(SELF)->os_handle = sock; + } + +/* + =item C Connects a socket object to an address.