Process.daemon() returns -1 on failure ifndef HAVE_DAEMON

 Process.daemon() 失敗時の挙動が、 HAVE_DAEMON 定義時と非定義時
ã¨ã§ç•°ãªã£ã¦ã„ã¾ã™ã€‚å¾Œè€…ã®å ´åˆã‚‚ã€ -1 を返すのではなく errno に
基づいた例外を上げるべきだと思いますがどうでしょう。


Akinori MUSHA / http://akinori.org/

Mon Mar 29 19:08:10 2010 Akinori MUSHA [email protected]

  • process.c (proc_daemon): Process.daemon should raise an error on
    failure regardless of whether the implementation uses daemon(3)
    or not.

Index: process.c

— process.c (revision 27080)
+++ process.c (working copy)
@@ -4531,8 +4531,8 @@ proc_setmaxgroups(VALUE obj, VALUE val)
#if defined(HAVE_DAEMON) || defined(HAVE_FORK)
/*

  • call-seq:
    • Process.daemon()                        => fixnum
      
    • Process.daemon(nochdir=nil,noclose=nil) => fixnum
      
    • Process.daemon()                        => 0
      
    • Process.daemon(nochdir=nil,noclose=nil) => 0
      
    • Detach the process from controlling terminal and run in
    • the background as system daemon. Unless the argument
      @@ -4540,6 +4540,7 @@ proc_setmaxgroups(VALUE obj, VALUE val)
    • working directory to the root (“/”). Unless the argument
    • noclose is true, daemon() will redirect standard input,
    • standard output and standard error to /dev/null.
    • Return zero on success, or raise one of Errno::*.
      */

static VALUE
@@ -4561,7 +4562,7 @@ proc_daemon(int argc, VALUE *argv)
#elif defined(HAVE_FORK)
switch (rb_fork(0, 0, 0, Qnil)) {
case -1:

  • return INT2FIX(-1);
  • rb_sys_fail(“daemon”);
    case 0:
    break;
    default:
    @@ -4573,7 +4574,7 @@ proc_daemon(int argc, VALUE argv)
    /
    must not be process-leader */
    switch (rb_fork(0, 0, 0, Qnil)) {
    case -1:
  • return INT2FIX(-1);
  • rb_sys_fail(“daemon”);
    case 0:
    break;
    default:

2010e$BG/e(B3e$B7ne(B29e$BF|e(B19:52 Akinori MUSHA [email protected]:

e$B!!e(BProcess.daemon() e$B<:GT;~$N5sF0$,!"e(B HAVE_DAEMON e$BDj5A;~$HHsDj5A;~e(B
e$B$H$G0[$J$C$F$$$^$9!#8e<T$N>l9g$b!"e(B -1 e$B$rJV$9$N$G$O$J$/e(B errno e$B$Ke(B
e$B4p$E$$$?Nc30$r>e$2$k$Y$-$@$H;W$$$^$9$,$I$&$G$7$g$&!#e(B

e$B<:GT;~$N5sF0$r9g$o$;$k$H$$$&%3%s%;%W%H$O;?@.$G$9$,!"e(Brb_fork()e$B$N$h$&$KJ#?t$Ne(B
e$B%7%9%F%`%3!<%k$r8F$V4X?t$KBP$7$Fe(Brb_sys_fail()e$B$r;H$&$N$O7y$+$b!#e(B
e$BM}M3$Oe(Berrnoe$B$r8+$F$b<:GT$7$F$$$k860x$r$^$C$?$/EA$($F$$$J$$$H9M$($k$+$i$G$9!#e(B

e$B0l$D<ALd$J$N$G$9$,!"$3$NNc30$O%9%/%j%W%HB&$G$I$&$$$&=hM}$r4|BT$7$F$$$^$9$+!)e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:40832] Process.daemon() returns -1 on failure
ifndef HAVE_DAEMON”
on Mon, 29 Mar 2010 19:52:00 +0900, “Akinori MUSHA”
[email protected] writes:

|e$B!!e(BProcess.daemon() e$B<:GT;~$N5sF0$,!"e(B HAVE_DAEMON e$BDj5A;~$HHsDj5A;~e(B
|e$B$H$G0[$J$C$F$$$^$9!#8e<T$N>l9g$b!"e(B -1 e$B$rJV$9$N$G$O$J$/e(B errno e$B$Ke(B
|e$B4p$E$$$?Nc30$r>e$2$k$Y$-$@$H;W$$$^$9$,$I$&$G$7$g$&!#e(B

e$BF10U$7$^$9!#e(B

2010e$BG/e(B3e$B7ne(B29e$BF|e(B19:52 Akinori MUSHA [email protected]:

e$B!!e(BProcess.daemon() e$B<:GT;~$N5sF0$,!"e(B HAVE_DAEMON e$BDj5A;~$HHsDj5A;~e(B
e$B$H$G0[$J$C$F$$$^$9!#8e<T$N>l9g$b!"e(B -1 e$B$rJV$9$N$G$O$J$/e(B errno e$B$Ke(B
e$B4p$E$$$?Nc30$r>e$2$k$Y$-$@$H;W$$$^$9$,$I$&$G$7$g$&!#e(B

e$B<:GT;~$N5sF0$r9g$o$;$k$H$$$&%3%s%;%W%H$O;?@.$G$9$,!"e(Brb_fork()e$B$N$h$&$KJ#?t$Ne(B
e$B%7%9%F%`%3!<%k$r8F$V4X?t$KBP$7$Fe(Brb_sys_fail()e$B$r;H$&$N$O7y$+$b!#e(B
e$BM}M3$Oe(Berrnoe$B$r8+$F$b<:GT$7$F$$$k860x$r$^$C$?$/EA$($F$$$J$$$H9M$($k$+$i$G$9!#e(B

e$B<+8J%l%9e(B
e$B8+D>$7$?$H$3$m!“e(Bprocess.ce$B$K;w$?$h$&$J=hM}$O$9$G$KBt;3$”$k$N$G!“$$$^$5$ie(B
e$B$H$$$&46$N$”$k;XE&$G$7$?!#<h$j>C$7$^$9!#$9$$$^$;$s!#e(B

At Tue, 30 Mar 2010 08:53:22 +0900,
KOSAKI Motohiro wrote:

見直したところ、process.cに似たような処理はすでに沢山あるので、いまさら
という感のある指摘でした。取り消します。すいません。

 そうなんです。rb_f_fork(Process.fork)がそうなっています。

 エミュレートしている *BSD 系の daemon(3) も、失敗時は一律に
-1 を返すので errno を見よ、に止まっています。

一つ質問なのですが、この例外はスクリプト側でどういう処理を期待していますか?

 ちょうど昨日、Twitterで popen(3) は様々な理由で失敗するのに
相互に区別できないエラーの組が複数あるという話をしていました。
本件は、気になって io.c や process.c で rb_sys_fail() している
箇所を調べていてたまたま見つけたものです。

 今のところは、 Errno::* については errno を発生したシステãƒ
コールが特定できてなおかつ各値についての対処法が(POSIX 的に)
明確なものを除いては、そのままユーザに伝えてあきらめるか代替
手段を取るくらいですね。

 Ruby(CRuby)としては、POSIX やメジャーな libc 実装等でより
適切なエラー処理が可能な新しいAPIが出てきたら対応を考える、と
いうのが妥当なところかも。

e$B<jCJ$r<h$k$/$i$$$G$9$M!#e(B

Rubye$B!Je(BCRubye$B!K$H$7$F$O!“e(BPOSIX e$B$d%a%8%c!<$Je(B libc e$B<BAuEy$G$h$je(B
e$BE,@Z$J%(%i!<=hM}$,2DG=$J?7$7$$e(BAPIe$B$,=P$F$-$?$iBP1~$r9M$($k!”$He(B
e$B$$$&$N$,BEEv$J$H$3$m$+$b!#e(B

e$B$J$k$[$I!#e(B
e$B<+J,$O%f!<%6%i%s%I$NG:$_$rJY6/$7$?$/$F!"$3$Ne(BMLe$B$r9XFI$5$;$F$b$i$C$F$$$kLL$,$"$j$^$9$N$Ge(B
e$B$3$&$$$&OC$OHs>o$K6=L#?<$$$G$9!#e(B