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

**URL:** <https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757>\
**Category:** Ruby\
**Created:** [October 11, 2006, 10:38am UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757 "2006-10-11T10:38:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![hanholl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a87d85/32.png) [@hanholl](https://www.ruby-forum.com/u/hanholl)\
**Post date:** [October 11, 2006, 10:38am UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757/1 "2006-10-11T10:38:11Z")

</div>

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 H.

---

<div class="post-metadata">

**Author:** ![hanholl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a87d85/32.png) [@hanholl](https://www.ruby-forum.com/u/hanholl)\
**Post date:** [October 11, 2006, 12:42pm UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757/2 "2006-10-11T12:42:54Z")

</div>

Hi,

At Wed, 11 Oct 2006 19:08:36 +0900,  
Nobuyoshi N. 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’.

---

<div class="post-metadata">

**Author:** ![hanholl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a87d85/32.png) [@hanholl](https://www.ruby-forum.com/u/hanholl)\
**Post date:** [October 11, 2006, 12:10pm UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757/3 "2006-10-11T12:10:36Z")

</div>

Hi,

At Wed, 11 Oct 2006 17:37:05 +0900,  
Han H. 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?

# Index: file.c

RCS file: /pub/cvs/ruby/file.c,v  
retrieving revision 1.253  
diff -U 2 -p -r1.253 file.c  
— file.c 25 Sep 2006 12:25:03 -0000 1.253  
+++ file.c 11 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 = NULL;  
long n;

- tvp[0] = rb\_time\_timeval(atime);
- tvp[1] = rb\_time\_timeval(mtime);

- if (!NIL\_P(atime) || !NIL\_P(mtime)) {

- tvp = tvs;

- tvp[0] = rb\_time\_timeval(atime);

- tvp[1] = rb\_time\_timeval(mtime);

- }

- struct utimbuf utbuf;

- struct utimbuf utbuf, \*utp = NULL;

- tv = rb\_time\_timeval(atime);
- utbuf.actime = tv.tv\_sec;
- tv = rb\_time\_timeval(mtime);
- utbuf.modtime = tv.tv\_sec;

- if (!NIL\_P(atime) || !NIL\_P(mtime)) {
- utp = &utbuf;
- tv = rb\_time\_timeval(atime);
- utp-\>actime = tv.tv\_sec;
- tv = rb\_time\_timeval(mtime);
- utp-\>modtime = tv.tv\_sec;
- }

- n = apply2files(utime\_internal, rest, &utbuf);

- n = apply2files(utime\_internal, rest, utp);  
return LONG2FIX(n);  
}  
@@ -2924,4 +2930,9 @@ rb\_file\_join(VALUE ary, VALUE sep)  
}  
else if (!\*tail) {  
+#ifdef DOSISH\_DRIVE\_LETTER
- 

```
  if ((tail - name == 2) && has_drive_letter(name)) {

```

- 

```
      rb_str_buf_cat(result, ".", 1);

```

- 

```
  }

```

# +#endif rb\_str\_buf\_append(result, sep); } 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  
— lib/fileutils.rb 9 Oct 2006 14:41:24 -0000 1.73  
+++ lib/fileutils.rb 11 Oct 2006 09:02:41 -0000  
@@ -1008,14 +1008,21 @@ module FileUtils  
fu\_check\_options options, OPT\_TABLE[‘touch’]  
list = 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 = Time.now

- created = nocreate = options[:nocreate]
- t = options[:mtime]  
list.each do |path|
- 

```
 created = nocreate
 begin
   File.utime(t, t, path)
 rescue Errno::ENOENT

```

- 

```
   raise unless created
   File.open(path, 'a') {
     ;
   }

```

- 

```
   created = true

```

- 

```
   retry if t
 end

```

end  
@@ -1023,5 +1030,5 @@ module FileUtils  
module\_function :touch

- OPT\_TABLE[‘touch’] = [:noop, :verbose]

- OPT\_TABLE[‘touch’] = [:noop, :verbose, :mtime, :nocreate]

---

<div class="post-metadata">

**Author:** ![hanholl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a87d85/32.png) [@hanholl](https://www.ruby-forum.com/u/hanholl)\
**Post date:** [October 11, 2006, 9:15pm UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757/4 "2006-10-11T21:15:06Z")

</div>

Hi,

In mail “Re: FileUtils.touch not consistent with system(‘touch’)”  
“Nobuyoshi N.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 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?

> Index: lib/fileutils.rb

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

Best Regards,  
Minero A.

---

<div class="post-metadata">

**Author:** ![hanholl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a87d85/32.png) [@hanholl](https://www.ruby-forum.com/u/hanholl)\
**Post date:** [October 12, 2006, 7:38am UTC](https://www.ruby-forum.com/t/fileutils-touch-not-consistent-with-system-touch/71757/5 "2006-10-12T07:38:32Z")

</div>

Hi,

At Wed, 11 Oct 2006 19:08:36 +0900,  
Nobuyoshi N. wrote in [ruby-talk:219042]:

> > Linux (and I assume this is Posix) allows a utime call with NULL if  
> > the file is writeable,

rb\_w32\_utime() didn’t support it.

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

# Index: win32/win32.c

RCS file: /pub/cvs/ruby/win32/win32.c,v  
retrieving revision 1.195  
diff -U 2 -p -r1.195 win32.c  
— win32/win32.c 12 Aug 2006 06:56:09 -0000 1.195  
+++ win32/win32.c 12 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)) {
- return -1;

- if (times) {
- if (unixtime\_to\_filetime(times-\>actime, &atime)) {
- 

```
  return -1;

```

- }
- if (unixtime\_to\_filetime(times-\>modtime, &mtime)) {
- 

```
  return -1;

```

- }  
}

- if (unixtime\_to\_filetime(times-\>modtime, &mtime)) {
- return -1;

- else {
- GetSystemTimeAsFileTime(&atime);
- mtime = atime;  
}
