diff --git a/dir.c b/dir.c index 9498d67da9..d67de8cf06 100644 --- a/dir.c +++ b/dir.c @@ -1586,23 +1586,29 @@ dir_chdir(VALUE dir) } #ifndef _WIN32 +static VALUE +getcwd_to_str(VALUE arg) +{ + const char *path = (const char *)arg; +#ifdef __APPLE__ + return rb_str_normalize_ospath(path, strlen(path)); +#else + return rb_str_new2(path); +#endif +} + +static VALUE +getcwd_xfree(VALUE arg) +{ + xfree((void *)arg); + return Qnil; +} + VALUE rb_dir_getwd_ospath(void) { - char *path; - VALUE cwd; - VALUE path_guard; - - path_guard = rb_imemo_tmpbuf_new(); - path = ruby_getcwd(); - rb_imemo_tmpbuf_set_ptr(path_guard, path); -#ifdef __APPLE__ - cwd = rb_str_normalize_ospath(path, strlen(path)); -#else - cwd = rb_str_new2(path); -#endif - rb_free_tmp_buffer(&path_guard); - return cwd; + char *path = ruby_getcwd(); + return rb_ensure(getcwd_to_str, (VALUE)path, getcwd_xfree, (VALUE)path); } #endif diff --git a/util.c b/util.c index 4caa324849..3315eb575e 100644 --- a/util.c +++ b/util.c @@ -529,45 +529,43 @@ ruby_strdup(const char *str) char * ruby_getcwd(void) { - VALUE guard = rb_imemo_tmpbuf_new(); int size = 200; char *buf = xmalloc(size); while (!getcwd(buf, size)) { int e = errno; if (e != ERANGE) { - rb_free_tmp_buffer(&guard); + xfree(buf); rb_syserr_fail(e, "getcwd"); } size *= 2; - rb_imemo_tmpbuf_set_ptr(guard, buf); - buf = xrealloc(buf, size); + xfree(buf); + buf = xmalloc(size); } - rb_imemo_tmpbuf_set_ptr(guard, NULL); return buf; } # else -static const rb_data_type_t getcwd_buffer_guard_type = { - .wrap_struct_name = "ruby_getcwd_guard", - .function = { - .dfree = free // not xfree. - }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED -}; +static VALUE +getcwd_strdup(VALUE arg) +{ + return (VALUE)ruby_strdup((const char *)arg); +} + +static VALUE +getcwd_free(VALUE arg) +{ + free((void *)arg); + return Qnil; +} char * ruby_getcwd(void) { - VALUE guard = TypedData_Wrap_Struct((VALUE)0, &getcwd_buffer_guard_type, NULL); - char *buf, *cwd = getcwd(NULL, 0); - RTYPEDDATA_DATA(guard) = cwd; + char *cwd = getcwd(NULL, 0); if (!cwd) rb_sys_fail("getcwd"); - buf = ruby_strdup(cwd); /* allocate by xmalloc */ - free(cwd); - RTYPEDDATA_DATA(RB_GC_GUARD(guard)) = NULL; - return buf; + return (char *)rb_ensure(getcwd_strdup, (VALUE)cwd, getcwd_free, (VALUE)cwd); } # endif