diff --git a/common/os_calls.c b/common/os_calls.c index afd5a95858..03c57b1fd2 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -2045,18 +2045,6 @@ g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs, int wcount, void g_random(char *data, int len) { -#if defined(_WIN32) - int index; - - srand(g_time1()); - - for (index = 0; index < len; index++) - { - data[index] = (char)rand(); /* rand returns a number between 0 and - RAND_MAX */ - } - -#else int fd; memset(data, 0x44, len); @@ -2075,8 +2063,6 @@ g_random(char *data, int len) close(fd); } - -#endif } /*****************************************************************************/ @@ -3778,51 +3764,21 @@ g_check_user_in_group(const char *username, int gid, int *ok) #endif // HAVE_GETGROUPLIST /*****************************************************************************/ -/* returns the time since the Epoch (00:00:00 UTC, January 1, 1970), - measured in seconds. - for windows, returns the number of seconds since the machine was - started. */ -int -g_time1(void) -{ -#if defined(_WIN32) - return GetTickCount() / 1000; -#else - return time(0); -#endif -} - -/*****************************************************************************/ -/* returns the number of milliseconds since the machine was - started. */ -int -g_time2(void) +unsigned int +g_get_elapsed_ms(void) { -#if defined(_WIN32) - return (int)GetTickCount(); -#else - struct tms tm; - clock_t num_ticks = 0; - g_memset(&tm, 0, sizeof(struct tms)); - num_ticks = times(&tm); - return (int)(num_ticks * 10); -#endif -} + unsigned int result = 0; + struct timespec tp; -/*****************************************************************************/ -/* returns time in milliseconds, uses gettimeofday - does not work in win32 */ -int -g_time3(void) -{ -#if defined(_WIN32) - return 0; -#else - struct timeval tp; + if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) + { + result = (unsigned int)tp.tv_sec * 1000; + // POSIX 1003.1-2004 specifies that tv_nsec is a long (i.e. a + // signed type), but can only contain [0..999,999,999] + result += tp.tv_nsec / 1000000; + } - gettimeofday(&tp, 0); - return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); -#endif + return result; } /******************************************************************************/ diff --git a/common/os_calls.h b/common/os_calls.h index be06b07b45..31e8933ba2 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -393,9 +393,26 @@ int g_getgroup_info(const char *groupname, int *gid); * Primary group of username is also checked */ int g_check_user_in_group(const char *username, int gid, int *ok); -int g_time1(void); -int g_time2(void); -int g_time3(void); + +/** + * Gets elapsed milliseconds since some arbitrary point in the past + * + * The returned value is unaffected by leap-seconds or time zone changes. + * + * @return elaped ms since some arbitrary point + * + * Calculate the duration of a task by calling this routine before and + * after the task, and subtracting the two values. + * + * The value wraps every so often (every 49.7 days on a 32-bit system), + * but as we are using unsigned arithmetic, the difference of any of these + * two values can be used to calculate elapsed time, whether-or-not a wrap + * occurs during the interval - provided of course the time being measured + * is less than the total wrap-around interval. + */ +unsigned int +g_get_elapsed_ms(void); + int g_save_to_bmp(const char *filename, char *data, int stride_bytes, int width, int height, int depth, int bits_per_pixel); void *g_shmat(int shmid); diff --git a/common/trans.c b/common/trans.c index 780b4c52a7..ceaf7802df 100644 --- a/common/trans.c +++ b/common/trans.c @@ -696,7 +696,7 @@ local_connect_shim(int fd, const char *server, const char *port) /**************************************************************************//** * Waits for an asynchronous connect to complete. * @param self - Transport object - * @param start_time Start time of connect (from g_time3()) + * @param start_time Start time of connect (from g_get_elapsed_ms()) * @param timeout Total wait timeout * @return 0 - connect succeeded, 1 - Connect failed * @@ -704,10 +704,10 @@ local_connect_shim(int fd, const char *server, const char *port) * on a regular basis. */ static int -poll_for_async_connect(struct trans *self, int start_time, int timeout) +poll_for_async_connect(struct trans *self, unsigned int start_time, int timeout) { int rv = 1; - int ms_remaining = timeout - (g_time3() - start_time); + int ms_remaining = timeout - (int)(g_get_elapsed_ms() - start_time); while (ms_remaining > 0) { @@ -736,7 +736,7 @@ poll_for_async_connect(struct trans *self, int start_time, int timeout) break; } - ms_remaining = timeout - (g_time3() - start_time); + ms_remaining = timeout - (int)(g_get_elapsed_ms() - start_time); } return rv; } @@ -747,7 +747,7 @@ int trans_connect(struct trans *self, const char *server, const char *port, int timeout) { - int start_time = g_time3(); + unsigned int start_time = g_get_elapsed_ms(); int error; int ms_before_next_connect; @@ -826,7 +826,7 @@ trans_connect(struct trans *self, const char *server, const char *port, } /* Have we reached the total timeout yet? */ - int ms_left = timeout - (g_time3() - start_time); + int ms_left = timeout - (int)(g_get_elapsed_ms() - start_time); if (ms_left <= 0) { error = 1; diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index f19346bc41..495d270c37 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -132,7 +132,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data) tui32 now; LOG_DEVEL(LOG_LEVEL_DEBUG, "add_timeout:"); - now = g_time3(); + now = g_get_elapsed_ms(); tobj = g_new0(struct timeout_obj, 1); tobj->mstime = now + msoffset; tobj->callback = callback; @@ -167,7 +167,7 @@ get_timeout(int *timeout) tobj = g_timeout_head; if (tobj != 0) { - now = g_time3(); + now = g_get_elapsed_ms(); while (tobj != 0) { LOG_DEVEL(LOG_LEVEL_DEBUG, " now %u tobj->mstime %u", now, tobj->mstime); @@ -215,7 +215,7 @@ check_timeout(void) while (tobj != 0) { count++; - now = g_time3(); + now = g_get_elapsed_ms(); if (now >= tobj->mstime) { tobj->callback(tobj->data); diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c index 90fed048af..0be2f6e68e 100644 --- a/sesman/chansrv/clipboard_file.c +++ b/sesman/chansrv/clipboard_file.c @@ -274,7 +274,7 @@ clipboard_get_file(const char *file, int bytes) list_add_item(g_files_list, (tintptr)cfi); cfi->size = g_file_get_size(full_fn); cfi->flags = CB_FILE_ATTRIBUTE_ARCHIVE; - cfi->time = (g_time1() + CB_EPOCH_DIFF) * 10000000LL; + cfi->time = (time(NULL) + CB_EPOCH_DIFF) * 10000000LL; LOG_DEVEL(LOG_LEVEL_DEBUG, "ok filename [%s] pathname [%s] size [%d]", cfi->filename, cfi->pathname, cfi->size); result = 0; diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c index 2c862f99bd..ba3685ae79 100644 --- a/sesman/chansrv/sound.c +++ b/sesman/chansrv/sound.c @@ -71,7 +71,7 @@ static struct trans *g_audio_c_trans_out = 0; /* connection */ static struct trans *g_audio_l_trans_in = 0; /* listener */ static struct trans *g_audio_c_trans_in = 0; /* connection */ -static int g_training_sent_time = 0; +static unsigned int g_training_sent_time = 0; static int g_cBlockNo = 0; static int g_bytes_in_stream = 0; struct fifo *g_in_fifo; @@ -86,7 +86,7 @@ static struct stream *g_stream_incoming_packet = NULL; #define MAX_BBUF_SIZE (1024 * 16) static char g_buffer[MAX_BBUF_SIZE]; static int g_buf_index = 0; -static int g_sent_time[256]; +static unsigned int g_sent_time[256]; static int g_bbuf_size = 1024 * 8; /* may change later */ @@ -341,7 +341,7 @@ sound_send_training(void) { struct stream *s; int bytes; - int time; + unsigned int time; char *size_ptr; make_stream(s); @@ -349,7 +349,7 @@ sound_send_training(void) out_uint16_le(s, SNDC_TRAINING); size_ptr = s->p; out_uint16_le(s, 0); /* size, set later */ - time = g_time3(); + time = g_get_elapsed_ms(); g_training_sent_time = time; out_uint16_le(s, time); out_uint16_le(s, 1024); @@ -885,7 +885,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes) { struct stream *s; int bytes; - int time; + unsigned int time; int format_index; char *size_ptr; @@ -912,7 +912,7 @@ sound_send_wave_data_chunk(char *data, int data_bytes) out_uint16_le(s, SNDC_WAVE); size_ptr = s->p; out_uint16_le(s, 0); /* size, set later */ - time = g_time3(); + time = g_get_elapsed_ms(); out_uint16_le(s, time); out_uint16_le(s, format_index); /* wFormatNo */ g_cBlockNo++; @@ -1040,7 +1040,7 @@ sound_process_training(struct stream *s, int size) { int time_diff; - time_diff = g_time3() - g_training_sent_time; + time_diff = g_get_elapsed_ms() - g_training_sent_time; LOG(LOG_LEVEL_INFO, "sound_process_training: round trip time %u", time_diff); return 0; } @@ -1052,12 +1052,12 @@ sound_process_wave_confirm(struct stream *s, int size) { int wTimeStamp; int cConfirmedBlockNo; - int time; + unsigned int time; int time_diff; int index; int acc; - time = g_time3(); + time = g_get_elapsed_ms(); in_uint16_le(s, wTimeStamp); in_uint8(s, cConfirmedBlockNo); time_diff = time - g_sent_time[cConfirmedBlockNo & 0xff]; @@ -1095,13 +1095,13 @@ static int process_pcm_message(int id, int size, struct stream *s) { static int sending_silence = 0; - static int silence_start_time = 0; + static unsigned int silence_start_time = 0; switch (id) { case 0: if ((g_client_does_fdk_aac || g_client_does_mp3lame) && sending_silence) { - if ((g_time3() - silence_start_time) < (int)g_cfg->msec_do_not_send) + if ((g_get_elapsed_ms() - silence_start_time) < g_cfg->msec_do_not_send) { /* do not send data within msec_do_not_send msec after SNDC_CLOSE is sent, to avoid stutter. setting from sesman.ini */ return 0; @@ -1119,7 +1119,7 @@ process_pcm_message(int id, int size, struct stream *s) if (buf != NULL) { int i; - silence_start_time = g_time3(); + silence_start_time = g_get_elapsed_ms(); sending_silence = 1; for (i = 0; i < send_silence_times; i++) { diff --git a/sesman/chansrv/xcommon.c b/sesman/chansrv/xcommon.c index 2e444e76cc..2067bbd6f4 100644 --- a/sesman/chansrv/xcommon.c +++ b/sesman/chansrv/xcommon.c @@ -85,17 +85,6 @@ xcommon_fatal_handler(Display *dis) return 0; } -/*****************************************************************************/ -/* returns time in milliseconds - this is like g_time2 in os_calls, but not milliseconds since machine was - up, something else - this is a time value similar to what the xserver uses */ -int -xcommon_get_local_time(void) -{ - return g_time3(); -} - /******************************************************************************/ /* this should be called first */ int diff --git a/sesman/chansrv/xcommon.h b/sesman/chansrv/xcommon.h index 75e93c0957..3195eda2a9 100644 --- a/sesman/chansrv/xcommon.h +++ b/sesman/chansrv/xcommon.h @@ -28,8 +28,6 @@ typedef void (*x_server_fatal_cb_type)(void); -int -xcommon_get_local_time(void); int xcommon_init(void); int diff --git a/sesman/libsesman/verify_user.c b/sesman/libsesman/verify_user.c index ccd289d238..fad83b422a 100644 --- a/sesman/libsesman/verify_user.c +++ b/sesman/libsesman/verify_user.c @@ -225,7 +225,7 @@ auth_check_pwd_chg(const char *user) } /* check if we need a pwd change */ - now = g_time1(); + now = time(NULL); today = now / SECS_PER_DAY; if (stp->sp_expire == -1) @@ -306,7 +306,7 @@ auth_change_pwd(const char *user, const char *newpwd) } stp->sp_pwdp = g_strdup(hash); - today = g_time1() / SECS_PER_DAY; + today = time(NULL) / SECS_PER_DAY; stp->sp_lstchg = today; stp->sp_expire = today + stp->sp_max + stp->sp_inact; fd = fopen("/etc/shadow", "rw"); @@ -377,7 +377,7 @@ auth_account_disabled(struct spwd *stp) return 1; } - today = g_time1() / SECS_PER_DAY; + today = time(NULL) / SECS_PER_DAY; LOG_DEVEL(LOG_LEVEL_DEBUG, "last %ld", stp->sp_lstchg); LOG_DEVEL(LOG_LEVEL_DEBUG, "min %ld", stp->sp_min); diff --git a/sesman/sesexec/login_info.c b/sesman/sesexec/login_info.c index adb8ef1add..bb9d3f9eb7 100644 --- a/sesman/sesexec/login_info.c +++ b/sesman/sesexec/login_info.c @@ -57,8 +57,8 @@ log_authfail_message(const char *username, const char *ip_addr) { ip_addr = "unknown"; } - LOG(LOG_LEVEL_INFO, "AUTHFAIL: user=%s ip=%s time=%d", - username, ip_addr, g_time1()); + LOG(LOG_LEVEL_INFO, "AUTHFAIL: user=%s ip=%s time=%ld", + username, ip_addr, (long)time(NULL)); } /******************************************************************************/ diff --git a/sesman/sesexec/session.c b/sesman/sesexec/session.c index 11ec979d95..13ac7f3596 100644 --- a/sesman/sesexec/session.c +++ b/sesman/sesexec/session.c @@ -674,7 +674,7 @@ session_start_wrapped(struct login_info *login_info, sd->win_mgr = window_manager_pid; sd->x_server = display_pid; sd->chansrv = chansrv_pid; - sd->start_time = g_time1(); + sd->start_time = time(NULL); status = E_SCP_SCREATE_OK; } } @@ -860,7 +860,7 @@ session_process_child_exit(struct session_data *sd, } else if (pid == sd->win_mgr) { - int wm_wait_time = g_time1() - sd->start_time; + int wm_wait_time = time(NULL) - sd->start_time; if (e->reason == E_PXR_STATUS_CODE && e->val == 0) { diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 072df9cc0a..96ee93c222 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -489,8 +489,8 @@ struct display_control_monitor_layout_data { struct display_size_description description; enum display_resize_state state; - int last_state_update_timestamp; - int start_time; + unsigned int last_state_update_timestamp; + unsigned int start_time; /// This flag is set if the state machine needs to /// shutdown/startup EGFX int using_egfx; diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 5d276c3b88..6bccd952ba 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1275,14 +1275,14 @@ advance_resize_state_machine(struct xrdp_mm *mm, "advance_resize_state_machine:" " Processing resize to: %d x %d." " Advancing state from %s to %s." - " Previous state took %d MS.", + " Previous state took %u MS.", description->description.session_width, description->description.session_height, XRDP_DISPLAY_RESIZE_STATE_TO_STR(description->state), XRDP_DISPLAY_RESIZE_STATE_TO_STR(new_state), - g_time3() - description->last_state_update_timestamp); + g_get_elapsed_ms() - description->last_state_update_timestamp); description->state = new_state; - description->last_state_update_timestamp = g_time3(); + description->last_state_update_timestamp = g_get_elapsed_ms(); g_set_wait_obj(mm->resize_ready); return 0; } @@ -1829,7 +1829,7 @@ process_display_control_monitor_layout_data(struct xrdp_wm *wm) // ever is, advance the state machine! if (chan->drdynvcs[mm->egfx->channel_id].status == XRDP_DRDYNVC_STATUS_CLOSED - || (g_time3() - description->last_state_update_timestamp) > 100) + || (g_get_elapsed_ms() - description->last_state_update_timestamp) > 100) { advance_resize_state_machine(mm, WMRZ_EGFX_CONN_CLOSED); break; @@ -2045,7 +2045,7 @@ dynamic_monitor_process_queue(struct xrdp_mm *self) g_malloc(LAYOUT_DATA_SIZE, 1); g_memcpy(&(self->resize_data->description), queue_head, sizeof(struct display_size_description)); - const int time = g_time3(); + const unsigned int time = g_get_elapsed_ms(); self->resize_data->start_time = time; self->resize_data->last_state_update_timestamp = time; self->resize_data->using_egfx = (self->egfx != NULL); @@ -2072,10 +2072,10 @@ dynamic_monitor_process_queue(struct xrdp_mm *self) if (self->resize_data->state == WMRZ_COMPLETE) { LOG(LOG_LEVEL_INFO, "dynamic_monitor_process_queue: Clearing" - " completed resize (w: %d x h: %d). It took %d milliseconds.", + " completed resize (w: %d x h: %d). It took %u milliseconds.", self->resize_data->description.session_width, self->resize_data->description.session_height, - g_time3() - self->resize_data->start_time); + g_get_elapsed_ms() - self->resize_data->start_time); g_set_wait_obj(self->resize_ready); } else if (self->resize_data->state == WMRZ_ERROR) @@ -3532,9 +3532,10 @@ xrdp_mm_get_wait_objs(struct xrdp_mm *self, { if (xrdp_region_not_empty(self->wm->screen_dirty_region)) { - int now = g_time3(); - int next_screen_draw_time = self->wm->last_screen_draw_time + - MIN_MS_BETWEEN_FRAMES; + unsigned int now = g_get_elapsed_ms(); + unsigned int next_screen_draw_time = + self->wm->last_screen_draw_time + + MIN_MS_BETWEEN_FRAMES; int diff = next_screen_draw_time - now; int ltimeout = *timeout; diff = MAX(diff, MIN_MS_TO_WAIT_FOR_MORE_UPDATES); @@ -3924,7 +3925,7 @@ xrdp_mm_check_wait_objs(struct xrdp_mm *self) { if (xrdp_region_not_empty(self->wm->screen_dirty_region)) { - int now = g_time3(); + unsigned int now = g_get_elapsed_ms(); int diff = now - self->wm->last_screen_draw_time; LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mm_check_wait_objs: not empty diff %d", diff); if ((diff < 0) || (diff >= 40)) diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index d972e02fd3..f4ef5cd143 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -589,7 +589,7 @@ struct xrdp_wm struct xrdp_tconfig_gfx *gfx_config; struct xrdp_region *screen_dirty_region; - int last_screen_draw_time; + unsigned int last_screen_draw_time; }; /* rdp process */