static public Method

Dir.chdir(...)

Dir.chdir( [ string] )  0
Dir.chdir( [ string] ) {| path | block }   anObject

Changes the current working directory of the process to the given string. When called without an argument, changes the directory to the value of the environment variable HOME, or LOGDIR. SystemCallError (probably Errno::ENOENT) if the target directory does not exist.

If a block is given, it is passed the name of the new current directory, and the block is executed with that as the current directory. The original working directory is restored when the block exits. The return value of chdir is the value of the block. chdir blocks can be nested, but in a multi-threaded program an error will be raised if a thread attempts to open a chdir block while another thread has one open.

Dir.chdir("/var/spool/mail")
puts Dir.pwd
Dir.chdir("/tmp") do
  puts Dir.pwd
  Dir.chdir("/usr") do
    puts Dir.pwd
  end
  puts Dir.pwd
end
puts Dir.pwd

produces:

/var/spool/mail
/tmp
/usr
/tmp
/var/spool/mail

Source Code

/*
*  call-seq:
*     Dir.chdir( [ string] ) => 0
*     Dir.chdir( [ string] ) {| path | block }  => anObject
*
*  Changes the current working directory of the process to the given
*  string. When called without an argument, changes the directory to
*  the value of the environment variable <code>HOME</code>, or
*  <code>LOGDIR</code>. <code>SystemCallError</code> (probably
*  <code>Errno::ENOENT</code>) if the target directory does not exist.
*
*  If a block is given, it is passed the name of the new current
*  directory, and the block is executed with that as the current
*  directory. The original working directory is restored when the block
*  exits. The return value of <code>chdir</code> is the value of the
*  block. <code>chdir</code> blocks can be nested, but in a
*  multi-threaded program an error will be raised if a thread attempts
*  to open a <code>chdir</code> block while another thread has one
*  open.
*
*     Dir.chdir("/var/spool/mail")
*     puts Dir.pwd
*     Dir.chdir("/tmp") do
*       puts Dir.pwd
*       Dir.chdir("/usr") do
*         puts Dir.pwd
*       end
*       puts Dir.pwd
*     end
*     puts Dir.pwd
*
*  <em>produces:</em>
*
*     /var/spool/mail
*     /tmp
*     /usr
*     /tmp
*     /var/spool/mail
*/
static VALUE
dir_s_chdir(argc, argv, obj)
   int argc;
   VALUE *argv;
   VALUE obj;
{
   VALUE path = Qnil;

   rb_secure(2);
   if (rb_scan_args(argc, argv, "01", &path) == 1) {
       SafeStringValue(path);
   }
   else {
       const char *dist = getenv("HOME");
       if (!dist) {
           dist = getenv("LOGDIR");
           if (!dist) rb_raise(rb_eArgError, "HOME/LOGDIR not set");
       }
       path = rb_str_new2(dist);
   }

   if (chdir_blocking > 0) {
       if (!rb_block_given_p() || rb_thread_current() != chdir_thread)
           rb_warn("conflicting chdir during another chdir block");
   }

   if (rb_block_given_p()) {
       struct chdir_data args;
       char *cwd = my_getcwd();

       args.old_path = rb_tainted_str_new2(cwd); free(cwd);
       args.new_path = path;
       args.done = Qfalse;
       return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
   }
   dir_chdir(path);

   return INT2FIX(0);
}
Comments

Have your say
Please use Textile formatting (click here for a cheat sheet). Use <code/> and <pre/> for code samples.
Click here to login with OpenID to to post comments.