[Bug:trunk] ENV.[]= should raise an error on failure

 現在 ENV.[]= は setenv(3) や putenv(3) の返り値を見ていませんが、
エラーは検知して例外を上げるべきではないでしょうか。

 わかりやすい例では ENV[“A=”] = “1” のように不正な名前の環境変数を
設定しようとすると Error::EINVAL が発生するようになります。

Index: hash.c

— hash.c (revision 26276)
+++ hash.c (working copy)
@@ -2049,7 +2049,8 @@ ruby_setenv(const char *name, const char
len = strlen(name) + 1 + strlen(value) + 1;
buf = ALLOCA_N(char, len);
snprintf(buf, len, “%s=%s”, name, value);

  • putenv(buf);
  • if (putenv(buf))

  •  rb_sys_fail("putenv");
    

    /* putenv() doesn’t handle empty value */
    if (*value)
    @@ -2064,10 +2065,13 @@ ruby_setenv(const char *name, const char
    #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
    #undef setenv
    #undef unsetenv

  • if (value)
  • setenv(name,value,1);
  • else
  • unsetenv(name);
  • if (value) {
  • if (setenv(name, value, 1))
  •  rb_sys_fail("setenv");
    
  • } else {
  • if (unsetenv(name))
  •  rb_sys_fail("unsetenv");
    
  • }
    #elif defined sun
    size_t len = strlen(name);
    char **env_ptr, *str;
    @@ -2081,7 +2085,8 @@ ruby_setenv(const char *name, const char
    if (value) {
    str = malloc(len += strlen(value) + 2);
    snprintf(str, len, “%s=%s”, name, value);
  • putenv(str);
  • if (putenv(str))
  •  rb_sys_fail("putenv");
    
    }
    #else /* WIN32 */
    size_t len;

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

In message “Re: [ruby-dev:40023] [Bug:trunk] ENV.[]= should raise an
error on failure”
on Mon, 11 Jan 2010 03:42:34 +0900, “Akinori MUSHA”
[email protected] writes:

|e$B!!8=:_e(B ENV.[]= e$B$Oe(B setenv(3) e$B$de(B putenv(3) e$B$NJV$jCM$r8+$F$$$^$;$s$,!"e(B
|e$B%(%i!<$O8!CN$7$FNc30$r>e$2$k$Y$-$G$O$J$$$G$7$g$&$+!#e(B
|
|e$B!!$o$+$j$d$9$$Nc$G$Oe(B ENV[“A=”] = “1” e$B$N$h$&$KIT@5$JL>A0$N4D6-JQ?t$re(B
|e$B@_Dj$7$h$&$H$9$k$He(B Error::EINVAL e$B$,H/@8$9$k$h$&$K$J$j$^$9!#e(B

e$B;?@.$7$^$9!#%3%_%C%H$7$F$/$@$5$$$^$;$s$+!#e(B

At Mon, 11 Jan 2010 09:27:58 +0900,
matz wrote:

In message “Re: [ruby-dev:40023] [Bug:trunk] ENV.[]= should raise an error on failure”
on Mon, 11 Jan 2010 03:42:34 +0900, “Akinori MUSHA” [email protected] writes:

| 現在 ENV.[]= は setenv(3) や putenv(3) の返り値を見ていませんが、
|エラーは検知して例外を上げるべきではないでしょうか。
|
| わかりやすい例では ENV[“A=”] = “1” のように不正な名前の環境変数を
|設定しようとすると Error::EINVAL が発生するようになります。

賛成します。コミットしてくださいませんか。

 コミットしました。

 さらに、 putenv(3) を呼ぶ(name と value を呼び出し側で合成する)
環境では name 中の ‘=’ を検知して EINVAL をエミュレートすべきかも
しれませんね。少し調べてからやります。

 なお、 #if defined(_WIN32) の中はいじらないでおきました。以下の
部分で、 Windowsã®å ´åˆã¯ putenv(3) の失敗を織り込んでいるようにも
読めるからです。

2052 putenv(buf);
2053
2054 /* putenv() doesn’t handle empty value */
2055 if (*value)
2056 SetEnvironmentVariable(name,value);

ところで、このコメントもそのまま取ると以下のようにするのが正しい
ように思えますが、真意は何でしょうか。

if (*value) {
    /* bufの作成 */
    putenv(buf);
} else {
    SetEnvironmentVariable(name, value);
}

e$B$3$s$K$A$O!"$J$+$`$ie(B(e$B$&e(B)e$B$G$9!#e(B

In message “[ruby-dev:40026] Re: [Bug:trunk] ENV.[]= should raise an
error on failure”
on Jan.11,2010 13:28:01, [email protected] wrote:

e$B$H$3$m$G!“$3$N%3%a%s%H$b$=$N$^$^<h$k$H0J2<$N$h$&$K$9$k$N$,@5$7$$e(B
e$B$h$&$K;W$($^$9$,!”??0U$O2?$G$7$g$&$+!#e(B

if (*value) {
    /* bufe$B$N:[email protected](B */
    putenv(buf);
} else {
    SetEnvironmentVariable(name, value);
}

e$B>r7o$,4V0c$C$F$$$?$N$OA4$/$=$NDL$j$G$9e(B orz
commite$B$7$F$*$-$^$7$?!#e(B

e$BI,$:e(Bputenv()e$B$rDL$7$F$$$k$N$O!“AG$Ne(Bgetenv()e$B$,8+$k$N$O??$N4D6-e(B
e$BJQ?tNN0h$G$O$J$/e(Bputenv()e$B$,A`:n$7$F$$$k%3%T!<NN0h$G$”$k$?$a!“e(B
e$B$=$A$i$K85$N4D6-JQ?tCM$,;D$C$F$7$^$&$N$rHr$1$k$?$a$G$9!#e(B
e$B$D$^$j!“6u$N4D6-JQ?tCM$r@_Dj$7$?$H$-!“85$N4D6-JQ?tCM$,;D$k$he(B
e$B$j!”$=$N4D6-JQ?t$,>C$($kJ}$,%^%7!”$H$$$&H=CG$G$9!#e(B
e$B$J$*!”$3$l$i$NOC$Oe(Brubye$B$K$OD>@$N1F6A$rM?$($k$b$N$G$O$J$/$F!"e(B
e$B;R%W%m%;%9$KEAGE$7$?;~$K$N$_1F6A$7$^$9!#e(B

e$B$=$l$G$O!#e(B