From: Sami Kerola Date: Sun, 9 Feb 2020 22:14:56 +0000 (+0000) Subject: various: use threadsafe versions of time functions [lgtm scan] X-Git-Tag: v2.36-rc1~225^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3160589d86470ce7d20c81090fb7f211b3822053;p=thirdparty%2Futil-linux.git various: use threadsafe versions of time functions [lgtm scan] Deprecating calls to not-thread safe asctime(), ctime(), and localtime() calls is pretty close to pointless change. Lets do it to reduce lgtm scan warnings with justification it's nicer to use static analysis tools when they have very few positives. Signed-off-by: Sami Kerola --- diff --git a/include/timeutils.h b/include/timeutils.h index 9318d2f986..e452e556a0 100644 --- a/include/timeutils.h +++ b/include/timeutils.h @@ -74,6 +74,7 @@ enum { ISO_TIMESTAMP_COMMA_GT = ISO_TIMESTAMP_COMMA_G | ISO_T }; +#define CTIME_BUFSIZ 26 #define ISO_BUFSIZ 42 int strtimeval_iso(struct timeval *tv, int flags, char *buf, size_t bufsz); diff --git a/login-utils/last.c b/login-utils/last.c index 20d69e9b58..77c5e1b47f 100644 --- a/login-utils/last.c +++ b/login-utils/last.c @@ -263,7 +263,9 @@ static int uread(FILE *fp, struct utmpx *u, int *quit, const char *filename) */ static char *showdate(void) { - char *s = ctime(&lastdate); + static char s[CTIME_BUFSIZ]; + + ctime_r(&lastdate, s); s[16] = 0; return s; } @@ -339,15 +341,22 @@ static int time_formatter(int fmt, char *dst, size_t dlen, time_t *when) break; case LAST_TIMEFTM_HHMM: { - struct tm *tm = localtime(when); - if (!snprintf(dst, dlen, "%02d:%02d", tm->tm_hour, tm->tm_min)) + struct tm tm; + + localtime_r(when, &tm); + if (!snprintf(dst, dlen, "%02d:%02d", tm.tm_hour, tm.tm_min)) ret = -1; break; } case LAST_TIMEFTM_CTIME: - snprintf(dst, dlen, "%s", ctime(when)); + { + char buf[CTIME_BUFSIZ]; + + ctime_r(when, buf); + snprintf(dst, dlen, "%s", buf); ret = rtrim_whitespace((unsigned char *) dst); break; + } case LAST_TIMEFTM_ISO8601: ret = strtime_iso(when, ISO_TIMESTAMP_T, dst, dlen); break; diff --git a/login-utils/login.c b/login-utils/login.c index 23bb3c4344..545aa52ed1 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -76,6 +76,7 @@ #include "xalloc.h" #include "all-io.h" #include "fileutils.h" +#include "timeutils.h" #include "ttyutils.h" #include "pwdutils.h" @@ -524,9 +525,12 @@ static void log_lastlog(struct login_context *cxt) if (!cxt->quiet) { if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0) { + char time_string[CTIME_BUFSIZ]; + time_t ll_time = (time_t) ll.ll_time; - printf(_("Last login: %.*s "), 24 - 5, ctime(&ll_time)); + ctime_r(&ll_time, time_string); + printf(_("Last login: %.*s "), 24 - 5, time_string); if (*ll.ll_host != '\0') printf(_("from %.*s\n"), (int)sizeof(ll.ll_host), ll.ll_host); diff --git a/misc-utils/cal.c b/misc-utils/cal.c index ca8e42e504..6f192cceaa 100644 --- a/misc-utils/cal.c +++ b/misc-utils/cal.c @@ -281,7 +281,7 @@ static time_t cal_time(time_t *t) int main(int argc, char **argv) { - struct tm *local_time; + struct tm local_time; char *term; time_t now; int ch = 0, yflag = 0, Yflag = 0; @@ -467,7 +467,7 @@ int main(int argc, char **argv) } else cal_time(&now); - local_time = localtime(&now); + localtime_r(&now, &local_time); switch(argc) { case 3: @@ -500,20 +500,20 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("illegal day value: use 1-%d"), dm); ctl.req.day = day_in_year(&ctl, ctl.req.day, ctl.req.month, ctl.req.year); - } else if ((int32_t) (local_time->tm_year + 1900) == ctl.req.year) { - ctl.req.day = local_time->tm_yday + 1; + } else if ((int32_t) (local_time.tm_year + 1900) == ctl.req.year) { + ctl.req.day = local_time.tm_yday + 1; } if (!ctl.req.month && !ctl.req.week) { - ctl.req.month = local_time->tm_mon + 1; + ctl.req.month = local_time.tm_mon + 1; if (!ctl.num_months) yflag = 1; } break; case 0: - ctl.req.day = local_time->tm_yday + 1; - ctl.req.year = local_time->tm_year + 1900; + ctl.req.day = local_time.tm_yday + 1; + ctl.req.year = local_time.tm_year + 1900; if (!ctl.req.month) - ctl.req.month = local_time->tm_mon + 1; + ctl.req.month = local_time.tm_mon + 1; break; default: warnx(_("bad usage")); diff --git a/misc-utils/logger.c b/misc-utils/logger.c index 4c2bfb0943..a7736ebe93 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -413,17 +413,17 @@ static char const *rfc3164_current_time(void) { static char time[32]; struct timeval tv; - struct tm *tm; + struct tm tm; static char const * const monthnames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; logger_gettimeofday(&tv, NULL); - tm = localtime(&tv.tv_sec); + localtime_r(&tv.tv_sec, &tm); snprintf(time, sizeof(time),"%s %2d %2.2d:%2.2d:%2.2d", - monthnames[tm->tm_mon], tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + monthnames[tm.tm_mon], tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); return time; } diff --git a/sys-utils/ipcs.c b/sys-utils/ipcs.c index 2d18a13cce..5fc96d7976 100644 --- a/sys-utils/ipcs.c +++ b/sys-utils/ipcs.c @@ -21,6 +21,7 @@ #include "c.h" #include "nls.h" #include "closestream.h" +#include "timeutils.h" #include "ipcutils.h" @@ -43,8 +44,14 @@ static void print_sem (int id); static void do_msg (char format, int unit); static void print_msg (int id, int unit); -/* we read time as int64_t from /proc, so cast... */ -#define xctime(_x) ctime((time_t *) (_x)) +static inline char *ctime64(int64_t *t) +{ + static char buf[CTIME_BUFSIZ]; + + /* we read time as int64_t from /proc, so cast... */ + ctime_r((time_t *)t, buf); + return buf; +} static void __attribute__((__noreturn__)) usage(void) { @@ -309,11 +316,11 @@ static void do_shm (char format, int unit) printf ("%-10d %-10u", shmdsp->shm_perm.id, shmdsp->shm_perm.uid); /* ctime uses static buffer: use separate calls */ printf(" %-20.16s", shmdsp->shm_atim - ? xctime(&shmdsp->shm_atim) + 4 : _("Not set")); + ? ctime64(&shmdsp->shm_atim) + 4 : _("Not set")); printf(" %-20.16s", shmdsp->shm_dtim - ? xctime(&shmdsp->shm_dtim) + 4 : _("Not set")); + ? ctime64(&shmdsp->shm_dtim) + 4 : _("Not set")); printf(" %-20.16s\n", shmdsp->shm_ctim - ? xctime(&shmdsp->shm_ctim) + 4 : _("Not set")); + ? ctime64(&shmdsp->shm_ctim) + 4 : _("Not set")); break; case PID: if (pw) @@ -427,9 +434,9 @@ static void do_sem (char format) else printf ("%-8d %-10u", semdsp->sem_perm.id, semdsp->sem_perm.uid); printf (" %-26.24s", semdsp->sem_otime - ? xctime(&semdsp->sem_otime) : _("Not set")); + ? ctime64(&semdsp->sem_otime) : _("Not set")); printf (" %-26.24s\n", semdsp->sem_ctime - ? xctime( &semdsp->sem_ctime) : _("Not set")); + ? ctime64( &semdsp->sem_ctime) : _("Not set")); break; case PID: break; @@ -535,11 +542,11 @@ static void do_msg (char format, int unit) else printf ("%-8d %-10u", msgdsp->msg_perm.id, msgdsp->msg_perm.uid); printf (" %-20.16s", msgdsp->q_stime - ? xctime(&msgdsp->q_stime) + 4 : _("Not set")); + ? ctime64(&msgdsp->q_stime) + 4 : _("Not set")); printf (" %-20.16s", msgdsp->q_rtime - ? xctime(&msgdsp->q_rtime) + 4 : _("Not set")); + ? ctime64(&msgdsp->q_rtime) + 4 : _("Not set")); printf (" %-20.16s\n", msgdsp->q_ctime - ? xctime(&msgdsp->q_ctime) + 4 : _("Not set")); + ? ctime64(&msgdsp->q_ctime) + 4 : _("Not set")); break; case PID: if (pw) @@ -593,10 +600,10 @@ static void print_shm(int shmid, int unit) shmdata->shm_lprid, shmdata->shm_cprid, shmdata->shm_nattch); printf(_("att_time=%-26.24s\n"), - shmdata->shm_atim ? xctime(&(shmdata->shm_atim)) : _("Not set")); + shmdata->shm_atim ? ctime64(&(shmdata->shm_atim)) : _("Not set")); printf(_("det_time=%-26.24s\n"), - shmdata->shm_dtim ? xctime(&shmdata->shm_dtim) : _("Not set")); - printf(_("change_time=%-26.24s\n"), xctime(&shmdata->shm_ctim)); + shmdata->shm_dtim ? ctime64(&shmdata->shm_dtim) : _("Not set")); + printf(_("change_time=%-26.24s\n"), ctime64(&shmdata->shm_ctim)); printf("\n"); ipc_shm_free_info(shmdata); @@ -624,11 +631,11 @@ static void print_msg(int msgid, int unit) msgdata->q_qnum, msgdata->q_lspid, msgdata->q_lrpid); printf(_("send_time=%-26.24s\n"), - msgdata->q_stime ? xctime(&msgdata->q_stime) : _("Not set")); + msgdata->q_stime ? ctime64(&msgdata->q_stime) : _("Not set")); printf(_("rcv_time=%-26.24s\n"), - msgdata->q_rtime ? xctime(&msgdata->q_rtime) : _("Not set")); + msgdata->q_rtime ? ctime64(&msgdata->q_rtime) : _("Not set")); printf(_("change_time=%-26.24s\n"), - msgdata->q_ctime ? xctime(&msgdata->q_ctime) : _("Not set")); + msgdata->q_ctime ? ctime64(&msgdata->q_ctime) : _("Not set")); printf("\n"); ipc_msg_free_info(msgdata); @@ -652,8 +659,8 @@ static void print_sem(int semid) semdata->sem_perm.mode, semdata->sem_perm.mode & 0777); printf(_("nsems = %ju\n"), semdata->sem_nsems); printf(_("otime = %-26.24s\n"), - semdata->sem_otime ? xctime(&semdata->sem_otime) : _("Not set")); - printf(_("ctime = %-26.24s\n"), xctime(&semdata->sem_ctime)); + semdata->sem_otime ? ctime64(&semdata->sem_otime) : _("Not set")); + printf(_("ctime = %-26.24s\n"), ctime64(&semdata->sem_ctime)); printf("%-10s %-10s %-10s %-10s %-10s\n", _("semnum"), _("value"), _("ncount"), _("zcount"), _("pid")); diff --git a/sys-utils/rtcwake.c b/sys-utils/rtcwake.c index 4f854bb0b0..da5ec9e3b9 100644 --- a/sys-utils/rtcwake.c +++ b/sys-utils/rtcwake.c @@ -195,21 +195,22 @@ static int get_basetimes(struct rtcwake_control *ctl, int fd) /* Unless the system uses UTC, either delta or tzone * reflects a seconds offset from UTC. The value can * help sort out problems like bugs in your C library. */ + char s[64]; printf("\tdelta = %ld\n", ctl->sys_time - ctl->rtc_time); printf("\ttzone = %ld\n", timezone); printf("\ttzname = %s\n", tzname[daylight]); gmtime_r(&ctl->rtc_time, &tm); printf("\tsystime = %ld, (UTC) %s", - (long) ctl->sys_time, asctime(gmtime(&ctl->sys_time))); + (long) ctl->sys_time, asctime_r(gmtime(&ctl->sys_time), s)); printf("\trtctime = %ld, (UTC) %s", - (long) ctl->rtc_time, asctime(&tm)); + (long) ctl->rtc_time, asctime_r(&tm, s)); } return 0; } static int setup_alarm(struct rtcwake_control *ctl, int fd, time_t *wakeup) { - struct tm *tm; + struct tm tm; struct rtc_wkalrm wake = { 0 }; /* The wakeup time is in POSIX time (more or less UTC). Ideally @@ -221,13 +222,13 @@ static int setup_alarm(struct rtcwake_control *ctl, int fd, time_t *wakeup) * * Else clock_mode == CM_LOCAL so the time given to the RTC will * instead use the local time zone. */ - tm = localtime(wakeup); - wake.time.tm_sec = tm->tm_sec; - wake.time.tm_min = tm->tm_min; - wake.time.tm_hour = tm->tm_hour; - wake.time.tm_mday = tm->tm_mday; - wake.time.tm_mon = tm->tm_mon; - wake.time.tm_year = tm->tm_year; + localtime_r(wakeup, &tm); + wake.time.tm_sec = tm.tm_sec; + wake.time.tm_min = tm.tm_min; + wake.time.tm_hour = tm.tm_hour; + wake.time.tm_mday = tm.tm_mday; + wake.time.tm_mon = tm.tm_mon; + wake.time.tm_year = tm.tm_year; /* wday, yday, and isdst fields are unused */ wake.time.tm_wday = -1; wake.time.tm_yday = -1; @@ -337,6 +338,7 @@ static int print_alarm(struct rtcwake_control *ctl, int fd) struct rtc_wkalrm wake; struct tm tm = { 0 }; time_t alarm; + char s[CTIME_BUFSIZ]; if (ioctl(fd, RTC_WKALM_RD, &wake) < 0) { warn(_("read rtc alarm failed")); @@ -362,7 +364,8 @@ static int print_alarm(struct rtcwake_control *ctl, int fd) } /* 0 if both UTC, or expresses diff if RTC in local time */ alarm += ctl->sys_time - ctl->rtc_time; - printf(_("alarm: on %s"), ctime(&alarm)); + ctime_r(&alarm, s); + printf(_("alarm: on %s"), s); return 0; } @@ -554,9 +557,12 @@ int main(int argc, char **argv) if (suspend != DISABLE_MODE && suspend != SHOW_MODE) { /* perform alarm setup when the show or disable modes are not set */ if (alarm) { - if (alarm < ctl.sys_time) - errx(EXIT_FAILURE, _("time doesn't go backward to %s"), - ctime(&alarm)); + if (alarm < ctl.sys_time) { + char s[CTIME_BUFSIZ]; + + ctime_r(&alarm, s); + errx(EXIT_FAILURE, _("time doesn't go backward to %s"), s); + } alarm -= ctl.sys_time - ctl.rtc_time; } else alarm = ctl.rtc_time + seconds + 1; @@ -564,14 +570,19 @@ int main(int argc, char **argv) if (setup_alarm(&ctl, fd, &alarm) < 0) exit(EXIT_FAILURE); - if (suspend == NO_MODE || suspend == ON_MODE) + if (suspend == NO_MODE || suspend == ON_MODE) { + char s[CTIME_BUFSIZ]; + + ctime_r(&alarm, s); printf(_("%s: wakeup using %s at %s"), - program_invocation_short_name, devname, - ctime(&alarm)); - else + program_invocation_short_name, devname, s); + } else { + char s[CTIME_BUFSIZ]; + + ctime_r(&alarm, s); printf(_("%s: wakeup from \"%s\" using %s at %s"), - program_invocation_short_name, ctl.mode_str, devname, - ctime(&alarm)); + program_invocation_short_name, ctl.mode_str, devname, s); + } fflush(stdout); xusleep(10 * 1000); } diff --git a/term-utils/agetty.c b/term-utils/agetty.c index dfc4921f57..49151e0854 100644 --- a/term-utils/agetty.c +++ b/term-utils/agetty.c @@ -2721,24 +2721,21 @@ static void output_special_char(struct issue *ie, case 't': { time_t now; - struct tm *tm; + struct tm tm; time(&now); - tm = localtime(&now); - - if (!tm) - break; + localtime_r(&now, &tm); if (c == 'd') /* ISO 8601 */ fprintf(ie->output, "%s %s %d %d", - nl_langinfo(ABDAY_1 + tm->tm_wday), - nl_langinfo(ABMON_1 + tm->tm_mon), - tm->tm_mday, - tm->tm_year < 70 ? tm->tm_year + 2000 : - tm->tm_year + 1900); + nl_langinfo(ABDAY_1 + tm.tm_wday), + nl_langinfo(ABMON_1 + tm.tm_mon), + tm.tm_mday, + tm.tm_year < 70 ? tm.tm_year + 2000 : + tm.tm_year + 1900); else fprintf(ie->output, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); + tm.tm_hour, tm.tm_min, tm.tm_sec); break; } case 'l': diff --git a/term-utils/wall.c b/term-utils/wall.c index bf92fe1b7b..97d9a56b5c 100644 --- a/term-utils/wall.c +++ b/term-utils/wall.c @@ -71,6 +71,7 @@ #include "cctype.h" #include "fileutils.h" #include "closestream.h" +#include "timeutils.h" #define TERM_WIDTH 79 #define WRITE_TIME_OUT 300 /* in seconds */ @@ -349,7 +350,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz, if (print_banner == TRUE) { char *hostname = xgethostname(); - char *whom, *where, *date; + char *whom, *where, date[CTIME_BUFSIZ]; struct passwd *pw; time_t now; @@ -366,7 +367,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz, where += 5; time(&now); - date = xstrdup(ctime(&now)); + ctime_r(&now, date); date[strlen(date) - 1] = '\0'; /* @@ -385,7 +386,6 @@ static char *makemsg(char *fname, char **mvec, int mvecsz, whom, hostname, where, date); buf_printf(bs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf); free(hostname); - free(date); } buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");