6

We have a file foobar not owned by me, but it is in my group:

$ ll
total 4,0K
-rw-rw-r-- 1 root hbogert 4 jan 19 12:27 foobar

I can touch it and it will update all times:

 $ stat foobar
  File: 'foobar'
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 4869333     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: ( 1000/ hbogert)
Access: 2017-01-19 12:27:04.499412133 +0100
Modify: 2017-01-19 12:27:04.499412133 +0100
Change: 2017-01-19 12:27:04.499412133 +0100
 Birth: -


 $ touch foobar


 $ stat foobar 
  File: 'foobar'
  Size: 4           Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 4869333     Links: 1
Access: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: ( 1000/ hbogert)
Access: 2017-01-19 12:32:04.375412133 +0100
Modify: 2017-01-19 12:32:04.375412133 +0100
Change: 2017-01-19 12:32:04.375412133 +0100
 Birth: -

However, when I just want to change the modification time, it fails:

$ touch -m foobar
touch: setting times of 'foobar': Operation not permitted

Is this expected behaviour?

6

The behaviour is expected, if rather non-obvious. At least on my system, touch does

utimensat(0, NULL, NULL, 0)

in the first case (touch file), and

utimensat(0, NULL, [UTIME_OMIT, UTIME_NOW], 0)

in the second (touch -m file). The first call is short-hand for "set the access and modification times to the current time"; the second says "leave the access time alone and change the modification time to the current time".

POSIX says

Only a process with the effective user ID equal to the user ID of the file, or with write access to the file, or with appropriate privileges may use futimens() or utimensat() with a null pointer as the times argument or with both tv_nsec fields set to the special value UTIME_NOW. Only a process with the effective user ID equal to the user ID of the file or with appropriate privileges may use futimens() or utimensat() with a non-null times argument that does not have both tv_nsec fields set to UTIME_NOW and does not have both tv_nsec fields set to UTIME_OMIT.

(times is the third argument to utimensat()). touch file falls under the first set of access restrictions: any write access to the file allows the access and modification times to be changed to "now". touch -m file falls under the second set of access restrictions: you need to be root or the owner of the file to be able to change the access and modification times to values which are not either both "now" or both "unchanged".

There are other ways of changing the access and/or modification times to "now" on files you don't own but can read or write:

  • reading a file will update the access time only;
  • writing a file (without reading it) will update the modification time only.
  • I have a feeling that some Unix/Linux variants do not allow you to set a modification time later than an access time as a file needs to be accessed to be modified. – MichaelJohn Jan 19 '17 at 12:03
  • Yeah. Its weird. I did the same test with a file that is owned by root and my user group, and 664 as permission set. Can confirm that i will be able to change all timestamps, but not "access only" or "modify only" - And taking a look at touch source code, this is the expected behavior on some systems... it will fall to group and other permissions when changing all timestamps, but will not allow one of the timestamps alone. – user34720 Jan 19 '17 at 12:13
  • Forgot the source code link - gist.github.com/JoshCheek/1224782 – user34720 Jan 19 '17 at 12:14
  • @nwildner The canonical source is also available directly from GNU. – Stephen Kitt Jan 19 '17 at 12:17
  • 1
    Yeah, i was just adding more information to your answer ;) – user34720 Jan 19 '17 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.