aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-05-03 13:19:52 +0100
committerMatt Fleming <matt.fleming@intel.com>2012-05-03 13:50:14 +0100
commitb6f8015f2335da9ce400b84787ca5721bf1bf867 (patch)
tree7baf23a1ceb6ac691f234b10125d0f114af6aa15
parent254db41a8b0cf5f92bd6ff3f3e20bbd64ede071e (diff)
downloadsyslinux-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.c65
-rw-r--r--com32/elflink/ldlinux/config.h1
-rw-r--r--com32/elflink/ldlinux/ldlinux.c24
-rw-r--r--com32/elflink/ldlinux/readconfig.c7
-rw-r--r--com32/include/menu.h1
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);