struct sudo_event *sigtstp_ev;
struct timing_closure {
const char *decimal;
- double max_delay;
+ struct timeval *max_delay;
int idx;
union {
struct {
static void read_keyboard(int fd, int what, void *v);
static void free_log_info(struct log_info *li);
static void help(void) __attribute__((__noreturn__));
-static int replay_session(double max_wait, const char *decimal, bool interactive);
+static int replay_session(struct timeval *max_wait, const char *decimal, bool interactive);
static void sudoreplay_cleanup(void);
static void usage(int);
static void write_output(int fd, int what, void *v);
const char *decimal, *id, *user = NULL, *pattern = NULL, *tty = NULL;
char *cp, *ep, path[PATH_MAX];
struct log_info *li;
- double max_delay = 0;
+ struct timeval max_delay_storage, *max_delay = NULL;
+ double dval;
debug_decl(main, SUDO_DEBUG_MAIN)
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
break;
case 'm':
errno = 0;
- max_delay = strtod(optarg, &ep);
+ dval = strtod(optarg, &ep);
if (*ep != '\0' || errno != 0)
sudo_fatalx(U_("invalid max wait: %s"), optarg);
+ if (dval <= 0.0) {
+ sudo_timevalclear(&max_delay_storage);
+ } else {
+ max_delay_storage.tv_sec = dval;
+ max_delay_storage.tv_usec =
+ (dval - max_delay_storage.tv_sec) * 1000000.0;
+ }
+ max_delay = &max_delay_storage;
break;
case 'n':
interactive = false;
closure->iobuf.toread = closure->timing.u.nbytes;
}
- /* Adjust delay using speed factor and clamp to max_delay */
+ /* Adjust delay using speed factor. */
delay /= speed_factor;
- if (closure->timing.max_delay && delay > closure->timing.max_delay)
- delay = closure->timing.max_delay;
/* Convert delay to a timeval. */
timeout.tv_sec = delay;
timeout.tv_usec = (delay - timeout.tv_sec) * 1000000.0;
+ /* Clamp timeout to max delay. */
+ if (closure->timing.max_delay != NULL) {
+ if (sudo_timevalcmp(&timeout, closure->timing.max_delay, >))
+ timeout = *closure->timing.max_delay;
+ }
+
/* Schedule the delay event. */
if (sudo_ev_add(closure->evbase, closure->delay_ev, &timeout, false) == -1)
sudo_fatal(U_("unable to add event to queue"));
}
static struct replay_closure *
-replay_closure_alloc(double max_delay, const char *decimal, bool interactive)
+replay_closure_alloc(struct timeval *max_delay, const char *decimal, bool interactive)
{
struct replay_closure *closure;
debug_decl(replay_closure_alloc, SUDO_DEBUG_UTIL)
}
static int
-replay_session(double max_delay, const char *decimal, bool interactive)
+replay_session(struct timeval *max_delay, const char *decimal, bool interactive)
{
struct replay_closure *closure;
int ret = 0;