mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	dir.c: replace_real_basename
* dir.c (replace_real_basename): get the real name and replace the base name with it by getattrlist(2) if available. suggested by Matthew Draper at [ruby-core:67116]. [Bug #10015] * dir.c (glob_helper): get the real name of the whole path, not only the last name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48990 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									913943270d
								
							
						
					
					
						commit
						0ebfc6f216
					
				
					 4 changed files with 74 additions and 12 deletions
				
			
		|  | @ -1,3 +1,12 @@ | |||
| Thu Dec 25 15:36:15 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org> | ||||
| 
 | ||||
| 	* dir.c (replace_real_basename): get the real name and replace the | ||||
| 	  base name with it by getattrlist(2) if available. | ||||
| 	  suggested by Matthew Draper at [ruby-core:67116].  [Bug #10015] | ||||
| 
 | ||||
| 	* dir.c (glob_helper): get the real name of the whole path, not | ||||
| 	  only the last name. | ||||
| 
 | ||||
| Thu Dec 25 13:59:17 2014  Nobuyoshi Nakada  <nobu@ruby-lang.org> | ||||
| 
 | ||||
| 	* configure.in (NET_LUID): include also ifdef.h as a workaround of | ||||
|  |  | |||
|  | @ -1188,6 +1188,7 @@ AC_CHECK_HEADERS( \ | |||
|   malloc_np.h \ | ||||
|   malloc/malloc.h \ | ||||
|   setjmpex.h \ | ||||
|   sys/attr.h \ | ||||
|   sys/id.h | ||||
| ) | ||||
| 
 | ||||
|  | @ -2038,6 +2039,7 @@ AC_CHECK_FUNCS(fmod) | |||
| AC_CHECK_FUNCS(fsync) | ||||
| AC_CHECK_FUNCS(ftruncate) | ||||
| AC_CHECK_FUNCS(ftruncate64)		# used for Win32 platform | ||||
| AC_CHECK_FUNCS(getattrlist) | ||||
| AC_CHECK_FUNCS(getcwd) | ||||
| AC_CHECK_FUNCS(getgidx) | ||||
| AC_CHECK_FUNCS(getgrnam) | ||||
|  |  | |||
							
								
								
									
										63
									
								
								dir.c
									
										
									
									
									
								
							
							
						
						
									
										63
									
								
								dir.c
									
										
									
									
									
								
							|  | @ -73,6 +73,16 @@ char *strchr(char*,char); | |||
| #define opendir(p) rb_w32_uopendir(p) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef HAVE_SYS_ATTR_H | ||||
| #include <sys/attr.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifdef HAVE_GETATTRLIST | ||||
| # define USE_NAME_ON_FS 1 | ||||
| #else | ||||
| # define USE_NAME_ON_FS 0 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __APPLE__ | ||||
| # define HAVE_HFS 1 | ||||
| #else | ||||
|  | @ -1053,6 +1063,7 @@ sys_warning_1(VALUE mesg) | |||
| 
 | ||||
| #define GLOB_ALLOC(type) ((type *)malloc(sizeof(type))) | ||||
| #define GLOB_ALLOC_N(type, n) ((type *)malloc(sizeof(type) * (n))) | ||||
| #define GLOB_REALLOC(ptr, size) realloc((ptr), (size)) | ||||
| #define GLOB_FREE(ptr) free(ptr) | ||||
| #define GLOB_JUMP_TAG(status) (((status) == -1) ? rb_memerror() : rb_jump_tag(status)) | ||||
| 
 | ||||
|  | @ -1241,8 +1252,7 @@ glob_make_pattern(const char *p, const char *e, int flags, rb_encoding *enc) | |||
| 	else { | ||||
| 	    const char *m = find_dirsep(p, e, flags, enc); | ||||
| 	    const enum glob_pattern_type magic = has_magic(p, m, flags, enc); | ||||
| 	    const enum glob_pattern_type non_magic = | ||||
| 		((HAVE_HFS || FNM_SYSCASE) && (m == e || (m+1 == e && *m == '/'))) ? PLAIN : ALPHA; | ||||
| 	    const enum glob_pattern_type non_magic = (USE_NAME_ON_FS || FNM_SYSCASE) ? PLAIN : ALPHA; | ||||
| 	    char *buf; | ||||
| 
 | ||||
| 	    if (!(FNM_SYSCASE || magic > non_magic) && !recursive && *m) { | ||||
|  | @ -1316,6 +1326,45 @@ join_path(const char *path, long len, int dirsep, const char *name, size_t namle | |||
|     return buf; | ||||
| } | ||||
| 
 | ||||
| #ifdef HAVE_GETATTRLIST | ||||
| static char * | ||||
| replace_real_basename(char *path, long base, int hfs_p) | ||||
| { | ||||
|     u_int32_t attrbuf[(sizeof(attrreference_t) + MAXPATHLEN * 3 + sizeof(u_int32_t) - 1) / sizeof(u_int32_t) + 1]; | ||||
|     struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_NAME}; | ||||
|     const attrreference_t *ar = (void *)(attrbuf+1); | ||||
|     const char *name; | ||||
|     long len; | ||||
|     char *tmp; | ||||
|     IF_HAVE_HFS(VALUE utf8str = Qnil); | ||||
| 
 | ||||
|     if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW)) | ||||
| 	return path; | ||||
| 
 | ||||
|     name = (char *)ar + ar->attr_dataoffset; | ||||
|     len = (long)ar->attr_length - 1; | ||||
|     if (name + len > (char *)attrbuf + sizeof(attrbuf)) | ||||
| 	return path; | ||||
| 
 | ||||
| # if HAVE_HFS | ||||
|     if (hfs_p && has_nonascii(name, len)) { | ||||
| 	if (!NIL_P(utf8str = rb_str_normalize_ospath(name, len))) { | ||||
| 	    RSTRING_GETMEM(utf8str, name, len); | ||||
| 	} | ||||
|     } | ||||
| # endif | ||||
| 
 | ||||
|     tmp = GLOB_REALLOC(path, base + len + 1); | ||||
|     if (tmp) { | ||||
| 	path = tmp; | ||||
| 	memcpy(path + base, name, len); | ||||
| 	path[base + len] = '\0'; | ||||
|     } | ||||
|     IF_HAVE_HFS(if (!NIL_P(utf8str)) rb_str_resize(utf8str, 0)); | ||||
|     return path; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| enum answer {UNKNOWN = -1, NO, YES}; | ||||
| 
 | ||||
| #ifndef S_ISDIR | ||||
|  | @ -1379,7 +1428,11 @@ glob_helper( | |||
| 	    plain = 1; | ||||
| 	    break; | ||||
| 	  case ALPHA: | ||||
| #ifdef HAVE_GETATTRLIST | ||||
| 	    plain = 1; | ||||
| #else | ||||
| 	    magical = 1; | ||||
| #endif | ||||
| 	    break; | ||||
| 	  case MAGICAL: | ||||
| 	    magical = 2; | ||||
|  | @ -1602,6 +1655,12 @@ glob_helper( | |||
| 		    status = -1; | ||||
| 		    break; | ||||
| 		} | ||||
| #ifdef HAVE_GETATTRLIST | ||||
| 		if ((*cur)->type == ALPHA) { | ||||
| 		    long base = pathlen + (dirsep != 0); | ||||
| 		    buf = replace_real_basename(buf, base, IF_HAVE_HFS(1)+0); | ||||
| 		} | ||||
| #endif | ||||
| 		status = glob_helper(buf, 1, UNKNOWN, UNKNOWN, new_beg, | ||||
| 				     new_end, flags, func, arg, enc); | ||||
| 		GLOB_FREE(buf); | ||||
|  |  | |||
|  | @ -237,16 +237,8 @@ class TestDir < Test::Unit::TestCase | |||
|       return unless File.exist?("filewithcases") | ||||
|       assert_equal(%w"FileWithCases", Dir.glob("filewithcases"), feature5994) | ||||
|     end | ||||
|     Dir.chdir(File.join(@root, "c")) do | ||||
|       open("FileWithCases", "w") {} | ||||
|       mode = File.stat(".").mode | ||||
|       begin | ||||
|         File.chmod(mode & ~0444, ".") | ||||
|         return if mode == File.stat(".").mode | ||||
|         assert_equal(%w"filewithcases", Dir.glob("filewithcases"), feature5994) | ||||
|       ensure | ||||
|         File.chmod(mode, ".") | ||||
|       end | ||||
|     Dir.chdir(@root) do | ||||
|       assert_equal(%w"a/FileWithCases", Dir.glob("A/filewithcases"), feature5994) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 nobu
						nobu