diff --git a/ChangeLog b/ChangeLog index c543f9e033..f4468db848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -Tue Mar 16 14:47:55 2010 Nobuyoshi Nakada +Tue Mar 16 15:20:13 2010 Nobuyoshi Nakada + + * ext/tmpdir: split from lib/tmpdir.rb. + + * win32/win32.c (rb_w32_system_tmpdir): extracted from init_env. * win32/win32.c (rb_w32_getcwd): remvoed duplicated code. diff --git a/ext/tmpdir/extconf.rb b/ext/tmpdir/extconf.rb new file mode 100644 index 0000000000..a283f851b0 --- /dev/null +++ b/ext/tmpdir/extconf.rb @@ -0,0 +1,6 @@ +case +when have_func("rb_w32_system_tmpdir") + ok = true # win32 +else +end +create_makefile("tmpdir") if ok diff --git a/ext/tmpdir/tmpdir.c b/ext/tmpdir/tmpdir.c new file mode 100644 index 0000000000..f046713b63 --- /dev/null +++ b/ext/tmpdir/tmpdir.c @@ -0,0 +1,32 @@ +#include +#include + +#define numberof(array) (sizeof(array) / sizeof(*array)) + +#ifdef HAVE_RB_W32_SYSTEM_TMPDIR +UINT rb_w32_system_tmpdir(WCHAR *path, UINT len); +VALUE rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc); +#endif + +static VALUE +system_tmpdir(void) +{ +#ifdef HAVE_RB_W32_SYSTEM_TMPDIR + WCHAR path[_MAX_PATH]; + UINT len = rb_w32_system_tmpdir(path, numberof(path)); + if (!len) return Qnil; + return rb_w32_conv_from_wchar(path, rb_filesystem_encoding()); +#else + return rb_filesystem_str_new_cstr("/tmp"); +#endif +} + +/* + * sets Dir.@@systmpdir. + */ +void +Init_tmpdir(void) +{ + rb_cvar_set(rb_cDir, rb_intern_const("@@systmpdir"), + rb_obj_freeze(system_tmpdir())); +} diff --git a/lib/tmpdir.rb b/lib/tmpdir.rb index 32befa3e8a..302c2fb39f 100644 --- a/lib/tmpdir.rb +++ b/lib/tmpdir.rb @@ -5,36 +5,14 @@ # require 'fileutils' +begin + require 'tmpdir.so' +rescue LoadError +end class Dir - @@systmpdir = '/tmp' - - if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and - begin - require 'Win32API' - true - rescue LoadError - end - CSIDL_LOCAL_APPDATA = 0x001c - max_pathlen = 260 - windir = "\0"*(max_pathlen+1) - begin - getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L') - raise RuntimeError if getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) != 0 - windir.rstrip! - rescue RuntimeError - begin - getdir = Win32API.new('kernel32', 'GetSystemWindowsDirectory', 'PL', 'L') - rescue RuntimeError - getdir = Win32API.new('kernel32', 'GetWindowsDirectory', 'PL', 'L') - end - windir[getdir.call(windir, windir.size)..-1] = "" - end - windir.force_encoding(Dir.pwd.encoding) - temp = File.expand_path('temp', windir.untaint) - @@systmpdir = temp if File.directory?(temp) and File.writable?(temp) - end + @@systmpdir ||= '/tmp' ## # Returns the operating system's temporary file path. diff --git a/win32/win32.c b/win32/win32.c index 8a348d849d..8216ac9918 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -430,6 +430,22 @@ get_system_directory(WCHAR *path, UINT len) #define numberof(array) (sizeof(array) / sizeof(*array)) +UINT +rb_w32_system_tmpdir(WCHAR *path, UINT len) +{ + static const WCHAR temp[] = L"temp"; + WCHAR *p; + + if (!get_special_folder(CSIDL_LOCAL_APPDATA, path)) { + if (get_system_directory(path, len)) return 0; + } + p = translate_wchar(path, L'\\', L'/'); + if (*(p - 1) != L'/') *p++ = L'/'; + if (p - path + numberof(temp) >= len) return 0; + memcpy(p, temp, sizeof(temp)); + return p - path + numberof(temp) - 1; +} + static void init_env(void) { @@ -484,15 +500,8 @@ init_env(void) if (!GetEnvironmentVariableW(TMPDIR, env, numberof(env)) && !GetEnvironmentVariableW(L"TMP", env, numberof(env)) && !GetEnvironmentVariableW(L"TEMP", env, numberof(env)) && - (get_special_folder(CSIDL_LOCAL_APPDATA, env) || - get_system_directory(env, numberof(env)))) { - static const WCHAR temp[] = L"temp"; - WCHAR *p = translate_wchar(env, L'\\', L'/'); - if (*(p - 1) != L'/') *p++ = L'/'; - if (p - env + numberof(temp) < numberof(env)) { - memcpy(p, temp, sizeof(temp)); - set_env_val(TMPDIR); - } + rb_w32_system_tmpdir(env, numberof(env))) { + set_env_val(TMPDIR); } #undef env