COMMON LISP JP > Archives > 2011/05/02

2011/05/02 13:50:48 UTCPocket
#
返信がかなり遅れました。なるほど情報ありがとうございます。
#
今、sbclをUbuntu環境でつかっていて外部プログラムの実行のためにsb-ext:run-programを利用しているのですが、run-programをする関数をどのように記述すればいいのかの部分で詰まっています。
#
というのも、(defun test-run-program (file-path) (sb-ext:run-program "program-path" '("--filename" file-path)))
#
というような引数からプログラムに渡す引数を受け取る関数を書いて適当な引数を(この場合は文字列)を渡すと、
#
file-path is not SEQUENCEというエラーが帰ってきてしまいます。
#
このような小さな関数だとマクロにしてしまって済むのですが、ほかの関数の中で引数にあたる文字列を作ってこのマクロに渡すようにするとやはり同様のエラーが発生します。
2011/05/02 14:43:30 UTCrayfill
#
run-programの第二引数は文字列のリストを期待しているのにクォートしたリストを渡しているのでfile-pathがシンボルで渡されてますよ。
おそらくはこういう関数にしたいってことですよね?
(defun test-run-program (file-path)
  (sb-ext:run-program "program-path" `("--filename" ,file-path)))
2011/05/02 14:46:40 UTCPocket
#
なるほど
2011/05/02 15:54:15 UTCPocket
#
無事実行できました。本当にありがとうございます。
#
質問を続けてしまって申し訳ないのですが、
#
SBCLでsave-lisp-and-dieでexecutableにしたファイルなどでCtrl-C(SIGINT)を受信したときに終了するようにするにはどのようにハンドラを登録すればいいのでしょうか?
2011/05/02 17:40:28 UTCrayfill
#
(defun run ()
  (handler-case
      (loop for i below 100
	 do (progn
	      (format t "i is ~A~%" i)
	      (sleep 1)))
    (sb-kernel::interactive-interrupt (int)
      (declare (ignorable int))
      (format t "caught sigint."))))

(save-lisp-and-die 
 (merge-pathnames (user-homedir-pathname)
		  (pathname "core"))
 :toplevel #'run
 :executable t)
#
こんなふうにsb-kernel::interactive-interrupt conditionを受け取ればsigintを処理できるようです。
2011/05/02 20:59:52 UTCPocket
#
ありがとうございます。私のプログラムを(おそらく)適当な形にhandler-caseを含む形に修正してみたのですが、
#
^C
debugger invoked on a SB-SYS:INTERACTIVE-INTERRUPT in thread #<THREAD
                                                               "initial thread" RUNNING
                                                               {BE2F8B1}>:
  Interactive interrupt at #xB7FE1416.

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE] Return from SB-UNIX:SIGINT.

("bogus stack frame")
#
のようにデバッガに入ってしまい、終了するという風にはなりませんでした。
2011/05/02 21:07:09 UTCPocket
#
私のコードをpaste.lispに貼ってみました。
#
http://paste.lisp.org/+2LX4
#
handler-caseの位置を色々変更してみたりしているので、どの箇所に置くべきなどありましたら宜しくお願いいたします。
2011/05/02 22:01:41 UTCrayfill
#
あー、interactive-interruptの定義位置が違うみたいですね。
#
debuggerのメッセージからすると
#
(handler-case
#
...
#
(sb-sys:interactive-interrupt (e)
#
...
#
とかに書き換えたら動きませんか?
#
こっちのバージョン(sbcl 1.0.45.0 on ubuntu 11.4)ではsb-sys:interactive-interruptでも動きました。こっちはcondition名がexportされてるからsb-sys:interactive-interruptのほうが想定されているトラップ用コンデションなんでしょうね。
#
http://www.rhinocerus.net/forum/lang-lisp/613272-handling-ctrl-c-interrupt-sbcl.html バージョンによってはバグっててデバッガに入ってしまうバージョンもあるみたいです