[前][次][番号順一覧][スレッド一覧]

ruby-changes:9906

From: nobu <ko1@a...>
Date: Mon, 12 Jan 2009 16:47:04 +0900 (JST)
Subject: [ruby-changes:9906] Ruby:r21447 (trunk, ruby_1_8): * win32/win32.c (open_dir_handle): extracted from rb_w32_opendir.

nobu	2009-01-12 16:45:31 +0900 (Mon, 12 Jan 2009)

  New Revision: 21447

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21447

  Log:
    * win32/win32.c (open_dir_handle): extracted from rb_w32_opendir.
    * win32/win32.c (winnt_stat): gets rid of strange behavior of
      GetFileAttributes().  [ruby-core:21269]

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/win32/win32.c
    trunk/ChangeLog
    trunk/test/ruby/test_file_exhaustive.rb
    trunk/win32/win32.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 21446)
+++ ChangeLog	(revision 21447)
@@ -1,3 +1,10 @@
+Mon Jan 12 16:45:28 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (open_dir_handle): extracted from rb_w32_opendir.
+
+	* win32/win32.c (winnt_stat): gets rid of strange behavior of
+	  GetFileAttributes().  [ruby-core:21269]
+
 Mon Jan 12 12:43:55 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* instruby.rb (parse_args, install): added --strip option.
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 21446)
+++ win32/win32.c	(revision 21447)
@@ -1412,13 +1412,44 @@
 #define BitOfIsRep(n) ((n) * 2 + 1)
 #define DIRENT_PER_CHAR (CHAR_BIT / 2)
 
+static HANDLE
+open_dir_handle(const char *filename, WIN32_FIND_DATA *fd)
+{
+    HANDLE fh;
+    static const char wildcard[] = "/*";
+    long len = strlen(filename);
+    char *scanname = malloc(len + sizeof(wildcard));
+
+    //
+    // Create the search pattern
+    //
+    if (!scanname) {
+	return INVALID_HANDLE_VALUE;
+    }
+    memcpy(scanname, filename, len + 1);
+
+    if (index("/\\:", *CharPrev(scanname, scanname + len)) == NULL)
+	memcpy(scanname + len, wildcard, sizeof(wildcard));
+    else
+	memcpy(scanname + len, wildcard + 1, sizeof(wildcard) - 1);
+
+    //
+    // do the FindFirstFile call
+    //
+    fh = FindFirstFile(scanname, fd);
+    free(scanname);
+    if (fh == INVALID_HANDLE_VALUE) {
+	errno = map_errno(GetLastError());
+    }
+    return fh;
+}
+
 DIR *
 rb_w32_opendir(const char *filename)
 {
     DIR               *p;
     long               len;
     long               idx;
-    char	      *scanname;
     char	      *tmp;
     struct stati64     sbuf;
     WIN32_FIND_DATA fd;
@@ -1436,6 +1467,11 @@
 	return NULL;
     }
 
+    fh = open_dir_handle(filename, &fd);
+    if (fh == INVALID_HANDLE_VALUE) {
+	return NULL;
+    }
+
     //
     // Get us a DIR structure
     //
@@ -1443,32 +1479,6 @@
     if (p == NULL)
 	return NULL;
 
-    //
-    // Create the search pattern
-    //
-    len = strlen(filename) + 2 + 1;
-    if (!(scanname = malloc(len))) {
-	free(p);
-	return NULL;
-    }
-    strlcpy(scanname, filename, len);
-
-    if (index("/\\:", *CharPrev(scanname, scanname + strlen(scanname))) == NULL)
-	strlcat(scanname, "/*", len);
-    else
-	strlcat(scanname, "*", len);
-
-    //
-    // do the FindFirstFile call
-    //
-    fh = FindFirstFile(scanname, &fd);
-    free(scanname);
-    if (fh == INVALID_HANDLE_VALUE) {
-	errno = map_errno(GetLastError());
-	free(p);
-	return NULL;
-    }
-
     idx = 0;
 
     //
@@ -3467,6 +3477,17 @@
 }
 
 static int
+check_valid_dir(const char *path)
+{
+    WIN32_FIND_DATA fd;
+    HANDLE fh = open_dir_handle(path, &fd);
+    if (fh == INVALID_HANDLE_VALUE)
+	return -1;
+    FindClose(fh);
+    return 0;
+}
+
+static int
 winnt_stat(const char *path, struct stati64 *st)
 {
     HANDLE h;
@@ -3496,6 +3517,9 @@
 	    errno = map_errno(GetLastError());
 	    return -1;
 	}
+	if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+	    if (check_valid_dir(path)) return -1;
+	}
 	st->st_mode  = fileattr_to_unixmode(attr, path);
     }
 
@@ -3505,6 +3529,21 @@
     return 0;
 }
 
+#ifdef WIN95
+static int
+win95_stat(const char *path, struct stati64 *st)
+{
+    int ret = stati64(path, st);
+    if (ret) return ret;
+    if (st->st_mode & S_IFDIR) {
+	return check_valid_dir(path);
+    }
+    return 0;
+}
+#else
+#define win95_stat(path, st) -1
+#endif
+
 int
 rb_w32_stat(const char *path, struct stat *st)
 {
@@ -3552,7 +3591,7 @@
     else if (*end == '\\' || (buf1 + 1 == end && *end == ':'))
 	strlcat(buf1, ".", size);
 
-    ret = IsWinNT() ? winnt_stat(buf1, st) : stati64(buf1, st);
+    ret = IsWinNT() ? winnt_stat(buf1, st) : win95_stat(buf1, st);
     if (ret == 0) {
 	st->st_mode &= ~(S_IWGRP | S_IWOTH);
     }
Index: test/ruby/test_file_exhaustive.rb
===================================================================
--- test/ruby/test_file_exhaustive.rb	(revision 21446)
+++ test/ruby/test_file_exhaustive.rb	(revision 21447)
@@ -97,6 +97,7 @@
 
   def test_directory_p
     assert(File.directory?(@dir))
+    assert(!(File.directory?(@dir+"/...")))
     assert(!(File.directory?(@file)))
     assert(!(File.directory?(@nofile)))
   end
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 21446)
+++ ruby_1_8/ChangeLog	(revision 21447)
@@ -1,3 +1,10 @@
+Mon Jan 12 16:45:28 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* win32/win32.c (open_dir_handle): extracted from rb_w32_opendir.
+
+	* win32/win32.c (winnt_stat): gets rid of strange behavior of
+	  GetFileAttributes().  [ruby-core:21269]
+
 Mon Jan 12 13:41:33 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* eval.c (rb_thread_start_0): must use ruby_longjmp instead of
Index: ruby_1_8/win32/win32.c
===================================================================
--- ruby_1_8/win32/win32.c	(revision 21446)
+++ ruby_1_8/win32/win32.c	(revision 21447)
@@ -1479,14 +1479,44 @@
 #define BitOfIsRep(n) ((n) * 2 + 1)
 #define DIRENT_PER_CHAR (CHAR_BIT / 2)
 
+static HANDLE
+open_dir_handle(const char *filename, WIN32_FIND_DATA *fd)
+{
+    HANDLE fh;
+    static const char wildcard[] = "/*";
+    long len = strlen(filename);
+    char *scanname = malloc(len + sizeof(wildcard));
+
+    //
+    // Create the search pattern
+    //
+    if (!scanname) {
+	return INVALID_HANDLE_VALUE;
+    }
+    memcpy(scanname, filename, len + 1);
+
+    if (index("/\\:", *CharPrev(scanname, scanname + len)) == NULL)
+	memcpy(scanname + len, wildcard, sizeof(wildcard));
+    else
+	memcpy(scanname + len, wildcard + 1, sizeof(wildcard) - 1);
+
+    //
+    // do the FindFirstFile call
+    //
+    fh = FindFirstFile(scanname, fd);
+    free(scanname);
+    if (fh == INVALID_HANDLE_VALUE) {
+	errno = map_errno(GetLastError());
+    }
+    return fh;
+}
+
 DIR *
 rb_w32_opendir(const char *filename)
 {
     DIR               *p;
     long               len;
     long               idx;
-    char               scannamespc[PATHLEN];
-    char	      *scanname = scannamespc;
     struct stat	       sbuf;
     WIN32_FIND_DATA fd;
     HANDLE          fh;
@@ -1504,37 +1534,19 @@
 	return NULL;
     }
 
+    fh = open_dir_handle(filename, &fd);
+    if (fh == INVALID_HANDLE_VALUE) {
+	return NULL;
+    }
+
     //
     // Get us a DIR structure
     //
-
-    p = xcalloc(sizeof(DIR), 1);
+    p = calloc(sizeof(DIR), 1);
     if (p == NULL)
 	return NULL;
-    
-    //
-    // Create the search pattern
-    //
 
-    strcpy(scanname, filename);
-
-    if (index("/\\:", *CharPrev(scanname, scanname + strlen(scanname))) == NULL)
-	strcat(scanname, "/*");
-    else
-	strcat(scanname, "*");
-
     //
-    // do the FindFirstFile call
-    //
-
-    fh = FindFirstFile(scanname, &fd);
-    if (fh == INVALID_HANDLE_VALUE) {
-	errno = map_errno(GetLastError());
-	free(p);
-	return NULL;
-    }
-
-    //
     // now allocate the first part of the string table for the
     // filenames that we find.
     //
@@ -3374,6 +3386,17 @@
 }
 
 static int
+check_valid_dir(const char *path)
+{
+    WIN32_FIND_DATA fd;
+    HANDLE fh = open_dir_handle(path, &fd);
+    if (fh == INVALID_HANDLE_VALUE)
+	return -1;
+    FindClose(fh);
+    return 0;
+}
+
+static int
 winnt_stat(const char *path, struct stat *st)
 {
     HANDLE h;
@@ -3403,6 +3426,9 @@
 	    errno = map_errno(GetLastError());
 	    return -1;
 	}
+	if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+	    if (check_valid_dir(path)) return -1;
+	}
 	st->st_mode  = fileattr_to_unixmode(attr, path);
     }
 
@@ -3412,6 +3438,21 @@
     return 0;
 }
 
+#ifdef WIN95
+static int
+win95_stat(const char *path, struct stat *st)
+{
+    int ret = stat(path, st);
+    if (ret) return ret;
+    if (st->st_mode & S_IFDIR) {
+	return check_valid_dir(path);
+    }
+    return 0;
+}
+#else
+#define win95_stat(path, st) -1
+#endif
+
 int
 rb_w32_stat(const char *path, struct stat *st)
 {
@@ -3447,7 +3488,7 @@
     } else if (*end == '\\' || (buf1 + 1 == end && *end == ':'))
 	strcat(buf1, ".");
 
-    ret = IsWinNT() ? winnt_stat(buf1, st) : stat(buf1, st);
+    ret = IsWinNT() ? winnt_stat(buf1, st) : win95_stat(buf1, st);
     if (ret == 0) {
 	st->st_mode &= ~(S_IWGRP | S_IWOTH);
     }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]