NMON running on 32-bit big-endian GNU/Linux systems (such as powerpc-unknown-linux-gnu
) will incorrectly displaying the boot time as 0
, 1970-01-01
, due to the following code:
ts = *localtime((time_t *)&boottime);
where it converts the long long int *
typed &boottime
, to type time_t *
; doing so is wrong becouse types long long int
and time_t
has different size on 32-bit GNU/Linux systems (sizeof(time_t) == 4
). This especially affecting big-endian systems because the most-significant 4 bytes of boottime
would be read by localtime(3) instead of least-significant 4 bytes that original author might expecting.
The following patch fixes the issue by first coverting boottime
into a local time_t
typed variable:
--- lmon16n.c.orig 2021-11-07 07:16:15.000000000 +0800
+++ lmon16n.c 2021-11-23 12:40:20.146989843 +0800
@@ -1869,11 +1869,12 @@
sscanf(&proc[P_STAT].line[ctxt_line][0], "ctxt %lld",
&p->cpu_total.ctxt);
if(boottime == 0) {
- struct tm ts;
- if (proc[P_STAT].lines >= btime_line)
- sscanf(&proc[P_STAT].line[btime_line][0], "btime %lld", &boottime);
- ts = *localtime((time_t *)&boottime);
- strftime (boottime_str, 64, "%I:%M %p %d-%b-%Y", &ts);
+ time_t t;
+ if (proc[P_STAT].lines >= btime_line) {
+ sscanf(&proc[P_STAT].line[btime_line][0], "btime %lld", &boottime);
+ }
+ t = boottime;
+ strftime (boottime_str, 64, "%I:%M %p %d-%b-%Y", localtime(&t));
}
if (proc[P_STAT].lines >= proc_line)
sscanf(&proc[P_STAT].line[proc_line][0], "processes %lld",
it also adds the missing indentation of the sscanf(3) call.
Tested on powerpc-unknown-linux-gnu
and x86_64-unknown-linux-gnu
.
Upload the diff file as an attachment since the TABs got converted into spaces in the first inline version.