* [Bug 2965] Local clock didn't work since 4.2.8p4. Martin Burnicki.
* [Bug 2969] Seg fault from ntpq/mrulist when looking at server with
lots of clients. perlinger@ntp.org
+* [Bug 2971] ntpq bails on ^C: select fails: Interrupted system call
+ - changed stacked/nested handling of CTRL-C. perlinger@ntp.org
* Unity cleanup for FreeBSD-6.4. Harlan Stenn.
* Unity test cleanup. Harlan Stenn.
* Libevent autoconf pthread fixes for FreeBSD-10. Harlan Stenn.
/*
* other local function prototypes
*/
-void mrulist_ctrl_c_hook(void);
+static int mrulist_ctrl_c_hook(void);
static mru * add_mru(mru *);
static int collect_mru_list(const char *, l_fp *);
static int fetch_nonce(char *, size_t);
} while (0)
-void
+int
mrulist_ctrl_c_hook(void)
{
mrulist_interrupted = TRUE;
+ return TRUE;
}
mon = emalloc_zero(cb);
ZERO(*pnow);
ZERO(last_older);
- mrulist_interrupted = FALSE;
- set_ctrl_c_hook(&mrulist_ctrl_c_hook);
- fprintf(stderr,
- "Ctrl-C will stop MRU retrieval and display partial results.\n");
- fflush(stderr);
next_report = time(NULL) + MRU_REPORT_SECS;
limit = min(3 * MAXFRAGS, ntpd_row_limit);
}
}
- set_ctrl_c_hook(NULL);
c_mru_l_rc = TRUE;
goto retain_hash_table;
int lstint;
size_t i;
+ mrulist_interrupted = FALSE;
+ push_ctrl_c_handler(&mrulist_ctrl_c_hook);
+ fprintf(stderr,
+ "Ctrl-C will stop MRU retrieval and display partial results.\n");
+ fflush(stderr);
+
order = MRUSORT_DEF;
parms_buf[0] = '\0';
parms = parms_buf;
free(hash_table);
hash_table = NULL;
INIT_DLIST(mru_list, mlink);
+
+ pop_ctrl_c_handler(&mrulist_ctrl_c_hook);
}
#ifndef BUILD_AS_LIB
static void getcmds (void);
#ifndef SYS_WINNT
-static RETSIGTYPE abortcmd (int);
+static int abortcmd (void);
#endif /* SYS_WINNT */
static void docmd (const char *);
static void tokenize (const char *, char **, int *);
static void endoutput (FILE *);
static void outputarr (FILE *, char *, int, l_fp *);
static int assoccmp (const void *, const void *);
+static void on_ctrlc (void);
u_short varfmt (const char *);
void ntpq_custom_opt_handler (tOptions *, tOptDesc *);
interactive = 1;
}
+ set_ctrl_c_hook(on_ctrlc);
#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
if (interactive)
- (void) signal_no_reset(SIGINT, abortcmd);
+ push_ctrl_c_handler(abortcmd);
#endif /* SYS_WINNT */
if (numcmds == 0) {
/*
* abortcmd - catch interrupts and abort the current command
*/
-static RETSIGTYPE
-abortcmd(
- int sig
- )
+static int
+abortcmd(void)
{
if (current_output == stdout)
- (void) fflush(stdout);
+ (void) fflush(stdout);
putc('\n', stderr);
(void) fflush(stderr);
- if (jump) longjmp(interrupt_buf, 1);
+ if (jump) {
+ jump = 0;
+ longjmp(interrupt_buf, 1);
+ }
+ return TRUE;
}
#endif /* !SYS_WINNT && !BUILD_AS_LIB */
return list;
}
+
+#define CTRLC_STACK_MAX 4
+static volatile size_t ctrlc_stack_len = 0;
+static volatile Ctrl_C_Handler ctrlc_stack[CTRLC_STACK_MAX];
+
+
+
+int/*BOOL*/
+push_ctrl_c_handler(
+ Ctrl_C_Handler func
+ )
+{
+ size_t size = ctrlc_stack_len;
+ if (func && (size < CTRLC_STACK_MAX)) {
+ ctrlc_stack[size] = func;
+ ctrlc_stack_len = size + 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int/*BOOL*/
+pop_ctrl_c_handler(
+ Ctrl_C_Handler func
+ )
+{
+ size_t size = ctrlc_stack_len;
+ if (size) {
+ --size;
+ if (func == NULL || func == ctrlc_stack[size]) {
+ ctrlc_stack_len = size;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+on_ctrlc(void)
+{
+ size_t size = ctrlc_stack_len;
+ while (size)
+ if ((*ctrlc_stack[--size])())
+ break;
+}
extern void makeascii (size_t, const char *, FILE *);
extern const char * trunc_left (const char *, size_t);
extern const char * trunc_right(const char *, size_t);
+
+typedef int/*BOOL*/ (*Ctrl_C_Handler)(void);
+extern int/*BOOL*/ push_ctrl_c_handler(Ctrl_C_Handler);
+extern int/*BOOL*/ pop_ctrl_c_handler(Ctrl_C_Handler);