[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Axiom-developer] Re: [Gcl-devel] Simple web server code for GCL for Win

From: Camm Maguire
Subject: [Axiom-developer] Re: [Gcl-devel] Simple web server code for GCL for Windows
Date: 28 Apr 2005 14:52:28 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings!  Here's a quick way to get started:

address@hidden:/fix/t1/camm/debian/gcl/gcl-2.6.6$ diff -u ../gcl-2.6.5/o/file.d 
--- ../gcl-2.6.5/o/file.d       2004-05-07 21:48:58.000000000 +0000
+++ o/file.d    2005-04-28 16:21:33.000000000 +0000
@@ -1200,11 +1200,19 @@
        switch (strm->sm.sm_mode) {
        case smm_socket:
-         { int ch  = getCharGclSocket(strm,Cnil);
-          if (ch == EOF) return FALSE;
-          else unreadc_stream(ch,strm);
-          return TRUE;
+         {
+           fd_set fds;
+           struct timeval tv;
+           FD_ZERO(&fds);
+           FD_SET(SOCKET_STREAM_FD(strm),&fds);
+           memset(&tv,0,sizeof(tv));
+           return select(SOCKET_STREAM_FD(strm)+1,&fds,NULL,NULL,&tv)>0 ? TRUE 
+/*       { int ch  = getCharGclSocket(strm,Cnil); */
+/*        if (ch == EOF) return FALSE; */
+/*        else unreadc_stream(ch,strm); */
+/*        return TRUE; */
+/*       } */
        case smm_input:
@@ -2302,6 +2310,42 @@
+#ifndef __MINGW32__
+#  include <sys/socket.h>
+#  include <netinet/in.h>
+#  include <arpa/inet.h>
+#  include <windows.h>
+#  include <winsock2.h>
+#include <errno.h>
+@(static defun accept (x)
+int fd,n;
+struct sockaddr_in addr;
+object server,host,port;
+  if (type_of(x) != t_stream)
+    FEerror("~S is not a steam~%",1,x);
+  if (x->sm.sm_mode!=smm_two_way)
+    FEerror("~S is not a two-way steam~%",1,x);
+  fd=accept(SOCKET_STREAM_FD(STREAM_INPUT_STREAM(x)),(struct sockaddr *)&addr, 
+  if (fd <0) {
+    FEerror("Error ~S on accepting connection to 
+    x=Cnil;
+  } else {
+    server=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_car;
+    host=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_car;
+    port=STREAM_INPUT_STREAM(x)->sm.sm_object0->c.c_cdr->c.c_cdr->c.c_car;
+    x = make_two_way_stream
+      (make_socket_stream(fd,gcl_sm_input,server,host,port,Cnil),
+       make_socket_stream(fd,gcl_sm_output,server,host,port,Cnil));
+  }
+  @(return `x`);
@@ -2441,6 +2485,7 @@
+       make_si_function("ACCEPT",Laccept);
        make_function("STREAMP", Lstreamp);
        make_function("INPUT-STREAM-P", Linput_stream_p);
Starting program: /fix/t1/camm/debian/gcl/gcl-2.6.6/unixport/saved_gcl .
GCL (GNU Common Lisp)  2.6.6 CLtL1    Apr 28 2005 17:10:11
Source License: LGPL(gcl,gmp), GPL(unexec,bfd)
Binary License:  GPL due to GPL'ed components: (READLINE BFD UNEXEC)
Modifications of this banner must retain notice of a compatible license
Dedicated to the memory of W. Schelter

Use (help) to get some basic information on how to use GCL.

>(defun foo (s) 
  (let* ((get (read s nil 'eof)) 
         (fn (and (eq get 'get) (string-downcase (read s nil 'eof))))
         (fn (when (probe-file fn) fn)))
    (format s "HTTP/1.1 ~S~%~%" (if fn 404 500))
    (when fn
      (if (pathname-name (pathname fn))
          (with-open-file (q fn) (si::copy-stream q s))
        (dolist (l (directory fn)) (format s "~a~%" (namestring l)))))
    (close s)))

>(defun bar (p fn) 
  (let ((s (si::socket p :server fn))) 
        (tagbody l 
                (when (si::listen s) 
                        (let ((w (si::accept s))) 
                                (foo w))) 
                (sleep 3) 
                (go l))))

>(bar 8080 #'foo)

Then point your browser to localhost:8080.  You should be able to get
directory listings and files.  There is obviously no protocol nor
error implementation here, but that should be straightforward for the
web gurus.

This will accept multiple simultaneous connections and process them
one at a time.  The delay mechanism can obviously be adjusted.  Each
connection is stateless -- a multiplexing solution for persistent
connections can be implemented in like manner.  Also, all connections
are in the same process.  It is trivial to fork() in linux for each
connection, but don't know how this would be done on Windows.
Speaking of which, does MS have select?  There are other hooks for
allowing work in the image while connections are handled in the
background, e.g. SIGIO, but don't know the portable nor most desirable
way of doing this.

Anything can be done here that one wishes -- my question is, what is
the advantage vis a vis an external server like apache?  Presumably,
axiom could spit out results directly instead of being called in a
cgi, which is of some value.  Anyway, more discussion on where and why
this should go if anywhere would be great!

Take care,

"Page, Bill" <address@hidden> writes:

> GCL Gurus,
> Does anyone know of a simple web server program in lisp that
> works (or should work) under GCL on both linux and Windows?
> I am correct to assume that with socket support working properly
> this should be quite easy (say 20 or 30 lines of code)?
> If an example code exists that works on linux, I would like to
> try it under Windows. If there are problems I would be glad to
> help try debugging it.
> Regards,
> Bill Page.
> _______________________________________________
> Gcl-devel mailing list
> address@hidden

Camm Maguire                                            address@hidden
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah

reply via email to

[Prev in Thread] Current Thread [Next in Thread]