From 394f3a47e464b67b17e2cb7166df066829250e88 Mon Sep 17 00:00:00 2001 From: dana Date: Wed, 20 Jun 2018 17:29:56 -0500 Subject: 43075: Support nanosecond-precision time formatting * Teach ztrftime() %9. and %N for nanoseconds * Update prompt expansion to pass sub-second times for time formatting * Update zsh/stat to pass sub-second times for atime/mtime/ctime Patch heavily based on Oliver's earlier work @ workers/24059 --- Src/utils.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'Src/utils.c') diff --git a/Src/utils.c b/Src/utils.c index b41851700..ee2ad207f 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -3224,7 +3224,7 @@ ztrftimebuf(int *bufsizeptr, int decr) /**/ mod_export int -ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec) +ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long nsec) { int hr12; #ifdef HAVE_STRFTIME @@ -3299,15 +3299,15 @@ morefmt: case '.': if (ztrftimebuf(&bufsize, digs)) return -1; - if (digs > 6) - digs = 6; - if (digs < 6) { + if (digs > 9) + digs = 9; + if (digs < 9) { int trunc; - for (trunc = 5 - digs; trunc; trunc--) - usec /= 10; - usec = (usec + 5) / 10; + for (trunc = 8 - digs; trunc; trunc--) + nsec /= 10; + nsec = (nsec + 8) / 10; } - sprintf(buf, "%0*ld", digs, usec); + sprintf(buf, "%0*ld", digs, nsec); buf += digs; break; case '\0': @@ -3369,6 +3369,12 @@ morefmt: *buf++ = '0' + tm->tm_min / 10; *buf++ = '0' + tm->tm_min % 10; break; + case 'N': + if (ztrftimebuf(&bufsize, 9)) + return -1; + sprintf(buf, "%09ld", nsec); + buf += 9; + break; case 'S': if (tm->tm_sec > 9 || !strip) *buf++ = '0' + tm->tm_sec / 10; -- cgit v1.2.3 From ad9f07e66fded8a44adba15d576960cef587f9d4 Mon Sep 17 00:00:00 2001 From: Jun-ichi Takimoto Date: Wed, 1 Aug 2018 21:36:44 +0900 Subject: 43227: fix memory leaks in term{cap,info}.c --- ChangeLog | 5 +++++ Src/Modules/termcap.c | 14 ++++---------- Src/Modules/terminfo.c | 14 ++++---------- Src/utils.c | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 20 deletions(-) (limited to 'Src/utils.c') diff --git a/ChangeLog b/ChangeLog index cf35c734f..462e21781 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2018-08-01 Jun-ichi Takimoto + + * 43227: Src/Modules/termcap.c, Src/Modules/terminfo.c, + Src/utils.c: fix memory leaks not fixed in 43219 + 2018-07-31 dana * 43207 (tweaked): Completion/Unix/Type/_bind_addresses, diff --git a/Src/Modules/termcap.c b/Src/Modules/termcap.c index 60a6e138a..af4009a3a 100644 --- a/Src/Modules/termcap.c +++ b/Src/Modules/termcap.c @@ -345,16 +345,7 @@ int boot_(UNUSED(Module m)) { #ifdef HAVE_TGETENT -# ifdef HAVE_SETUPTERM - int errret; - - /* - * Just because we can't set up the terminal doesn't - * mean the modules hasn't booted---TERM may change, - * and it should be handled dynamically---so ignore errors here. - */ - (void)setupterm((char *)0, 1, &errret); -# endif + zsetupterm(); #endif return 0; } @@ -363,6 +354,9 @@ boot_(UNUSED(Module m)) int cleanup_(Module m) { +#ifdef HAVE_TGETENT + zdeleteterm(); +#endif return setfeatureenables(m, &module_features, NULL); } diff --git a/Src/Modules/terminfo.c b/Src/Modules/terminfo.c index bbd325899..4596b41d2 100644 --- a/Src/Modules/terminfo.c +++ b/Src/Modules/terminfo.c @@ -338,16 +338,7 @@ int boot_(UNUSED(Module m)) { #ifdef USE_TERMINFO_MODULE -# ifdef HAVE_SETUPTERM - int errret; - - /* - * Just because we can't set up the terminal doesn't - * mean the modules hasn't booted---TERM may change, - * and it should be handled dynamically---so ignore errors here. - */ - (void)setupterm((char *)0, 1, &errret); -# endif + zsetupterm(); #endif return 0; @@ -357,6 +348,9 @@ boot_(UNUSED(Module m)) int cleanup_(Module m) { +#ifdef USE_TERMINFO_MODULE + zdeleteterm(); +#endif return setfeatureenables(m, &module_features, NULL); } diff --git a/Src/utils.c b/Src/utils.c index ee2ad207f..075d27241 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -375,6 +375,43 @@ zerrmsg(FILE *file, const char *fmt, va_list ap) fflush(file); } +/* + * Wrapper for setupterm() and del_curterm(). + * These are called from terminfo.c and termcap.c. + */ +static int term_count; /* reference count of cur_term */ + +/**/ +mod_export void +zsetupterm(void) +{ +#ifdef HAVE_SETUPTERM + int errret; + + DPUTS(term_count < 0 || (term_count > 0 && !cur_term), + "inconsistent term_count and/or cur_term"); + /* + * Just because we can't set up the terminal doesn't + * mean the modules hasn't booted---TERM may change, + * and it should be handled dynamically---so ignore errors here. + */ + if (term_count++ == 0) + (void)setupterm((char *)0, 1, &errret); +#endif +} + +/**/ +mod_export void +zdeleteterm(void) +{ +#ifdef HAVE_SETUPTERM + DPUTS(term_count < 1 || !cur_term, + "inconsistent term_count and/or cur_term"); + if (--term_count == 0) + del_curterm(cur_term); +#endif +} + /* Output a single character, for the termcap routines. * * This is used instead of putchar since it can be a macro. */ -- cgit v1.2.3