mirror of
https://github.com/neovim/neovim.git
synced 2025-09-27 13:38:34 +00:00
Introduce os_localtime_r() and os_get_local_time()
Replace localtime() with os_localtime_r() in `eval.c` and `undo.c`.
This commit is contained in:
10
src/eval.c
10
src/eval.c
@@ -65,6 +65,7 @@
|
||||
#include "os/job.h"
|
||||
#include "os/rstream.h"
|
||||
#include "os/rstream_defs.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#if defined(FEAT_FLOAT)
|
||||
# include <math.h>
|
||||
@@ -14163,7 +14164,6 @@ static void f_str2nr(typval_T *argvars, typval_T *rettv)
|
||||
static void f_strftime(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u result_buf[256];
|
||||
struct tm *curtime;
|
||||
time_t seconds;
|
||||
char_u *p;
|
||||
|
||||
@@ -14174,9 +14174,11 @@ static void f_strftime(typval_T *argvars, typval_T *rettv)
|
||||
seconds = time(NULL);
|
||||
else
|
||||
seconds = (time_t)get_tv_number(&argvars[1]);
|
||||
curtime = localtime(&seconds);
|
||||
|
||||
struct tm curtime;
|
||||
struct tm *curtime_ptr = os_localtime_r(&seconds, &curtime);
|
||||
/* MSVC returns NULL for an invalid value of seconds. */
|
||||
if (curtime == NULL)
|
||||
if (curtime_ptr == NULL)
|
||||
rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)"));
|
||||
else {
|
||||
vimconv_T conv;
|
||||
@@ -14189,7 +14191,7 @@ static void f_strftime(typval_T *argvars, typval_T *rettv)
|
||||
p = string_convert(&conv, p, NULL);
|
||||
if (p != NULL)
|
||||
(void)strftime((char *)result_buf, sizeof(result_buf),
|
||||
(char *)p, curtime);
|
||||
(char *)p, curtime_ptr);
|
||||
else
|
||||
result_buf[0] = NUL;
|
||||
|
||||
|
17
src/log.c
17
src/log.c
@@ -11,6 +11,7 @@
|
||||
#include "misc1.h"
|
||||
#include "types.h"
|
||||
#include "os/os.h"
|
||||
#include "os/time.h"
|
||||
|
||||
#define USR_LOG_FILE "$HOME/.nvimlog"
|
||||
|
||||
@@ -117,23 +118,13 @@ static bool v_do_log_to_file(FILE *log_file, int log_level,
|
||||
assert(log_level >= DEBUG_LOG_LEVEL && log_level <= ERROR_LOG_LEVEL);
|
||||
|
||||
// format current timestamp in local time
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
struct tm local_time;
|
||||
if (os_get_localtime(&local_time) == NULL) {
|
||||
return false;
|
||||
}
|
||||
#ifdef UNIX
|
||||
// localtime() is not thread-safe. POSIX provides localtime_r() as a
|
||||
// thread-safe version.
|
||||
struct tm local_time_allocated;
|
||||
struct tm *local_time = localtime_r(&tv.tv_sec, &local_time_allocated);
|
||||
#else
|
||||
// Windows version of localtime() is thread-safe.
|
||||
// See http://msdn.microsoft.com/en-us/library/bf12f0hc%28VS.80%29.aspx
|
||||
struct tm *local_time = localtime(&tv.tv_sec); // NOLINT
|
||||
#endif
|
||||
char date_time[20];
|
||||
if (strftime(date_time, sizeof(date_time), "%Y/%m/%d %H:%M:%S",
|
||||
local_time) == 0) {
|
||||
&local_time) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
@@ -59,3 +60,27 @@ static void microdelay(uint64_t microseconds)
|
||||
|
||||
uv_mutex_unlock(&delay_mutex);
|
||||
}
|
||||
|
||||
struct tm *os_localtime_r(const time_t *clock, struct tm *result)
|
||||
{
|
||||
#ifdef UNIX
|
||||
// POSIX provides localtime_r() as a thread-safe version of localtime().
|
||||
return localtime_r(clock, result);
|
||||
#else
|
||||
// Windows version of localtime() is thread-safe.
|
||||
// See http://msdn.microsoft.com/en-us/library/bf12f0hc%28VS.80%29.aspx
|
||||
struct tm *local_time = localtime(clock); // NOLINT
|
||||
*result = *local_time;
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct tm *os_get_localtime(struct tm *result)
|
||||
{
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return os_localtime_r(&tv.tv_sec, result);
|
||||
}
|
||||
|
@@ -19,6 +19,17 @@ void os_delay(uint64_t milliseconds, bool ignoreinput);
|
||||
/// @param ignoreinput If true, allow a SIGINT to interrupt us
|
||||
void os_microdelay(uint64_t microseconds, bool ignoreinput);
|
||||
|
||||
/// Portable version of POSIX localtime_r()
|
||||
///
|
||||
/// @return NULL in case of error
|
||||
struct tm *os_localtime_r(const time_t *clock, struct tm *result);
|
||||
|
||||
/// Obtains the current UNIX timestamp and adjusts it to local time
|
||||
///
|
||||
/// @param result Pointer to a 'struct tm' where the result should be placed
|
||||
/// @return A pointer to a 'struct tm' in the current time zone (the 'result'
|
||||
/// argument) or NULL in case of error
|
||||
struct tm *os_get_localtime(struct tm *result);
|
||||
|
||||
#endif // NEOVIM_OS_TIME_H
|
||||
|
||||
|
@@ -103,6 +103,7 @@
|
||||
#include "screen.h"
|
||||
#include "sha256.h"
|
||||
#include "os/os.h"
|
||||
#include "os/time.h"
|
||||
|
||||
static long get_undolevel(void);
|
||||
static void u_unch_branch(u_header_T *uhp);
|
||||
@@ -2455,16 +2456,16 @@ void ex_undolist(exarg_T *eap)
|
||||
*/
|
||||
static void u_add_time(char_u *buf, size_t buflen, time_t tt)
|
||||
{
|
||||
struct tm *curtime;
|
||||
struct tm curtime;
|
||||
|
||||
if (time(NULL) - tt >= 100) {
|
||||
curtime = localtime(&tt);
|
||||
os_localtime_r(&tt, &curtime);
|
||||
if (time(NULL) - tt < (60L * 60L * 12L))
|
||||
/* within 12 hours */
|
||||
(void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
|
||||
(void)strftime((char *)buf, buflen, "%H:%M:%S", &curtime);
|
||||
else
|
||||
/* longer ago */
|
||||
(void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", curtime);
|
||||
(void)strftime((char *)buf, buflen, "%Y/%m/%d %H:%M:%S", &curtime);
|
||||
} else
|
||||
vim_snprintf((char *)buf, buflen, _("%" PRId64 " seconds ago"),
|
||||
(int64_t)(time(NULL) - tt));
|
||||
|
Reference in New Issue
Block a user