From ctian at common-lisp.net Fri Apr 1 08:05:39 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 04:05:39 -0400
Subject: [usocket-cvs] r628 - usocket/branches/0.5.x
Message-ID:
Author: ctian
Date: Fri Apr 1 04:05:38 2011
New Revision: 628
Log:
Update ChangeLog
Modified:
usocket/branches/0.5.x/CHANGES
Modified: usocket/branches/0.5.x/CHANGES
==============================================================================
--- usocket/branches/0.5.x/CHANGES (original)
+++ usocket/branches/0.5.x/CHANGES Fri Apr 1 04:05:38 2011
@@ -8,6 +8,9 @@
0.5.1:
+* New feature: [CLISP] add UDP (Datagram) support based on FFI, no RAWSOCK needed.
+* Enhancement: SOCKET-SERVER return a second value (socket) when calling in new-thread mode.
+* Enhancement: [CLISP] Full support of DNS helper functions (GET-HOST-BY-NAME, ...) added.
* Bugfix: Fixed wrong macro expansions of {IP|PORT}-{FROM|TO}-OCTET-BUFFER functions!
* Bugfix: SOCKET-CONNECT didn't set CONNECTED-P for datagram usockets on most backends.
* Bugfix: [SBCL] Fixes for "SBCL/Win32: finalizer problem, etc", by Anton Kovalenko
@@ -15,12 +18,9 @@
* Bugfix: [SBCL] SOCKET-CONNECT's TIMEOUT argument now works as a "connection timeout".
* Bugfix: [CMUCL] Fixed SOCKET-SEND on unconnected usockets under Unicode version of CMUCL.
* Bugfix: [LispWorks] Better network error type detection on LispWorks.
-* Bugfix: [CLISP] Fixed UDP (Datagram) support (RAWSOCK version), confirmed by CL-NET-SNMP.
-* Enhancement: SOCKET-SERVER return a second value (socket) when calling in new-thread mode.
-* Enhancement: [CLISP] Full support of DNS helper functions (GET-HOST-BY-NAME, ...) added.
+* Bugfix: [CLISP] Fixed and confirmed UDP (Datagram) support (RAWSOCK version).
[TODO]
-* New feature: CLISP support UDP without RAWSOCK (using FFI interface)
* New feature: CLISP support some advanced TCP features which CLISP's SOCKET interface not provide
* New feature: Macintosh Common Lisp (MCL) support Datagram sockets (UDP)
From ctian at common-lisp.net Fri Apr 1 08:45:48 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 04:45:48 -0400
Subject: [usocket-cvs] r629 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Fri Apr 1 04:45:48 2011
New Revision: 629
Log:
[CLISP] SOCKET-RECEIVE (RAWSOCK version) returns reduced buffer when calling with a NIL buffer argument.
Modified:
usocket/branches/0.5.x/backend/clisp.lisp
Modified: usocket/branches/0.5.x/backend/clisp.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/clisp.lisp (original)
+++ usocket/branches/0.5.x/backend/clisp.lisp Fri Apr 1 04:45:48 2011
@@ -237,15 +237,19 @@
(sockaddr (rawsock:make-sockaddr :inet))
(real-length (or length +max-datagram-packet-size+))
(real-buffer (or buffer
- (make-array real-length :element-type '(unsigned-byte 8))))
- (rv (rawsock:recvfrom sock real-buffer sockaddr
+ (make-array real-length
+ :element-type '(unsigned-byte 8)))))
+ (let ((rv (rawsock:recvfrom sock real-buffer sockaddr
:start 0 :end real-length))
- (host 0) (port 0))
- (unless (connected-p socket)
- (let ((data (rawsock:sockaddr-data sockaddr)))
- (setq host (ip-from-octet-buffer data :start 4)
- port (port-from-octet-buffer data :start 2))))
- (values real-buffer rv host port)))
+ (host 0) (port 0))
+ (unless (connected-p socket)
+ (let ((data (rawsock:sockaddr-data sockaddr)))
+ (setq host (ip-from-octet-buffer data :start 4)
+ port (port-from-octet-buffer data :start 2))))
+ (values (if buffer real-buffer (subseq real-buffer 0 rv))
+ rv
+ host
+ port))))
(defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
"Returns the number of octets sent."
From ctian at common-lisp.net Fri Apr 1 10:33:17 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 06:33:17 -0400
Subject: [usocket-cvs] r630 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Fri Apr 1 06:33:17 2011
New Revision: 630
Log:
[CLISP] rewrite error handling facility.
Modified:
usocket/branches/0.5.x/backend/clisp.lisp
Modified: usocket/branches/0.5.x/backend/clisp.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/clisp.lisp (original)
+++ usocket/branches/0.5.x/backend/clisp.lisp Fri Apr 1 06:33:17 2011
@@ -44,35 +44,74 @@
(mapcar #'host-to-vector-quad
(posix:hostent-addr-list hostent)))))
-#+win32
-(defun remap-maybe-for-win32 (z)
- (mapcar #'(lambda (x)
- (cons (mapcar #'(lambda (y)
- (+ 10000 y))
- (car x))
- (cdr x)))
- z))
-
+;; Format: ((UNIX Windows) . CONDITION)
(defparameter +clisp-error-map+
- #+win32
- (append (remap-maybe-for-win32 +unix-errno-condition-map+)
- (remap-maybe-for-win32 +unix-errno-error-map+))
#-win32
- (append +unix-errno-condition-map+
- +unix-errno-error-map+))
+ `((:EADDRINUSE . address-in-use-error)
+ (:EADDRNOTAVAIL . address-not-available-error)
+ (:EBADF . bad-file-descriptor-error)
+ (:ECONNREFUSED . connection-refused-error)
+ (:ECONNRESET . connection-reset-error)
+ (:ECONNABORTED . connection-aborted-error)
+ (:EINVAL . invalid-argument-error)
+ (:ENOBUFS . no-buffers-error)
+ (:ENOMEM . out-of-memory-error)
+ (:ENOTSUP . operation-not-supported-error)
+ (:EPERM . operation-not-permitted-error)
+ (:EPROTONOSUPPORT . protocol-not-supported-error)
+ (:ESOCKTNOSUPPORT . socket-type-not-supported-error)
+ (:ENETUNREACH . network-unreachable-error)
+ (:ENETDOWN . network-down-error)
+ (:ENETRESET . network-reset-error)
+ (:ESHUTDOWN . already-shutdown-error)
+ (:ETIMEDOUT . timeout-error)
+ (:EHOSTDOWN . host-down-error)
+ (:EHOSTUNREACH . host-unreachable-error))
+ #+win32
+ `((:WSAEADDRINUSE . address-in-use-error)
+ (:WSAEADDRNOTAVAIL . address-not-available-error)
+ (:WSAEBADF . bad-file-descriptor-error)
+ (:WSAECONNREFUSED . connection-refused-error)
+ (:WSAECONNRESET . connection-reset-error)
+ (:WSAECONNABORTED . connection-aborted-error)
+ (:WSAEINVAL . invalid-argument-error)
+ (:WSAENOBUFS . no-buffers-error)
+ (:WSAENOMEM . out-of-memory-error)
+ (:WSAENOTSUP . operation-not-supported-error)
+ (:WSAEPERM . operation-not-permitted-error)
+ (:WSAEPROTONOSUPPORT . protocol-not-supported-error)
+ (:WSAESOCKTNOSUPPORT . socket-type-not-supported-error)
+ (:WSAENETUNREACH . network-unreachable-error)
+ (:WSAENETDOWN . network-down-error)
+ (:WSAENETRESET . network-reset-error)
+ (:WSAESHUTDOWN . already-shutdown-error)
+ (:WSAETIMEDOUT . timeout-error)
+ (:WSAEHOSTDOWN . host-down-error)
+ (:WSAEHOSTUNREACH . host-unreachable-error)))
(defun handle-condition (condition &optional (socket nil))
"Dispatch correct usocket condition."
- (typecase condition
- (system::simple-os-error
- (let ((usock-err
- (cdr (assoc (car (simple-condition-format-arguments condition))
- +clisp-error-map+ :test #'member))))
- (when usock-err ;; don't claim the error if we don't know
- ;; it's actually a socket error ...
- (if (subtypep usock-err 'error)
- (error usock-err :socket socket)
- (signal usock-err :socket socket)))))))
+ (let (error-keyword error-string)
+ (typecase condition
+ (system::simple-os-error
+ (let ((errno (car (simple-condition-format-arguments condition))))
+ (setq error-keyword (os:errno errno)
+ error-string (os:strerror errno))))
+ (simple-error
+ (let ((keyword
+ (car (simple-condition-format-arguments condition))))
+ (setq error-keyword keyword
+ error-string (os:strerror keyword))))
+ (error (error 'unknown-error :real-error condition))
+ (condition (signal 'unknown-condition :real-condition condition)))
+ (when error-keyword
+ (let ((usocket-error
+ (cdr (assoc error-keyword +clisp-error-map+ :test #'eq))))
+ (if usocket-error
+ (if (subtypep usocket-error 'error)
+ (error usocket-error :socket socket)
+ (signal usocket-error :socket socket))
+ (error "Unknown OS error: ~A (~A)" error-string error-keyword))))))
(defun socket-connect (host port &key (protocol :stream) (element-type 'character)
timeout deadline (nodelay t nodelay-specified)
@@ -505,14 +544,19 @@
(rsock_addr (when remote-host
(fill-sockaddr_in (ffi:allocate-shallow 'sockaddr_in)
remote-host (or remote-port local-port)))))
+ (unless (plusp sock)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (socket): ~A" (os:errno)))
(unwind-protect
- (progn
- (%bind sock (ffi:cast (ffi:foreign-value lsock_addr) 'sockaddr)
- *length-of-sockaddr_in*)
+ (let ((rv (%bind sock (ffi:cast (ffi:foreign-value lsock_addr) 'sockaddr)
+ *length-of-sockaddr_in*)))
+ (unless (zerop rv)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (bind): ~A" (os:errno)))
(when rsock_addr
- (%connect sock
- (ffi:cast (ffi:foreign-value rsock_addr) 'sockaddr)
- *length-of-sockaddr_in*)))
+ (let ((rv (%connect sock
+ (ffi:cast (ffi:foreign-value rsock_addr) 'sockaddr)
+ *length-of-sockaddr_in*)))
+ (unless (zerop rv)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (connect): ~A" (os:errno))))))
(ffi:foreign-free lsock_addr)
(when remote-host
(ffi:foreign-free rsock_addr)))
@@ -549,6 +593,8 @@
0 ; flags
(ffi:cast (ffi:foreign-value remote-address) 'sockaddr)
(ffi:foreign-value remote-address-length))
+ (when (minusp n)
+ (error "SOCKET-RECEIVE ERROR: ~A" (os:errno)))
(setq nbytes n)
(when (= address-length *length-of-sockaddr_in*)
(let ((data (sockaddr-sa_data address)))
@@ -561,8 +607,7 @@
(end-2 (min n +max-datagram-packet-size+)))
(replace buffer return-buffer :end1 end-1 :end2 end-2))
(setq buffer (subseq return-buffer 0 (min n +max-datagram-packet-size+))))))
- ((zerop n)) ; do nothing
- (t))) ; TODO: handle error here.
+ ((zerop n))))
(ffi:foreign-free remote-address)
(ffi:foreign-free remote-address-length))
(values buffer nbytes host port)))
@@ -583,23 +628,25 @@
(ffi:allocate-deep 'ffi:uint8 (subseq buffer 0 length) :count length :read-only t)
;; then we allocate the whole buffer directly, that should be faster.
(ffi:allocate-deep 'ffi:uint8 buffer :count (length buffer) :read-only t))))
- nbytes)
+ (real-length (min length +max-datagram-packet-size+))
+ (nbytes 0))
(unwind-protect
(let ((n (if remote-address
(%sendto (socket usocket)
(ffi:foreign-address send-buffer)
- (min length +max-datagram-packet-size+) 0
+ real-length
+ 0 ; flags
(ffi:cast (ffi:foreign-value remote-address) 'sockaddr)
*length-of-sockaddr_in*)
(%send (socket usocket)
- ;; (ffi:cast (ffi:foreign-value send-buffer) 'ffi:c-pointer)
(ffi:foreign-address send-buffer)
- (min length +max-datagram-packet-size+) 0))))
+ real-length
+ 0))))
(cond ((plusp n)
(setq nbytes n))
((zerop n)
(setq nbytes n))
- (t))) ; TODO: error handling
+ (t (error "SOCKET-SEND ERROR: ~A" (os:errno)))))
(ffi:foreign-free send-buffer)
(when remote-address
(ffi:foreign-free remote-address))
@@ -621,7 +668,7 @@
(let ((data (sockaddr-sa_data return-address)))
(setq host (ip-from-octet-buffer data :start 2)
port (port-from-octet-buffer data)))
- (error "get-socket-name error"))) ; TODO: convert this
+ (error "GET-SOCKET-NAME ERROR: ~A" (os:errno))))
(ffi:foreign-free address)
(ffi:foreign-free address-length))
(values (hbo-to-vector-quad host) port)))
From ctian at common-lisp.net Fri Apr 1 10:51:57 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 06:51:57 -0400
Subject: [usocket-cvs] r631 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Fri Apr 1 06:51:57 2011
New Revision: 631
Log:
[CLISP, LW] Use IP_PROTO_UCP when doing socket() system call.
Modified:
usocket/branches/0.5.x/backend/clisp.lisp
usocket/branches/0.5.x/backend/lispworks.lisp
Modified: usocket/branches/0.5.x/backend/clisp.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/clisp.lisp (original)
+++ usocket/branches/0.5.x/backend/clisp.lisp Fri Apr 1 06:51:57 2011
@@ -520,6 +520,8 @@
;; socket constants
(defconstant +socket-af-inet+ 2)
(defconstant +socket-sock-dgram+ 2)
+ (defconstant +socket-ip-proto-udp+ 17)
+
(defconstant +sockopt-so-rcvtimeo+ #-linux #x1006 #+linux 20 "Socket receive timeout")
(defvar *length-of-sockaddr_in* (ffi:sizeof 'sockaddr_in))
@@ -538,7 +540,7 @@
&key (local-host *wildcard-host*)
remote-host
remote-port)
- (let ((sock (%socket +socket-af-inet+ +socket-sock-dgram+ 0))
+ (let ((sock (%socket +socket-af-inet+ +socket-sock-dgram+ +socket-ip-proto-udp+))
(lsock_addr (fill-sockaddr_in (ffi:allocate-shallow 'sockaddr_in)
local-host local-port))
(rsock_addr (when remote-host
Modified: usocket/branches/0.5.x/backend/lispworks.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/lispworks.lisp (original)
+++ usocket/branches/0.5.x/backend/lispworks.lisp Fri Apr 1 06:51:57 2011
@@ -81,6 +81,8 @@
(defconstant *socket_sock_dgram* 2
"Connectionless, unreliable datagrams of fixed maximum length.")
+(defconstant *socket_ip_proto_udp* 17)
+
(defconstant *sockopt_so_rcvtimeo*
#-linux #x1006
#+linux 20
@@ -186,7 +188,7 @@
"Open a unconnected UDP socket.
For binding on address ANY(*), just not set LOCAL-ADDRESS (NIL),
for binding on random free unused port, set LOCAL-PORT to 0."
- (let ((socket-fd (comm::socket comm::*socket_af_inet* *socket_sock_dgram* comm::*socket_pf_unspec*)))
+ (let ((socket-fd (comm::socket comm::*socket_af_inet* *socket_sock_dgram* *socket_ip_proto_udp*)))
(if socket-fd
(progn
(when read-timeout (set-socket-receive-timeout socket-fd read-timeout))
From ctian at common-lisp.net Fri Apr 1 11:54:03 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 07:54:03 -0400
Subject: [usocket-cvs] r632 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Fri Apr 1 07:54:02 2011
New Revision: 632
Log:
[CLISP] Serious FFI fixes for Linux, confirmed by CL-NET-SNMP.
Modified:
usocket/branches/0.5.x/backend/clisp.lisp
Modified: usocket/branches/0.5.x/backend/clisp.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/clisp.lisp (original)
+++ usocket/branches/0.5.x/backend/clisp.lisp Fri Apr 1 07:54:02 2011
@@ -342,23 +342,22 @@
#+(and ffi (not rawsock))
(progn
;; C primitive types
- (ffi:def-c-type size_t)
- (ffi:def-c-type in_addr_t ffi:uint32)
- (ffi:def-c-type in_port_t ffi:uint16)
- (ffi:def-c-type sa_family_t ffi:uint8)
- (ffi:def-c-type socklen_t ffi:uint32)
+ (ffi:def-c-type socklen_t ffi:uint32)
;; C structures
(ffi:def-c-struct sockaddr
- (sa_len ffi:uint8)
- (sa_family sa_family_t)
+ #+macos (sa_len ffi:uint8)
+ (sa_family #-macos ffi:ushort
+ #+macos ffi:uint8)
(sa_data (ffi:c-array ffi:char 14)))
(ffi:def-c-struct sockaddr_in
- (sin_len ffi:uint8)
- (sin_family sa_family_t)
- (sin_port in_port_t)
- (sin_addr in_addr_t) ; should be struct in_addr
+ #+macos (sin_len ffi:uint8)
+ (sin_family #-macos ffi:short
+ #+macos ffi:uint8)
+ (sin_port #-macos ffi:ushort
+ #+macos ffi:uint16)
+ (sin_addr ffi:uint32)
(sin_zero (ffi:c-array ffi:char 8)))
(ffi:def-c-struct timeval
@@ -524,14 +523,15 @@
(defconstant +sockopt-so-rcvtimeo+ #-linux #x1006 #+linux 20 "Socket receive timeout")
- (defvar *length-of-sockaddr_in* (ffi:sizeof 'sockaddr_in))
+ (defparameter *length-of-sockaddr_in* (ffi:sizeof 'sockaddr_in))
(declaim (inline fill-sockaddr_in))
(defun fill-sockaddr_in (sockaddr host port)
(let ((hbo (host-to-hbo host)))
(ffi:with-c-place (place sockaddr)
- (setf (ffi:slot place 'sin_len) *length-of-sockaddr_in*
- (ffi:slot place 'sin_family) +socket-af-inet+
+ #+macos
+ (setf (ffi:slot place 'sin_len) *length-of-sockaddr_in*)
+ (setf (ffi:slot place 'sin_family) +socket-af-inet+
(ffi:slot place 'sin_port) (%htons port)
(ffi:slot place 'sin_addr) (%htonl hbo)))
sockaddr))
From ctian at common-lisp.net Fri Apr 1 12:06:28 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 08:06:28 -0400
Subject: [usocket-cvs] r633 - usocket/branches/0.5.x
Message-ID:
Author: ctian
Date: Fri Apr 1 08:06:23 2011
New Revision: 633
Log:
Update ChangeLog, prepare for 0.5.1 release
Modified:
usocket/branches/0.5.x/CHANGES
usocket/branches/0.5.x/README
usocket/branches/0.5.x/usocket-test.asd
usocket/branches/0.5.x/usocket.asd
Modified: usocket/branches/0.5.x/CHANGES
==============================================================================
--- usocket/branches/0.5.x/CHANGES (original)
+++ usocket/branches/0.5.x/CHANGES Fri Apr 1 08:06:23 2011
@@ -8,16 +8,17 @@
0.5.1:
-* New feature: [CLISP] add UDP (Datagram) support based on FFI, no RAWSOCK needed.
+* New feature: [CLISP] UDP (Datagram) support based on FFI (Win/Mac/Linux), no RAWSOCK needed.
* Enhancement: SOCKET-SERVER return a second value (socket) when calling in new-thread mode.
* Enhancement: [CLISP] Full support of DNS helper functions (GET-HOST-BY-NAME, ...) added.
-* Bugfix: Fixed wrong macro expansions of {IP|PORT}-{FROM|TO}-OCTET-BUFFER functions!
+* Enhancement: [CLISP] Better network error type detection based on OS error code.
+* Enhancement: [LispWorks] Better network error type detection based on OS error code.
+* Bugfix: Fixed wrong macro expansions of {IP|PORT}-{FROM|TO}-OCTET-BUFFER functions (since 0.4.0)
* Bugfix: SOCKET-CONNECT didn't set CONNECTED-P for datagram usockets on most backends.
* Bugfix: [SBCL] Fixes for "SBCL/Win32: finalizer problem, etc", by Anton Kovalenko
* Bugfix: [SBCL] Fixed SOCKET-SERVER (UDP) on SBCL due to a issue in SOCKET-CONNECT when HOST is NIL.
* Bugfix: [SBCL] SOCKET-CONNECT's TIMEOUT argument now works as a "connection timeout".
* Bugfix: [CMUCL] Fixed SOCKET-SEND on unconnected usockets under Unicode version of CMUCL.
-* Bugfix: [LispWorks] Better network error type detection on LispWorks.
* Bugfix: [CLISP] Fixed and confirmed UDP (Datagram) support (RAWSOCK version).
[TODO]
Modified: usocket/branches/0.5.x/README
==============================================================================
--- usocket/branches/0.5.x/README (original)
+++ usocket/branches/0.5.x/README Fri Apr 1 08:06:23 2011
@@ -1,6 +1,5 @@
- -*- text -*-
-
-$Id$
+;;;; -*- Mode: Text -*-
+;;;; $Id$
Content
=======
@@ -164,14 +163,3 @@
reuse the FFI code on all platforms (including Windows). This benefit
currently outweighs the additional requirement. (hey, it's *Embeddable*
Common Lisp, so, you probably wanted to embed it all along, right?)
-
-- LispWorks has a bug(?) in wait-for-input-streams which make it
- unsuited for waiting for input on stream socket servers, making it
- necessary to resort to different means. With the absence of notice-fd
- on Windows, that currenty leaves Windows unsupported.
-
-- SBCL can't use select() on Windows because it would mean porting
- the FD_* macros and the select structures which I'm not sure
- is the right way yet (if I need to write custom Win32 code anyway...)
- The alternative is to use WSAEventSelect() and friends (which don't
- have a limited number of sockets).
Modified: usocket/branches/0.5.x/usocket-test.asd
==============================================================================
--- usocket/branches/0.5.x/usocket-test.asd (original)
+++ usocket/branches/0.5.x/usocket-test.asd Fri Apr 1 08:06:23 2011
@@ -15,7 +15,8 @@
(defsystem usocket-test
:name "usocket test"
:author "Erik Enge"
- :version "0.1.0"
+ :maintainer "Chun Tian (binghe)"
+ :version "0.2.0"
:licence "MIT"
:description "Tests for usocket"
:depends-on (:usocket
Modified: usocket/branches/0.5.x/usocket.asd
==============================================================================
--- usocket/branches/0.5.x/usocket.asd (original)
+++ usocket/branches/0.5.x/usocket.asd Fri Apr 1 08:06:23 2011
@@ -14,6 +14,7 @@
(defsystem usocket
:name "usocket"
:author "Erik Enge & Erik Huelsmann"
+ :maintainer "Chun Tian (binghe)"
:version "0.5.1"
:licence "MIT"
:description "Universal socket library for Common Lisp"
From ctian at common-lisp.net Fri Apr 1 12:41:51 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 08:41:51 -0400
Subject: [usocket-cvs] r634 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Fri Apr 1 08:41:51 2011
New Revision: 634
Log:
[CCL] Clozure CL doesn't understand VALUES declaration ...
Modified:
usocket/branches/0.5.x/backend/openmcl.lisp
Modified: usocket/branches/0.5.x/backend/openmcl.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/openmcl.lisp (original)
+++ usocket/branches/0.5.x/backend/openmcl.lisp Fri Apr 1 08:41:51 2011
@@ -157,10 +157,6 @@
(ccl::send-for-usocket (socket usocket) buffer length))))
(defmethod socket-receive ((usocket datagram-usocket) buffer length &key)
- (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
- (integer 0) ; size
- (unsigned-byte 32) ; host
- (unsigned-byte 16))) ; port
(with-mapped-conditions (usocket)
(openmcl-socket:receive-from (socket usocket) length :buffer buffer)))
From ctian at common-lisp.net Fri Apr 1 16:52:19 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 12:52:19 -0400
Subject: [usocket-cvs] r635 - in usocket/trunk: . backend test
Message-ID:
Author: ctian
Date: Fri Apr 1 12:52:18 2011
New Revision: 635
Log:
Merge all changes from branch 0.5.x (r616-r634) before tagging the 0.5.1
Modified:
usocket/trunk/CHANGES
usocket/trunk/README
usocket/trunk/backend/abcl.lisp
usocket/trunk/backend/allegro.lisp
usocket/trunk/backend/clisp.lisp
usocket/trunk/backend/cmucl.lisp
usocket/trunk/backend/lispworks.lisp
usocket/trunk/backend/sbcl.lisp
usocket/trunk/backend/scl.lisp
usocket/trunk/test/test-usocket.lisp
usocket/trunk/usocket-test.asd
usocket/trunk/usocket.lisp
Modified: usocket/trunk/CHANGES
==============================================================================
--- usocket/trunk/CHANGES (original)
+++ usocket/trunk/CHANGES Fri Apr 1 12:52:18 2011
@@ -8,20 +8,21 @@
0.5.1:
-* Bugfix: Fixed wrong macro expansions of {IP|PORT}-{FROM|TO}-OCTET-BUFFER functions!
+* New feature: [CLISP] UDP (Datagram) support based on FFI (Win/Mac/Linux), no RAWSOCK needed.
+* Enhancement: SOCKET-SERVER return a second value (socket) when calling in new-thread mode.
+* Enhancement: [CLISP] Full support of DNS helper functions (GET-HOST-BY-NAME, ...) added.
+* Enhancement: [CLISP] Better network error type detection based on OS error code.
+* Enhancement: [LispWorks] Better network error type detection based on OS error code.
+* Bugfix: Fixed wrong macro expansions of {IP|PORT}-{FROM|TO}-OCTET-BUFFER functions (since 0.4.0)
* Bugfix: SOCKET-CONNECT didn't set CONNECTED-P for datagram usockets on most backends.
* Bugfix: [SBCL] Fixes for "SBCL/Win32: finalizer problem, etc", by Anton Kovalenko
* Bugfix: [SBCL] Fixed SOCKET-SERVER (UDP) on SBCL due to a issue in SOCKET-CONNECT when HOST is NIL.
* Bugfix: [SBCL] SOCKET-CONNECT's TIMEOUT argument now works as a "connection timeout".
* Bugfix: [CMUCL] Fixed SOCKET-SEND on unconnected usockets under Unicode version of CMUCL.
-* Bugfix: [LispWorks] Better network error type detection on LispWorks.
-* Bugfix: [CLISP] Fixed UDP (Datagram) support (RAWSOCK version), confirmed by CL-NET-SNMP.
-* Enhancement: SOCKET-SERVER return a second value (socket) when calling in new-thread mode.
-* Enhancement: [CLISP] Full support of DNS helper functions (GET-HOST-BY-NAME, ...) added.
+* Bugfix: [CLISP] Fixed and confirmed UDP (Datagram) support (RAWSOCK version).
[TODO]
-* New feature: CLISP support UDP without RAWSOCK (using FFI interface)
* New feature: CLISP support some advanced TCP features which CLISP's SOCKET interface not provide
* New feature: Macintosh Common Lisp (MCL) support Datagram sockets (UDP)
Modified: usocket/trunk/README
==============================================================================
--- usocket/trunk/README (original)
+++ usocket/trunk/README Fri Apr 1 12:52:18 2011
@@ -1,6 +1,5 @@
- -*- text -*-
-
-$Id$
+;;;; -*- Mode: Text -*-
+;;;; $Id$
Content
=======
@@ -164,14 +163,3 @@
reuse the FFI code on all platforms (including Windows). This benefit
currently outweighs the additional requirement. (hey, it's *Embeddable*
Common Lisp, so, you probably wanted to embed it all along, right?)
-
-- LispWorks has a bug(?) in wait-for-input-streams which make it
- unsuited for waiting for input on stream socket servers, making it
- necessary to resort to different means. With the absence of notice-fd
- on Windows, that currenty leaves Windows unsupported.
-
-- SBCL can't use select() on Windows because it would mean porting
- the FD_* macros and the select structures which I'm not sure
- is the right way yet (if I need to write custom Win32 code anyway...)
- The alternative is to use WSAEventSelect() and friends (which don't
- have a limited number of sockets).
Modified: usocket/trunk/backend/abcl.lisp
==============================================================================
--- usocket/trunk/backend/abcl.lisp (original)
+++ usocket/trunk/backend/abcl.lisp Fri Apr 1 12:52:18 2011
@@ -343,6 +343,10 @@
;;; TODO: return-host and return-port cannot be get ...
(defmethod socket-receive ((usocket datagram-usocket) buffer length
&key (element-type '(unsigned-byte 8)))
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(let* ((socket (socket usocket))
(real-length (or length +max-datagram-packet-size+))
(byte-array (jnew-array $*byte real-length))
Modified: usocket/trunk/backend/allegro.lisp
==============================================================================
--- usocket/trunk/backend/allegro.lisp (original)
+++ usocket/trunk/backend/allegro.lisp Fri Apr 1 12:52:18 2011
@@ -155,6 +155,10 @@
(socket:send-to s buffer length :remote-host host :remote-port port))))
(defmethod socket-receive ((socket datagram-usocket) buffer length &key)
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(with-mapped-conditions (socket)
(let ((s (socket socket)))
(socket:receive-from s length :buffer buffer :extract t))))
Modified: usocket/trunk/backend/clisp.lisp
==============================================================================
--- usocket/trunk/backend/clisp.lisp (original)
+++ usocket/trunk/backend/clisp.lisp Fri Apr 1 12:52:18 2011
@@ -44,40 +44,80 @@
(mapcar #'host-to-vector-quad
(posix:hostent-addr-list hostent)))))
-#+win32
-(defun remap-maybe-for-win32 (z)
- (mapcar #'(lambda (x)
- (cons (mapcar #'(lambda (y)
- (+ 10000 y))
- (car x))
- (cdr x)))
- z))
-
+;; Format: ((UNIX Windows) . CONDITION)
(defparameter +clisp-error-map+
- #+win32
- (append (remap-maybe-for-win32 +unix-errno-condition-map+)
- (remap-maybe-for-win32 +unix-errno-error-map+))
#-win32
- (append +unix-errno-condition-map+
- +unix-errno-error-map+))
+ `((:EADDRINUSE . address-in-use-error)
+ (:EADDRNOTAVAIL . address-not-available-error)
+ (:EBADF . bad-file-descriptor-error)
+ (:ECONNREFUSED . connection-refused-error)
+ (:ECONNRESET . connection-reset-error)
+ (:ECONNABORTED . connection-aborted-error)
+ (:EINVAL . invalid-argument-error)
+ (:ENOBUFS . no-buffers-error)
+ (:ENOMEM . out-of-memory-error)
+ (:ENOTSUP . operation-not-supported-error)
+ (:EPERM . operation-not-permitted-error)
+ (:EPROTONOSUPPORT . protocol-not-supported-error)
+ (:ESOCKTNOSUPPORT . socket-type-not-supported-error)
+ (:ENETUNREACH . network-unreachable-error)
+ (:ENETDOWN . network-down-error)
+ (:ENETRESET . network-reset-error)
+ (:ESHUTDOWN . already-shutdown-error)
+ (:ETIMEDOUT . timeout-error)
+ (:EHOSTDOWN . host-down-error)
+ (:EHOSTUNREACH . host-unreachable-error))
+ #+win32
+ `((:WSAEADDRINUSE . address-in-use-error)
+ (:WSAEADDRNOTAVAIL . address-not-available-error)
+ (:WSAEBADF . bad-file-descriptor-error)
+ (:WSAECONNREFUSED . connection-refused-error)
+ (:WSAECONNRESET . connection-reset-error)
+ (:WSAECONNABORTED . connection-aborted-error)
+ (:WSAEINVAL . invalid-argument-error)
+ (:WSAENOBUFS . no-buffers-error)
+ (:WSAENOMEM . out-of-memory-error)
+ (:WSAENOTSUP . operation-not-supported-error)
+ (:WSAEPERM . operation-not-permitted-error)
+ (:WSAEPROTONOSUPPORT . protocol-not-supported-error)
+ (:WSAESOCKTNOSUPPORT . socket-type-not-supported-error)
+ (:WSAENETUNREACH . network-unreachable-error)
+ (:WSAENETDOWN . network-down-error)
+ (:WSAENETRESET . network-reset-error)
+ (:WSAESHUTDOWN . already-shutdown-error)
+ (:WSAETIMEDOUT . timeout-error)
+ (:WSAEHOSTDOWN . host-down-error)
+ (:WSAEHOSTUNREACH . host-unreachable-error)))
(defun handle-condition (condition &optional (socket nil))
"Dispatch correct usocket condition."
- (typecase condition
- (system::simple-os-error
- (let ((usock-err
- (cdr (assoc (car (simple-condition-format-arguments condition))
- +clisp-error-map+ :test #'member))))
- (when usock-err ;; don't claim the error if we don't know
- ;; it's actually a socket error ...
- (if (subtypep usock-err 'error)
- (error usock-err :socket socket)
- (signal usock-err :socket socket)))))))
+ (let (error-keyword error-string)
+ (typecase condition
+ (system::simple-os-error
+ (let ((errno (car (simple-condition-format-arguments condition))))
+ (setq error-keyword (os:errno errno)
+ error-string (os:strerror errno))))
+ (simple-error
+ (let ((keyword
+ (car (simple-condition-format-arguments condition))))
+ (setq error-keyword keyword
+ error-string (os:strerror keyword))))
+ (error (error 'unknown-error :real-error condition))
+ (condition (signal 'unknown-condition :real-condition condition)))
+ (when error-keyword
+ (let ((usocket-error
+ (cdr (assoc error-keyword +clisp-error-map+ :test #'eq))))
+ (if usocket-error
+ (if (subtypep usocket-error 'error)
+ (error usocket-error :socket socket)
+ (signal usocket-error :socket socket))
+ (error "Unknown OS error: ~A (~A)" error-string error-keyword))))))
(defun socket-connect (host port &key (protocol :stream) (element-type 'character)
timeout deadline (nodelay t nodelay-specified)
local-host local-port)
- (declare (ignore nodelay))
+ (declare (ignore nodelay)
+ (ignorable timeout local-host local-port))
(when deadline (unsupported 'deadline 'socket-connect))
(when nodelay-specified (unsupported 'nodelay 'socket-connect))
(case protocol
@@ -97,13 +137,11 @@
(make-stream-socket :socket socket
:stream socket))) ;; the socket is a stream too
(:datagram
- #+rawsock
+ #+(or rawsock ffi)
(socket-create-datagram (or local-port *auto-port*)
:local-host (or local-host *wildcard-host*)
- :remote-host host
+ :remote-host (and host (host-to-vector-quad host))
:remote-port port)
- #+(and ffi (not rawsock))
- ()
#-(or rawsock ffi)
(unsupported '(protocol :datagram) 'socket-connect))))
@@ -147,7 +185,7 @@
(remove-waiter (wait-list usocket) usocket))
(socket:socket-server-close (socket usocket)))
-(defmethod get-local-name ((usocket usocket))
+(defmethod get-local-name ((usocket stream-usocket))
(multiple-value-bind
(address port)
(socket:socket-stream-local (socket usocket) t)
@@ -162,13 +200,13 @@
(defmethod get-local-address ((usocket usocket))
(nth-value 0 (get-local-name usocket)))
-(defmethod get-peer-address ((usocket stream-usocket))
+(defmethod get-peer-address ((usocket usocket))
(nth-value 0 (get-peer-name usocket)))
(defmethod get-local-port ((usocket usocket))
(nth-value 1 (get-local-name usocket)))
-(defmethod get-peer-port ((usocket stream-usocket))
+(defmethod get-peer-port ((usocket usocket))
(nth-value 1 (get-peer-name usocket)))
(defun %setup-wait-list (wait-list)
@@ -235,17 +273,22 @@
"Returns the buffer, the number of octets copied into the buffer (received)
and the address of the sender as values."
(let* ((sock (socket socket))
- (sockaddr (unless (connected-p socket)
- (rawsock:make-sockaddr :inet)))
- (rv (if sockaddr
- (rawsock:recvfrom sock buffer sockaddr :start 0 :end length)
- (rawsock:recv sock buffer :start 0 :end length)))
- (host 0) (port 0))
- (unless (connected-p socket)
- (let ((data (rawsock:sockaddr-data sockaddr)))
- (setq host (ip-from-octet-buffer data :start 4)
- port (port-from-octet-buffer data :start 2))))
- (values buffer rv host port)))
+ (sockaddr (rawsock:make-sockaddr :inet))
+ (real-length (or length +max-datagram-packet-size+))
+ (real-buffer (or buffer
+ (make-array real-length
+ :element-type '(unsigned-byte 8)))))
+ (let ((rv (rawsock:recvfrom sock real-buffer sockaddr
+ :start 0 :end real-length))
+ (host 0) (port 0))
+ (unless (connected-p socket)
+ (let ((data (rawsock:sockaddr-data sockaddr)))
+ (setq host (ip-from-octet-buffer data :start 4)
+ port (port-from-octet-buffer data :start 2))))
+ (values (if buffer real-buffer (subseq real-buffer 0 rv))
+ rv
+ host
+ port))))
(defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
"Returns the number of octets sent."
@@ -256,19 +299,40 @@
(make-sockaddr_in)
(host-byte-order host)
port))))
+ (real-length (or length (length buffer)))
+ (real-buffer (if (typep buffer '(simple-array (unsigned-byte 8) (*)))
+ buffer
+ (make-array real-length
+ :element-type '(unsigned-byte 8)
+ :initial-contents (subseq buffer 0 real-length))))
(rv (if (and host port)
- (rawsock:sendto sock buffer sockaddr
+ (rawsock:sendto sock real-buffer sockaddr
:start 0
- :end length)
- (rawsock:send sock buffer
+ :end real-length)
+ (rawsock:send sock real-buffer
:start 0
- :end length))))
+ :end real-length))))
rv))
(defmethod socket-close ((usocket datagram-usocket))
(when (wait-list usocket)
(remove-waiter (wait-list usocket) usocket))
(rawsock:sock-close (socket usocket)))
+
+ (declaim (inline get-socket-name))
+ (defun get-socket-name (socket function)
+ (let ((sockaddr (rawsock:make-sockaddr :inet (make-sockaddr_in))))
+ (funcall function socket sockaddr)
+ (let ((data (rawsock:sockaddr-data sockaddr)))
+ (values (hbo-to-vector-quad (ip-from-octet-buffer data :start 2))
+ (port-from-octet-buffer data :start 0)))))
+
+ (defmethod get-local-name ((usocket datagram-usocket))
+ (get-socket-name (socket usocket) 'rawsock:getsockname))
+
+ (defmethod get-peer-name ((usocket datagram-usocket))
+ (get-socket-name (socket usocket) 'rawsock:getpeername))
+
) ; progn
;;;
@@ -278,27 +342,22 @@
#+(and ffi (not rawsock))
(progn
;; C primitive types
- (ffi:def-c-type size_t)
- (ffi:def-c-type in_addr_t ffi:uint32)
- (ffi:def-c-type in_port_t ffi:uint16)
- (ffi:def-c-type sa_family_t ffi:uint8)
- (ffi:def-c-type socklen_t ffi:uint32)
+ (ffi:def-c-type socklen_t ffi:uint32)
;; C structures
(ffi:def-c-struct sockaddr
- (sa_len ffi:uint8)
- (sa_family sa_family_t)
+ #+macos (sa_len ffi:uint8)
+ (sa_family #-macos ffi:ushort
+ #+macos ffi:uint8)
(sa_data (ffi:c-array ffi:char 14)))
- #+ignore
- (ffi:def-c-struct in_addr
- (s_addr in_addr_t))
-
(ffi:def-c-struct sockaddr_in
- (sin_len ffi:uint8)
- (sin_family sa_family_t)
- (sin_port in_port_t)
- (sin_addr in_addr_t) ; should be struct in_addr
+ #+macos (sin_len ffi:uint8)
+ (sin_family #-macos ffi:short
+ #+macos ffi:uint8)
+ (sin_port #-macos ffi:ushort
+ #+macos ffi:uint16)
+ (sin_addr ffi:uint32)
(sin_zero (ffi:c-array ffi:char 8)))
(ffi:def-c-struct timeval
@@ -308,7 +367,7 @@
;; foreign functions
(ffi:def-call-out %sendto (:name "sendto")
(:arguments (socket ffi:int)
- (buffer (ffi:c-ptr ffi:uint8))
+ (buffer ffi:c-pointer)
(length ffi:int)
(flags ffi:int)
(address (ffi:c-ptr sockaddr))
@@ -319,13 +378,24 @@
#+win32 :stdc-stdcall)
(:return-type ffi:int))
+ (ffi:def-call-out %send (:name "send")
+ (:arguments (socket ffi:int)
+ (buffer ffi:c-pointer)
+ (length ffi:int)
+ (flags ffi:int))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
(ffi:def-call-out %recvfrom (:name "recvfrom")
(:arguments (socket ffi:int)
- (buffer (ffi:c-ptr ffi:uint8) :out)
+ (buffer ffi:c-pointer)
(length ffi:int)
(flags ffi:int)
- (address (ffi:c-ptr sockaddr) :out)
- (address-len (ffi:c-ptr ffi:int) :out))
+ (address (ffi:c-ptr sockaddr) :in-out)
+ (address-len (ffi:c-ptr ffi:int) :in-out))
#+win32 (:library "WS2_32")
#-win32 (:library :default)
(:language #-win32 :stdc
@@ -342,6 +412,34 @@
#+win32 :stdc-stdcall)
(:return-type ffi:int))
+ (ffi:def-call-out %connect (:name "connect")
+ (:arguments (socket ffi:int)
+ (address (ffi:c-ptr sockaddr) :in)
+ (address_len socklen_t))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
+ (ffi:def-call-out %bind (:name "bind")
+ (:arguments (socket ffi:int)
+ (address (ffi:c-ptr sockaddr) :in)
+ (address_len socklen_t))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
+ (ffi:def-call-out %close (:name #-win32 "close" #+win32 "closesocket")
+ (:arguments (socket ffi:int))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
(ffi:def-call-out %getsockopt (:name "getsockopt")
(:arguments (sockfd ffi:int)
(level ffi:int)
@@ -366,18 +464,221 @@
#+win32 :stdc-stdcall)
(:return-type ffi:int))
+ (ffi:def-call-out %htonl (:name "htonl")
+ (:arguments (hostlong ffi:uint32))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:uint32))
+
+ (ffi:def-call-out %htons (:name "htons")
+ (:arguments (hostshort ffi:uint16))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:uint16))
+
+ (ffi:def-call-out %ntohl (:name "ntohl")
+ (:arguments (netlong ffi:uint32))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:uint32))
+
+ (ffi:def-call-out %ntohs (:name "ntohs")
+ (:arguments (netshort ffi:uint16))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:uint16))
+
+ (ffi:def-call-out %getsockname (:name "getsockname")
+ (:arguments (sockfd ffi:int)
+ (localaddr (ffi:c-ptr sockaddr) :in-out)
+ (addrlen (ffi:c-ptr socklen_t) :in-out))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
+ (ffi:def-call-out %getpeername (:name "getpeername")
+ (:arguments (sockfd ffi:int)
+ (peeraddr (ffi:c-ptr sockaddr) :in-out)
+ (addrlen (ffi:c-ptr socklen_t) :in-out))
+ #+win32 (:library "WS2_32")
+ #-win32 (:library :default)
+ (:language #-win32 :stdc
+ #+win32 :stdc-stdcall)
+ (:return-type ffi:int))
+
;; socket constants
(defconstant +socket-af-inet+ 2)
- (defconstant +socket-pf-unspec+ 0)
(defconstant +socket-sock-dgram+ 2)
+ (defconstant +socket-ip-proto-udp+ 17)
+
(defconstant +sockopt-so-rcvtimeo+ #-linux #x1006 #+linux 20 "Socket receive timeout")
- (defun open-udp-socket (&key local-address local-port read-timeout)
- "Open a unconnected UDP socket. For binding on address ANY(*), just not set LOCAL-ADDRESS (NIL),
-for binding on random free unused port, set LOCAL-PORT to 0."
- (let ((socket-fd (%socket +socket-af-inet+ +socket-sock-dgram+ +socket-pf-unspec+)))
- (if socket-fd
- (progn
- )
- (error "cannot create socket"))))
+ (defparameter *length-of-sockaddr_in* (ffi:sizeof 'sockaddr_in))
+
+ (declaim (inline fill-sockaddr_in))
+ (defun fill-sockaddr_in (sockaddr host port)
+ (let ((hbo (host-to-hbo host)))
+ (ffi:with-c-place (place sockaddr)
+ #+macos
+ (setf (ffi:slot place 'sin_len) *length-of-sockaddr_in*)
+ (setf (ffi:slot place 'sin_family) +socket-af-inet+
+ (ffi:slot place 'sin_port) (%htons port)
+ (ffi:slot place 'sin_addr) (%htonl hbo)))
+ sockaddr))
+
+ (defun socket-create-datagram (local-port
+ &key (local-host *wildcard-host*)
+ remote-host
+ remote-port)
+ (let ((sock (%socket +socket-af-inet+ +socket-sock-dgram+ +socket-ip-proto-udp+))
+ (lsock_addr (fill-sockaddr_in (ffi:allocate-shallow 'sockaddr_in)
+ local-host local-port))
+ (rsock_addr (when remote-host
+ (fill-sockaddr_in (ffi:allocate-shallow 'sockaddr_in)
+ remote-host (or remote-port local-port)))))
+ (unless (plusp sock)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (socket): ~A" (os:errno)))
+ (unwind-protect
+ (let ((rv (%bind sock (ffi:cast (ffi:foreign-value lsock_addr) 'sockaddr)
+ *length-of-sockaddr_in*)))
+ (unless (zerop rv)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (bind): ~A" (os:errno)))
+ (when rsock_addr
+ (let ((rv (%connect sock
+ (ffi:cast (ffi:foreign-value rsock_addr) 'sockaddr)
+ *length-of-sockaddr_in*)))
+ (unless (zerop rv)
+ (error "SOCKET-CREATE-DATAGRAM ERROR (connect): ~A" (os:errno))))))
+ (ffi:foreign-free lsock_addr)
+ (when remote-host
+ (ffi:foreign-free rsock_addr)))
+ (make-datagram-socket sock :connected-p (if rsock_addr t nil))))
+
+ (defun finalize-datagram-usocket (object)
+ (when (datagram-usocket-p object)
+ (socket-close object)))
+
+ (defmethod initialize-instance :after ((usocket datagram-usocket) &key)
+ (setf (slot-value usocket 'recv-buffer)
+ (ffi:allocate-shallow 'ffi:uint8 :count +max-datagram-packet-size+))
+ ;; finalize the object
+ (ext:finalize usocket 'finalize-datagram-usocket))
+
+ (defmethod socket-close ((usocket datagram-usocket))
+ (when (wait-list usocket)
+ (remove-waiter (wait-list usocket) usocket))
+ (with-slots (recv-buffer socket) usocket
+ (ffi:foreign-free recv-buffer)
+ (zerop (%close socket))))
+
+ (defmethod socket-receive ((usocket datagram-usocket) buffer length &key)
+ (let ((remote-address (ffi:allocate-shallow 'sockaddr_in))
+ (remote-address-length (ffi:allocate-shallow 'ffi:int))
+ nbytes (host 0) (port 0))
+ (setf (ffi:foreign-value remote-address-length)
+ *length-of-sockaddr_in*)
+ (unwind-protect
+ (multiple-value-bind (n address address-length)
+ (%recvfrom (socket usocket)
+ (ffi:foreign-address (slot-value usocket 'recv-buffer))
+ +max-datagram-packet-size+
+ 0 ; flags
+ (ffi:cast (ffi:foreign-value remote-address) 'sockaddr)
+ (ffi:foreign-value remote-address-length))
+ (when (minusp n)
+ (error "SOCKET-RECEIVE ERROR: ~A" (os:errno)))
+ (setq nbytes n)
+ (when (= address-length *length-of-sockaddr_in*)
+ (let ((data (sockaddr-sa_data address)))
+ (setq host (ip-from-octet-buffer data :start 2)
+ port (port-from-octet-buffer data))))
+ (cond ((plusp n)
+ (let ((return-buffer (ffi:foreign-value (slot-value usocket 'recv-buffer))))
+ (if buffer ; replace exist buffer of create new return buffer
+ (let ((end-1 (min (or length (length buffer)) +max-datagram-packet-size+))
+ (end-2 (min n +max-datagram-packet-size+)))
+ (replace buffer return-buffer :end1 end-1 :end2 end-2))
+ (setq buffer (subseq return-buffer 0 (min n +max-datagram-packet-size+))))))
+ ((zerop n))))
+ (ffi:foreign-free remote-address)
+ (ffi:foreign-free remote-address-length))
+ (values buffer nbytes host port)))
+
+ ;; implementation note: different from socket-receive, we know how many bytes we want to send everytime,
+ ;; so, a send buffer will not needed, and if there is a buffer, it's hard to fill its content like those
+ ;; in LispWorks. So, we allocate new foreign buffer for holding data (unknown sequence subtype) every time.
+ ;;
+ ;; I don't know if anyone is watching my coding work, but I think this design is reasonable for CLISP.
+ (defmethod socket-send ((usocket datagram-usocket) buffer length &key host port)
+ (declare (type sequence buffer)
+ (type integer length))
+ (let ((remote-address (when (and host port)
+ (fill-sockaddr_in (ffi:allocate-shallow 'sockaddr_in) host port)))
+ (send-buffer (let ((buffer-length (length buffer)))
+ (if (> buffer-length (* length 2))
+ ;; if buffer is too big, then we copy out a subseq and only allocate as need
+ (ffi:allocate-deep 'ffi:uint8 (subseq buffer 0 length) :count length :read-only t)
+ ;; then we allocate the whole buffer directly, that should be faster.
+ (ffi:allocate-deep 'ffi:uint8 buffer :count (length buffer) :read-only t))))
+ (real-length (min length +max-datagram-packet-size+))
+ (nbytes 0))
+ (unwind-protect
+ (let ((n (if remote-address
+ (%sendto (socket usocket)
+ (ffi:foreign-address send-buffer)
+ real-length
+ 0 ; flags
+ (ffi:cast (ffi:foreign-value remote-address) 'sockaddr)
+ *length-of-sockaddr_in*)
+ (%send (socket usocket)
+ (ffi:foreign-address send-buffer)
+ real-length
+ 0))))
+ (cond ((plusp n)
+ (setq nbytes n))
+ ((zerop n)
+ (setq nbytes n))
+ (t (error "SOCKET-SEND ERROR: ~A" (os:errno)))))
+ (ffi:foreign-free send-buffer)
+ (when remote-address
+ (ffi:foreign-free remote-address))
+ nbytes)))
+
+ (declaim (inline get-socket-name))
+ (defun get-socket-name (socket function)
+ (let ((address (ffi:allocate-shallow 'sockaddr_in))
+ (address-length (ffi:allocate-shallow 'ffi:int))
+ (host 0) (port 0))
+ (setf (ffi:foreign-value address-length) *length-of-sockaddr_in*)
+ (unwind-protect
+ (multiple-value-bind (rv return-address return-address-length)
+ (funcall function socket
+ (ffi:cast (ffi:foreign-value address) 'sockaddr)
+ (ffi:foreign-value address-length))
+ (declare (ignore return-address-length))
+ (if (zerop rv)
+ (let ((data (sockaddr-sa_data return-address)))
+ (setq host (ip-from-octet-buffer data :start 2)
+ port (port-from-octet-buffer data)))
+ (error "GET-SOCKET-NAME ERROR: ~A" (os:errno))))
+ (ffi:foreign-free address)
+ (ffi:foreign-free address-length))
+ (values (hbo-to-vector-quad host) port)))
+
+ (defmethod get-local-name ((usocket datagram-usocket))
+ (get-socket-name (socket usocket) '%getsockname))
+
+ (defmethod get-peer-name ((usocket datagram-usocket))
+ (get-socket-name (socket usocket) '%getpeername))
+
) ; progn
Modified: usocket/trunk/backend/cmucl.lisp
==============================================================================
--- usocket/trunk/backend/cmucl.lisp (original)
+++ usocket/trunk/backend/cmucl.lisp Fri Apr 1 12:52:18 2011
@@ -183,6 +183,10 @@
(%unix-send (socket usocket) buffer length 0))))
(defmethod socket-receive ((usocket datagram-usocket) buffer length &key)
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(let ((real-buffer (or buffer
(make-array length :element-type '(unsigned-byte 8))))
(real-length (or length
@@ -190,8 +194,7 @@
(multiple-value-bind (nbytes remote-host remote-port)
(with-mapped-conditions (usocket)
(ext:inet-recvfrom (socket usocket) real-buffer real-length))
- (when (plusp nbytes)
- (values real-buffer nbytes remote-host remote-port)))))
+ (values real-buffer nbytes remote-host remote-port))))
(defmethod get-local-name ((usocket usocket))
(multiple-value-bind
@@ -269,17 +272,17 @@
(multiple-value-bind
(secs musecs)
(split-timeout (or timeout 1))
- (multiple-value-bind
- (count err)
- (unix:unix-fast-select (1+ (reduce #'max
- (wait-list-%wait wait-list)))
- (alien:addr rfds) nil nil
- (when timeout secs) musecs)
+ (multiple-value-bind (count err)
+ (unix:unix-fast-select (1+ (reduce #'max
+ (wait-list-%wait wait-list)))
+ (alien:addr rfds) nil nil
+ (when timeout secs) musecs)
+ (declare (ignore err))
(if (<= 0 count)
;; process the result...
(dolist (x (wait-list-waiters wait-list))
(when (unix:fd-isset (socket x) rfds)
(setf (state x) :READ)))
- (progn
- ;;###FIXME generate an error, except for EINTR
- )))))))
+ (progn
+ ;;###FIXME generate an error, except for EINTR
+ )))))))
Modified: usocket/trunk/backend/lispworks.lisp
==============================================================================
--- usocket/trunk/backend/lispworks.lisp (original)
+++ usocket/trunk/backend/lispworks.lisp Fri Apr 1 12:52:18 2011
@@ -81,6 +81,8 @@
(defconstant *socket_sock_dgram* 2
"Connectionless, unreliable datagrams of fixed maximum length.")
+(defconstant *socket_ip_proto_udp* 17)
+
(defconstant *sockopt_so_rcvtimeo*
#-linux #x1006
#+linux 20
@@ -186,7 +188,7 @@
"Open a unconnected UDP socket.
For binding on address ANY(*), just not set LOCAL-ADDRESS (NIL),
for binding on random free unused port, set LOCAL-PORT to 0."
- (let ((socket-fd (comm::socket comm::*socket_af_inet* *socket_sock_dgram* comm::*socket_pf_unspec*)))
+ (let ((socket-fd (comm::socket comm::*socket_af_inet* *socket_sock_dgram* *socket_ip_proto_udp*)))
(if socket-fd
(progn
(when read-timeout (set-socket-receive-timeout socket-fd read-timeout))
@@ -358,15 +360,14 @@
:element-type '(unsigned-byte 8)
:allocation :static)))
+(defvar *length-of-sockaddr_in*
+ (fli:size-of '(:struct comm::sockaddr_in)))
+
(defun send-message (socket-fd message buffer &optional (length (length buffer)) host service)
"Send message to a socket, using sendto()/send()"
(declare (type integer socket-fd)
(type sequence buffer))
- (fli:with-dynamic-foreign-objects ((client-addr (:struct comm::sockaddr_in))
- (len :int
- #-(or lispworks4 lispworks5.0) ; <= 5.0
- :initial-element
- (fli:size-of '(:struct comm::sockaddr_in))))
+ (fli:with-dynamic-foreign-objects ((client-addr (:struct comm::sockaddr_in)))
(fli:with-dynamic-lisp-array-pointer (ptr message :type '(:unsigned :byte))
(replace message buffer :end2 length)
(if (and host service)
@@ -374,7 +375,7 @@
(comm::initialize-sockaddr_in client-addr comm::*socket_af_inet* host service "udp")
(%sendto socket-fd ptr (min length +max-datagram-packet-size+) 0
(fli:copy-pointer client-addr :type '(:struct comm::sockaddr))
- (fli:dereference len)))
+ *length-of-sockaddr_in*))
(comm::%send socket-fd ptr (min length +max-datagram-packet-size+) 0)))))
(defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
@@ -397,8 +398,9 @@
(fli:with-dynamic-foreign-objects ((client-addr (:struct comm::sockaddr_in))
(len :int
#-(or lispworks4 lispworks5.0) ; <= 5.0
- :initial-element
- (fli:size-of '(:struct comm::sockaddr_in))))
+ :initial-element *length-of-sockaddr_in*))
+ #+(or lispworks4 lispworks5.0) ; <= 5.0
+ (setf (fli:dereference len) *length-of-sockaddr_in*)
(fli:with-dynamic-lisp-array-pointer (ptr message :type '(:unsigned :byte))
;; setup new read timeout
(when read-timeout
@@ -433,6 +435,10 @@
(values nil n 0 0)))))))
(defmethod socket-receive ((socket datagram-usocket) buffer length &key timeout)
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(multiple-value-bind (buffer size host port)
(receive-message (socket socket)
(slot-value socket 'recv-buffer)
Modified: usocket/trunk/backend/sbcl.lisp
==============================================================================
--- usocket/trunk/backend/sbcl.lisp (original)
+++ usocket/trunk/backend/sbcl.lisp Fri Apr 1 12:52:18 2011
@@ -387,6 +387,10 @@
(defmethod socket-receive ((socket datagram-usocket) buffer length
&key (element-type '(unsigned-byte 8)))
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(with-mapped-conditions (socket)
(let ((s (socket socket)))
(sb-bsd-sockets:socket-receive s buffer length :element-type element-type))))
Modified: usocket/trunk/backend/scl.lisp
==============================================================================
--- usocket/trunk/backend/scl.lisp (original)
+++ usocket/trunk/backend/scl.lisp Fri Apr 1 12:52:18 2011
@@ -145,6 +145,10 @@
(scl-map-socket-error errno :socket socket)))))
(defmethod socket-receive ((socket datagram-usocket) buffer length &key)
+ (declare (values (simple-array (unsigned-byte 8) (*)) ; buffer
+ (integer 0) ; size
+ (unsigned-byte 32) ; host
+ (unsigned-byte 16))) ; port
(let ((s (socket socket)))
(let ((real-buffer (or buffer
(make-array length :element-type '(unsigned-byte 8))))
Modified: usocket/trunk/test/test-usocket.lisp
==============================================================================
--- usocket/trunk/test/test-usocket.lisp (original)
+++ usocket/trunk/test/test-usocket.lisp Fri Apr 1 12:52:18 2011
@@ -118,13 +118,11 @@
(unwind-protect
(progn
(format (usocket:socket-stream sock)
- "GET / HTTP/1.0~c~c~c~c"
- #\Return #\linefeed #\Return #\linefeed)
+ "GET / HTTP/1.0~2%")
(force-output (usocket:socket-stream sock))
- (read-line (usocket:socket-stream sock)))
+ (subseq (read-line (usocket:socket-stream sock)) 0 15))
(usocket:socket-close sock))))
- #+(or mcl clisp) "HTTP/1.1 200 OK"
- #-(or mcl clisp) #.(format nil "HTTP/1.1 200 OK~A" #\Return) nil)
+ "HTTP/1.1 200 OK")
(deftest socket-name.1
(with-caught-conditions (nil nil)
@@ -188,14 +186,12 @@
(unwind-protect
(progn
(format (usocket:socket-stream sock)
- "GET / HTTP/1.0~c~c~c~c"
- #\Return #\linefeed #\Return #\linefeed)
+ "GET / HTTP/1.0~2%")
(force-output (usocket:socket-stream sock))
(usocket:wait-for-input sock :timeout *wait-for-input-timeout*)
- (read-line (usocket:socket-stream sock)))
+ (subseq (read-line (usocket:socket-stream sock)) 0 15))
(usocket:socket-close sock))))
- #+(or mcl clisp) "HTTP/1.1 200 OK"
- #-(or mcl clisp) #.(format nil "HTTP/1.1 200 OK~A" #\Return) nil)
+ "HTTP/1.1 200 OK")
(defun run-usocket-tests ()
(do-tests))
Modified: usocket/trunk/usocket-test.asd
==============================================================================
--- usocket/trunk/usocket-test.asd (original)
+++ usocket/trunk/usocket-test.asd Fri Apr 1 12:52:18 2011
@@ -16,7 +16,7 @@
:name "usocket test"
:author "Erik Enge"
:maintainer "Chun Tian (binghe)"
- :version "0.1.0"
+ :version "0.2.0"
:licence "MIT"
:description "Tests for usocket"
:depends-on (:usocket
Modified: usocket/trunk/usocket.lisp
==============================================================================
--- usocket/trunk/usocket.lisp (original)
+++ usocket/trunk/usocket.lisp Fri Apr 1 12:52:18 2011
@@ -99,18 +99,20 @@
((connected-p :type boolean
:accessor connected-p
:initarg :connected-p)
- #+(or cmu scl lispworks)
+ #+(or cmu
+ scl
+ lispworks
+ (and clisp ffi (not rawsock)))
(%open-p :type boolean
:accessor %open-p
:initform t
:documentation "Flag to indicate if usocket is open,
for GC on implementions operate on raw socket fd.")
+ #+(or lispworks
+ (and clisp ffi (not rawsock)))
+ (recv-buffer :documentation "Private RECV buffer.")
#+lispworks
- (recv-buffer
- :documentation "Private RECV buffer.")
- #+lispworks
- (send-buffer
- :documentation "Private SEND buffer."))
+ (send-buffer :documentation "Private SEND buffer."))
(:documentation "UDP (inet-datagram) socket"))
(defun usocket-p (socket)
From ctian at common-lisp.net Fri Apr 1 16:55:57 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 12:55:57 -0400
Subject: [usocket-cvs] r636 - usocket/tags/0.5.1
Message-ID:
Author: ctian
Date: Fri Apr 1 12:55:57 2011
New Revision: 636
Log:
Created tag 0.5.1.
Added:
usocket/tags/0.5.1/
- copied from r635, /usocket/branches/0.5.x/
From ctian at common-lisp.net Fri Apr 1 17:00:03 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 13:00:03 -0400
Subject: [usocket-cvs] r637 - public_html/releases
Message-ID:
Author: ctian
Date: Fri Apr 1 13:00:01 2011
New Revision: 637
Log:
usocket-0.5.1 source tarball
Added:
public_html/releases/usocket-0.5.1.tar.gz (contents, props changed)
Added: public_html/releases/usocket-0.5.1.tar.gz
==============================================================================
Binary file. No diff available.
From ctian at common-lisp.net Fri Apr 1 17:01:34 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 13:01:34 -0400
Subject: [usocket-cvs] r638 - public_html/releases
Message-ID:
Author: ctian
Date: Fri Apr 1 13:01:33 2011
New Revision: 638
Log:
Add asc file and modify links
Added:
public_html/releases/usocket-0.5.1.tar.gz.asc
Modified:
public_html/releases/usocket-latest.tar.gz
public_html/releases/usocket-latest.tar.gz.asc
Added: public_html/releases/usocket-0.5.1.tar.gz.asc
==============================================================================
--- (empty file)
+++ public_html/releases/usocket-0.5.1.tar.gz.asc Fri Apr 1 13:01:33 2011
@@ -0,0 +1,7 @@
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.11 (Darwin)
+
+iEYEABECAAYFAk2WBEQACgkQny6v4+l8uLD5WwCg38v7uAIFjxVE4yeA+nu0BbGJ
+ic8AoJOGSyNPi7OwVPHPt02ALnHdWsx3
+=uppv
+-----END PGP SIGNATURE-----
Modified: public_html/releases/usocket-latest.tar.gz
==============================================================================
--- public_html/releases/usocket-latest.tar.gz (original)
+++ public_html/releases/usocket-latest.tar.gz Fri Apr 1 13:01:33 2011
@@ -1 +1 @@
-link usocket-0.5.0.tar.gz
\ No newline at end of file
+link usocket-0.5.1.tar.gz
\ No newline at end of file
Modified: public_html/releases/usocket-latest.tar.gz.asc
==============================================================================
--- public_html/releases/usocket-latest.tar.gz.asc (original)
+++ public_html/releases/usocket-latest.tar.gz.asc Fri Apr 1 13:01:33 2011
@@ -1 +1 @@
-link usocket-0.5.0.tar.gz.asc
\ No newline at end of file
+link usocket-0.5.1.tar.gz.asc
\ No newline at end of file
From ctian at common-lisp.net Fri Apr 1 17:07:27 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 01 Apr 2011 13:07:27 -0400
Subject: [usocket-cvs] r639 - public_html
Message-ID:
Author: ctian
Date: Fri Apr 1 13:07:26 2011
New Revision: 639
Log:
Release 0.5.1
Modified:
public_html/index.shtml
Modified: public_html/index.shtml
==============================================================================
--- public_html/index.shtml (original)
+++ public_html/index.shtml Fri Apr 1 13:07:26 2011
@@ -1,5 +1,5 @@
-
+
USOCKET
@@ -98,7 +98,8 @@
to
the
commit
-message mailing list. To use the latest development
+message
+mailing list. To use the latest development
version, make sure you have Subversion
installed and execute this command:
$ svn checkout svn://common-lisp.net/project/usocket/svn/usocket/trunk usocket-svn
@@ -128,6 +129,7 @@
+
Summary
+ Apr 2, 2011
+
+ 0.5.1
+
+ Improved
+CLISP support using FFI; Lots of bugfix for CMUCL, SBCL,
+LispWorks, etc.
+
+
+
Mar 12, 2011
0.5.0
- UDP support; Lots of bugfixes since 0.4.1; support for WAIT-FOR-INPUT for
- SBCL and ECL on Win32; new platform added: Macintosh Common Lisp
- (5.0 and up)
+ UDP support; Lots of bugfixes since 0.4.1; support for
+WAIT-FOR-INPUT for SBCL and ECL on Win32; new platform added: Macintosh
+Common Lisp (5.0 and up)
Dec 27, 2008
@@ -500,6 +512,7 @@
fix
+
issue #6
and API preparation for server side sockets (not in this release)
From ctian at common-lisp.net Sun Apr 10 14:29:36 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Sun, 10 Apr 2011 10:29:36 -0400
Subject: [usocket-cvs] r640 - usocket/branches/0.5.x/backend
Message-ID:
Author: ctian
Date: Sun Apr 10 10:29:35 2011
New Revision: 640
Log:
[CLISP] Fixed WAIT-FOR-INPUT, this made Hunchentoot working on CLISP. (Thanks to Anton Vodonosov )
Modified:
usocket/branches/0.5.x/backend/clisp.lisp
Modified: usocket/branches/0.5.x/backend/clisp.lisp
==============================================================================
--- usocket/branches/0.5.x/backend/clisp.lisp (original)
+++ usocket/branches/0.5.x/backend/clisp.lisp Sun Apr 10 10:29:35 2011
@@ -232,9 +232,9 @@
(socket:socket-status request-list)))
(sockets (wait-list-waiters wait-list)))
(do* ((x (pop sockets) (pop sockets))
- (y (pop status-list) (pop status-list)))
+ (y (cdr (pop status-list)) (cdr (pop status-list))))
((null x))
- (when (eq y :INPUT)
+ (when (member y '(T :INPUT))
(setf (state x) :READ)))
wait-list))))
From ctian at common-lisp.net Sun Apr 10 14:30:08 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Sun, 10 Apr 2011 10:30:08 -0400
Subject: [usocket-cvs] r641 - usocket/branches/0.5.x
Message-ID:
Author: ctian
Date: Sun Apr 10 10:30:07 2011
New Revision: 641
Log:
Update ChangeLog
Modified:
usocket/branches/0.5.x/CHANGES
Modified: usocket/branches/0.5.x/CHANGES
==============================================================================
--- usocket/branches/0.5.x/CHANGES (original)
+++ usocket/branches/0.5.x/CHANGES Sun Apr 10 10:30:07 2011
@@ -1,10 +1,6 @@
-0.5.0:
+0.5.2:
-* New supported platform: Macintosh Common Lisp (5.0 and up, plus RMCL)
-* Support for UDP (datagram-usocket) was added (for all supported platform except MCL)
-* Add WAIT-FOR-INPUT support for SBCL and ECL on win32.
-* Simple TCP and UDP server API: SOCKET-SERVER
-* Lots of bug fixed since 0.4.1
+* Bugfix: CLISP's WAIT-FOR-INPUT misused underlying CLISP API, this made Hunchentoot working on CLISP. (Thanks to Anton Vodonosov )
0.5.1:
@@ -21,6 +17,14 @@
* Bugfix: [CMUCL] Fixed SOCKET-SEND on unconnected usockets under Unicode version of CMUCL.
* Bugfix: [CLISP] Fixed and confirmed UDP (Datagram) support (RAWSOCK version).
+0.5.0:
+
+* New supported platform: Macintosh Common Lisp (5.0 and up, plus RMCL)
+* Support for UDP (datagram-usocket) was added (for all supported platform except MCL)
+* Add WAIT-FOR-INPUT support for SBCL and ECL on win32.
+* Simple TCP and UDP server API: SOCKET-SERVER
+* Lots of bug fixed since 0.4.1
+
[TODO]
* New feature: CLISP support some advanced TCP features which CLISP's SOCKET interface not provide
From ctian at common-lisp.net Fri Apr 15 18:05:55 2011
From: ctian at common-lisp.net (Chun Tian (binghe))
Date: Fri, 15 Apr 2011 14:05:55 -0400
Subject: [usocket-cvs] r642 - usocket/trunk
Message-ID:
Author: ctian
Date: Fri Apr 15 14:05:55 2011
New Revision: 642
Log:
Fixed compilation warnings in SOCKET-OPTION, patched by Robert Brown
Modified:
usocket/trunk/option.lisp
Modified: usocket/trunk/option.lisp
==============================================================================
--- usocket/trunk/option.lisp (original)
+++ usocket/trunk/option.lisp Fri Apr 15 14:05:55 2011
@@ -41,7 +41,9 @@
(defmethod socket-option ((usocket stream-usocket)
(option (eql :receive-timeout)) &key)
+ (declare (ignore option))
(let ((socket (socket usocket)))
+ (declare (ignorable socket))
#+abcl
() ; TODO
#+allegro
@@ -65,9 +67,11 @@
(defmethod (setf socket-option) (new-value (usocket stream-usocket)
(option (eql :receive-timeout)) &key)
- (declare (type number new-value))
+ (declare (type number new-value)
+ (ignore option))
(let ((socket (socket usocket))
(timeout new-value))
+ (declare (ignorable socket timeout))
#+abcl
() ; TODO
#+allegro