[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
touch - change file timestamps
Lines of code: 439
Principal syscalls: futimens() via fdutimensat(), open() via fd_reopen()
Support syscalls: close(), stat()
Options: 15 (8 short, 7 long)
Descended from touch introduced in Version 7 UNIX (1979)
Added to Fileutils in October 1992 [First version]
Number of revisions: 187
The primary work behind touch updates file timestamps, although it is often used to create empty files.
Helpers:get_reldate()
- Calculates a relative date between two input datestouch()
- Performs the touch procedure for one target file
die()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process terminationget_stat_atime()
- Retrieves the access time from a stat structureget_stat_mtime()
- Retrieves the modified time from a stat structuregettime()
- Gets the system time in a timespec structureposixtime()
- Tests if an input date is a POSIX format (from gnulib)
Setup
touch declares several global flags that control execution flow and are defined during parsing:
amtime_now
- Flag to change both access and modify timeschange_times
- Bitflag for access and modify timesnewtime[]
- Struct array for the access and modify timesno_create
- Flag to skip file creation if it doesn't existno_dereference
- Flag to prevent following links (update link time, not target time)*ref_file
- The path to the reference fileuse_ref
- Flag if a reference file is provided
touch initializes a few local variables in main()
, including:
c
- The first letter of the next option to processdate_set
- Flag if a date is provided*flex_date
- Holds the time input by the userok
- The final return status of the utility
Parsing
Parsing touch considers five questions:
- Are we only interested in modified or access times?
- Should we use an alternate timestamp?
- Is there a reference file providing the timestamp?
- Should we create non-existent files?
- If touching a link, should we update the link or the target?
Parsing failures
These failure cases are explicitly checked:
- Invalid date format
- Using conflicting time source (reference file and a direct date)
- Unknown options used
Failures result in a short error message followed by the usage instructions.
Execution
The touch
begins by locating the desired times for the target time. This comes from three possible sources: A reference file, discovered via a stat()
syscall. From the user directly as input on the cli. Or finally, from the current system time. The requested access/modified times are loaded in to the newtime
structure.
Once the desired time is known and available in newtime[]
structure, we 'touch' each target file with the requested time. The process is:
- Open the target file -- this may create the file if it doesn't exist
- Change the desired times, passing the target and behaviors to fdutimensat() in gnulib
- Close the target file
- Check errno and report issues
- Repeat for the next target file
Failure cases:
- No access to path or file
- Cannot change times
- Cannot close the file
- No target files provided
stat()
failed on the reference file
Failures at this stage output an error message to STDERR unless quiet mode was enabled