Subject: Re: Resolving Conflicts between (invoke-restart) and (in-package)?
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 21 Mar 2007 00:46:55 -0500
Newsgroups: comp.lang.lisp
Message-ID: <yJGdnV_Q4axSW53bnZ2dnUVZ_t6qnZ2d@speakeasy.net>
[Apologies for the slow reply... I was under the weather this
past weekend with the crud that's going around locally...]

dpapathanasiou <denis.papathanasiou@gmail.com> wrote:
+---------------
| > Instead of trying to *handle* SIGPIPE, simply *ignore* it instead
| > (set it to SIG_IGN), and handle the much simpler I/O errors you're
| > going to get when you WRITE (or PRINC or FORMAT) into a closed pipe
| > or socket. Code for doing this in CMUCL may be found here:
| >
| >    http://groups.google.com/group/comp.lang.lisp/msg/ee284119a99c0d68
| 
| Rob,
| 
| I got a chance to implement this, but when I recreated the condition,
| I got thrown into the debugger, like this:
| 
| Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable UNIX:UNIX-
| ERRNO is unbound.
|    [Condition of type UNBOUND-VARIABLE]
...
| So the (handler-bind) logic did its job correctly, but lisp complains
| about the UNIX:UNIX-ERRNO variable in the first (cond) block.
| 
| I read the UNIX package chapter in the CMUCL manual, but couldn't find
| any references to UNIX:UNIX-ERRNO specifically.
| 
| Is this a typo in your example, or am I doing something else wrong?
+---------------

Oops! My apologies for not warning you!! I had forgotten about that!!
Yes, way back when the above example URL was posted to the group
[December 2005] it *was* correct code [no typo], but at the time
it was written I was probably using CMUCL-18e, and in that version
and on up through CMUCL-19a, UNIX:UNIX-ERRNO was defined as an
"alien" variable [using CMUCL's internal "alien" FFI mechanism]:

    $ src/cmd/cmucl-19a/bin/lisp -quiet -noinit -nositeinit
    * (list (lisp-implementation-type) (lisp-implementation-version))

    ("CMU Common Lisp" "19a-pre3 02-Jul-2004"
    cmu> (describe 'unix:unix-errno)

    UNIX-ERRNO is an external symbol in the UNIX package.
    It is an alien at #x08068454 of type (ALIEN:SIGNED 32).
    Its current value is 2.
    cmu> 

But sometime between CMUCL-19a and CMUCL-19c -- what I'm currently
using and what you're probably using [or later] -- the definition of
UNIX:UNIX-ERRNO changed from an alien variable to a normal function
[probably to handle the underlying changes in "errno" in versions of
Unix/Linux with threads enabled]:

    $ src/cmd/cmucl-19c/bin/lisp -quiet -noinit -nositeinit
    * (list (lisp-implementation-type) (lisp-implementation-version))

    ("CMU Common Lisp" "19c Release (19C)")
    * (describe 'unix:unix-errno)

    UNIX-ERRNO is an external symbol in the UNIX package.
    Function: #<Function UNIX:UNIX-ERRNO {1004C851}>
    Function arguments:
      There are no arguments.
    Its defined argument types are:
      NIL
    Its result type is:
      (SIGNED-BYTE 32)
    On Wednesday, 11/16/05 05:13:27 pm PST it was compiled from:
    target:code/unix.lisp
      Created: Monday, 10/10/05 11:46:39 am PDT
      Comment: $Header: /project/cmucl/cvsroot/src/code/unix.lisp,v 1.107 2005/10/10 18:46:39 rtoy Exp $
    *   

As a result of this change, the UNIX:UNIX-ERRNO *variable*
became undefined! :-(

My current code has this horrible conditional in it, which will
break (oops!) if there's ever a CMUCL-20"x" release:

    #+(or cmu19a (not cmu19)) unix:unix-errno
    #+(and cmu19 (not cmu19a)) (unix:unix-errno)

You could use that [and worry about CMUCL-20"x" later], or if
you *know* you're never going back, just use the function form.

+---------------
| Inside modlisp-handler.lisp, I've explicitly added :unix to the :use
| definition;
+---------------

I don't use "modlisp-handler.lisp" myself [I wrote my own], and I
prefer not to clutter my packages with all the symbols in UNIX, but
it's certainly o.k. to do that if it doesn't cause you any conflicts.

+---------------
| I've also invoked (defvar *old-sigpipe-handler*
| (system:enable-interrupt :sigpipe :ignore)) and it is defined at
| runtime (though it is not external to the package, since it's not
| used outside modlisp-handler):
| 
| * modlisp-handler:*old-sigpipe-handler*
| 
| The symbol "*OLD-SIGPIPE-HANDLER*" is not external in the MODLISP-
| HANDLER package.
|    [Condition of type LISP::READER-PACKAGE-ERROR]
| 
| Restarts:
|   0: [CONTINUE] Use symbol anyway.
|   1: [ABORT   ] Return to Top-Level.
| 
| Debug  (type H for help)
| 0] 0
| 
| #<Function UNIX::SIGPIPE-HANDLER {10300AD9}>
| 
| Any suggestions?
+---------------

You weren't in the MODLISP-HANDLER package when you dropped into
the debugger, and as you said, "it is not external to the package",
so you needed to have typed MODLISP-HANDLER::*OLD-SIGPIPE-HANDLER*
(two colons) instead of MODLISP-HANDLER:*OLD-SIGPIPE-HANDLER*.
It would have worked fine then.


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607