diff options
author | Matt Fleming <matt.fleming@intel.com> | 2012-05-03 13:19:52 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2012-05-03 13:50:14 +0100 |
commit | b6f8015f2335da9ce400b84787ca5721bf1bf867 (patch) | |
tree | 7baf23a1ceb6ac691f234b10125d0f114af6aa15 | |
parent | 254db41a8b0cf5f92bd6ff3f3e20bbd64ede071e (diff) | |
download | syslinux-b6f8015f2335da9ce400b84787ca5721bf1bf867.tar.gz syslinux-b6f8015f2335da9ce400b84787ca5721bf1bf867.tar.xz syslinux-b6f8015f2335da9ce400b84787ca5721bf1bf867.zip |
elflink: Fix TIMEOUT and TOTALTIMEOUT handling
Paulo reported that his default command line wasn't being executed
when the timeout specified in his config file elapsed. This is because
mygetkey() wasn't correctly applying the timeout when waiting for
input.
Furthermore, it seems the ONTIMEOUT parsing was also broken.
Reported-by: Paulo Alcantara <pcacjr@zytor.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | com32/elflink/ldlinux/cli.c | 65 | ||||
-rw-r--r-- | com32/elflink/ldlinux/config.h | 1 | ||||
-rw-r--r-- | com32/elflink/ldlinux/ldlinux.c | 24 | ||||
-rw-r--r-- | com32/elflink/ldlinux/readconfig.c | 7 | ||||
-rw-r--r-- | com32/include/menu.h | 1 |
5 files changed, 50 insertions, 48 deletions
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index 498644e2..211a796b 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -19,8 +19,6 @@ #include "cli.h" #include "config.h" -static jmp_buf timeout_jump; - static struct list_head cli_history_head; void clear_screen(void) @@ -29,46 +27,37 @@ void clear_screen(void) fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout); } -int mygetkey(clock_t timeout) +static int mygetkey_timeout(clock_t *kbd_to, clock_t *tto) { - clock_t t0, t; - clock_t tto, to; + clock_t t0, t1; int key; - //dprintf("enter"); - if (!totaltimeout) - return get_key(stdin, 0); - - for (;;) { - tto = min(totaltimeout, INT_MAX); - to = timeout ? min(tto, timeout) : tto; + t0 = times(NULL); + key = get_key(stdin, *kbd_to ? *kbd_to : *tto); - t0 = 0; - key = get_key(stdin, 0); - t = 0 - t0; + /* kbdtimeout only applies to the first character */ + if (*kbd_to) + *kbd_to = 0; - if (totaltimeout <= t) - longjmp(timeout_jump, 1); + t1 = times(NULL) - t0; + if (*tto) { + /* Timed out. */ + if (*tto <= (long long)t1) + key = KEY_NONE; + else { + /* Did it wrap? */ + if (*tto > totaltimeout) + key = KEY_NONE; - totaltimeout -= t; - - if (key != KEY_NONE) { - //dprintf("get key 0x%x", key); - return key; - } - - if (timeout) { - if (timeout <= t) { - //dprintf("timeout"); - return KEY_NONE; - } - - timeout -= t; + *tto -= t1; } } + + return key; } -static const char * cmd_reverse_search(int *cursor) +static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to, + clock_t *tto) { int key; int i = 0; @@ -83,7 +72,7 @@ static const char * cmd_reverse_search(int *cursor) eprintf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m"); while (1) { - key = mygetkey(0); + key = mygetkey_timeout(kbd_to, tto); if (key == KEY_CTRL('C')) { return NULL; @@ -140,6 +129,8 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , const char *ret; int width = 0; struct cli_command *comm_counter = NULL; + clock_t kbd_to = kbdtimeout; + clock_t tto = totaltimeout; if (!width) { int height; @@ -205,9 +196,13 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , redraw = 0; } - key = mygetkey(0); + key = mygetkey_timeout(&kbd_to, &tto); switch (key) { + case KEY_NONE: + /* We timed out. */ + return NULL; + case KEY_CTRL('L'): redraw = 2; break; @@ -381,7 +376,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , * Handle this case in another function, since it's * a kind of special. */ - const char *p = cmd_reverse_search(&cursor); + const char *p = cmd_reverse_search(&cursor, &kbd_to, &tto); if (p) { strcpy(cmdline, p); len = strlen(cmdline); diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h index cab4c70b..b15a0828 100644 --- a/com32/elflink/ldlinux/config.h +++ b/com32/elflink/ldlinux/config.h @@ -35,6 +35,7 @@ extern short nohalt; //idle.inc extern const char *default_cmd; //"default" command line extern const char *onerror; //"onerror" command line +extern const char *ontimeout; //"ontimeout" command line extern void cat_help_file(int key); extern struct menu_entry *find_label(const char *str); diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c index 18915262..c9ec9ac3 100644 --- a/com32/elflink/ldlinux/ldlinux.c +++ b/com32/elflink/ldlinux/ldlinux.c @@ -209,16 +209,12 @@ static void enter_cmdline(void) /* Enter endless command line prompt, should support "exit" */ while (1) { cmdline = edit_cmdline("syslinux$", 1, NULL, cat_help_file); - if (!cmdline) - continue; - - /* return if user only press enter */ - if (cmdline[0] == '\0') { - printf("\n"); - continue; - } printf("\n"); + /* return if user only press enter or we timed out */ + if (!cmdline || cmdline[0] == '\0') + return; + load_kernel(cmdline); } } @@ -226,6 +222,7 @@ static void enter_cmdline(void) int main(int argc __unused, char **argv __unused) { const void *adv; + const char *cmdline; size_t count = 0; char *config_argv[2] = { NULL, NULL }; @@ -242,7 +239,6 @@ int main(int argc __unused, char **argv __unused) * We apparently have a boot-once set; clear it and * then execute the boot-once. */ - const char *cmdline; char *src, *dst; size_t i; @@ -270,12 +266,14 @@ int main(int argc __unused, char **argv __unused) if (forceprompt) goto cmdline; + cmdline = default_cmd; +auto_boot: /* * Auto boot */ if (defaultlevel || noescape) { if (defaultlevel) { - load_kernel(default_cmd); /* Shouldn't return */ + load_kernel(cmdline); /* Shouldn't return */ } else { printf("No DEFAULT or UI configuration directive found!\n"); @@ -285,8 +283,12 @@ int main(int argc __unused, char **argv __unused) } cmdline: - /* Should never return */ + /* Only returns if the user pressed enter or input timed out */ enter_cmdline(); + cmdline = ontimeoutlen ? ontimeout : default_cmd; + + goto auto_boot; + return 0; } diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c index 70fe3461..885c81aa 100644 --- a/com32/elflink/ldlinux/readconfig.c +++ b/com32/elflink/ldlinux/readconfig.c @@ -68,6 +68,7 @@ short nohalt = 1; //idle.inc const char *default_cmd = NULL; //"default" command line const char *onerror = NULL; //"onerror" command line +const char *ontimeout = NULL; //"ontimeout" command line /* Empty refstring */ const char *empty_string; @@ -79,6 +80,7 @@ struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu; int shiftkey = 0; /* Only display menu if shift key pressed */ int hiddenmenu = 0; long long totaltimeout = 0; +unsigned int kbdtimeout = 0; /* Keep track of global default */ static int has_ui = 0; /* DEFAULT only counts if UI is found */ @@ -1081,11 +1083,12 @@ do_include: //dprintf("got a kernel: %s, type = %d", ld.kernel, ld.type); } } else if (looking_at(p, "timeout")) { - m->timeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10; + kbdtimeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10; } else if (looking_at(p, "totaltimeout")) { totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10; } else if (looking_at(p, "ontimeout")) { - m->ontimeout = refstrdup(skipspace(p + 9)); + ontimeout = refstrdup(skipspace(p + 9)); + ontimeoutlen = strlen(ontimeout); } else if (looking_at(p, "allowoptions")) { m->allowedit = !!atoi(skipspace(p + 12)); } else if (looking_at(p, "ipappend")) { diff --git a/com32/include/menu.h b/com32/include/menu.h index 1db4d7c9..ba6b9ced 100644 --- a/com32/include/menu.h +++ b/com32/include/menu.h @@ -187,6 +187,7 @@ extern int shiftkey; extern int hiddenmenu; extern int clearmenu; extern long long totaltimeout; +extern clock_t kbdtimeout; extern const char *hide_key[KEY_MAX]; void parse_configs(char **argv); |