FileUtils.touch not consistent with system('touch')

H

Han Holl

Hi,

I have a world-writable file, not owned by me, that I try to touch:

-rwxrwxrwx 1 root root 0 Oct 11 10:29 /tmp/file

ruby -rfileutils -e 'FileUtils.touch("/tmp/file")'
/usr/lib/ruby/1.8/fileutils.rb:1014:in `utime': Operation not
permitted - /tmp/file (Errno::EPERM)
from /usr/lib/ruby/1.8/fileutils.rb:1014:in `touch'
from /usr/lib/ruby/1.8/fileutils.rb:1012:in `touch'
from -e:1

but:
ruby -e 'system("touch /tmp/file")'

succeeds.

The reason is that File.utime cannot be called with a NULL argument.
Linux (and I assume this is Posix) allows a utime call with NULL if
the file is writeable,
but to change the time a process must have special privileges.
With the current File.utime FileUtils cannot implement this.

Cheers,

Han Holl
 
N

Nobuyoshi Nakada

Hi,

At Wed, 11 Oct 2006 17:37:05 +0900,
Han Holl wrote in [ruby-talk:219037]:
The reason is that File.utime cannot be called with a NULL argument.
Linux (and I assume this is Posix) allows a utime call with NULL if
the file is writeable,
but to change the time a process must have special privileges.
With the current File.utime FileUtils cannot implement this.

What about this?

=0C
Index: file.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pub/cvs/ruby/file.c,v
retrieving revision 1.253
diff -U 2 -p -r1.253 file.c
--- file.c=0925 Sep 2006 12:25:03 -0000=091.253
+++ file.c=0911 Oct 2006 08:53:57 -0000
@@ -1966,11 +1966,14 @@ rb_file_s_utime(int argc, VALUE *argv)
{
VALUE atime, mtime, rest;
- struct timeval tvp[2];
+ struct timeval tvs[2], *tvp =3D NULL;
long n;

rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest);

- tvp[0] =3D rb_time_timeval(atime);
- tvp[1] =3D rb_time_timeval(mtime);
+ if (!NIL_P(atime) || !NIL_P(mtime)) {
+=09tvp =3D tvs;
+=09tvp[0] =3D rb_time_timeval(atime);
+=09tvp[1] =3D rb_time_timeval(mtime);
+ }

n =3D apply2files(utime_internal, rest, tvp);
@@ -2001,14 +2004,17 @@ rb_file_s_utime(int argc, VALUE *argv)
long n;
struct timeval tv;
- struct utimbuf utbuf;
+ struct utimbuf utbuf, *utp =3D NULL;

rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest);

- tv =3D rb_time_timeval(atime);
- utbuf.actime =3D tv.tv_sec;
- tv =3D rb_time_timeval(mtime);
- utbuf.modtime =3D tv.tv_sec;
+ if (!NIL_P(atime) || !NIL_P(mtime)) {
+=09utp =3D &utbuf;
+=09tv =3D rb_time_timeval(atime);
+=09utp->actime =3D tv.tv_sec;
+=09tv =3D rb_time_timeval(mtime);
+=09utp->modtime =3D tv.tv_sec;
+ }

- n =3D apply2files(utime_internal, rest, &utbuf);
+ n =3D apply2files(utime_internal, rest, utp);
return LONG2FIX(n);
}
@@ -2924,4 +2930,9 @@ rb_file_join(VALUE ary, VALUE sep)
=09 }
=09 else if (!*tail) {
+#ifdef DOSISH_DRIVE_LETTER
+=09=09if ((tail - name =3D=3D 2) && has_drive_letter(name)) {
+=09=09 rb_str_buf_cat(result, ".", 1);
+=09=09}
+#endif
=09=09rb_str_buf_append(result, sep);
=09 }
Index: lib/fileutils.rb
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pub/cvs/ruby/lib/fileutils.rb,v
retrieving revision 1.73
diff -U 2 -p -r1.73 fileutils.rb
--- lib/fileutils.rb=099 Oct 2006 14:41:24 -0000=091.73
+++ lib/fileutils.rb=0911 Oct 2006 09:02:41 -0000
@@ -1008,14 +1008,21 @@ module FileUtils
fu_check_options options, OPT_TABLE['touch']
list =3D fu_list(list)
- fu_output_message "touch #{list.join ' '}" if options[:verbose]
+ if options[:verbose]
+ fu_output_message "touch #{options[:nocreate] ? ' -c' :
''}#{options[:mtime] ? options[:mtime].strftime(' -t %Y%m%d%H%M.%S') :
''}#{list.join ' '}"
+ end
return if options[:noop]
- t =3D Time.now
+ created =3D nocreate =3D options[:nocreate]
+ t =3D options[:mtime]
list.each do |path|
+ created =3D nocreate
begin
File.utime(t, t, path)
rescue Errno::ENOENT
+ raise unless created
File.open(path, 'a') {
;
}
+ created =3D true
+ retry if t
end
end
@@ -1023,5 +1030,5 @@ module FileUtils
module_function :touch

- OPT_TABLE['touch'] =3D [:noop, :verbose]
+ OPT_TABLE['touch'] =3D [:noop, :verbose, :mtime, :nocreate]

private
=0C

--=20
Nobu Nakada
 
N

Nobuyoshi Nakada

Hi,

At Wed, 11 Oct 2006 19:08:36 +0900,
Nobuyoshi Nakada wrote in [ruby-talk:219042]:
Index: lib/fileutils.rb
===================================================================
RCS file: /pub/cvs/ruby/lib/fileutils.rb,v
retrieving revision 1.73
diff -U 2 -p -r1.73 fileutils.rb
+ raise unless created

Sorry, should be `if' but not `unless'.
 
M

Minero Aoki

Hi,

In mail "Re: FileUtils.touch not consistent with system('touch')"
Nobuyoshi Nakada said:
What about this?
Index: lib/fileutils.rb

This part seems nice, please commit it after File.utime
patch is committed.

Best Regards,
Minero Aoki
 
N

Nobuyoshi Nakada

Hi,

At Wed, 11 Oct 2006 19:08:36 +0900,
Nobuyoshi Nakada wrote in [ruby-talk:219042]:
rb_w32_utime() didn't support it.

I'm not sure it should be LocalFileTime or not.

=0C
Index: win32/win32.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pub/cvs/ruby/win32/win32.c,v
retrieving revision 1.195
diff -U 2 -p -r1.195 win32.c
--- win32/win32.c=0912 Aug 2006 06:56:09 -0000=091.195
+++ win32/win32.c=0912 Oct 2006 04:50:36 -0000
@@ -4118,9 +4118,15 @@ rb_w32_utime(const char *path, const str
}

- if (unixtime_to_filetime(times->actime, &atime)) {
-=09return -1;
+ if (times) {
+=09if (unixtime_to_filetime(times->actime, &atime)) {
+=09 return -1;
+=09}
+=09if (unixtime_to_filetime(times->modtime, &mtime)) {
+=09 return -1;
+=09}
}
- if (unixtime_to_filetime(times->modtime, &mtime)) {
-=09return -1;
+ else {
+=09GetSystemTimeAsFileTime(&atime);
+=09mtime =3D atime;
}

=0C

--=20
Nobu Nakada
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top