зеркало из https://github.com/github/ruby.git
* win32/win32.c (rb_w32_telldir, rb_w32_seekdir): should use long.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22885 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
f5315680aa
Коммит
bf065f2e2e
|
@ -1,3 +1,7 @@
|
|||
Wed Mar 11 13:16:58 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* win32/win32.c (rb_w32_telldir, rb_w32_seekdir): should use long.
|
||||
|
||||
Wed Mar 11 13:03:12 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* ext/dl/handle.c (rb_dlhandle_sym): fixed heap corruption.
|
||||
|
|
|
@ -30,8 +30,8 @@ typedef struct {
|
|||
DIR* rb_w32_opendir(const char*);
|
||||
struct direct* rb_w32_readdir(DIR *);
|
||||
struct direct* rb_w32_readdir_with_enc(DIR *, rb_encoding *);
|
||||
off_t rb_w32_telldir(DIR *);
|
||||
void rb_w32_seekdir(DIR *, off_t);
|
||||
long rb_w32_telldir(DIR *);
|
||||
void rb_w32_seekdir(DIR *, long);
|
||||
void rb_w32_rewinddir(DIR *);
|
||||
void rb_w32_closedir(DIR *);
|
||||
|
||||
|
|
121
win32/win32.c
121
win32/win32.c
|
@ -371,6 +371,18 @@ translate_char(char *p, int from, int to)
|
|||
return p;
|
||||
}
|
||||
|
||||
#ifndef CSIDL_LOCAL_APPDATA
|
||||
#define CSIDL_LOCAL_APPDATA 28
|
||||
#endif
|
||||
#ifndef CSIDL_COMMON_APPDATA
|
||||
#define CSIDL_COMMON_APPDATA 35
|
||||
#endif
|
||||
#ifndef CSIDL_WINDOWS
|
||||
#define CSIDL_WINDOWS 36
|
||||
#endif
|
||||
#ifndef CSIDL_SYSTEM
|
||||
#define CSIDL_SYSTEM 37
|
||||
#endif
|
||||
#ifndef CSIDL_PROFILE
|
||||
#define CSIDL_PROFILE 40
|
||||
#endif
|
||||
|
@ -400,11 +412,27 @@ regulate_path(WCHAR *path)
|
|||
}
|
||||
}
|
||||
|
||||
static UINT
|
||||
get_system_directory(WCHAR *path, UINT len)
|
||||
{
|
||||
HANDLE hKernel = GetModuleHandle("kernel32.dll");
|
||||
|
||||
if (hKernel) {
|
||||
typedef UINT WINAPI wgetdir_func(WCHAR*, UINT);
|
||||
FARPROC ptr = GetProcAddress(hKernel, "GetSystemWindowsDirectoryW");
|
||||
if (ptr) {
|
||||
return (*(wgetdir_func *)ptr)(path, len);
|
||||
}
|
||||
}
|
||||
return GetWindowsDirectoryW(path, len);
|
||||
}
|
||||
|
||||
#define numberof(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
static void
|
||||
init_env(void)
|
||||
{
|
||||
static const WCHAR TMPDIR[] = L"TMPDIR";
|
||||
WCHAR env[_MAX_PATH];
|
||||
DWORD len;
|
||||
BOOL f;
|
||||
|
@ -442,6 +470,20 @@ init_env(void)
|
|||
SetEnvironmentVariableW(L"USER", env);
|
||||
}
|
||||
NTLoginName = strdup(rb_w32_getenv("USER"));
|
||||
|
||||
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));
|
||||
SetEnvironmentVariableW(TMPDIR, env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1639,12 +1681,11 @@ win32_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *dummy)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
|
||||
VALUE
|
||||
rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc)
|
||||
{
|
||||
static rb_encoding *utf16 = (rb_encoding *)-1;
|
||||
VALUE src;
|
||||
VALUE dst;
|
||||
VALUE opthash;
|
||||
int ecflags;
|
||||
VALUE ecopts;
|
||||
|
@ -1656,14 +1697,23 @@ ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
|
|||
}
|
||||
if (!utf16)
|
||||
/* maybe miniruby */
|
||||
return win32_direct_conv(file, entry, NULL);
|
||||
return Qnil;
|
||||
|
||||
src = rb_enc_str_new((char *)file, lstrlenW(file) * sizeof(WCHAR), utf16);
|
||||
src = rb_enc_str_new((char *)wstr, lstrlenW(wstr) * sizeof(WCHAR), utf16);
|
||||
opthash = rb_hash_new();
|
||||
rb_hash_aset(opthash, ID2SYM(rb_intern("undef")),
|
||||
ID2SYM(rb_intern("replace")));
|
||||
ecflags = rb_econv_prepare_opts(opthash, &ecopts);
|
||||
dst = rb_str_encode(src, rb_enc_from_encoding(enc), ecflags, ecopts);
|
||||
return rb_str_encode(src, rb_enc_from_encoding(enc), ecflags, ecopts);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ruby_direct_conv(const WCHAR *file, struct direct *entry, rb_encoding *enc)
|
||||
{
|
||||
VALUE dst = rb_w32_conv_from_wchar(file, enc);
|
||||
|
||||
if (NIL_P(dst))
|
||||
return win32_direct_conv(file, entry, NULL);
|
||||
|
||||
entry->d_namlen = RSTRING_LEN(dst);
|
||||
if (!(entry->d_name = malloc(entry->d_namlen + 1)))
|
||||
|
@ -1727,7 +1777,7 @@ rb_w32_readdir_with_enc(DIR *dirp, rb_encoding *enc)
|
|||
// Telldir returns the current string pointer position
|
||||
//
|
||||
|
||||
off_t
|
||||
long
|
||||
rb_w32_telldir(DIR *dirp)
|
||||
{
|
||||
return dirp->loc;
|
||||
|
@ -1738,7 +1788,7 @@ rb_w32_telldir(DIR *dirp)
|
|||
// (Saved by telldir).
|
||||
|
||||
void
|
||||
rb_w32_seekdir(DIR *dirp, off_t loc)
|
||||
rb_w32_seekdir(DIR *dirp, long loc)
|
||||
{
|
||||
if (dirp->loc > loc) rb_w32_rewinddir(dirp);
|
||||
|
||||
|
@ -4951,3 +5001,58 @@ rb_w32_fsopen(const char *path, const char *mode, int shflags)
|
|||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL
|
||||
rb_w32_get_special_directory(int n, WCHAR *path)
|
||||
{
|
||||
if (!get_special_folder(n, path))
|
||||
return FALSE;
|
||||
regulate_path(path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
w32_get_special_directory(VALUE self, VALUE num)
|
||||
{
|
||||
VALUE str;
|
||||
int n = NUM2INT(num);
|
||||
WCHAR path[_MAX_PATH];
|
||||
|
||||
if (!rb_w32_get_special_directory(n, path)) {
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
|
||||
OBJ_TAINT(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
w32_get_system_directory(VALUE self)
|
||||
{
|
||||
VALUE str;
|
||||
WCHAR path[_MAX_PATH];
|
||||
|
||||
if (!get_system_directory(path, numberof(path))) {
|
||||
rb_sys_fail(0);
|
||||
}
|
||||
regulate_path(path);
|
||||
str = rb_w32_conv_from_wchar(path, rb_filesystem_encoding());
|
||||
OBJ_TAINT(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
void
|
||||
Init_win32(void)
|
||||
{
|
||||
VALUE mWin32 = rb_define_module("Win32");
|
||||
VALUE dir = rb_define_module_under(mWin32, "Dir");
|
||||
rb_define_module_function(dir, "special", w32_get_special_directory, 1);
|
||||
rb_define_module_function(dir, "system", w32_get_system_directory, 0);
|
||||
rb_define_const(dir, "LOCAL_APPDATA", UINT2NUM(CSIDL_LOCAL_APPDATA));
|
||||
rb_define_const(dir, "COMMON_APPDATA", UINT2NUM(CSIDL_COMMON_APPDATA));
|
||||
rb_define_const(dir, "WINDOWS", UINT2NUM(CSIDL_WINDOWS));
|
||||
rb_define_const(dir, "SYSTEM", UINT2NUM(CSIDL_SYSTEM));
|
||||
rb_define_const(dir, "PROFILE", UINT2NUM(CSIDL_PROFILE));
|
||||
rb_define_const(dir, "PERSONAL", UINT2NUM(CSIDL_PERSONAL));
|
||||
rb_define_const(mWin32, "Version", UINT2NUM(rb_w32_osver()));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче