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

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/

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