Subject: [clisp-list] shutdown(2) & sockets

From: Sam Steingold <[email-masked]>
Date: Thu Mar 28 16:10:27 2002

Todd (?) asked for shutdown(2) for sockets.

I want to add a keyword arg :DIRECTION to CLOSE.
then
        (close 2way-stream :direction :in)
is the same as
        (close (two-way-input-stream 2way-stream))
and
        (close socket :direction in)
is the same as
        shutdown(handle(socket),SHUT_RD);

do people like the interface?

I don't think this breaks ANSI "too much".  in CLISP the "official
signature" of the generic function CLOSE is already (stream &rest args).

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
Even Windows doesn't suck, when you use Common Lisp

---

From: Sam Steingold <[email-masked]>
Date: Sat Mar 30 15:18:30 2002

> * In message <[email-masked]>
> * On the subject of "[clisp-list] shutdown(2) & sockets"
> * Sent on 28 Mar 2002 19:10:19 -0500
> * Honorable Sam Steingold <[email-masked]> writes:
>

Done.
I would appreciate it if non-autoconf platform (like woe32) users
reported whether they have
        int shutdown(int, int);
available on their systems.
(the first argument may actually be something like HANDLE or Handle or
Socket or ...)

thanks.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
If your VCR is still blinking 12:00, you don't want Linux.

---

From: Arseny Slobodjuck <[email-masked]>
Date: Sat Mar 30 17:08:33 2002

Hello Sam,

Sam> I would appreciate it if non-autoconf platform (like woe32) users
Sam> reported whether they have
Sam>         int shutdown(int, int);
Sam> available on their systems.
Sam> (the first argument may actually be something like HANDLE or Handle or
Sam> Socket or ...)

That helps ?

shutdown
The Windows Sockets shutdown function disables sends or receives on a socket.

int shutdown (
  SOCKET   s,  
  int      how    
);
Parameters
s 
[in] Descriptor identifying a socket. 
how 
[in] Flag that describes what types of operation will no longer be allowed. 
Return Values
If  no  error  occurs,  shutdown  returns  zero. Otherwise, a value of
SOCKET_ERROR  is  returned, and a specific error code can be retrieved
by calling WSAGetLastError.

Error code Meaning 
WSANOTINITIALISED A successful WSAStartup call must occur before using
this function.
WSAENETDOWN The network subsystem has failed. 
WSAEINVAL  The  how  parameter is not valid, or is not consistent with
the  socket  type. For example, SD_SEND is used with a UNI_RECV socket
type.
WSAEINPROGRESS  A blocking Windows Sockets 1.1 call is in progress, or
the service provider is still processing a callback function.
WSAENOTCONN The socket is not connected (connection-oriented sockets only). 
WSAENOTSOCK The descriptor is not a socket. 

Remarks
The  shutdown  function  is  used  on  all types of sockets to disable
reception, transmission, or both.

If  the  how  parameter  is  SD_RECEIVE,  subsequent calls to the recv
function  on  the socket will be disallowed. This has no effect on the
lower  protocol layers. For TCP sockets, if there is still data queued
on  the  socket  waiting to be received, or data arrives subsequently,
the  connection  is  reset,  since the data cannot be delivered to the
user.  For UDP sockets, incoming datagrams are accepted and queued. In
no case will an ICMP error packet be generated.

If the how parameter is SD_SEND, subsequent calls to the send function
are  disallowed. For TCP sockets, a FIN will be sent after all data is
sent and acknowledged by the receiver.

Setting  how  to SD_BOTH disables both sends and receives as described
above.

The  shutdown  function  does  not  close  the  socket.  Any resources
attached to the socket will not be freed until closesocket is invoked.

To  assure  that  all  data is sent and received on a connected socket
before  it  is  closed,  an  application  should use shutdown to close
connection  before  calling  closesocket.  For  example, to initiate a
graceful disconnect:

Call WSAAsyncSelect to register for FD_CLOSE notification.
Call shutdown with how=SD_SEND. 
When FD_CLOSE received, call recv until zero returned, or SOCKET_ERROR. 
Call closesocket. 
Note  The shutdown function does not block regardless of the SO_LINGER
setting on the socket.

An  application  should not rely on being able to reuse a socket after
it  has  been  shut down. In particular, a Windows Sockets provider is
not  required  to support the use of connect on a socket that has been
shut down.

Notes for ATM
There  are  important  issues associated with connection teardown when
using Asynchronous Transfer Mode (ATM) and Windows Sockets 2. For more
information  about  these  important  considerations,  see the section
titled  Notes  for  ATM  in  the  Remarks  section  of the closesocket
function reference.

Requirements 
  Version: Requires Windows Sockets 1.1 or later.
  Header: Declared in Winsock2.h.
  Library: Use Ws2_32.lib.

-- 
Best regards,
 Arseny                            mailto:[email-masked]

---

From: Sam Steingold <[email-masked]>
Date: Sat Mar 30 17:29:05 2002

Arseny,

> * In message <[email-masked]>
> * On the subject of "Re[2]: [clisp-list] shutdown(2) & sockets"
> * Sent on Sun, 31 Mar 2002 11:08:09 +1000
> * Honorable Arseny Slobodjuck <[email-masked]> writes:
>

yes, thanks!

please try this:

(setq s (socket-connect 80 "gnu.org"))
==> #<IO UNBUFFERED SOCKET-STREAM CHARACTER gnu.org:80>
(write-line "GET / HTTP/1.0" s)
==> "GET / HTTP/1.0"
(close s :direction :output)
==> T
(output-stream-p s)
==> NIL
(read-line s)
==> "HTTP/1.1 200 OK" ; NIL
(close s :direction :input)
==> T
(input-stream-p s)
==> NIL
(open-stream-p s)
==> NIL
(close s)
==> T
s
==> #<CLOSED UNBUFFERED SOCKET-STREAM CHARACTER gnu.org:80>
(setq i (open "/dev/null" :direction :input) 
      o (open "/dev/null" :direction :output)
      2w (make-two-way-stream i o) 
      e (make-echo-stream i o))
==> 
#<IO ECHO-STREAM #<INPUT UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>
  #<OUTPUT UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>>
(close e :direction :input)
*** - (SYSTEM::BUILT-IN-STREAM-CLOSE :INPUT) on 
#<IO ECHO-STREAM #<INPUT UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>
  #<OUTPUT UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>> is illegal
(close 2w :direction :input)
==> T
2w
==> 
#<OUTPUT TWO-WAY-STREAM
  #<CLOSED UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>
  #<OUTPUT UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>>
i
==> #<CLOSED UNBUFFERED FILE-STREAM CHARACTER #P"/dev/null" @1>

thanks.
-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
My inferiority complex is the only thing I can be proud of.

---

From: Arseny Slobodjuck <[email-masked]>
Date: Sat Mar 30 22:38:05 2002

Hello Sam,

Sunday, March 31, 2002, 11:28:44 AM, you wrote:

Sam> please try this:
...
Works exactly same, just need /nul instead of /dev/null on
win32.

Msvc makefiles needs to be regenerated in cvs tree. It refers
dirkey.lisp.

---

From: Todd Sabin <[email-masked]>
Date: Sun Mar 31 12:25:20 2002

> signature" of the generic function CLOSE is already (stream &rest args).

Well, I'm not much of a ANSI CL language lawyer, but this seems to be
nonconformant.  The Hyperspec page for close says that close on a
composite stream should have no effect on the constituent streams.
Therefore, I'd expect that (close 2w :direction :input) would just
make 2w unusable for input, but not affect the stream
(two-way-stream-input-stream 2w).

BTW, an orthogonal issue is that the CLOSE page also contains this
example, which fails in clisp:

 (setq s (make-broadcast-stream)) =>  #<BROADCAST-STREAM>
 (close s) =>  T
 (output-stream-p s) =>  true

clisp returns NIL for the final form.

Todd

---

From: Sam Steingold <[email-masked]>
Date: Tue Apr 2 00:16:46 2002

okay - it appears that people did not like my clever CLOSE extension.
fine.  you will get SOCKET-STREAM-SHUTDOWN instead.

how do I tell whether the socket has been shut down in one direction
already?   this is crucial since otherwise there will be random
crashes (SIGPIPE) when trying to use the socket incorrectly.

> * In message <[email-masked]>
> * On the subject of "Re: [clisp-list] shutdown(2) & sockets"
> * Sent on 31 Mar 2002 15:23:50 -0500
> * Honorable Todd Sabin <[email-masked]> writes:
>

as does CMUCL.

I just fixed this.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
Save your burned out bulbs for me, I'm building my own dark room.

---

From: Arseny Slobodjuck <[email-masked]>
Date: Tue Apr 2 05:46:00 2002

Hello Sam,

Tuesday, April 02, 2002, 7:23:36 AM, you wrote:

Sam> okay - it appears that people did not like my clever CLOSE extension.
Sam> fine.  you will get SOCKET-STREAM-SHUTDOWN instead.

I like it. It's like that it cannot (syntactically) break conformant code,
right ? It can be abstracted to two way streams, not only on sockets.
But we need :direction option in open-stream-p too. As for
{input|output}-stream-p - I vote not to change it after close
(I think of it as of types).