From: Tanaka Akira Date: 2008-07-29T20:43:39+09:00 Subject: [ruby-dev:35685] encoding of Dir#path 以下のように、Dir#path で返ってくるもののエンコーディングが、 Dir.open に渡したものと異なるのは変ではないでしょうか。 % ./ruby -Ku -ve ' dirname = "/tmp/\x91\x92\x93" Dir.mkdir(dirname) p [dirname, dirname.encoding] d = Dir.open(dirname) dirname2 = d.path p [dirname2, dirname2.encoding] ' ruby 1.9.0 (2008-07-29 revision 18257) [i686-linux] ["/tmp/\x91\x92\x93", #] ["/tmp/\x91\x92\x93", #] というわけで以下のようにするのはどうでしょう。 Index: dir.c =================================================================== --- dir.c (revision 18254) +++ dir.c (working copy) @@ -290,16 +290,21 @@ VALUE rb_cDir; struct dir_data { DIR *dir; - char *path; + VALUE path; rb_encoding *extenc; }; static void +mark_dir(struct dir_data *dir) +{ + rb_gc_mark(dir->path); +} + +static void free_dir(struct dir_data *dir) { if (dir) { if (dir->dir) closedir(dir->dir); - if (dir->path) xfree(dir->path); } xfree(dir); } @@ -310,10 +315,10 @@ static VALUE dir_s_alloc(VALUE klass) { struct dir_data *dirp; - VALUE obj = Data_Make_Struct(klass, struct dir_data, 0, free_dir, dirp); + VALUE obj = Data_Make_Struct(klass, struct dir_data, mark_dir, free_dir, dirp); dirp->dir = NULL; - dirp->path = NULL; + dirp->path = Qnil; dirp->extenc = NULL; return obj; @@ -358,9 +363,8 @@ dir_initialize(int argc, VALUE *argv, VA Data_Get_Struct(dir, struct dir_data, dp); if (dp->dir) closedir(dp->dir); - if (dp->path) xfree(dp->path); dp->dir = NULL; - dp->path = NULL; + dp->path = Qnil; dp->extenc = extencoding; dp->dir = opendir(RSTRING_PTR(dirname)); if (dp->dir == NULL) { @@ -372,7 +376,7 @@ dir_initialize(int argc, VALUE *argv, VA rb_sys_fail(RSTRING_PTR(dirname)); } } - dp->path = strdup(RSTRING_PTR(dirname)); + dp->path = rb_str_dup_frozen(dirname); return dir; } @@ -392,7 +396,7 @@ static VALUE dir_s_open(int argc, VALUE *argv, VALUE klass) { struct dir_data *dp; - VALUE dir = Data_Make_Struct(klass, struct dir_data, 0, free_dir, dp); + VALUE dir = Data_Make_Struct(klass, struct dir_data, mark_dir, free_dir, dp); dir_initialize(argc, argv, dir); if (rb_block_given_p()) { @@ -441,9 +445,9 @@ dir_inspect(VALUE dir) struct dir_data *dirp; Data_Get_Struct(dir, struct dir_data, dirp); - if (dirp->path) { + if (!NIL_P(dirp->path)) { const char *c = rb_obj_classname(dir); - return rb_sprintf("#<%s:%s>", c, dirp->path); + return rb_sprintf("#<%s:%s>", c, RSTRING_PTR(dirp->path)); } return rb_funcall(dir, rb_intern("to_s"), 0, 0); } @@ -463,8 +467,8 @@ dir_path(VALUE dir) struct dir_data *dirp; Data_Get_Struct(dir, struct dir_data, dirp); - if (!dirp->path) return Qnil; - return dir_enc_str(rb_str_new2(dirp->path), dirp); + if (NIL_P(dirp->path)) return Qnil; + return rb_str_dup(dirp->path); } /* -- [田中 哲][たなか あきら][Tanaka Akira]