ruby-changes:7438
From: nobu <ko1@a...>
Date: Sun, 31 Aug 2008 00:07:54 +0900 (JST)
Subject: [ruby-changes:7438] Ruby:r18957 (mvm): * string.c (rb_str_wrap_cstr): new function.
nobu 2008-08-31 00:03:04 +0900 (Sun, 31 Aug 2008) New Revision: 18957 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18957 Log: * string.c (rb_str_wrap_cstr): new function. * dir.c (ruby_dirfd): returns directory fd. * dir.c (chdir_restore): restores thread cwd. * file.c (ruby_fd_getcwd): returns path for fd. Modified files: branches/mvm/ChangeLog branches/mvm/dir.c branches/mvm/file.c branches/mvm/include/ruby/intern.h branches/mvm/include/ruby/util.h branches/mvm/process.c branches/mvm/string.c branches/mvm/thread.c branches/mvm/version.h branches/mvm/vm.c branches/mvm/vm_core.h Index: mvm/include/ruby/intern.h =================================================================== --- mvm/include/ruby/intern.h (revision 18956) +++ mvm/include/ruby/intern.h (revision 18957) @@ -531,6 +531,7 @@ VALUE rb_str_format(int, const VALUE *, VALUE); /* string.c */ VALUE rb_str_wrap(char*, long); +VALUE rb_str_wrap_cstr(char *); VALUE rb_str_new(const char*, long); VALUE rb_str_new_cstr(const char*); VALUE rb_str_new2(const char*); Index: mvm/include/ruby/util.h =================================================================== --- mvm/include/ruby/util.h (revision 18956) +++ mvm/include/ruby/util.h (revision 18957) @@ -64,6 +64,8 @@ #define strdup(s) ruby_strdup(s) char *ruby_getcwd(void); +char *ruby_fd_getcwd(int); +int ruby_dirfd(const char *); #define my_getcwd() ruby_getcwd() double ruby_strtod(const char *, char **); Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 18956) +++ mvm/ChangeLog (revision 18957) @@ -1,3 +1,13 @@ +Sun Aug 31 00:02:49 2008 Nobuyoshi Nakada <nobu@r...> + + * string.c (rb_str_wrap_cstr): new function. + + * dir.c (ruby_dirfd): returns directory fd. + + * dir.c (chdir_restore): restores thread cwd. + + * file.c (ruby_fd_getcwd): returns path for fd. + Sat Aug 30 22:45:00 2008 Nobuyoshi Nakada <nobu@r...> * thread.c (rb_queue_shift): fix memory leak. Index: mvm/vm_core.h =================================================================== --- mvm/vm_core.h (revision 18956) +++ mvm/vm_core.h (revision 18957) @@ -510,10 +510,11 @@ #endif struct { -#if USE_OPENAT +#if HAVE_FCHDIR int fd; +#else + VALUE path; #endif - char *path; } cwd; struct rb_thread_struct *join_list_next; Index: mvm/string.c =================================================================== --- mvm/string.c (revision 18956) +++ mvm/string.c (revision 18957) @@ -420,6 +420,12 @@ } VALUE +rb_str_wrap_cstr(char *ptr) +{ + return rb_str_wrap(ptr, strlen(ptr)); +} + +VALUE rb_str_new(const char *ptr, long len) { return str_new(rb_cString, ptr, len); Index: mvm/thread.c =================================================================== --- mvm/thread.c (revision 18956) +++ mvm/thread.c (revision 18957) @@ -499,10 +499,11 @@ native_mutex_initialize(&th->interrupt_lock); /* kick thread */ st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id); -#if USE_OPENAT - th->cwd.fd = openat(GET_THREAD()->cwd.fd, ".", O_RDONLY); +#ifdef HAVE_FCHDIR + th->cwd.fd = ruby_dirfd("."); +#else + th->cwd.path = rb_str_new_shared(GET_THREAD()->cwd.path); #endif - th->cwd.path = strdup(GET_THREAD()->cwd.path); native_thread_create(th); return thval; } @@ -3638,19 +3639,14 @@ ruby_thread_getcwd(rb_thread_t *th) { char *ruby_sys_getcwd(void); - char *cwd; -#if USE_OPENAT && defined HAVE_READLINK - extern char *ruby_readlink(const char *, long *); - static const char fdpat[] = "/proc/self/fd/%d"; - char fdname[sizeof(fdpat) + sizeof(int) * 5 / 2]; - long len; - - snprintf(fdname, sizeof(fdname), fdpat, th->cwd.fd); - cwd = ruby_readlink(fdname, &len); +#if HAVE_FCHDIR + extern char * ruby_fd_getcwd(int fd); + char *cwd = ruby_fd_getcwd(th->cwd.fd); if (cwd) return cwd; +#else + if (RTEST(th->cwd.path)) + return ruby_strdup(RSTRING_PTR(th->cwd.path)); #endif - if ((cwd = th->cwd.path) != 0) - return ruby_strdup(cwd); return ruby_sys_getcwd(); } Index: mvm/dir.c =================================================================== --- mvm/dir.c (revision 18956) +++ mvm/dir.c (revision 18957) @@ -667,12 +667,11 @@ return Qnil; } +#ifdef HAVE_FCHDIR static void -dir_chdir(VALUE path) +dir_fchdir(int dir, VALUE path) { rb_thread_t *th = GET_THREAD(); -#if USE_OPENAT - int dir = openat(th->cwd.fd, RSTRING_PTR(path), O_RDONLY); if (dir < 0) rb_sys_fail(RSTRING_PTR(path)); if (ruby_system_alone() && rb_thread_alone()) { @@ -680,16 +679,47 @@ rb_sys_fail(RSTRING_PTR(path)); } } - close(th->cwd.fd); th->cwd.fd = dir; +} +#endif + +#ifdef HAVE_FCHDIR +int +ruby_dirfd(const char *path) +{ +# if USE_OPENAT + rb_thread_t *th = GET_THREAD(); + return openat(th->cwd.fd, path, O_RDONLY); +# elif defined HAVE_DIRFD + DIR *cwd = opendir(path); + int fd = dup(dirfd(cwd)); + closedir(cwd); + return fd; +# elif defined O_DIRECTORY + return open(path, O_RDONLY|O_DIRECTORY); +# else +# error don't know how to open directory. +# endif +} +#endif + +#if USE_OPENAT +static void +dir_chdir(VALUE path) +{ + dir_fchdir(ruby_dirfd(RSTRING_PTR(dir)), path); +} +#define dir_chdir(path, fullpath) dir_chdir(path) #else - VALUE fullpath; +static void +dir_chdir(VALUE path, VALUE fullpath) +{ +# ifdef HAVE_FCHDIR + dir_fchdir(ruby_dirfd(RSTRING_PTR(fullpath)), path); +# else struct stat st; - const char *dir; - char *olddir = th->cwd.path; + const char *dir = RSTRING_PTR(fullpath); - RB_GC_GUARD(fullpath) = rb_file_expand_path(path, Qnil); - dir = RSTRING_PTR(fullpath); if (eaccess(dir, X_OK) != 0 || stat(dir, &st) != 0 || (!S_ISDIR(st.st_mode) && (errno = ENOTDIR))) { rb_sys_fail(RSTRING_PTR(path)); @@ -699,42 +729,33 @@ rb_sys_fail(RSTRING_PTR(path)); } } - th->cwd.path = ruby_strdup(dir); - xfree(olddir); -#endif + GET_THREAD()->cwd.path = fullpath; +# endif } - -#ifdef HAVE_FCHDIR -# if defined HAVE_OPENAT -# define get_cwd_fd() openat(GET_THREAD()->cwd.fd, ".", O_RDONLY) -# elif defined HAVE_DIRFD -int -get_cwd_fd(void) -{ - DIR *cwd = opendir(GET_THREAD()->cwd.path); - int fd = dup(dirfd(cwd)); - closedir(cwd); - return fd; -} -# define get_cwd_fd() get_cwd_fd() -# elif defined O_DIRECTORY -# define get_cwd_fd() open(GET_THREAD()->cwd.path, O_RDONLY|O_DIRECTORY) -# endif #endif struct chdir_data { VALUE new_path; -#ifdef get_cwd_fd +#ifdef HAVE_FCHDIR int old_dir; #endif +#if !USE_OPENAT VALUE old_path; +#endif int done; }; +#ifdef HAVE_FCHDIR +#define fd_path(c) rb_str_wrap_cstr(ruby_fd_getcwd((c)->old_dir)) +#else +#define fd_path(c) (c)->old_path +#endif + static VALUE chdir_yield(struct chdir_data *args) { - dir_chdir(args->new_path); + dir_chdir(args->new_path, + rb_file_absolute_path(args->new_path, fd_path(args))); args->done = Qtrue; return rb_yield(args->new_path); } @@ -743,14 +764,13 @@ chdir_restore(struct chdir_data *args) { if (args->done) { -#ifdef get_cwd_fd +#ifdef HAVE_FCHDIR if (fchdir(args->old_dir) < 0) { - close(args->old_dir); - rb_sys_fail(RSTRING_PTR(args->old_path)); + rb_sys_fail(0); } - close(args->old_dir); + GET_THREAD()->cwd.fd = args->old_dir; #else - dir_chdir(args->old_path); + dir_chdir(args->old_path, args->old_path); #endif } return Qnil; @@ -760,10 +780,11 @@ dir_chdir_block(VALUE path) { struct chdir_data args; -#ifdef get_cwd_fd - args.old_dir = get_cwd_fd(); +#ifdef HAVE_FCHDIR + args.old_dir = GET_THREAD()->cwd.fd; +#else + args.old_path = GET_THREAD()->cwd.path; #endif - args.old_path = rb_tainted_str_new2(GET_THREAD()->cwd.path); args.new_path = path; args.done = Qfalse; return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); @@ -830,7 +851,7 @@ return dir_chdir_block(path); } - dir_chdir(path); + dir_chdir(path, rb_file_absolute_path(path, Qnil)); return INT2FIX(0); } Index: mvm/process.c =================================================================== --- mvm/process.c (revision 18956) +++ mvm/process.c (revision 18957) @@ -2132,7 +2132,7 @@ return -1; } else { -#if USE_OPENAT +#ifdef HAVE_FCHDIR if (fchdir(GET_THREAD()->cwd.fd) == -1) return -1; #else Index: mvm/vm.c =================================================================== --- mvm/vm.c (revision 18956) +++ mvm/vm.c (revision 18957) @@ -1960,10 +1960,14 @@ th->cfp->iseq = iseq; th->cfp->pc = iseq->iseq_encoded; vm_init_redefined_flag(vm); -#if USE_OPENAT - th->cwd.fd = openat(AT_FDCWD, ".", O_RDONLY); +#ifdef HAVE_FCHDIR +# ifdef AT_FDCWD + th->cwd.fd = AT_FDCWD; +# endif + th->cwd.fd = ruby_dirfd("."); +#else + th->cwd.path = ruby_getcwd(); #endif - th->cwd.path = ruby_getcwd(); } } Index: mvm/version.h =================================================================== --- mvm/version.h (revision 18956) +++ mvm/version.h (revision 18957) @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2008-08-30" +#define RUBY_RELEASE_DATE "2008-08-31" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20080830 +#define RUBY_RELEASE_CODE 20080831 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 8 -#define RUBY_RELEASE_DAY 30 +#define RUBY_RELEASE_DAY 31 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; Index: mvm/file.c =================================================================== --- mvm/file.c (revision 18956) +++ mvm/file.c (revision 18957) @@ -2290,6 +2290,19 @@ } #endif +#if HAVE_FCHDIR +char * +ruby_fd_getcwd(int fd) +{ + static const char fdpat[] = "/proc/self/fd/%d"; + char fdname[sizeof(fdpat) + sizeof(int) * 5 / 2]; + long len; + + snprintf(fdname, sizeof(fdname), fdpat, fd); + return ruby_readlink(fdname, &len); +} +#endif + /* * call-seq: * File.readlink(link_name) -> file_name -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/