Bug 186851 - Can't use touch(1) when /proc is not mounted or unavailable
Summary: Can't use touch(1) when /proc is not mounted or unavailable
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Fedora
Classification: Fedora
Component: coreutils
Version: 5
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Tim Waugh
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2006-03-27 02:57 UTC by Russell Coker
Modified: 2007-11-30 22:11 UTC (History)
1 user (show)

Fixed In Version: FC6
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-12-15 12:07:18 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Russell Coker 2006-03-27 02:57:53 UTC
The touch(1) command will open the file in question and then call 
utimes("/proc/self/fd/0", NULL) to set the time.  This means that if /proc is 
not mounted or if SE Linux denies access to /proc (which will be the case for 
some shell scripts on a strict or MLS system and may also occur with the 
targeted policy) then the touch will return 1 and the time stamp will not be 
changed. 
 
Also if the file in question does exist then touch(1) will create it (thus 
giving it the desired time stamp as part of the process) but still return an 
error! 
 
I can't work out why touch calls open(2) before utimes(2). 
 
I suggest that a better algorithm would be: 
 
fd = open(filename, O_WRONLY|O_NONBLOCK|O_CREATE|O_EXCL, 0666); 
if(fd == -1) 
  utimes(filename, NULL); 
else 
  close(fd); 
 
This will save one system call in the case where the file is created, make it 
work when /proc is not mounted or not available, and has no down-side that I 
can think of.

Comment 1 Jim Meyering 2006-03-27 08:28:30 UTC
Thanks for the report. That has been fixed upstream.
Now, it falls back on using utimes if futimes or futimesat
(the libc calls that might use /proc/self/fd/0) fails.
Also, with newer kernels (2.6.16), futimesat is a syscall,
so doesn't rely on /proc.

If we know beforehand that the file doesn't exist, then you're right that we
could save syscalls.  However, it's not possible to detect the condition in a
useful/reliable manner -- there'd be a race: someone could create the file
between when lstat says it doesn't exist and the open above.  Then touch would
fail unnecessarily once again.


Note You need to log in before you can comment on or make changes to this bug.