Greetings! Here's a quick way to get started: ============================================================================= [EMAIL PROTECTED]:/fix/t1/camm/debian/gcl/gcl-2.6.6$ diff -u ../gcl-2.6.5/o/file.d 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) { #ifdef HAVE_NSOCKET 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 : FALSE; } +/* { int ch = getCharGclSocket(strm,Cnil); */ +/* if (ch == EOF) return FALSE; */ +/* else unreadc_stream(ch,strm); */ +/* return TRUE; */ +/* } */ #endif case smm_input: @@ -2302,6 +2310,42 @@ @) +#ifndef __MINGW32__ +# include <sys/socket.h> +# include <netinet/in.h> +# include <arpa/inet.h> +#else +# include <windows.h> +# include <winsock2.h> +#endif +#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, &n); + if (fd <0) { + FEerror("Error ~S on accepting connection to ~S~%",1,make_simple_string(strerror(errno)),x); + 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`); + + +@) + DEF_ORDINARY("MYADDR",sKmyaddr,KEYWORD,""); DEF_ORDINARY("MYPORT",sKmyport,KEYWORD,""); DEF_ORDINARY("ASYNC",sKasync,KEYWORD,""); @@ -2441,6 +2485,7 @@ make_si_function("FREAD",Lfread); #ifdef HAVE_NSOCKET make_si_function("SOCKET",Lsocket); + make_si_function("ACCEPT",Laccept); #endif 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" <[EMAIL PROTECTED]> 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 > Gcl-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/gcl-devel > > -- Camm Maguire [EMAIL PROTECTED] ========================================================================== "The earth is but one country, and mankind its citizens." -- Baha'u'llah _______________________________________________ Gcl-devel mailing list Gcl-devel@gnu.org http://lists.gnu.org/mailman/listinfo/gcl-devel