CommonLispで何かを作る 4 SBCLでCGI

CGIって

#!sbclのパス

その後にプログラムを書く

って感じでいいと思うんだけど、sbclのパスってどこなんだろ?
findで調べんのかなぁ、って思ってたら昔書いたメモ発見。

which xxx

でパスがわかるってさ。

which sbcl

/usr/bin/sbcl

て返ってきた。
というわけで書いてみたCGIがこんなの
test.cgi

#!/usr/bin/sbcl
(print "Content-type: text/plain~%~%")
(print "Hello, LISP CGI!!")

これをpublic_htmlにおいて、chmod 755 test.cgi

でブラウザからhttp://localhost/~xxx/test.cgiにアクセス。
...ダメ。でない。
Internal Server Errorだそうだ。
そう上手くはいかないかぁ。

なんでダメなんやろ?

ともあれ、シェルから走らせてみる。

./test.cgi

っと。
やっぱり動かない。
こりゃそもそも動いてないや。

色々探すと、SBCLのマニュアルに答えがあった。
http://www.sbcl.org/manual/Unix_002dstyle-Command-Line-Protocol.html#Unix_002dstyle-Command-Line-Protocol
SBCLはシェバンスクリプトに対応していないらしい。
つうか、#!で書くヤツってシェバンっていうのね。

マニュアルに下がって設定ファイルを書いていく
~/に.sbclrcを作る。内容はこんなん。

;;; If the first user-processable command-line argument is a filename,
;;; disable the debugger, load the file handling shebang-line and quit.
(let ((script (and (second *posix-argv*)
(probe-file (second *posix-argv*)))))
(when script
;; Handle shebang-line
(set-dispatch-macro-character #\# #\!
(lambda (stream char arg)
(declare (ignore char arg))
(read-line stream)))
;; Disable debugger
(setf *invoke-debugger-hook*
(lambda (condition hook)
(declare (ignore hook))
;; Uncomment to get backtraces on errors
;; (sb-debug:backtrace 20)
(format *error-output* "Error: ~A~%" condition)
(quit)))
(load script)
(quit)))

test.cgiはこんな風に変える。

#!/usr/bin/sbcl --noinform
(format t "Content-type: text/plain~%~%")
(format t "Hello, LISP CGI!!~%")

で./test.cgiを走らせると

Content-type: text/plain

Hello, LISP CGI!!

って表示された。
おお。いけるか?

もう一度http://localhost/~xxx/test.cgiにアクセスしてみる。
いけ!
ってやっぱりだめ。
うーん。/home/xxx/に.sbclrcを作ってるからダメなのかな。
Apacheから動かしたときってどのユーザでsbclが動くんだろ。

sbclをやめてclispにしてみた

#!/usr/bin/clisp
(format t"Content-type: text/plain~%~%")
(format t "hello clisp!!~%")

clispではちゃんとブラウザに

hello clisp!!

と表示された。

んーー。どうしよう。
clispに変えるか?
でも、もともとclispだったのをsbclに変えたんだよな。
sbclにはスレッドのサポートがあったから。
何せwindowsのプログラマなのでスレッドが好きなんです。
fork??何それ??って感じなのです。

どうするかなぁ、、、と考えつつあちこちのサイトをうろつく。
FastCGIやらforkを調べてみたり・・・。
しばらくして気がつくとファイルソケットでのプロセス間通信を試している自分に気がつく。
・・・あれ?もともと何しようとしてたんだっけ?

つづく。