Skip to content

Commit 3277a23

Browse files
esyrldv-alt
andcommitted
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec that handle nanoseconds and microseconds, respectively. Always print raw values of time data fields, format string representations of time as comments. * defs.h (sprinttime): Change argument type from time_t to long long. (sprinttime_nsec, sprinttime_usec): New prototypes. * util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New functions. (sprinttime): Turn into a thin wrapper around sprinttime_ex. * stat.h (struct strace_stat): Add has_nsec field. * fetch_struct_stat.c (HAVE_NSEC): New macro. (fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC. * fetch_struct_stat64.c (HAVE_NSEC): New macro. (fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC. * print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>: Print raw values of time fields, use sprinttime_nsec to format a string representation of time, use tprints_comment to print it as a comment. * statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise. * utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime and struct utimbuf.modtime fields, use sprinttime to format a string representation of time, use tprints_comment to print it as a comment. * tests/tests.h (print_time_t_nsec): Add int argument. * tests/print_time.c (print_time_t_ex): New function. (print_time_t_nsec): Add int argument, turn into a thin wrapper around print_time_t_ex. * tests/utime.c (main): Update expected output. * tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro. [!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update expected output. * NEWS: Mention this timestamps representation improvement. Co-authored-by: Dmitry V. Levin <[email protected]>
1 parent c349527 commit 3277a23

File tree

13 files changed

+135
-52
lines changed

13 files changed

+135
-52
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Noteworthy changes in release ?.?? (????-??-??)
88

99
* Improvements
1010
* Optimized syscall filtering.
11+
* Improved representation of timestamps.
1112
* Enhanced decoding of sched_setattr syscall.
1213
* Added -e trace=%stat option for tracing variants of stat syscall.
1314
* Added -e trace=%lstat option for tracing variants of lstat syscall.

defs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,9 @@ extern int printargs_d(struct tcb *);
547547
extern void addflags(const struct xlat *, uint64_t);
548548
extern int printflags64(const struct xlat *, uint64_t, const char *);
549549
extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
550-
extern const char *sprinttime(time_t);
550+
extern const char *sprinttime(long long sec);
551+
extern const char *sprinttime_nsec(long long sec, unsigned long long nsec);
552+
extern const char *sprinttime_usec(long long sec, unsigned long long usec);
551553
extern void print_symbolic_mode_t(unsigned int);
552554
extern void print_numeric_umode_t(unsigned short);
553555
extern void print_numeric_long_umask(unsigned long);

fetch_struct_stat.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ typedef struct stat struct_stat;
6565

6666
#ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
6767
# define TIME_NSEC(arg) zero_extend_signed_to_ull(arg)
68+
# define HAVE_NSEC true
6869
#else
6970
# define TIME_NSEC(arg) 0
71+
# define HAVE_NSEC false
7072
#endif
7173

7274
MPERS_PRINTER_DECL(bool, fetch_struct_stat,
@@ -94,6 +96,7 @@ MPERS_PRINTER_DECL(bool, fetch_struct_stat,
9496
dst->atime_nsec = TIME_NSEC(buf.st_atime_nsec);
9597
dst->ctime_nsec = TIME_NSEC(buf.st_ctime_nsec);
9698
dst->mtime_nsec = TIME_NSEC(buf.st_mtime_nsec);
99+
dst->has_nsec = HAVE_NSEC;
97100
return true;
98101
#else /* !HAVE_STRUCT_STAT */
99102
printaddr(addr);

fetch_struct_stat64.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ typedef struct stat64 struct_stat64;
6363

6464
#ifdef HAVE_STRUCT_STAT64_ST_MTIME_NSEC
6565
# define TIME_NSEC(arg) zero_extend_signed_to_ull(arg)
66+
# define HAVE_NSEC true
6667
#else
6768
# define TIME_NSEC(arg) 0
69+
# define HAVE_NSEC false
6870
#endif
6971

7072
MPERS_PRINTER_DECL(bool, fetch_struct_stat64,
@@ -92,6 +94,7 @@ MPERS_PRINTER_DECL(bool, fetch_struct_stat64,
9294
dst->atime_nsec = TIME_NSEC(buf.st_atime_nsec);
9395
dst->ctime_nsec = TIME_NSEC(buf.st_ctime_nsec);
9496
dst->mtime_nsec = TIME_NSEC(buf.st_mtime_nsec);
97+
dst->has_nsec = HAVE_NSEC;
9598
return true;
9699
#else /* !HAVE_STRUCT_STAT64 */
97100
printaddr(addr);

print_struct_stat.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,16 @@ print_struct_stat(struct tcb *tcp, const struct strace_stat *const st)
6565
}
6666

6767
if (!abbrev(tcp)) {
68-
#define PRINT_ST_TIME(field) \
69-
tprints(", st_" #field "="); \
70-
tprints(sprinttime(st->field)); \
71-
if (st->field ## _nsec) \
72-
tprintf(".%09llu", st->field ## _nsec)
68+
#define PRINT_ST_TIME(field) \
69+
do { \
70+
tprintf(", st_" #field "=%lld", (long long) st->field); \
71+
tprints_comment(sprinttime_nsec(st->field, \
72+
zero_extend_signed_to_ull(st->field ## _nsec)));\
73+
if (st->has_nsec) \
74+
tprintf(", st_" #field "_nsec=%llu", \
75+
zero_extend_signed_to_ull( \
76+
st->field ## _nsec)); \
77+
} while (0)
7378

7479
PRINT_ST_TIME(atime);
7580
PRINT_ST_TIME(mtime);

stat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct strace_stat {
4545
unsigned long long atime_nsec;
4646
unsigned long long ctime_nsec;
4747
unsigned long long mtime_nsec;
48+
bool has_nsec;
4849
};
4950

5051
#endif /* !STRACE_STAT_H */

statx.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ SYS_FUNC(statx)
5959

6060
#define PRINT_FIELD_TIME(field) \
6161
do { \
62-
tprints(", " #field "="); \
63-
tprints(sprinttime(stx.field.sec)); \
64-
if (stx.field.nsec) \
65-
tprintf(".%09" PRId32, stx.field.nsec); \
62+
tprintf(", " #field "={tv_sec=%" PRId64 \
63+
", tv_nsec=%" PRIu32 "}", \
64+
stx.field.sec, stx.field.nsec); \
65+
tprints_comment(sprinttime_nsec(stx.field.sec, \
66+
zero_extend_signed_to_ull(stx.field.nsec))); \
6667
} while (0)
6768

6869
struct_statx stx;

tests/print_time.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,39 @@
3131
#include <stdio.h>
3232
#include <time.h>
3333

34-
void
35-
print_time_t_nsec(const time_t t, const unsigned long long nsec)
34+
static void
35+
print_time_t_ex(const time_t t, const unsigned long long part_sec,
36+
const unsigned int max_part_sec, const int width,
37+
const int comment)
3638
{
37-
if (t) {
38-
const struct tm *const p = localtime(&t);
39-
char buf[256];
4039

41-
if (!p) {
42-
perror_msg_and_fail("localtime");
43-
}
40+
if ((!t && !part_sec) || part_sec > max_part_sec)
41+
return;
42+
43+
const struct tm *const p = localtime(&t);
44+
char buf[256];
45+
if (!p || !strftime(buf, sizeof(buf), "%FT%T", p))
46+
return;
47+
48+
if (comment)
49+
fputs(" /* ", stdout);
50+
51+
fputs(buf, stdout);
52+
53+
if (part_sec)
54+
printf(".%0*llu", width, part_sec);
4455

45-
strftime(buf, sizeof(buf), "%FT%T%z", p);
56+
if (strftime(buf, sizeof(buf), "%z", p))
4657
fputs(buf, stdout);
47-
} else {
48-
putchar('0');
49-
}
5058

51-
if (nsec) {
52-
printf(".%09llu", nsec);
53-
}
59+
if (comment)
60+
fputs(" */", stdout);
61+
62+
return;
63+
}
64+
65+
void
66+
print_time_t_nsec(const time_t t, const unsigned long long nsec, int comment)
67+
{
68+
print_time_t_ex(t, nsec, 999999999, 9, comment);
5469
}

tests/tests.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void print_quoted_string(const char *);
123123
void print_quoted_memory(const char *, size_t);
124124

125125
/* Print time_t and nanoseconds in symbolic format. */
126-
void print_time_t_nsec(time_t, unsigned long long);
126+
void print_time_t_nsec(time_t, unsigned long long, int);
127127

128128
/* Read an int from the file. */
129129
int read_int_from_file(const char *, int *);

tests/utime.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ main(void)
6868

6969
rc = k_utime("utime\nfilename", tail_u);
7070
const char *errstr = sprintrc(rc);
71-
printf("utime(\"utime\\nfilename\", {actime=");
72-
print_time_t_nsec(t, 0);
73-
printf(", modtime=");
74-
print_time_t_nsec(t, 0);
71+
printf("utime(\"utime\\nfilename\", {actime=%lld", (long long) t);
72+
print_time_t_nsec(t, 0, 1);
73+
printf(", modtime=%lld", (long long) t);
74+
print_time_t_nsec(t, 0, 1);
7575
printf("}) = %s\n", errstr);
7676

7777
puts("+++ exited with 0 +++");

0 commit comments

Comments
 (0)