in utils/adjust-times/adjust-times.cpp [169:324]
int main(int argc, char **argv) {
using namespace llvm;
cl::opt<int> Adjust ("adjust", cl::init(0), cl::desc("Move access and modification times"));
cl::alias AdjustA ("a", cl::aliasopt(Adjust));
cl::opt<bool> MTimeA ("mtime-add-ulp", cl::desc("Move the a/mtime a smallest amount backwards"));
cl::opt<bool> MTimeM ("mtime-minus-ulp", cl::desc("Move the a/mtime a smallest amount Forwards"));
cl::opt<bool> NowP ("now-plus-ulp", cl::desc("Set to current time plus epsilon"));
cl::opt<bool> NowM ("now-minus-ulp", cl::desc("Set to current time minus epsilon"));
cl::opt<std::string> Filename ("from-file", cl::init(""), cl::desc("Set access and modification times from FILE"), cl::value_desc("file"));
cl::alias FilenameA("f", cl::aliasopt(Filename));
cl::opt<bool> Verbose ("verbose", cl::desc("Show what is being done"));
cl::alias VerboseA ("v", cl::aliasopt(Verbose));
cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<Input files>"), cl::OneOrMore);
cl::ParseCommandLineOptions(argc, argv, "Modify timestamps of existing files\n");
enum mode {
ModeSetToNow,
ModeSetToFile, // -f, --from-file
ModeAdjustMtime, // -a, --adjust
ModeMtimeMinusULP, // --mtime-minus-ulp
ModeMtimePlusULP, // --mtime-plus-ulp
ModeNowMinusULP, // --now-minus-ulp
ModeNowPlusULP, // --now-plus-ulp
} mode = ModeSetToNow;
struct timespec time_to_set = { 0, UTIME_NOW };
double adjust_relative_sec = 0;
if (MTimeM) {
mode = ModeMtimeMinusULP;
}
if (MTimeA) {
mode = ModeMtimePlusULP;
}
if (NowP) {
mode = ModeNowPlusULP;
}
if (NowM) {
mode = ModeNowMinusULP;
}
if (Adjust) {
double value = Adjust;
if (value < -1000000 || value > 1000000) {
errno = ERANGE;
}
if (errno != 0) {
std::cerr << "--adjust " << Adjust << ": " << strerror(errno) << std::endl;
exit(EX_DATAERR);
}
adjust_relative_sec = value;
mode = ModeAdjustMtime;
}
if (!Filename.empty()) {
if (get_file_mtime(Filename.c_str(), &time_to_set) == -1) {
std::cerr << "--from-file " << Filename << ": " << strerror(errno) << std::endl;
exit(EX_DATAERR);
}
mode = ModeSetToFile;
}
// A list of filenames is required.
if (InputFilenames.empty()) {
cl::PrintHelpMessage();
exit(EX_USAGE);
}
// Modify all files' access and modification times.
for (std::string file : InputFilenames) {
const char* filename = file.c_str();
struct timespec previous_timestamp = { 0, UTIME_OMIT };
if (Verbose) {
if (get_file_mtime(filename, &previous_timestamp) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
}
switch (mode) {
case ModeSetToNow:
case ModeSetToFile: // -f, --from
if (file_time_set_fixed(filename, time_to_set) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
break;
case ModeAdjustMtime: // -a, --adjust
if (file_time_adjust_relative(filename, adjust_relative_sec) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
break;
case ModeMtimePlusULP:
case ModeMtimeMinusULP:
if (file_time_adjust_epsilon(filename, mode == ModeMtimeMinusULP ? -1 : 1) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
break;
case ModeNowPlusULP:
case ModeNowMinusULP:
struct timespec now = { 0, UTIME_NOW };
if (file_time_set_fixed(filename, now) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
if (file_time_adjust_epsilon(filename, mode == ModeNowMinusULP ? -1 : 1) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
break;
}
if (Verbose) {
struct timespec final_timestamp;
if (get_file_mtime(filename, &final_timestamp) == -1) {
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
exit(EX_NOINPUT);
}
fprintf(stderr, "%s: ", filename);
switch (mode) {
case ModeSetToNow:
case ModeSetToFile:
fprintf(stderr, "reset");
break;
case ModeAdjustMtime:
fprintf(stderr, "adjusted %+.9gs", adjust_relative_sec);
break;
case ModeMtimeMinusULP:
fprintf(stderr, "adjusted backward");
break;
case ModeMtimePlusULP:
fprintf(stderr, "adjusted forward");
break;
case ModeNowMinusULP:
fprintf(stderr, "set to now - epsilon");
break;
case ModeNowPlusULP:
fprintf(stderr, "set to now + epsilon");
break;
}
char buf_prev[64];
char buf_final[64];
time_format(buf_prev, sizeof(buf_prev), previous_timestamp);
time_format(buf_final, sizeof(buf_final), final_timestamp);
fprintf(stderr, "\n from %s\n to %s\n", buf_prev, buf_final);
}
}
return 0;
}