1
0
forked from aniani/vim

patch 8.1.1313: warnings for using localtime() and ctime()

Problem:    Warnings for using localtime() and ctime().
Solution:   Use localtime_r() if available.  Avoid using ctime().
This commit is contained in:
Bram Moolenaar
2019-05-10 21:28:38 +02:00
parent 4ca41534b7
commit 63d2555c9c
10 changed files with 83 additions and 35 deletions

13
src/auto/configure vendored
View File

@@ -12650,10 +12650,21 @@ $as_echo "$vim_cv_getcwd_broken" >&6; }
if test "x$vim_cv_getcwd_broken" = "xyes" ; then if test "x$vim_cv_getcwd_broken" = "xyes" ; then
$as_echo "#define BAD_GETCWD 1" >>confdefs.h $as_echo "#define BAD_GETCWD 1" >>confdefs.h
for ac_func in getwd
do :
ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd"
if test "x$ac_cv_func_getwd" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_GETWD 1
_ACEOF
fi
done
fi fi
for ac_func in fchdir fchown fchmod fsync getcwd getpseudotty \ for ac_func in fchdir fchown fchmod fsync getcwd getpseudotty \
getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat \ getpwent getpwnam getpwuid getrlimit gettimeofday localtime_r lstat \
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \

View File

@@ -174,6 +174,7 @@
#undef HAVE_GETTIMEOFDAY #undef HAVE_GETTIMEOFDAY
#undef HAVE_GETWD #undef HAVE_GETWD
#undef HAVE_ICONV #undef HAVE_ICONV
#undef HAVE_LOCALTIME_R
#undef HAVE_LSTAT #undef HAVE_LSTAT
#undef HAVE_MEMSET #undef HAVE_MEMSET
#undef HAVE_MKDTEMP #undef HAVE_MKDTEMP

View File

@@ -3736,12 +3736,13 @@ main()
if test "x$vim_cv_getcwd_broken" = "xyes" ; then if test "x$vim_cv_getcwd_broken" = "xyes" ; then
AC_DEFINE(BAD_GETCWD) AC_DEFINE(BAD_GETCWD)
AC_CHECK_FUNCS(getwd)
fi fi
dnl Check for functions in one big call, to reduce the size of configure. dnl Check for functions in one big call, to reduce the size of configure.
dnl Can only be used for functions that do not require any include. dnl Can only be used for functions that do not require any include.
AC_CHECK_FUNCS(fchdir fchown fchmod fsync getcwd getpseudotty \ AC_CHECK_FUNCS(fchdir fchown fchmod fsync getcwd getpseudotty \
getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat \ getpwent getpwnam getpwuid getrlimit gettimeofday localtime_r lstat \
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \

View File

@@ -13213,6 +13213,9 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
f_strftime(typval_T *argvars, typval_T *rettv) f_strftime(typval_T *argvars, typval_T *rettv)
{ {
char_u result_buf[256]; char_u result_buf[256];
# ifdef HAVE_LOCALTIME_R
struct tm tmval;
# endif
struct tm *curtime; struct tm *curtime;
time_t seconds; time_t seconds;
char_u *p; char_u *p;
@@ -13224,7 +13227,11 @@ f_strftime(typval_T *argvars, typval_T *rettv)
seconds = time(NULL); seconds = time(NULL);
else else
seconds = (time_t)tv_get_number(&argvars[1]); seconds = (time_t)tv_get_number(&argvars[1]);
# ifdef HAVE_LOCALTIME_R
curtime = localtime_r(&seconds, &tmval);
# else
curtime = localtime(&seconds); curtime = localtime(&seconds);
# endif
/* MSVC returns NULL for an invalid value of seconds. */ /* MSVC returns NULL for an invalid value of seconds. */
if (curtime == NULL) if (curtime == NULL)
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));

View File

@@ -2723,9 +2723,7 @@ prt_add_resource(struct prt_ps_resource_S *resource)
int int
mch_print_begin(prt_settings_T *psettings) mch_print_begin(prt_settings_T *psettings)
{ {
time_t now;
int bbox[4]; int bbox[4];
char *p_time;
double left; double left;
double right; double right;
double top; double top;
@@ -2734,7 +2732,6 @@ mch_print_begin(prt_settings_T *psettings)
struct prt_ps_resource_S *res_encoding; struct prt_ps_resource_S *res_encoding;
char buffer[256]; char buffer[256];
char_u *p_encoding; char_u *p_encoding;
char_u *p;
struct prt_ps_resource_S *res_cidfont; struct prt_ps_resource_S *res_cidfont;
struct prt_ps_resource_S *res_cmap; struct prt_ps_resource_S *res_cmap;
int retval = FALSE; int retval = FALSE;
@@ -2761,13 +2758,8 @@ mch_print_begin(prt_settings_T *psettings)
prt_dsc_textline("For", buffer); prt_dsc_textline("For", buffer);
prt_dsc_textline("Creator", VIM_VERSION_LONG); prt_dsc_textline("Creator", VIM_VERSION_LONG);
/* Note: to ensure Clean8bit I don't think we can use LC_TIME */ /* Note: to ensure Clean8bit I don't think we can use LC_TIME */
now = time(NULL);
p_time = ctime(&now); prt_dsc_textline("CreationDate", get_ctime(time(NULL), FALSE));
/* Note: ctime() adds a \n so we have to remove it :-( */
p = vim_strchr((char_u *)p_time, '\n');
if (p != NULL)
*p = NUL;
prt_dsc_textline("CreationDate", p_time);
prt_dsc_textline("DocumentData", "Clean8Bit"); prt_dsc_textline("DocumentData", "Clean8Bit");
prt_dsc_textline("Orientation", "Portrait"); prt_dsc_textline("Orientation", "Portrait");
prt_dsc_atend("Pages"); prt_dsc_atend("Pages");

View File

@@ -2077,6 +2077,41 @@ get_b0_dict(char_u *fname, dict_T *d)
} }
#endif #endif
/*
* Replacement for ctime(), which is not safe to use.
* Requires strftime(), otherwise returns "(unknown)".
* If "thetime" is invalid returns "(invalid)". Never returns NULL.
* When "add_newline" is TRUE add a newline like ctime() does.
* Uses a static buffer.
*/
char *
get_ctime(time_t thetime, int add_newline)
{
static char buf[50];
#ifdef HAVE_STRFTIME
# ifdef HAVE_LOCALTIME_R
struct tm tmval;
# endif
struct tm *curtime;
# ifdef HAVE_LOCALTIME_R
curtime = localtime_r(&thetime, &tmval);
# else
curtime = localtime(&thetime);
# endif
/* MSVC returns NULL for an invalid value of seconds. */
if (curtime == NULL)
STRCPY(buf, _("(Invalid)"));
else
(void)strftime(buf, sizeof(buf) - 1, "%a %b %d %H:%M:%S %Y", curtime);
#else
STRCPY(buf, "(unknown)");
#endif
if (add_newline)
STRCAT(buf, "\n");
return buf;
}
/* /*
* Give information about an existing swap file. * Give information about an existing swap file.
* Returns timestamp (0 when unknown). * Returns timestamp (0 when unknown).
@@ -2087,17 +2122,15 @@ swapfile_info(char_u *fname)
stat_T st; stat_T st;
int fd; int fd;
struct block0 b0; struct block0 b0;
time_t x = (time_t)0;
char *p;
#ifdef UNIX #ifdef UNIX
char_u uname[B0_UNAME_SIZE]; char_u uname[B0_UNAME_SIZE];
#endif #endif
/* print the swap file date */ // print the swap file date
if (mch_stat((char *)fname, &st) != -1) if (mch_stat((char *)fname, &st) != -1)
{ {
#ifdef UNIX #ifdef UNIX
/* print name of owner of the file */ // print name of owner of the file
if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK) if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
{ {
msg_puts(_(" owned by: ")); msg_puts(_(" owned by: "));
@@ -2107,13 +2140,10 @@ swapfile_info(char_u *fname)
else else
#endif #endif
msg_puts(_(" dated: ")); msg_puts(_(" dated: "));
x = st.st_mtime; /* Manx C can't do &st.st_mtime */ msg_puts(get_ctime(st.st_mtime, TRUE));
p = ctime(&x); /* includes '\n' */
if (p == NULL)
msg_puts("(invalid)\n");
else
msg_puts(p);
} }
else
st.st_mtime = 0;
/* /*
* print the original file name * print the original file name
@@ -2191,7 +2221,7 @@ swapfile_info(char_u *fname)
msg_puts(_(" [cannot be opened]")); msg_puts(_(" [cannot be opened]"));
msg_putchar('\n'); msg_putchar('\n');
return x; return st.st_mtime;
} }
/* /*
@@ -4412,15 +4442,14 @@ attention_message(
char_u *fname) /* swap file name */ char_u *fname) /* swap file name */
{ {
stat_T st; stat_T st;
time_t x, sx; time_t swap_mtime;
char *p;
++no_wait_return; ++no_wait_return;
(void)emsg(_("E325: ATTENTION")); (void)emsg(_("E325: ATTENTION"));
msg_puts(_("\nFound a swap file by the name \"")); msg_puts(_("\nFound a swap file by the name \""));
msg_home_replace(fname); msg_home_replace(fname);
msg_puts("\"\n"); msg_puts("\"\n");
sx = swapfile_info(fname); swap_mtime = swapfile_info(fname);
msg_puts(_("While opening file \"")); msg_puts(_("While opening file \""));
msg_outtrans(buf->b_fname); msg_outtrans(buf->b_fname);
msg_puts("\"\n"); msg_puts("\"\n");
@@ -4431,13 +4460,8 @@ attention_message(
else else
{ {
msg_puts(_(" dated: ")); msg_puts(_(" dated: "));
x = st.st_mtime; /* Manx C can't do &st.st_mtime */ msg_puts(get_ctime(st.st_mtime, TRUE));
p = ctime(&x); /* includes '\n' */ if (swap_mtime != 0 && st.st_mtime > swap_mtime)
if (p == NULL)
msg_puts("(invalid)\n");
else
msg_puts(p);
if (sx != 0 && x > sx)
msg_puts(_(" NEWER than swap file!\n")); msg_puts(_(" NEWER than swap file!\n"));
} }
/* Some of these messages are long to allow translation to /* Some of these messages are long to allow translation to

View File

@@ -80,12 +80,13 @@ nbdebug_log_init(
char *file; /* possible nb_debug output file */ char *file; /* possible nb_debug output file */
char *cp; /* nb_dlevel pointer */ char *cp; /* nb_dlevel pointer */
if (log_var && (file = getenv(log_var)) != NULL) { if (log_var && (file = getenv(log_var)) != NULL)
{
time_t now; time_t now;
nb_debug = fopen(file, "a"); nb_debug = fopen(file, "a");
time(&now); time(&now);
fprintf(nb_debug, "%s", asctime(localtime(&now))); fprintf(nb_debug, "%s", get_ctime(now, TRUE));
if (level_var && (cp = getenv(level_var)) != NULL) { if (level_var && (cp = getenv(level_var)) != NULL) {
nb_dlevel = strtoul(cp, NULL, 0); nb_dlevel = strtoul(cp, NULL, 0);
} else { } else {

View File

@@ -13,6 +13,7 @@ void ml_recover(void);
int recover_names(char_u *fname, int list, int nr, char_u **fname_out); int recover_names(char_u *fname, int list, int nr, char_u **fname_out);
char_u *make_percent_swname(char_u *dir, char_u *name); char_u *make_percent_swname(char_u *dir, char_u *name);
void get_b0_dict(char_u *fname, dict_T *d); void get_b0_dict(char_u *fname, dict_T *d);
char *get_ctime(time_t thetime, int add_newline);
void ml_sync_all(int check_file, int check_char); void ml_sync_all(int check_file, int check_char);
void ml_preserve(buf_T *buf, int message); void ml_preserve(buf_T *buf, int message);
char_u *ml_get(linenr_T lnum); char_u *ml_get(linenr_T lnum);

View File

@@ -3110,11 +3110,19 @@ ex_undolist(exarg_T *eap UNUSED)
u_add_time(char_u *buf, size_t buflen, time_t tt) u_add_time(char_u *buf, size_t buflen, time_t tt)
{ {
#ifdef HAVE_STRFTIME #ifdef HAVE_STRFTIME
# ifdef HAVE_LOCALTIME_R
struct tm tmval;
# endif
struct tm *curtime; struct tm *curtime;
if (vim_time() - tt >= 100) if (vim_time() - tt >= 100)
{ {
curtime = localtime(&tt); curtime = localtime(&tt);
# ifdef HAVE_LOCALTIME_R
curtime = localtime_r(&tt, &tmval);
# else
curtime = localtime(&tt);
# endif
if (vim_time() - tt < (60L * 60L * 12L)) if (vim_time() - tt < (60L * 60L * 12L))
/* within 12 hours */ /* within 12 hours */
(void)strftime((char *)buf, buflen, "%H:%M:%S", curtime); (void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);

View File

@@ -767,6 +767,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1313,
/**/ /**/
1312, 1312,
/**/ /**/