diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c index 00ca85205b..e2c3c36dbf 100644 --- a/ext/pathname/pathname.c +++ b/ext/pathname/pathname.c @@ -35,6 +35,7 @@ static ID id_lchmod; static ID id_lchown; static ID id_link; static ID id_lstat; +static ID id_lutime; static ID id_mkdir; static ID id_mtime; static ID id_open; @@ -764,6 +765,19 @@ path_utime(VALUE self, VALUE atime, VALUE mtime) return rb_funcall(rb_cFile, id_utime, 3, atime, mtime, get_strpath(self)); } +/* + * Update the access and modification times of the file. + * + * Same as Pathname#utime, but does not follow symbolic links. + * + * See File.lutime. + */ +static VALUE +path_lutime(VALUE self, VALUE atime, VALUE mtime) +{ + return rb_funcall(rb_cFile, id_lutime, 3, atime, mtime, get_strpath(self)); +} + /* * Returns the last component of the path. * @@ -1465,6 +1479,7 @@ path_f_pathname(VALUE self, VALUE str) * - #make_symlink(old) * - #truncate(length) * - #utime(atime, mtime) + * - #lutime(atime, mtime) * - #basename(*args) * - #dirname * - #extname @@ -1563,6 +1578,7 @@ Init_pathname(void) rb_define_method(rb_cPathname, "make_symlink", path_make_symlink, 1); rb_define_method(rb_cPathname, "truncate", path_truncate, 1); rb_define_method(rb_cPathname, "utime", path_utime, 2); + rb_define_method(rb_cPathname, "lutime", path_lutime, 2); rb_define_method(rb_cPathname, "basename", path_basename, -1); rb_define_method(rb_cPathname, "dirname", path_dirname, 0); rb_define_method(rb_cPathname, "extname", path_extname, 0); @@ -1646,6 +1662,7 @@ InitVM_pathname(void) id_lchown = rb_intern("lchown"); id_link = rb_intern("link"); id_lstat = rb_intern("lstat"); + id_lutime = rb_intern("lutime"); id_mkdir = rb_intern("mkdir"); id_mtime = rb_intern("mtime"); id_open = rb_intern("open"); diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb index c971597602..a23dc21ae3 100644 --- a/test/pathname/test_pathname.rb +++ b/test/pathname/test_pathname.rb @@ -1043,6 +1043,25 @@ class TestPathname < Test::Unit::TestCase } end + def test_lutime + return if !has_symlink? + with_tmpchdir('rubytest-pathname') {|dir| + open("a", "w") {|f| f.write "abc" } + atime = File.atime("a") + mtime = File.mtime("a") + latime = Time.utc(2000) + lmtime = Time.utc(1999) + File.symlink("a", "l") + Pathname("l").utime(latime, lmtime) + s = File.lstat("a") + ls = File.lstat("l") + assert_equal(atime, s.atime) + assert_equal(mtime, s.mtime) + assert_equal(latime, ls.atime) + assert_equal(lmtime, ls.mtime) + } + end + def test_basename assert_equal(Pathname("basename"), Pathname("dirname/basename").basename) assert_equal(Pathname("bar"), Pathname("foo/bar.x").basename(".x"))