Bug #3825

ENV.delete raise Exception on Windows

Added by phasis68 (Heesob Park) over 1 year ago. Updated about 1 year ago.

[ruby-core:32353]
Status:Closed Start date:09/13/2010
Priority:Normal Due date:
Assignee:usa (Usaku NAKAMURA) % Done:

100%

Category:core
Target version:2.0.0
ruby -v:ruby 1.9.3dev (2010-09-12 trunk 29234) [i386-mswin32_90]

Description

ENV.delete raises Invalid argument Exception on Windows.

The error is due to trying SetEnvironmentVariable even if putenv succeeded.

C:\>ruby  -ve "ENV['foo']='bar';ENV.delete('foo')"
ruby 1.9.3dev (2010-09-12 trunk 29234) [i386-mswin32_90]
-e:1:in `delete': Invalid argument - ruby_setenv (Errno::EINVAL)
        from -e:1:in `<main>'

The patch is simple as like this:


--- hash.c.org  2010-09-13 11:31:01.000000000 +0900
+++ hash.c      2010-09-13 11:51:08.000000000 +0900
@@ -2156,7 +2156,7 @@
     /* even if putenv() failed, clean up and try to delete the
      * variable from the system area. */
     rb_str_resize(buf, 0);
-    if (!value || !*value) {
+    if (failed && (!value || !*value)) {
        /* putenv() doesn't handle empty value */
        if (!SetEnvironmentVariable(name,value)) goto fail;
     }

Associated revisions

Revision 29377
Added by usa (Usaku NAKAMURA) over 1 year ago

* hash.c (ruby_setenv): workaround for old Windows. a patch from Heesob Park. [ruby-core:32353]

History

Updated by nobu (Nobuyoshi Nakada) over 1 year ago

Hi,

At Mon, 13 Sep 2010 12:05:11 +0900,
Heesob Park wrote in [ruby-core:32353]:
> ENV.delete raises Invalid argument Exception on Windows.
> 
> The error is due to trying SetEnvironmentVariable even if putenv succeeded.

Does test/ruby/test_env.rb fail now?  I can't check it now.

-- 
Nobu Nakada

Updated by phasis68 (Heesob Park) over 1 year ago

Hi,

2010/9/13 Nobuyoshi Nakada <nobu@ruby-lang.org>:
> Hi,
>
> At Mon, 13 Sep 2010 12:05:11 +0900,
> Heesob Park wrote in [ruby-core:32353]:
>> ENV.delete raises Invalid argument Exception on Windows.
>>
>> The error is due to trying SetEnvironmentVariable even if putenv succeeded.
>
> Does test/ruby/test_env.rb fail now?  I can't check it now.
>
On Windows XP Home SP3:
Test run options: --seed 1488

Loaded suite test_env
Started
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
Finished in 0.156250 seconds.

  1) Error:
test_aset(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

  2) Error:
test_assoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

  3) Error:
test_bracket(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

  4) Error:
test_bracket(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

  5) Error:
test_clear(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:223:in `clear'
    test_env.rb:223:in `test_clear'

  6) Error:
test_clear(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

  7) Failure:
test_delete(TestEnv) [test_env.rb:92]:
Exception raised:
<#<Errno::EINVAL: Invalid argument - ruby_setenv>>.

  8) Error:
test_delete(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

  9) Error:
test_each_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 10) Error:
test_each_pair(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 11) Error:
test_each_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 12) Error:
test_empty_p(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:269:in `clear'
    test_env.rb:269:in `test_empty_p'

 13) Error:
test_empty_p(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 14) Error:
test_fetch(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:104:in `delete'
    test_env.rb:104:in `test_fetch'

 15) Error:
test_fetch(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 16) Error:
test_getenv(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 17) Error:
test_has_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 18) Error:
test_has_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

 19) Error:
test_has_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 20) Error:
test_has_value2(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:297:in `clear'
    test_env.rb:297:in `test_has_value2'

 21) Error:
test_has_value2(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 22) Error:
test_huge_value(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 23) Error:
test_inspect(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:232:in `clear'
    test_env.rb:232:in `test_inspect'

 24) Error:
test_inspect(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 25) Error:
test_invert(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:352:in `clear'
    test_env.rb:352:in `test_invert'

 26) Error:
test_invert(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 27) Error:
test_key(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 28) Error:
test_keys(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

 29) Error:
test_keys(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 30) Error:
test_rassoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:304:in `clear'
    test_env.rb:304:in `test_rassoc'

 31) Error:
test_rassoc(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 32) Error:
test_rehash(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 33) Error:
test_reject(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 34) Error:
test_reject_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

 35) Error:
test_reject_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 36) Error:
test_replace(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:360:in `replace'
    test_env.rb:360:in `test_replace'

 37) Error:
test_replace(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 38) Error:
test_select(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 39) Error:
test_select_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

 40) Error:
test_select_bang(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 41) Error:
test_shift(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:342:in `clear'
    test_env.rb:342:in `test_shift'

 42) Error:
test_shift(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 43) Error:
test_size(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 44) Error:
test_to_a(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:11:in `delete'
    test_env.rb:11:in `setup'

 45) Error:
test_to_a(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 46) Error:
test_to_hash(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 47) Error:
test_to_s(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 48) Error:
test_update(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:365:in `clear'
    test_env.rb:365:in `test_update'

 49) Error:
test_update(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 50) Error:
test_values(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

 51) Error:
test_values_at(TestEnv):
Errno::EINVAL: Invalid argument - ruby_setenv
    test_env.rb:17:in `clear'
    test_env.rb:17:in `teardown'

34 tests, 209 assertions, 1 failures, 50 errors, 0 skips

Test run options: --seed 1488


---------------------------------------------------------------------------------
BTW, On Windows 7, it works fine:

Test run options: --seed 34498

Loaded suite test_env
Started
..................................
Finished in 0.454000 seconds.

34 tests, 391 assertions, 0 failures, 0 errors, 0 skips

Test run options: --seed 34498


Regards,
Park Heesob

Updated by pweldon (Peter Weldon) over 1 year ago

Knowing the value of GetLastError() after SetEnvironmentVariable() fails may give a clue. Can you try get that?

In VS, I would, add "$err,hr" to my watch window and put a break point at the fail: label in hash.c (setenv).

Updated by phasis68 (Heesob Park) over 1 year ago

2010/9/14 Peter Weldon <redmine@ruby-lang.org>:
> Issue #3825 has been updated by Peter Weldon.
>
>
> Knowing the value of GetLastError() after SetEnvironmentVariable() fails may give a clue. Can you try get that?
>
> In VS, I would, add "$err,hr" to my watch window and put a break point at the fail: label in hash.c (setenv).

The value of GetLastError() is 203 and which defined as
#define ERROR_ENVVAR_NOT_FOUND      203

I am not sure in which case, SetEnvironmentVariable() with null value fails.

The another possible patch is

--- hash.c      2010-09-14 09:47:12.000000000 +0900
+++ hash.c.new  2010-09-14 09:47:12.000000000 +0900
@@ -2158,7 +2158,7 @@
     rb_str_resize(buf, 0);
     if (!value || !*value) {
        /* putenv() doesn't handle empty value */
-       if (!SetEnvironmentVariable(name,value)) goto fail;
+       if (!SetEnvironmentVariable(name,value) && GetLastError() !=
ERROR_ENVVAR_NOT_FOUND) goto fail;
     }
     if (failed) goto fail;
 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)

Updated by shyouhei (Shyouhei Urabe) over 1 year ago

  • Status changed from Open to Assigned
  • Assignee set to usa (Usaku NAKAMURA)

Updated by phasis68 (Heesob Park) over 1 year ago

I confirmed this issue occurs on Windows 2000, XP, 2003.

Is there any specific reason for this issue not fixed?

Updated by usa (Usaku NAKAMURA) over 1 year ago

Does this occur in trunk?
Though I cannot reproduce.

Updated by phasis68 (Heesob Park) over 1 year ago

2010/9/30 Usaku NAKAMURA <redmine@ruby-lang.org>:
> Issue #3825 has been updated by Usaku NAKAMURA.
>
>
> Does this occur in trunk?
> Though I cannot reproduce.

Yes, it occur in trunk on Windows XP. I know it does not occur on Windows 7.

C:\>ruby  -ve "ENV['foo']='bar';ENV.delete('foo')"
ruby 1.9.3dev (2010-09-28 trunk 29354) [i386-mswin32_90]
-e:1:in `delete': Invalid argument - ruby_setenv (Errno::EINVAL)
        from -e:1:in `<main>'

Updated by usa (Usaku NAKAMURA) over 1 year ago

Hello,

In message "[ruby-core:32647] Re: [Ruby 1.9-Bug#3825] ENV.delete raise Exception on Windows"
    on Sep.30,2010 10:31:34, <phasis@gmail.com> wrote:
> Yes, it occur in trunk on Windows XP. I know it does not occur on Windows 7.

Oh, I see.
Just merged your patch. thanks!


Regards,
-- 
U.Nakamura <usa@garbagecollect.jp>

Updated by usa (Usaku NAKAMURA) over 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100
This issue was solved with changeset r29377.
Heesob, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

Also available in: Atom PDF