ls: fix time handling by augmenting time resolution

ls was using (old) UNIX spec (struct stat).st_[acm]time.
It now uses POSIX (struct stat).(struct timespec st_[acm]tim) which
gives time resolution in seconds and nanoseconds.
If two files have the same time in seconds, we extend the comparision to
nanoseconds.
This commit is contained in:
Quentin Rameau 2015-11-01 18:12:46 +01:00 committed by sin
parent 57d220b3dc
commit 4859f4c825

15
ls.c
View File

@ -21,7 +21,7 @@ struct entry {
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
off_t size; off_t size;
time_t t; struct timespec t;
dev_t dev; dev_t dev;
dev_t rdev; dev_t rdev;
ino_t ino, tino; ino_t ino, tino;
@ -71,11 +71,11 @@ mkent(struct entry *ent, char *path, int dostat, int follow)
ent->gid = st.st_gid; ent->gid = st.st_gid;
ent->size = st.st_size; ent->size = st.st_size;
if (cflag) if (cflag)
ent->t = st.st_ctime; ent->t = st.st_ctim;
else if (uflag) else if (uflag)
ent->t = st.st_atime; ent->t = st.st_atim;
else else
ent->t = st.st_mtime; ent->t = st.st_mtim;
ent->dev = st.st_dev; ent->dev = st.st_dev;
ent->rdev = st.st_rdev; ent->rdev = st.st_rdev;
ent->ino = st.st_ino; ent->ino = st.st_ino;
@ -187,12 +187,12 @@ output(const struct entry *ent)
else else
snprintf(grname, sizeof(grname), "%d", ent->gid); snprintf(grname, sizeof(grname), "%d", ent->gid);
if (time(NULL) > ent->t + (180 * 24 * 60 * 60)) /* 6 months ago? */ if (time(NULL) > ent->t.tv_sec + (180 * 24 * 60 * 60)) /* 6 months ago? */
fmt = "%b %d %Y"; fmt = "%b %d %Y";
else else
fmt = "%b %d %H:%M"; fmt = "%b %d %H:%M";
strftime(buf, sizeof(buf), fmt, localtime(&ent->t)); strftime(buf, sizeof(buf), fmt, localtime(&ent->t.tv_sec));
printf("%s %4ld %-8.8s %-8.8s ", mode, (long)ent->nlink, pwname, grname); printf("%s %4ld %-8.8s %-8.8s ", mode, (long)ent->nlink, pwname, grname);
if (S_ISBLK(ent->mode) || S_ISCHR(ent->mode)) if (S_ISBLK(ent->mode) || S_ISCHR(ent->mode))
@ -226,7 +226,8 @@ entcmp(const void *va, const void *vb)
cmp = b->size - a->size; cmp = b->size - a->size;
break; break;
case 't': case 't':
cmp = b->t - a->t; if (!(cmp = b->t.tv_sec - a->t.tv_sec))
cmp = b->t.tv_nsec - a->t.tv_nsec;
break; break;
} }