From: John Carter Date: 2009-05-15T17:41:16+09:00 Subject: [ruby-core:23460] [Bug #1472] rb_f_syscall converts string value to null terminated c string, but syscall structs can contain nulls. Bug #1472: rb_f_syscall converts string value to null terminated c string, but syscall structs can contain nulls. http://redmine.ruby-lang.org/issues/show/1472 Author: John Carter Status: Open, Priority: Normal ruby -v: ruby 1.8.7 (2009-04-08 patchlevel 160) [i686-linux] The following snippet invokes the statfs64 syscall. bug.rb================================================================ string = " "* 84 p syscall( 268, "/", string.size, string) string = "\0"* 84 p syscall( 268, "/", string.size, string) ====================================================================== If I run this under ruby 1.8.6, both invocations work. If I run this under ruby 1.8.7, the second one fails with... ruby -w bug.rb 0 bug.rb:4:in `syscall': string contains null byte (ArgumentError) from bug.rb:4 The reason is in ruby-1.8.7-p22/io.c in the function rb_f_syscall there is this code.... if (!NIL_P(v)) { StringValue(v); rb_str_modify(v); arg[i] = (unsigned long)StringValueCStr(v); } In ruby 1.8.6 is was if (!NIL_P(v)) { StringValue(v); rb_str_modify(v); arg[i] = (unsigned long)RSTRING(v)->ptr; } The macro StringValueCStr is defined in ruby.h as.... #define StringValueCStr(v) rb_string_value_cstr(&(v)) The function rb_string_value_cstr is defined in string.c as .... rb_string_value_cstr(ptr) volatile VALUE *ptr; { VALUE str = rb_string_value(ptr); char *s = RSTRING(str)->ptr; if (!s || RSTRING(str)->len != strlen(s)) { rb_raise(rb_eArgError, "string contains null byte"); } return s; } I believe the original 1.8.6 implementation was correct and this particular changed should be rolled back. Thanks. http://rubyforge.org/tracker/index.php?func=detail&aid=20895&group_id=426&atid=1698 Applies to 1.8.7 and 1.9.1 p 129 ---------------------------------------- http://redmine.ruby-lang.org