From: Petter Gustad
Subject: daemons in Common Lisp?
Date: 
Message-ID: <87snc36ajl.fsf@filestore.home.gustad.com>
I'm looking for libraries, code snippets, or advice on how to
implement a daemon in Common Lisp, presumably in a portable way. Some
features which comes to mind:

A telnet type server so the user can log into the top level.

A way to redirect the input to the reader, or to provide a minimal top
level without a reader interface.

A stream interface to the syslog facility.

A way to receive a HUP signal in order to re-read a config file or
similar. This would not be necessary with a telnet type of server
since a reload command could be easily implemented.

Petter
-- 
________________________________________________________________________
Petter Gustad   8'h2B | (~8'h2B) - Hamlet in Verilog   http://gustad.com

From: Faried Nawaz
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <457e22d8.0110281332.6cf8fe03@posting.google.com>
Petter Gustad <·············@gustad.com> wrote in message news:<··············@filestore.home.gustad.com>...
> I'm looking for libraries, code snippets, or advice on how to
> implement a daemon in Common Lisp, presumably in a portable way.

I, too, am looking for something similar.  Is there a portable way of running
both a reader and a server/daemon in the same lisp application?  Will I need
threads support for this?

I'd really like to run a network server or client for <insert protocol>, and
be able to change code while the server/client's running.  This is a feature
Emacs gives me, but emacs isn't common-lisp...
From: Thomas F. Burdick
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <xcv668z1li1.fsf@apocalypse.OCF.Berkeley.EDU>
··@hungry.com (Faried Nawaz) writes:

> Petter Gustad <·············@gustad.com> wrote in message news:<··············@filestore.home.gustad.com>...
> > I'm looking for libraries, code snippets, or advice on how to
> > implement a daemon in Common Lisp, presumably in a portable way.
> 
> I, too, am looking for something similar.  Is there a portable way
> of running both a reader and a server/daemon in the same lisp
> application?  Will I need threads support for this?

You don't strictly need threads -- you could do it with CMUCL's
serve-event architecture, for example (cf. Araneida
<http://araneida.telent.net/docs/index.html>).  But some sort of
support for doing more than one thing at once is needed, yes.  The
multiprocessing in most CL's is pretty similar, so the code you use
will be pretty similar, particularly if you use the portable wrapper
from CLOCC.

> I'd really like to run a network server or client for <insert
> protocol>, and be able to change code while the server/client's
> running.  This is a feature Emacs gives me, but emacs isn't
> common-lisp...

Yeah, and the problem is, if you start a project in Emacs, thinking
"I'll rewrite it later in Common Lisp, after learning how to do X, Y,
and Z, that I already know how to do in Emacs" -- well, Emacs is a
good enough lisp environment that one is (or I am, anyhow) likely to
just keep it in Emacs.  I mean, I'd rather develop something in
Elisp/Emacs over C/Unix, where feasible, but it's hardly CL.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Daniel Barlow
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <87bsirsnh8.fsf@noetbook.telent.net>
Petter Gustad <·············@gustad.com> writes:

> I'm looking for libraries, code snippets, or advice on how to
> implement a daemon in Common Lisp, presumably in a portable way. Some
> features which comes to mind:
> 
> A telnet type server so the user can log into the top level.

If the target is a fairly recent Unix, you might want to look at
detachtty, which lets you start interactive processes and (using ssh)
attach/detach from their streams across a network connection.

If the target is Debian GNU/Linux unstable, it's packaged in the
archive and available with "apt-get install detachtty"

If the target is something else, http://ww.telent.net/cliki/detachtty
has a link to the download site.

It's been tested on Linux and FreeBSD, and should work (perhaps with
some header file frobbing) on anything with a forkpty() call.


-dan

-- 

  http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources 
From: Petter Gustad
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <87k7xfy087.fsf@filestore.home.gustad.com>
Daniel Barlow <···@telent.net> writes:

> Petter Gustad <·············@gustad.com> writes:
> 
> > I'm looking for libraries, code snippets, or advice on how to
> > implement a daemon in Common Lisp, presumably in a portable way. Some
> > features which comes to mind:
> > 
> > A telnet type server so the user can log into the top level.
> 
> If the target is a fairly recent Unix, you might want to look at
> detachtty, which lets you start interactive processes and (using ssh)
> attach/detach from their streams across a network connection.

Thanks for the tip. I'll check it out.

Petter
-- 
________________________________________________________________________
Petter Gustad   8'h2B | (~8'h2B) - Hamlet in Verilog   http://gustad.com
From: Petter Gustad
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <877ktd613x.fsf@filestore.home.gustad.com>
Daniel Barlow <···@telent.net> writes:

> If the target is a fairly recent Unix, you might want to look at
> detachtty, which lets you start interactive processes and (using ssh)

Great tool - thanks! I can use it for my Verilog simulations too, they
run for weeks and weeks...

Petter
-- 
________________________________________________________________________
Petter Gustad   8'h2B | (~8'h2B) - Hamlet in Verilog   http://gustad.com
From: Kent M Pitman
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <sfw4rojptxk.fsf@world.std.com>
How apropos.  A question about daemons for Halloween... :-)

Petter Gustad <·············@gustad.com> writes:

> I'm looking for libraries, code snippets, or advice on how to
> implement a daemon in Common Lisp, presumably in a portable way. Some
> features which comes to mind:
> 
> A telnet type server so the user can log into the top level.

Network servers are per-vendor.  Most give you a way to listen on a port
and to run a function when there's a connection.  The function will get
socket arguments from which you can obtain a stream.  

You have to make a decision about whether you will give each user access
to the same Lisp (shared address space) or whether you want multiple Lisps.
To my knowledge, no extant Lisp allows you to have separate address spaces
within the same Lisp image.
 
> A way to redirect the input to the reader, or to provide a minimal top
> level without a reader interface.

You can call READ with a stream.  See CLHS.

http://www.xanalys.com/software_tools/reference/HyperSpec/FrontMatter/

> A stream interface to the syslog facility.

Except for specification of the actual filename (which you'll have to do
from a configuration file, probably) and making sure you have the right
permissions (which you'll have to probably do from a shell or in the
file system when you start the Lisp that spawns the server), this can be
done portably.  See CLHS for information about I/O.  Logs files are just 
files with logs in them.

> A way to receive a HUP signal in order to re-read a config file or
> similar. This would not be necessary with a telnet type of server
> since a reload command could be easily implemented.

This is vendor specific.  Contact your vendor.  But the normal fallback
if you don't have a HUP interrupt is to just stop and restart lisp.
From: Petter Gustad
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <87n12by0cf.fsf@filestore.home.gustad.com>
Kent M Pitman <······@world.std.com> writes:

> How apropos.  A question about daemons for Halloween... :-)

I didn't even think about that :-)

> Petter Gustad <·············@gustad.com> writes:
> 
> > I'm looking for libraries, code snippets, or advice on how to
> > implement a daemon in Common Lisp, presumably in a portable way. Some
> > features which comes to mind:
> > 
> > A telnet type server so the user can log into the top level.
> 
> Network servers are per-vendor.  Most give you a way to listen on a port
> and to run a function when there's a connection.  The function will get
> socket arguments from which you can obtain a stream.  
> 
> You have to make a decision about whether you will give each user access
> to the same Lisp (shared address space) or whether you want multiple Lisps.
> To my knowledge, no extant Lisp allows you to have separate address spaces
> within the same Lisp image.

I understand. There are quite a few security issues related to this...


> > A way to redirect the input to the reader, or to provide a minimal top
> > level without a reader interface.
> 
> You can call READ with a stream.  See CLHS.

I was thinking if there is a (portable?) way to bind the *terminal-io*
(or whatever) for the top level to some sort of device. If you do a
simple redirect input from /dev/null I guess you'll get an end of file
and your lisp will quit.

I minimal top level with no reader interface would do the job too.

> http://www.xanalys.com/software_tools/reference/HyperSpec/FrontMatter/
> 
> > A stream interface to the syslog facility.
> 
> Except for specification of the actual filename (which you'll have to do
> from a configuration file, probably) and making sure you have the right
> permissions (which you'll have to probably do from a shell or in the
> file system when you start the Lisp that spawns the server), this can be
> done portably.  See CLHS for information about I/O.  Logs files are just 
> files with logs in them.

I was thinking of the syslog facility under UNIX, which is a little
more advanced than a plain file. It's a socket interface and talks to
the syslog daemons which has a config file where one can describe
the destination of the output.

> > A way to receive a HUP signal in order to re-read a config file or
> > similar. This would not be necessary with a telnet type of server
> > since a reload command could be easily implemented.
> 
> This is vendor specific.  Contact your vendor.  But the normal fallback
> if you don't have a HUP interrupt is to just stop and restart lisp.

OK. I haven't picked a vendor for this project yet. I have been
playing with some free implementations as well as a couple commercial
packages (trial versions).
 
I know that most of my questions could be solved by using a foreign
function interface to the socket library, syslog, and some sort of
signal handler. Most of the Lisp programs I've written have been
either interactive of some kind of filters. I was asking in case there
were some idioms or common tricks to use to implement daemons in
Common Lisp.

Petter
-- 
________________________________________________________________________
Petter Gustad   8'h2B | (~8'h2B) - Hamlet in Verilog   http://gustad.com
From: Kent M Pitman
Subject: Re: daemons in Common Lisp?
Date: 
Message-ID: <sfwofmr75b3.fsf@world.std.com>
Petter Gustad <·············@gustad.com> writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> I was thinking if there is a (portable?) way to bind the *terminal-io*
> (or whatever) for the top level to some sort of device. If you do a
> simple redirect input from /dev/null I guess you'll get an end of file
> and your lisp will quit.

You can approximate a read-eval-print loop with

  (defun repl () (loop (print (eval (read)))))

of course. It doesn't hurt to add rubout handling and a way to exit, so
it gets a little messier. It will tend to look something like the following
(which I didn't test, but will give you an idea about the shape to expect):

  (defun repl (&key (standard-input *standard-input*)
                    (standard-output *standard-output*))
    (let ((*standard-input* standard-input)
          (*standard-output* standard-output))
      (handler-bind ((error #'(lambda (condition) 
                                (format t "~&Error: ~A" condition)
                                (abort))))
        (with-simple-restart (listener-exit "Exit listener.")
          (loop
            (with-simple-restart (abort "Return to listener toplevel.")
              (let* ((form (with-input-editing (read)))
                     (results (multiple-value-list (eval form))))
                (format t "~&=> ~{~S~^,~%   ~}~%" results))))))))

Note that you CANNOT bind *terminal-io*.  This is intentional.  It is
about windows/terminals.  Contrary to what Unix may sometimes suggest,
arbitrary streams are not terminals.  For example, you can't display 
to them, you can't rubout, clear screen, etc.

You CAN bind *standard-input* and *standard-output*, but you won't get
a rubout-handling console.  You can WRITE such a thing, of course.
That's what the WITH-INPUT-EDITING in the above is doing.  
See my paper http://world.std.com/~pitman/PS/Ambitious.html for hints
about how to do rubout handling in Lisp.  It's fairly doable and 
can be quite elegant, actually.

> I minimal top level with no reader interface would do the job too.
> 
> > http://www.xanalys.com/software_tools/reference/HyperSpec/FrontMatter/
> > 
> > > A stream interface to the syslog facility.
> > 
> > Except for specification of the actual filename (which you'll have to do
> > from a configuration file, probably) and making sure you have the right
> > permissions (which you'll have to probably do from a shell or in the
> > file system when you start the Lisp that spawns the server), this can be
> > done portably.  See CLHS for information about I/O.  Logs files are just 
> > files with logs in them.
> 
> I was thinking of the syslog facility under UNIX, which is a little
> more advanced than a plain file. It's a socket interface and talks to
> the syslog daemons which has a config file where one can describe
> the destination of the output.

Use the sockets interface that your system provides, then.  CL has none
built in.
 
> > > A way to receive a HUP signal in order to re-read a config file or
> > > similar. This would not be necessary with a telnet type of server
> > > since a reload command could be easily implemented.
> > 
> > This is vendor specific.  Contact your vendor.  But the normal fallback
> > if you don't have a HUP interrupt is to just stop and restart lisp.
> 
> OK. I haven't picked a vendor for this project yet. I have been
> playing with some free implementations as well as a couple commercial
> packages (trial versions).
>  
> I know that most of my questions could be solved by using a foreign
> function interface to the socket library,

Xanalys and Franz both have this packaged as Lisp functions.  I'd be
surprised if a number of the free implementations didn't also.

> syslog, 

This would be easy to write in Xanalys or Franz if all you have to do is
connect to a given socket and run some simple protocol.  Franz's
AllegroServe might implement it; you could check there.  Check their
license, though.  I don't know if you're allowed to subset AllegroServe.

(I also had heard you can't load AllegroServe into Allegro without
paying additional money for a more fancy license to have your lisp be
a "server" instead of just a "terminal console".  It would be weird if
this were so, but I have not had a chance to track this down.  It's
something to ask about and/or to check your license agreement for if
you get that far.  Maybe someone from Franz will read this and 
clarify/correct my understanding.  I'd hate to spread misinformation.)

> and some sort of signal handler.

This is probably something you can do from Lisp, too.  Don't write foreign
functions except as last resort.  Even if you could do it from C, you might
clash with other support the system itself is doing through its own C code,
so it's better to keep things coordinated if you can.

> Most of the Lisp programs I've written have been
> either interactive of some kind of filters. I was asking in case there
> were some idioms or common tricks to use to implement daemons in
> Common Lisp.