* [PATCH] Handler support
@ 2009-02-12 12:01 Bean
2009-02-14 14:46 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-02-12 12:01 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 2717 bytes --]
Hi,
This patch add handler support, the lowest level structure is list,
which represent a linked list:
struct grub_list
{
struct grub_list *next;
};
functions to manipulate the list object:
grub_list_push, grub_list_pop, grub_list_remove and grub_list_iterate.
Another new structure is handler class, which represent a class of handlers:
struct grub_handler_class
{
struct grub_handler_class *next;
const char *name;
grub_list_t handler_list;
struct grub_handler *cur_handler;
};
functions:
grub_handler_class_register, grub_handler_class_unregister,
grub_handler_class_iterate
Finally, it's the handler structure:
struct grub_handler
{
struct grub_handler *next;
const char *name;
grub_err_t (*init) (void);
grub_err_t (*fini) (void);
};
functions:
grub_handler_register, grub_handler_unregister, grub_handler_iterate,
grub_handler_set_current, grub_handler_get_current
handler class and handler are lists, the register and unregister
function calls the list function to do the job.
I convert the terminal_input and terminal_output to use the new
handler modal, but this can also apply to other parts of grub2.
Structure lile fs, partmap, modules, commands are lists, and script
engine, menu viewer and so on can be converted to handlers.
Using handler method, terminal_input and terminal_output command are
not necessary anymore. Instead, we can have a generic handler command:
handler [class [handler]]
called with no argument, it lists all handler class.
called with 1 argument, it lists all handlers in a selected class.
called with 2 argument, it set the current handler for a selected class.
handler might be better implemented using the object orient features,
however, this would be a overkill for grub2. Instead, I use a simpler
compiler type checking method. For example, here is a code segment:
void
grub_handler_register (grub_handler_class_t class, void *handler)
{
int first_handler = (class->cur_handler == 0);
GRUB_ASSERT_IS_LIST (grub_handler);
grub_list_push (&class->handler_list, handler);
if (first_handler)
grub_handler_set_current (class, handler);
}
the handler type is void*, which allows it to pass pointers around
without casting. Inside the function, when we want to use handler as a
list object, we call macro GRUB_ASSERT_IS_LIST. This macro confirms
that the fields required by grub_list is at the same location as in
grub_handler, so we don't run into problem when accessing the
structure in lower layout. Likewise, GRUB_ASSERT_IS_HANDLER checks
whether a structure, such as grub_term_input_t, can be safely cast as
grub_handler_t. The macro runs at compiled time, if no problem is
found, it wouldn't generate any extra code.
--
Bean
[-- Attachment #2: handler.diff --]
[-- Type: text/plain, Size: 40058 bytes --]
diff --git a/commands/handler.c b/commands/handler.c
new file mode 100644
index 0000000..04f89f8
--- /dev/null
+++ b/commands/handler.c
@@ -0,0 +1,105 @@
+/* handler.c - test module for dynamic loading */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/handler.h>
+
+static grub_err_t
+grub_cmd_handler (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ char *find_name;
+ void *find_result;
+ void *curr_item = 0;
+
+ auto int list_item (grub_handler_class_t item);
+ int list_item (grub_handler_class_t item)
+ {
+ if (item == curr_item)
+ grub_putchar ('*');
+
+ grub_printf ("%s\n", item->name);
+
+ return 0;
+ }
+
+ auto int find_item (grub_handler_class_t item);
+ int find_item (grub_handler_class_t item)
+ {
+ if (! grub_strcmp (item->name, find_name))
+ {
+ find_result = item;
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (argc == 0)
+ {
+ grub_handler_class_iterate (list_item);
+ }
+ else
+ {
+ grub_handler_class_t class;
+
+ find_name = args[0];
+ find_result = 0;
+ grub_handler_class_iterate (find_item);
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+ class = find_result;
+
+ if (argc == 1)
+ {
+ curr_item = class->cur_handler;
+ grub_handler_iterate (find_result, (grub_list_hook_t) list_item);
+ }
+ else
+ {
+ find_name = args[1];
+ find_result = 0;
+ grub_handler_iterate (class, (grub_list_hook_t) find_item);
+
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+ grub_handler_set_current (class, find_result);
+ }
+ }
+
+ return 0;
+}
+
+GRUB_MOD_INIT(handler)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("handler", grub_cmd_handler, GRUB_COMMAND_FLAG_BOTH,
+ "handler [class [handler]]",
+ "List or select a handler", 0);
+}
+
+GRUB_MOD_FINI(handler)
+{
+ grub_unregister_command ("hello");
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index dfd481a..9a62ac3 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -330,7 +330,7 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS)
scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Commands.
-pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \
+pkglib_MODULES += hello.mod boot.mod handler.mod ls.mod \
cmp.mod cat.mod help.mod search.mod \
loopback.mod fs_uuid.mod configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
@@ -346,10 +346,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index f26bf4a..d837281 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -17,7 +17,7 @@ kernel_elf_SOURCES = kern/i386/coreboot/startup.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
@@ -30,7 +30,7 @@ kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h
+ machine/memory.h machine/loader.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic
@@ -57,7 +57,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index dc0547e..fe83f71 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -34,7 +34,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -87,14 +87,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h
+ efi/efi.h efi/time.h efi/disk.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 90fc2f0..3a8886f 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -20,7 +20,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/env.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
@@ -29,7 +29,8 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h
+ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+ list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
@@ -55,7 +56,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 2fd03b5..7abfa58 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -42,7 +42,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
@@ -56,7 +56,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
- machine/kernel.h machine/pxe.h
+ machine/kernel.h machine/pxe.h list.h handler.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -114,7 +114,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index b48f303..17e92bf 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -40,7 +40,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/search.c commands/terminal.c commands/test.c \
+ commands/search.c commands/handler.c commands/test.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
disk/loopback.c \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index ce133e9..3a28e94 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -44,7 +44,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
# For grub-emu
#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
# commands/configfile.c commands/default.c commands/help.c \
-# commands/search.c commands/terminal.c commands/ls.c \
+# commands/search.c commands/handler.c commands/ls.c \
# commands/timeout.c commands/test.c \
# commands/halt.c commands/reboot.c \
# disk/loopback.c \
@@ -75,8 +75,8 @@ kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \
kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \
kern/generic/millisleep.c kern/generic/get_time_ms.c \
- kern/sparc64/cache.S kern/parser.c
-kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h
+ kern/sparc64/cache.S kern/parser.c kern/list.c kern/handler.c
+kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc
@@ -85,7 +85,7 @@ kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-me
#_linux.mod linux.mod
pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ boot.mod cmp.mod cat.mod handler.mod fshelp.mod amiga.mod apple.mod \
pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
configfile.mod search.mod gzio.mod xfs.mod \
affs.mod sfs.mod acorn.mod
@@ -185,10 +185,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 973260b..66b3d1a 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -36,7 +36,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -89,14 +89,14 @@ kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
term/efi/console.c disk/efi/efidisk.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h machine/loader.h
+ efi/efi.h efi/time.h efi/disk.h machine/loader.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/include/grub/handler.h b/include/grub/handler.h
new file mode 100644
index 0000000..26c98d3
--- /dev/null
+++ b/include/grub/handler.h
@@ -0,0 +1,69 @@
+/* handler.h - header for grub handler */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+ struct grub_handler *next;
+ const char *name;
+ grub_err_t (*init) (void);
+ grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+ struct grub_handler_class *next;
+ const char *name;
+ grub_list_t handler_list;
+ struct grub_handler *cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+void EXPORT_FUNC(grub_handler_class_register) (grub_handler_class_t class);
+void EXPORT_FUNC(grub_handler_class_unregister) (grub_handler_class_t class);
+void EXPORT_FUNC(grub_handler_class_iterate) (int (*hook)
+ (grub_handler_class_t item));
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+ void *handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+ void *handler);
+void EXPORT_FUNC(grub_handler_iterate) (grub_handler_class_t class,
+ grub_list_hook_t hook);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+ void *handler);
+void * EXPORT_FUNC(grub_handler_get_current) (grub_handler_class_t class);
+
+#define GRUB_ASSERT_IS_HANDLER(type) \
+ { \
+ struct type t1; \
+ struct grub_handler t2; \
+ GRUB_ASSERT_CHECK_FIELD (next); \
+ GRUB_ASSERT_CHECK_FIELD (name); \
+ GRUB_ASSERT_CHECK_FIELD (init); \
+ GRUB_ASSERT_CHECK_FIELD (fini); \
+ }
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/list.h b/include/grub/list.h
new file mode 100644
index 0000000..7620937
--- /dev/null
+++ b/include/grub/list.h
@@ -0,0 +1,56 @@
+/* list.h - header for grub list */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_list
+{
+ struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, void *item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, void *item);
+void EXPORT_FUNC(grub_list_iterate) (grub_list_t head,
+ grub_list_hook_t hook);
+
+/* This function doesn't exist, so if assertion is false for some reason, the
+ linker would fail. */
+extern void grub_assert_fail (void);
+
+#define GRUB_ASSERT_CHECK_FIELD(field) \
+ if ((char *) &t1. field - (char *) &t1 != \
+ (char *) &t2. field - (char *) &t2) \
+ grub_assert_fail ();
+
+#define GRUB_ASSERT_IS_LIST(type) \
+ { \
+ struct type t1; \
+ struct grub_list t2; \
+ GRUB_ASSERT_CHECK_FIELD (next); \
+ }
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
index 13835bb..fbe890d 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -38,6 +38,7 @@
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
+#include <grub/handler.h>
/* These are used to represent the various color states we use. */
typedef enum
@@ -139,6 +140,9 @@ grub_term_color_state;
struct grub_term_input
{
+ /* The next terminal. */
+ struct grub_term_input *next;
+
/* The terminal name. */
const char *name;
@@ -153,14 +157,14 @@ struct grub_term_input
/* Get a character. */
int (*getkey) (void);
-
- /* The next terminal. */
- struct grub_term_input *next;
};
typedef struct grub_term_input *grub_term_input_t;
struct grub_term_output
{
+ /* The next terminal. */
+ struct grub_term_output *next;
+
/* The terminal name. */
const char *name;
@@ -208,24 +212,9 @@ struct grub_term_output
/* The feature flags defined above. */
grub_uint32_t flags;
-
- /* The next terminal. */
- struct grub_term_output *next;
};
typedef struct grub_term_output *grub_term_output_t;
-void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
-void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
-void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
-void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
-void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
-void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
-
-grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
-grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
-grub_term_input_t EXPORT_FUNC(grub_term_get_current_input) (void);
-grub_term_output_t EXPORT_FUNC(grub_term_get_current_output) (void);
-
void EXPORT_FUNC(grub_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
@@ -248,6 +237,15 @@ void EXPORT_FUNC(grub_set_more) (int onoff);
/* For convenience. */
#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff)
+extern struct grub_handler_class EXPORT_VAR(grub_term_input_class);
+extern struct grub_handler_class EXPORT_VAR(grub_term_output_class);
+
+#define grub_cur_term_input \
+ ((grub_term_input_t) grub_term_input_class.cur_handler)
+
+#define grub_cur_term_output \
+ ((grub_term_output_t) grub_term_output_class.cur_handler)
+
#endif /* ! ASM_FILE */
#endif /* ! GRUB_TERM_HEADER */
diff --git a/kern/handler.c b/kern/handler.c
new file mode 100644
index 0000000..203d7b0
--- /dev/null
+++ b/kern/handler.c
@@ -0,0 +1,88 @@
+/* handler.c - grub handler function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+static grub_list_t grub_handler_class_list;
+
+void
+grub_handler_class_register (grub_handler_class_t class)
+{
+ GRUB_ASSERT_IS_LIST (grub_handler_class);
+ grub_list_push (&grub_handler_class_list, class);
+}
+
+void
+grub_handler_class_unregister (grub_handler_class_t class)
+{
+ grub_list_remove (&grub_handler_class_list, class);
+}
+
+void
+grub_handler_class_iterate (int (*hook) (grub_handler_class_t item))
+{
+ grub_list_iterate (grub_handler_class_list, (grub_list_hook_t) hook);
+}
+
+void
+grub_handler_register (grub_handler_class_t class, void *handler)
+{
+ int first_handler = (class->cur_handler == 0);
+
+ GRUB_ASSERT_IS_LIST (grub_handler);
+ grub_list_push (&class->handler_list, handler);
+
+ if (first_handler)
+ grub_handler_set_current (class, handler);
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, void *handler)
+{
+ grub_list_remove (&class->handler_list, handler);
+}
+
+void
+grub_handler_iterate (grub_handler_class_t class, grub_list_hook_t hook)
+{
+ grub_list_iterate (class->handler_list, hook);
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, void *handler)
+{
+ grub_handler_t new_handler = handler;
+
+ if (class->cur_handler && class->cur_handler->fini)
+ if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (new_handler->init)
+ if ((new_handler->init) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ class->cur_handler = new_handler;
+ return GRUB_ERR_NONE;
+}
+
+void *
+grub_handler_get_current (grub_handler_class_t class)
+{
+ return class->cur_handler;
+}
diff --git a/kern/list.c b/kern/list.c
new file mode 100644
index 0000000..cdeeecf
--- /dev/null
+++ b/kern/list.c
@@ -0,0 +1,62 @@
+/* list.c - grub list function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+
+void
+grub_list_push (grub_list_t *head, void *item)
+{
+ ((grub_list_t) item)->next = *head;
+ *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+ grub_list_t item;
+
+ item = *head;
+ if (item)
+ *head = item->next;
+
+ return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, void *item)
+{
+ grub_list_t *p, q;
+
+ for (p = head, q = *p; q; p = &(q->next), q = q->next)
+ if (q == item)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+void
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+ grub_list_t p;
+
+ for (p = head; p; p = p->next)
+ if (hook (p))
+ break;
+}
diff --git a/kern/main.c b/kern/main.c
index 40300b2..000374c 100644
--- a/kern/main.c
+++ b/kern/main.c
@@ -27,6 +27,7 @@
#include <grub/device.h>
#include <grub/env.h>
#include <grub/mm.h>
+#include <grub/handler.h>
void
grub_module_iterate (int (*hook) (struct grub_module_header *header))
@@ -60,7 +61,7 @@ grub_load_modules (void)
{
/* Not an ELF module, skip. */
if (header->type != OBJ_TYPE_ELF)
- return 0;
+ return 0;
if (! grub_dl_load_core ((char *) header + sizeof (struct grub_module_header),
(header->size - sizeof (struct grub_module_header))))
@@ -126,6 +127,12 @@ grub_load_normal_mode (void)
void
grub_main (void)
{
+ /* Register handler classes. */
+ GRUB_ASSERT_IS_HANDLER(grub_term_input);
+ GRUB_ASSERT_IS_HANDLER(grub_term_output);
+ grub_handler_class_register (&grub_term_input_class);
+ grub_handler_class_register (&grub_term_output_class);
+
/* First of all, initialize the machine. */
grub_machine_init ();
diff --git a/kern/misc.c b/kern/misc.c
index 641bd7a..97a61f2 100644
--- a/kern/misc.c
+++ b/kern/misc.c
@@ -1063,11 +1063,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
void
grub_abort (void)
{
- if (grub_term_get_current_output ())
+ if (grub_cur_term_output)
{
grub_printf ("\nAborted.");
- if (grub_term_get_current_input ())
+ if (grub_cur_term_input)
{
grub_printf (" Press any key to exit.");
grub_getkey ();
diff --git a/kern/term.c b/kern/term.c
index 8d5a23b..524b79d 100644
--- a/kern/term.c
+++ b/kern/term.c
@@ -21,14 +21,17 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
+#include <grub/handler.h>
-/* The list of terminals. */
-static grub_term_input_t grub_term_list_input;
-static grub_term_output_t grub_term_list_output;
+struct grub_handler_class grub_term_input_class =
+ {
+ .name = "input"
+ };
-/* The current terminal. */
-static grub_term_input_t grub_cur_term_input;
-static grub_term_output_t grub_cur_term_output;
+struct grub_handler_class grub_term_output_class =
+ {
+ .name = "output"
+ };
/* The amount of lines counted by the pager. */
static int grub_more_lines;
@@ -39,112 +42,6 @@ static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
-void
-grub_term_register_input (grub_term_input_t term)
-{
- term->next = grub_term_list_input;
- grub_term_list_input = term;
- if (! grub_cur_term_input)
- grub_term_set_current_input (term);
-}
-
-void
-grub_term_register_output (grub_term_output_t term)
-{
- term->next = grub_term_list_output;
- grub_term_list_output = term;
- if (! grub_cur_term_output)
- grub_term_set_current_output (term);
-}
-
-void
-grub_term_unregister_input (grub_term_input_t term)
-{
- grub_term_input_t *p, q;
-
- for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
-}
-
-void
-grub_term_unregister_output (grub_term_output_t term)
-{
- grub_term_output_t *p, q;
-
- for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
-}
-
-void
-grub_term_iterate_input (int (*hook) (grub_term_input_t term))
-{
- grub_term_input_t p;
-
- for (p = grub_term_list_input; p; p = p->next)
- if (hook (p))
- break;
-}
-
-void
-grub_term_iterate_output (int (*hook) (grub_term_output_t term))
-{
- grub_term_output_t p;
-
- for (p = grub_term_list_output; p; p = p->next)
- if (hook (p))
- break;
-}
-
-grub_err_t
-grub_term_set_current_input (grub_term_input_t term)
-{
- if (grub_cur_term_input && grub_cur_term_input->fini)
- if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_input = term;
- return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_term_set_current_output (grub_term_output_t term)
-{
- if (grub_cur_term_output && grub_cur_term_output->fini)
- if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_output = term;
- return GRUB_ERR_NONE;
-}
-
-grub_term_input_t
-grub_term_get_current_input (void)
-{
- return grub_cur_term_input;
-}
-
-grub_term_output_t
-grub_term_get_current_output (void)
-{
- return grub_cur_term_output;
-}
-
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code)
diff --git a/term/efi/console.c b/term/efi/console.c
index 0bf2449..0974fdf 100644
--- a/term/efi/console.c
+++ b/term/efi/console.c
@@ -366,13 +366,13 @@ grub_console_init (void)
return;
}
- grub_term_register_input (&grub_console_term_input);
- grub_term_register_output (&grub_console_term_output);
+ grub_handler_register (&grub_term_output_class, &grub_console_term_output);
+ grub_handler_register (&grub_term_input_class, &grub_console_term_input);
}
void
grub_console_fini (void)
{
- grub_term_unregister_input (&grub_console_term_input);
- grub_term_unregister_output (&grub_console_term_output);
+ grub_handler_unregister (&grub_term_input_class, &grub_console_term_input);
+ grub_handler_unregister (&grub_term_output_class, &grub_console_term_output);
}
diff --git a/term/gfxterm.c b/term/gfxterm.c
index abb1b9e..ad2edec 100644
--- a/term/gfxterm.c
+++ b/term/gfxterm.c
@@ -1164,7 +1164,7 @@ static struct grub_term_output grub_video_term =
GRUB_MOD_INIT(term_gfxterm)
{
my_mod = mod;
- grub_term_register_output (&grub_video_term);
+ grub_handler_register (&grub_term_output_class, &grub_video_term);
grub_register_command ("background_image",
grub_gfxterm_background_image_cmd,
@@ -1177,5 +1177,5 @@ GRUB_MOD_INIT(term_gfxterm)
GRUB_MOD_FINI(term_gfxterm)
{
grub_unregister_command ("bgimage");
- grub_term_unregister_output (&grub_video_term);
+ grub_handler_unregister (&grub_term_output_class, &grub_video_term);
}
diff --git a/term/i386/pc/at_keyboard.c b/term/i386/pc/at_keyboard.c
index ff5246d..5b67303 100644
--- a/term/i386/pc/at_keyboard.c
+++ b/term/i386/pc/at_keyboard.c
@@ -226,10 +226,10 @@ static struct grub_term_input grub_at_keyboard_term =
GRUB_MOD_INIT(at_keyboard)
{
- grub_term_register_input (&grub_at_keyboard_term);
+ grub_handler_register (&grub_term_input_class, &grub_at_keyboard_term);
}
GRUB_MOD_FINI(at_keyboard)
{
- grub_term_unregister_input (&grub_at_keyboard_term);
+ grub_handler_unregister (&grub_term_input_class, &grub_at_keyboard_term);
}
diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c
index 6c6be46..5769fd8 100644
--- a/term/i386/pc/console.c
+++ b/term/i386/pc/console.c
@@ -46,8 +46,8 @@ static struct grub_term_output grub_console_term_output =
void
grub_console_init (void)
{
- grub_term_register_output (&grub_console_term_output);
- grub_term_register_input (&grub_console_term_input);
+ grub_handler_register (&grub_term_output_class, &grub_console_term_output);
+ grub_handler_register (&grub_term_input_class, &grub_console_term_input);
}
void
@@ -55,8 +55,8 @@ grub_console_fini (void)
{
/* This is to make sure the console is restored to text mode before
we boot. */
- grub_term_set_current_output (&grub_console_term_output);
+ grub_handler_set_current (&grub_term_output_class, &grub_console_term_output);
- grub_term_unregister_input (&grub_console_term_input);
- grub_term_unregister_output (&grub_console_term_output);
+ grub_handler_unregister (&grub_term_input_class, &grub_console_term_input);
+ grub_handler_unregister (&grub_term_output_class, &grub_console_term_output);
}
diff --git a/term/i386/pc/serial.c b/term/i386/pc/serial.c
index 03a46ba..5368188 100644
--- a/term/i386/pc/serial.c
+++ b/term/i386/pc/serial.c
@@ -577,8 +577,8 @@ grub_cmd_serial (struct grub_arg_list *state,
/* Register terminal if not yet registered. */
if (registered == 0)
{
- grub_term_register_input (&grub_serial_term_input);
- grub_term_register_output (&grub_serial_term_output);
+ grub_handler_register (&grub_term_input_class, &grub_serial_term_input);
+ grub_handler_register (&grub_term_output_class, &grub_serial_term_output);
registered = 1;
}
}
@@ -593,8 +593,8 @@ grub_cmd_serial (struct grub_arg_list *state,
if (serial_hw_init () != GRUB_ERR_NONE)
{
/* If unable to restore settings, unregister terminal. */
- grub_term_unregister_input (&grub_serial_term_input);
- grub_term_unregister_output (&grub_serial_term_output);
+ grub_handler_unregister (&grub_term_input_class, &grub_serial_term_input);
+ grub_handler_unregister (&grub_term_output_class, &grub_serial_term_output);
registered = 0;
}
}
@@ -621,7 +621,7 @@ GRUB_MOD_FINI(serial)
grub_unregister_command ("serial");
if (registered == 1) /* Unregister terminal only if registered. */
{
- grub_term_unregister_input (&grub_serial_term_input);
- grub_term_unregister_output (&grub_serial_term_output);
+ grub_handler_unregister (&grub_term_input_class, &grub_serial_term_input);
+ grub_handler_unregister (&grub_term_output_class, &grub_serial_term_output);
}
}
diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c
index d32c86e..2f22c5d 100644
--- a/term/i386/pc/vga.c
+++ b/term/i386/pc/vga.c
@@ -510,10 +510,10 @@ GRUB_MOD_INIT(vga)
#ifndef GRUB_UTIL
my_mod = mod;
#endif
- grub_term_register_output (&grub_vga_term);
+ grub_handler_register (&grub_term_output_class, &grub_vga_term);
}
GRUB_MOD_FINI(vga)
{
- grub_term_unregister_output (&grub_vga_term);
+ grub_handler_unregister (&grub_term_output_class, &grub_vga_term);
}
diff --git a/term/i386/pc/vga_text.c b/term/i386/pc/vga_text.c
index e067ed6..c292cd5 100644
--- a/term/i386/pc/vga_text.c
+++ b/term/i386/pc/vga_text.c
@@ -168,10 +168,10 @@ static struct grub_term_output grub_vga_text_term =
GRUB_MOD_INIT(vga_text)
{
- grub_term_register_output (&grub_vga_text_term);
+ grub_handler_register (&grub_term_output_class, &grub_vga_text_term);
}
GRUB_MOD_FINI(vga_text)
{
- grub_term_unregister_output (&grub_vga_text_term);
+ grub_handler_unregister (&grub_term_output_class, &grub_vga_text_term);
}
diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c
index 70fda9a..54bc2cc 100644
--- a/term/ieee1275/ofconsole.c
+++ b/term/ieee1275/ofconsole.c
@@ -420,13 +420,13 @@ static struct grub_term_output grub_ofconsole_term_output =
void
grub_console_init (void)
{
- grub_term_register_input (&grub_ofconsole_term_input);
- grub_term_register_output (&grub_ofconsole_term_output);
+ grub_handler_register (&grub_term_output_class, &grub_ofconsole_term_output);
+ grub_handler_register (&grub_term_input_class, &grub_ofconsole_term_input);
}
void
grub_console_fini (void)
{
- grub_term_unregister_input (&grub_ofconsole_term_input);
- grub_term_unregister_output (&grub_ofconsole_term_output);
+ grub_handler_unregister (&grub_term_input_class, &grub_ofconsole_term_input);
+ grub_handler_unregister (&grub_term_output_class, &grub_ofconsole_term_output);
}
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
index 475d12d..18f5725 100644
--- a/util/grub-editenv.c
+++ b/util/grub-editenv.c
@@ -21,6 +21,7 @@
#include <grub/types.h>
#include <grub/util/misc.h>
#include <grub/lib/envblk.h>
+#include <grub/term.h>
#include <stdio.h>
#include <unistd.h>
@@ -28,6 +29,9 @@
#include <stdlib.h>
#include <getopt.h>
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
void
grub_putchar (int c)
{
@@ -40,18 +44,6 @@ grub_refresh (void)
fflush (stdout);
}
-void *
-grub_term_get_current_input (void)
-{
- return 0;
-}
-
-void *
-grub_term_get_current_output (void)
-{
- return 0;
-}
-
int
grub_getkey (void)
{
diff --git a/util/grub-fstest.c b/util/grub-fstest.c
index ca25425..720734a 100644
--- a/util/grub-fstest.c
+++ b/util/grub-fstest.c
@@ -41,6 +41,9 @@
#include <stdlib.h>
#include <getopt.h>
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
void
grub_putchar (int c)
{
@@ -53,18 +56,6 @@ grub_getkey (void)
return -1;
}
-grub_term_input_t
-grub_term_get_current_input (void)
-{
- return 0;
-}
-
-grub_term_output_t
-grub_term_get_current_output (void)
-{
- return 0;
-}
-
void
grub_refresh (void)
{
diff --git a/util/grub-probe.c b/util/grub-probe.c
index 402b758..d2b5128 100644
--- a/util/grub-probe.c
+++ b/util/grub-probe.c
@@ -54,6 +54,9 @@ enum {
int print = PRINT_FS;
static unsigned int argument_is_device = 0;
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
void
grub_putchar (int c)
{
@@ -66,18 +69,6 @@ grub_getkey (void)
return -1;
}
-grub_term_input_t
-grub_term_get_current_input (void)
-{
- return 0;
-}
-
-grub_term_output_t
-grub_term_get_current_output (void)
-{
- return 0;
-}
-
void
grub_refresh (void)
{
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
index ccbb465..3b8f446 100644
--- a/util/i386/pc/grub-setup.c
+++ b/util/i386/pc/grub-setup.c
@@ -62,6 +62,9 @@ struct boot_blocklist
grub_uint16_t segment;
} __attribute__ ((packed));
+struct grub_handler_class grub_term_input_class;
+struct grub_handler_class grub_term_output_class;
+
void
grub_putchar (int c)
{
@@ -74,18 +77,6 @@ grub_getkey (void)
return -1;
}
-grub_term_input_t
-grub_term_get_current_input (void)
-{
- return 0;
-}
-
-grub_term_output_t
-grub_term_get_current_output (void)
-{
- return 0;
-}
-
void
grub_refresh (void)
{
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-12 12:01 [PATCH] Handler support Bean
@ 2009-02-14 14:46 ` Bean
2009-02-14 15:11 ` Felix Zielcke
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-02-14 14:46 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 3610 bytes --]
Hi,
This new version of handler patch contain the following changes:
1, Register/unregister handler class automatically, so there is no
need to usel grub_handler_class_register/grub_handler_class_unregister
anymore.
2, Keep the original api function of term.c, so that there is no need
to change modules depend on it. Inside term.c, it rely on the handler
function to do the job.
3. Use a new method of compile time checking. Now, instead of using
void*, it uses normal type, for example:
void grub_handler_register (grub_handler_class_t class, grub_handler_t handler);
Codes that calls grub_handler_register should looks like this:
grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
macro GRUB_AS_HANDLER check the various fields required by
grub_handler_t is at the same location as term, and then cast it to
type grub_handler_t. Just as before, if the testing succeed, it
wouldn't generate extra runtime code.
If there is no objection, I'd commit this patch in a few days.
2009-02-14 Bean <bean123ch@gmail.com>
* commands/handler.c: New file.
* include/grub/list.h: Likewise.
* include/grub/handler.h: Likewise.
* kern/list.c: Likewise.
* kern/handler.c: Likewise.
* kern/term.h: Include header file <grub/handler.h>.
(grub_term_input): Move next field to the beginning.
(grub_term_output): Likewise.
(grub_term_iterate_input): Removed.
(grub_term_iterate_output): Likewise.
* kern/term.c (grub_term_list_input): Removed.
(grub_term_list_output): Likewise.
(grub_term_input_class): New variable.
(grub_term_output_class): Likewise.
(grub_cur_term_input): Change varaible as macro.
(grub_cur_term_output): Likewise.
(grub_term_register_input): Call underlying handler function to do the
job.
(grub_term_register_output): Likewise.
(grub_term_unregister_input): Likewise.
(grub_term_unregister_output): Likewise.
(grub_term_set_current_input): Likewise.
(grub_term_set_current_output): Likewise.
(grub_term_iterate_input): Removed.
(grub_term_iterate_output): Likewise.
(grub_term_get_current_input): Use grub_term_input_class to retrive
the current handler.
(grub_term_get_current_output): Likewise.
* conf/common.rmk (pkglib_MODULES): Replace terminal with handler.
(terminal_mod_SOURCES): Likewise.
(terminal_mod_CFLAGS): Likewise.
(terminal_mod_LDFLAGS): Likewise.
* conf/i386-pc.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_img_SOURCES): Add list.c and handler.c.
(kernel_img_HEADERS): Add list.h and handler.h.
* conf/i386-efi.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_mod_SOURCES): Add list.c and handler.c.
(kernel_mod_HEADERS): Add list.h and handler.h.
* conf/i386-coreboot.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_elf_SOURCES): Add list.c and handler.c.
(kernel_elf_HEADERS): Add list.h and handler.h.
* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_elf_SOURCES): Add list.c and handler.c.
(kernel_elf_HEADERS): Add list.h and handler.h.
* conf/x86_64-efi.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_mod_SOURCES): Add list.c and handler.c.
(kernel_mod_HEADERS): Add list.h and handler.h.
* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_elf_SOURCES): Add list.c and handler.c.
(kernel_elf_HEADERS): Add list.h and handler.h.
* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Replace terminal.c with
handler.c.
(kernel_elf_SOURCES): Add list.c and handler.c.
(kernel_elf_HEADERS): Add list.h and handler.h.
--
Bean
[-- Attachment #2: handler_2.diff --]
[-- Type: text/x-patch, Size: 28216 bytes --]
diff --git a/commands/handler.c b/commands/handler.c
new file mode 100644
index 0000000..04f89f8
--- /dev/null
+++ b/commands/handler.c
@@ -0,0 +1,105 @@
+/* handler.c - test module for dynamic loading */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/handler.h>
+
+static grub_err_t
+grub_cmd_handler (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ char *find_name;
+ void *find_result;
+ void *curr_item = 0;
+
+ auto int list_item (grub_handler_class_t item);
+ int list_item (grub_handler_class_t item)
+ {
+ if (item == curr_item)
+ grub_putchar ('*');
+
+ grub_printf ("%s\n", item->name);
+
+ return 0;
+ }
+
+ auto int find_item (grub_handler_class_t item);
+ int find_item (grub_handler_class_t item)
+ {
+ if (! grub_strcmp (item->name, find_name))
+ {
+ find_result = item;
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (argc == 0)
+ {
+ grub_handler_class_iterate (list_item);
+ }
+ else
+ {
+ grub_handler_class_t class;
+
+ find_name = args[0];
+ find_result = 0;
+ grub_handler_class_iterate (find_item);
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+ class = find_result;
+
+ if (argc == 1)
+ {
+ curr_item = class->cur_handler;
+ grub_handler_iterate (find_result, (grub_list_hook_t) list_item);
+ }
+ else
+ {
+ find_name = args[1];
+ find_result = 0;
+ grub_handler_iterate (class, (grub_list_hook_t) find_item);
+
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+ grub_handler_set_current (class, find_result);
+ }
+ }
+
+ return 0;
+}
+
+GRUB_MOD_INIT(handler)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("handler", grub_cmd_handler, GRUB_COMMAND_FLAG_BOTH,
+ "handler [class [handler]]",
+ "List or select a handler", 0);
+}
+
+GRUB_MOD_FINI(handler)
+{
+ grub_unregister_command ("hello");
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index dfd481a..9a62ac3 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -330,7 +330,7 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS)
scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Commands.
-pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \
+pkglib_MODULES += hello.mod boot.mod handler.mod ls.mod \
cmp.mod cat.mod help.mod search.mod \
loopback.mod fs_uuid.mod configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
@@ -346,10 +346,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index b97483b..4938665 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -17,7 +17,7 @@ kernel_elf_SOURCES = kern/i386/coreboot/startup.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
@@ -30,7 +30,7 @@ kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h
+ machine/memory.h machine/loader.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic
@@ -57,7 +57,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 3814abb..7ae9c5e 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -34,7 +34,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -88,14 +88,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h
+ efi/efi.h efi/time.h efi/disk.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 903113e..16a3fba 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -20,7 +20,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/env.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
@@ -29,7 +29,8 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h
+ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+ list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
@@ -55,7 +56,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 3ef351e..9e83bda 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -42,7 +42,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
@@ -56,7 +56,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
- machine/kernel.h machine/pxe.h
+ machine/kernel.h machine/pxe.h list.h handler.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -114,7 +114,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 51e7c07..bedd4e0 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -40,7 +40,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/search.c commands/terminal.c commands/test.c \
+ commands/search.c commands/handler.c commands/test.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
disk/loopback.c \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index 640ceda..18c108e 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -44,7 +44,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
# For grub-emu
#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
# commands/configfile.c commands/default.c commands/help.c \
-# commands/search.c commands/terminal.c commands/ls.c \
+# commands/search.c commands/handler.c commands/ls.c \
# commands/timeout.c commands/test.c \
# commands/halt.c commands/reboot.c \
# disk/loopback.c \
@@ -76,8 +76,8 @@ kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \
kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \
kern/generic/millisleep.c kern/generic/get_time_ms.c \
- kern/sparc64/cache.S kern/parser.c
-kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h
+ kern/sparc64/cache.S kern/parser.c kern/list.c kern/handler.c
+kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc
@@ -86,7 +86,7 @@ kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-me
#_linux.mod linux.mod
pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ boot.mod cmp.mod cat.mod handler.mod fshelp.mod amiga.mod apple.mod \
pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
configfile.mod search.mod gzio.mod xfs.mod \
affs.mod sfs.mod acorn.mod
@@ -187,10 +187,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 5b108d2..07bf1a6 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -36,7 +36,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -90,14 +90,14 @@ kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
term/efi/console.c disk/efi/efidisk.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h machine/loader.h
+ efi/efi.h efi/time.h efi/disk.h machine/loader.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/include/grub/handler.h b/include/grub/handler.h
new file mode 100644
index 0000000..826fd2b
--- /dev/null
+++ b/include/grub/handler.h
@@ -0,0 +1,63 @@
+/* handler.h - header for grub handler */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+ struct grub_handler *next;
+ const char *name;
+ grub_err_t (*init) (void);
+ grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+ struct grub_handler_class *next;
+ const char *name;
+ grub_list_t handler_list;
+ struct grub_handler *cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+void EXPORT_FUNC(grub_handler_class_iterate) (int (*hook)
+ (grub_handler_class_t item));
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+ grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+ grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_iterate) (grub_handler_class_t class,
+ grub_list_hook_t hook);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+ grub_handler_t handler);
+
+#define GRUB_AS_HANDLER(ptr) \
+ ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
+ (grub_handler_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/list.h b/include/grub/list.h
new file mode 100644
index 0000000..59b352a
--- /dev/null
+++ b/include/grub/list.h
@@ -0,0 +1,50 @@
+/* list.h - header for grub list */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_list
+{
+ struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
+void EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
+
+/* This function doesn't exist, so if assertion is false for some reason, the
+ linker would fail. */
+extern void* grub_assert_fail (void);
+
+#define GRUB_FIELD_MATCH(ptr, type, field) \
+ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
+
+#define GRUB_AS_LIST(ptr) \
+ (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
+ (grub_list_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
index 13835bb..8ac8bc5 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -38,6 +38,7 @@
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
+#include <grub/handler.h>
/* These are used to represent the various color states we use. */
typedef enum
@@ -139,6 +140,9 @@ grub_term_color_state;
struct grub_term_input
{
+ /* The next terminal. */
+ struct grub_term_input *next;
+
/* The terminal name. */
const char *name;
@@ -153,14 +157,14 @@ struct grub_term_input
/* Get a character. */
int (*getkey) (void);
-
- /* The next terminal. */
- struct grub_term_input *next;
};
typedef struct grub_term_input *grub_term_input_t;
struct grub_term_output
{
+ /* The next terminal. */
+ struct grub_term_output *next;
+
/* The terminal name. */
const char *name;
@@ -208,9 +212,6 @@ struct grub_term_output
/* The feature flags defined above. */
grub_uint32_t flags;
-
- /* The next terminal. */
- struct grub_term_output *next;
};
typedef struct grub_term_output *grub_term_output_t;
@@ -218,8 +219,6 @@ void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
-void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
-void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
diff --git a/kern/handler.c b/kern/handler.c
new file mode 100644
index 0000000..b22d9af
--- /dev/null
+++ b/kern/handler.c
@@ -0,0 +1,72 @@
+/* handler.c - grub handler function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+static grub_list_t grub_handler_class_list;
+
+void
+grub_handler_class_iterate (int (*hook) (grub_handler_class_t item))
+{
+ grub_list_iterate (grub_handler_class_list, (grub_list_hook_t) hook);
+}
+
+void
+grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
+{
+ int first_handler = (class->handler_list == 0);
+
+ grub_list_push (&class->handler_list, GRUB_AS_LIST (handler));
+
+ if (first_handler)
+ {
+ grub_list_push (&grub_handler_class_list, GRUB_AS_LIST (class));
+ grub_handler_set_current (class, handler);
+ }
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
+{
+ grub_list_remove (&class->handler_list, GRUB_AS_LIST (handler));
+
+ if (class->handler_list == 0)
+ grub_list_remove (&grub_handler_class_list, GRUB_AS_LIST (class));
+}
+
+void
+grub_handler_iterate (grub_handler_class_t class, grub_list_hook_t hook)
+{
+ grub_list_iterate (class->handler_list, hook);
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
+{
+ if (class->cur_handler && class->cur_handler->fini)
+ if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (handler->init)
+ if ((handler->init) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ class->cur_handler = handler;
+ return GRUB_ERR_NONE;
+}
diff --git a/kern/list.c b/kern/list.c
new file mode 100644
index 0000000..e553443
--- /dev/null
+++ b/kern/list.c
@@ -0,0 +1,62 @@
+/* list.c - grub list function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+
+void
+grub_list_push (grub_list_t *head, grub_list_t item)
+{
+ item->next = *head;
+ *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+ grub_list_t item;
+
+ item = *head;
+ if (item)
+ *head = item->next;
+
+ return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, grub_list_t item)
+{
+ grub_list_t *p, q;
+
+ for (p = head, q = *p; q; p = &(q->next), q = q->next)
+ if (q == item)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+void
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+ grub_list_t p;
+
+ for (p = head; p; p = p->next)
+ if (hook (p))
+ break;
+}
diff --git a/kern/term.c b/kern/term.c
index 8d5a23b..3de1db4 100644
--- a/kern/term.c
+++ b/kern/term.c
@@ -22,14 +22,6 @@
#include <grub/misc.h>
#include <grub/env.h>
-/* The list of terminals. */
-static grub_term_input_t grub_term_list_input;
-static grub_term_output_t grub_term_list_output;
-
-/* The current terminal. */
-static grub_term_input_t grub_cur_term_input;
-static grub_term_output_t grub_cur_term_output;
-
/* The amount of lines counted by the pager. */
static int grub_more_lines;
@@ -39,98 +31,58 @@ static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
+static struct grub_handler_class grub_term_input_class =
+ {
+ .name = "input"
+ };
+
+static struct grub_handler_class grub_term_output_class =
+ {
+ .name = "output"
+ };
+
+#define grub_cur_term_input \
+ ((grub_term_input_t) grub_term_input_class.cur_handler)
+
+#define grub_cur_term_output \
+ ((grub_term_output_t) grub_term_output_class.cur_handler)
+
void
grub_term_register_input (grub_term_input_t term)
{
- term->next = grub_term_list_input;
- grub_term_list_input = term;
- if (! grub_cur_term_input)
- grub_term_set_current_input (term);
+ grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_register_output (grub_term_output_t term)
{
- term->next = grub_term_list_output;
- grub_term_list_output = term;
- if (! grub_cur_term_output)
- grub_term_set_current_output (term);
+ grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_input (grub_term_input_t term)
{
- grub_term_input_t *p, q;
-
- for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
+ grub_handler_unregister (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_output (grub_term_output_t term)
{
- grub_term_output_t *p, q;
-
- for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
-}
-
-void
-grub_term_iterate_input (int (*hook) (grub_term_input_t term))
-{
- grub_term_input_t p;
-
- for (p = grub_term_list_input; p; p = p->next)
- if (hook (p))
- break;
-}
-
-void
-grub_term_iterate_output (int (*hook) (grub_term_output_t term))
-{
- grub_term_output_t p;
-
- for (p = grub_term_list_output; p; p = p->next)
- if (hook (p))
- break;
+ grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_input (grub_term_input_t term)
{
- if (grub_cur_term_input && grub_cur_term_input->fini)
- if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_input = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_input_class,
+ GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_output (grub_term_output_t term)
{
- if (grub_cur_term_output && grub_cur_term_output->fini)
- if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_output = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_output_class,
+ GRUB_AS_HANDLER (term));
}
grub_term_input_t
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-14 14:46 ` Bean
@ 2009-02-14 15:11 ` Felix Zielcke
2009-02-14 15:28 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Felix Zielcke @ 2009-02-14 15:11 UTC (permalink / raw)
To: The development of GRUB 2
A. Am Samstag, den 14.02.2009, 22:46 +0800 schrieb Bean:
> If there is no objection, I'd commit this patch in a few days.
Hello Bean,
if you want to drop termin_input and terminal_output command then please
don't forget to update util/grub.d/00_header.in
+GRUB_MOD_INIT(handler)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("handler", grub_cmd_handler,
GRUB_COMMAND_FLAG_BOTH,
+ "handler [class [handler]]",
+ "List or select a handler", 0);
+}
+
+GRUB_MOD_FINI(handler)
+{
+ grub_unregister_command ("hello");
+}
This should probable be grub_unregister_command ("handler").
--
Felix Zielcke
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-14 15:11 ` Felix Zielcke
@ 2009-02-14 15:28 ` Bean
2009-02-15 7:32 ` Vesa Jääskeläinen
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-02-14 15:28 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 866 bytes --]
On Sat, Feb 14, 2009 at 11:11 PM, Felix Zielcke <fzielcke@z-51.de> wrote:
> A. Am Samstag, den 14.02.2009, 22:46 +0800 schrieb Bean:
>
>> If there is no objection, I'd commit this patch in a few days.
>
> Hello Bean,
>
> if you want to drop termin_input and terminal_output command then please
> don't forget to update util/grub.d/00_header.in
>
> +GRUB_MOD_INIT(handler)
> +{
> + (void)mod; /* To stop warning. */
> + grub_register_command ("handler", grub_cmd_handler,
> GRUB_COMMAND_FLAG_BOTH,
> + "handler [class [handler]]",
> + "List or select a handler", 0);
> +}
> +
> +GRUB_MOD_FINI(handler)
> +{
> + grub_unregister_command ("hello");
> +}
>
> This should probable be grub_unregister_command ("handler").
Hi,
Thanks for pointing out, this new patch should fix the problem.
--
Bean
[-- Attachment #2: handler_2.diff --]
[-- Type: text/x-patch, Size: 30406 bytes --]
diff --git a/commands/handler.c b/commands/handler.c
new file mode 100644
index 0000000..9f4e632
--- /dev/null
+++ b/commands/handler.c
@@ -0,0 +1,105 @@
+/* handler.c - test module for dynamic loading */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/handler.h>
+
+static grub_err_t
+grub_cmd_handler (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ char *find_name;
+ void *find_result;
+ void *curr_item = 0;
+
+ auto int list_item (grub_handler_class_t item);
+ int list_item (grub_handler_class_t item)
+ {
+ if (item == curr_item)
+ grub_putchar ('*');
+
+ grub_printf ("%s\n", item->name);
+
+ return 0;
+ }
+
+ auto int find_item (grub_handler_class_t item);
+ int find_item (grub_handler_class_t item)
+ {
+ if (! grub_strcmp (item->name, find_name))
+ {
+ find_result = item;
+ return 1;
+ }
+
+ return 0;
+ }
+
+ if (argc == 0)
+ {
+ grub_handler_class_iterate (list_item);
+ }
+ else
+ {
+ grub_handler_class_t class;
+
+ find_name = args[0];
+ find_result = 0;
+ grub_handler_class_iterate (find_item);
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+ class = find_result;
+
+ if (argc == 1)
+ {
+ curr_item = class->cur_handler;
+ grub_handler_iterate (find_result, (grub_list_hook_t) list_item);
+ }
+ else
+ {
+ find_name = args[1];
+ find_result = 0;
+ grub_handler_iterate (class, (grub_list_hook_t) find_item);
+
+ if (! find_result)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+ grub_handler_set_current (class, find_result);
+ }
+ }
+
+ return 0;
+}
+
+GRUB_MOD_INIT(handler)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("handler", grub_cmd_handler, GRUB_COMMAND_FLAG_BOTH,
+ "handler [class [handler]]",
+ "List or select a handler", 0);
+}
+
+GRUB_MOD_FINI(handler)
+{
+ grub_unregister_command ("handler");
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index dfd481a..9a62ac3 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -330,7 +330,7 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS)
scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Commands.
-pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \
+pkglib_MODULES += hello.mod boot.mod handler.mod ls.mod \
cmp.mod cat.mod help.mod search.mod \
loopback.mod fs_uuid.mod configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
@@ -346,10 +346,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index b97483b..4938665 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -17,7 +17,7 @@ kernel_elf_SOURCES = kern/i386/coreboot/startup.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
@@ -30,7 +30,7 @@ kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h
+ machine/memory.h machine/loader.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic
@@ -57,7 +57,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 3814abb..7ae9c5e 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -34,7 +34,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -88,14 +88,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h
+ efi/efi.h efi/time.h efi/disk.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 903113e..16a3fba 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -20,7 +20,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/env.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
@@ -29,7 +29,8 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h
+ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+ list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
@@ -55,7 +56,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 3ef351e..9e83bda 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -42,7 +42,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
@@ -56,7 +56,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
- machine/kernel.h machine/pxe.h
+ machine/kernel.h machine/pxe.h list.h handler.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -114,7 +114,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 51e7c07..bedd4e0 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -40,7 +40,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/search.c commands/terminal.c commands/test.c \
+ commands/search.c commands/handler.c commands/test.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
disk/loopback.c \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index 640ceda..18c108e 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -44,7 +44,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
# For grub-emu
#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
# commands/configfile.c commands/default.c commands/help.c \
-# commands/search.c commands/terminal.c commands/ls.c \
+# commands/search.c commands/handler.c commands/ls.c \
# commands/timeout.c commands/test.c \
# commands/halt.c commands/reboot.c \
# disk/loopback.c \
@@ -76,8 +76,8 @@ kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \
kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \
kern/generic/millisleep.c kern/generic/get_time_ms.c \
- kern/sparc64/cache.S kern/parser.c
-kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h
+ kern/sparc64/cache.S kern/parser.c kern/list.c kern/handler.c
+kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc
@@ -86,7 +86,7 @@ kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-me
#_linux.mod linux.mod
pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ boot.mod cmp.mod cat.mod handler.mod fshelp.mod amiga.mod apple.mod \
pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
configfile.mod search.mod gzio.mod xfs.mod \
affs.mod sfs.mod acorn.mod
@@ -187,10 +187,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 5b108d2..07bf1a6 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -36,7 +36,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -90,14 +90,14 @@ kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
term/efi/console.c disk/efi/efidisk.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h machine/loader.h
+ efi/efi.h efi/time.h efi/disk.h machine/loader.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/include/grub/handler.h b/include/grub/handler.h
new file mode 100644
index 0000000..826fd2b
--- /dev/null
+++ b/include/grub/handler.h
@@ -0,0 +1,63 @@
+/* handler.h - header for grub handler */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+ struct grub_handler *next;
+ const char *name;
+ grub_err_t (*init) (void);
+ grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+ struct grub_handler_class *next;
+ const char *name;
+ grub_list_t handler_list;
+ struct grub_handler *cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+void EXPORT_FUNC(grub_handler_class_iterate) (int (*hook)
+ (grub_handler_class_t item));
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+ grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+ grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_iterate) (grub_handler_class_t class,
+ grub_list_hook_t hook);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+ grub_handler_t handler);
+
+#define GRUB_AS_HANDLER(ptr) \
+ ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
+ (grub_handler_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/list.h b/include/grub/list.h
new file mode 100644
index 0000000..59b352a
--- /dev/null
+++ b/include/grub/list.h
@@ -0,0 +1,50 @@
+/* list.h - header for grub list */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_list
+{
+ struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
+void EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
+
+/* This function doesn't exist, so if assertion is false for some reason, the
+ linker would fail. */
+extern void* grub_assert_fail (void);
+
+#define GRUB_FIELD_MATCH(ptr, type, field) \
+ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
+
+#define GRUB_AS_LIST(ptr) \
+ (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
+ (grub_list_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
index 13835bb..8ac8bc5 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -38,6 +38,7 @@
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
+#include <grub/handler.h>
/* These are used to represent the various color states we use. */
typedef enum
@@ -139,6 +140,9 @@ grub_term_color_state;
struct grub_term_input
{
+ /* The next terminal. */
+ struct grub_term_input *next;
+
/* The terminal name. */
const char *name;
@@ -153,14 +157,14 @@ struct grub_term_input
/* Get a character. */
int (*getkey) (void);
-
- /* The next terminal. */
- struct grub_term_input *next;
};
typedef struct grub_term_input *grub_term_input_t;
struct grub_term_output
{
+ /* The next terminal. */
+ struct grub_term_output *next;
+
/* The terminal name. */
const char *name;
@@ -208,9 +212,6 @@ struct grub_term_output
/* The feature flags defined above. */
grub_uint32_t flags;
-
- /* The next terminal. */
- struct grub_term_output *next;
};
typedef struct grub_term_output *grub_term_output_t;
@@ -218,8 +219,6 @@ void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
-void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
-void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
diff --git a/kern/handler.c b/kern/handler.c
new file mode 100644
index 0000000..b22d9af
--- /dev/null
+++ b/kern/handler.c
@@ -0,0 +1,72 @@
+/* handler.c - grub handler function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+static grub_list_t grub_handler_class_list;
+
+void
+grub_handler_class_iterate (int (*hook) (grub_handler_class_t item))
+{
+ grub_list_iterate (grub_handler_class_list, (grub_list_hook_t) hook);
+}
+
+void
+grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
+{
+ int first_handler = (class->handler_list == 0);
+
+ grub_list_push (&class->handler_list, GRUB_AS_LIST (handler));
+
+ if (first_handler)
+ {
+ grub_list_push (&grub_handler_class_list, GRUB_AS_LIST (class));
+ grub_handler_set_current (class, handler);
+ }
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
+{
+ grub_list_remove (&class->handler_list, GRUB_AS_LIST (handler));
+
+ if (class->handler_list == 0)
+ grub_list_remove (&grub_handler_class_list, GRUB_AS_LIST (class));
+}
+
+void
+grub_handler_iterate (grub_handler_class_t class, grub_list_hook_t hook)
+{
+ grub_list_iterate (class->handler_list, hook);
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
+{
+ if (class->cur_handler && class->cur_handler->fini)
+ if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (handler->init)
+ if ((handler->init) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ class->cur_handler = handler;
+ return GRUB_ERR_NONE;
+}
diff --git a/kern/list.c b/kern/list.c
new file mode 100644
index 0000000..e553443
--- /dev/null
+++ b/kern/list.c
@@ -0,0 +1,62 @@
+/* list.c - grub list function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+
+void
+grub_list_push (grub_list_t *head, grub_list_t item)
+{
+ item->next = *head;
+ *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+ grub_list_t item;
+
+ item = *head;
+ if (item)
+ *head = item->next;
+
+ return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, grub_list_t item)
+{
+ grub_list_t *p, q;
+
+ for (p = head, q = *p; q; p = &(q->next), q = q->next)
+ if (q == item)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+void
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+ grub_list_t p;
+
+ for (p = head; p; p = p->next)
+ if (hook (p))
+ break;
+}
diff --git a/kern/term.c b/kern/term.c
index 8d5a23b..3de1db4 100644
--- a/kern/term.c
+++ b/kern/term.c
@@ -22,14 +22,6 @@
#include <grub/misc.h>
#include <grub/env.h>
-/* The list of terminals. */
-static grub_term_input_t grub_term_list_input;
-static grub_term_output_t grub_term_list_output;
-
-/* The current terminal. */
-static grub_term_input_t grub_cur_term_input;
-static grub_term_output_t grub_cur_term_output;
-
/* The amount of lines counted by the pager. */
static int grub_more_lines;
@@ -39,98 +31,58 @@ static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
+static struct grub_handler_class grub_term_input_class =
+ {
+ .name = "input"
+ };
+
+static struct grub_handler_class grub_term_output_class =
+ {
+ .name = "output"
+ };
+
+#define grub_cur_term_input \
+ ((grub_term_input_t) grub_term_input_class.cur_handler)
+
+#define grub_cur_term_output \
+ ((grub_term_output_t) grub_term_output_class.cur_handler)
+
void
grub_term_register_input (grub_term_input_t term)
{
- term->next = grub_term_list_input;
- grub_term_list_input = term;
- if (! grub_cur_term_input)
- grub_term_set_current_input (term);
+ grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_register_output (grub_term_output_t term)
{
- term->next = grub_term_list_output;
- grub_term_list_output = term;
- if (! grub_cur_term_output)
- grub_term_set_current_output (term);
+ grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_input (grub_term_input_t term)
{
- grub_term_input_t *p, q;
-
- for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
+ grub_handler_unregister (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_output (grub_term_output_t term)
{
- grub_term_output_t *p, q;
-
- for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
-}
-
-void
-grub_term_iterate_input (int (*hook) (grub_term_input_t term))
-{
- grub_term_input_t p;
-
- for (p = grub_term_list_input; p; p = p->next)
- if (hook (p))
- break;
-}
-
-void
-grub_term_iterate_output (int (*hook) (grub_term_output_t term))
-{
- grub_term_output_t p;
-
- for (p = grub_term_list_output; p; p = p->next)
- if (hook (p))
- break;
+ grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_input (grub_term_input_t term)
{
- if (grub_cur_term_input && grub_cur_term_input->fini)
- if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_input = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_input_class,
+ GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_output (grub_term_output_t term)
{
- if (grub_cur_term_output && grub_cur_term_output->fini)
- if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_output = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_output_class,
+ GRUB_AS_HANDLER (term));
}
grub_term_input_t
diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in
index d8fa416..236ba51 100644
--- a/util/grub.d/00_header.in
+++ b/util/grub.d/00_header.in
@@ -60,10 +60,14 @@ case x${GRUB_TERMINAL_INPUT} in
;;
x*)
cat << EOF
-if terminal_input ${GRUB_TERMINAL_INPUT} ; then true ; else
- # For backward compatibility with versions of terminal.mod that don't
- # understand terminal_input
- terminal ${GRUB_TERMINAL_INPUT}
+if handler input ${GRUB_TERMINAL_INPUT} ; then true ; else
+ # For backward compatibility with versions that uses terminal.mod instead
+ # of handler.mod
+ if terminal_input ${GRUB_TERMINAL_INPUT} ; then true ; else
+ # For backward compatibility with versions of terminal.mod that don't
+ # understand terminal_input
+ terminal ${GRUB_TERMINAL_INPUT}
+ fi
fi
EOF
;;
@@ -91,10 +95,14 @@ if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then
set gfxmode=${GRUB_GFXMODE}
insmod gfxterm
insmod ${video_backend}
- if terminal_output gfxterm ; then true ; else
- # For backward compatibility with versions of terminal.mod that don't
- # understand terminal_output
- terminal gfxterm
+ if handler output gfxterm ; then true ; else
+ # For backward compatibility with versions that uses terminal.mod instead
+ # of handler.mod
+ if terminal_output gfxterm ; then true ; else
+ # For backward compatibility with versions of terminal.mod that don't
+ # understand terminal_output
+ terminal gfxterm
+ fi
fi
fi
EOF
@@ -104,10 +112,14 @@ EOF
;;
x*)
cat << EOF
-if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
- # For backward compatibility with versions of terminal.mod that don't
- # understand terminal_output
- terminal ${GRUB_TERMINAL_OUTPUT}
+if handler output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
+ # For backward compatibility with versions that uses terminal.mod instead
+ # of handler.mod
+ if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
+ # For backward compatibility with versions of terminal.mod that don't
+ # understand terminal_output
+ terminal ${GRUB_TERMINAL_OUTPUT}
+ fi
fi
EOF
;;
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-14 15:28 ` Bean
@ 2009-02-15 7:32 ` Vesa Jääskeläinen
2009-02-15 8:58 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Vesa Jääskeläinen @ 2009-02-15 7:32 UTC (permalink / raw)
To: The development of GRUB 2
Bean wrote:
> On Sat, Feb 14, 2009 at 11:11 PM, Felix Zielcke <fzielcke@z-51.de> wrote:
>> A. Am Samstag, den 14.02.2009, 22:46 +0800 schrieb Bean:
>>
>>> If there is no objection, I'd commit this patch in a few days.
>> Hello Bean,
>>
>> if you want to drop termin_input and terminal_output command then please
>> don't forget to update util/grub.d/00_header.in
>>
>> +GRUB_MOD_INIT(handler)
>> +{
>> + (void)mod; /* To stop warning. */
>> + grub_register_command ("handler", grub_cmd_handler,
>> GRUB_COMMAND_FLAG_BOTH,
>> + "handler [class [handler]]",
>> + "List or select a handler", 0);
>> +}
>> +
>> +GRUB_MOD_FINI(handler)
>> +{
>> + grub_unregister_command ("hello");
>> +}
>>
>> This should probable be grub_unregister_command ("handler").
>
> Hi,
>
> Thanks for pointing out, this new patch should fix the problem.
Hi,
Ok. I a way this functionality could be used. I just don't like how it
is visible to the user.
> +if handler output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
> + # For backward compatibility with versions that uses terminal.mod instead
> + # of handler.mod
> + if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
> + # For backward compatibility with versions of terminal.mod that don't
> + # understand terminal_output
> + terminal ${GRUB_TERMINAL_OUTPUT}
> + fi
If we look at this snippet, for me keyword handler doesn't say a thing.
where it could be terminal for terminal handlers.
So I would propose to change it in following ways:
1. Do not register handler command unless you need to enumerate those or
allow more flexibility to configuration
2. Register command functions/alias to more understandable grub commands.
So following could be:
terminal output <whatever>
or keep it what it is (I would prefer above line)
terminal_output
Good idea with this handler stuff would be that if someone writes following:
terminal console
It would lookup if this console provides input and output service and
would use them out of the box.
Now if some-one writes something like:
terminal --input usbkbd --input console --output console
or:
terminal --input usbkbd
terminal --input console
terminal --output console
or
terminal_input usbkbd
terminal_input console
terminal_output console
or
terminal_input usbkbd console
terminal_output console
or
terminal_input console
terminal_output console
termianl_input --add usbkbd
User would now get two input sources like ps2 keyboard and usb keyboard
and then output to console.
Anyway... my point being... handler does not say anything to me in a
sens what does it logically give to user. It hinders the understanding
of the user for grub 2 usage...
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-15 7:32 ` Vesa Jääskeläinen
@ 2009-02-15 8:58 ` Bean
2009-02-15 15:14 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-02-15 8:58 UTC (permalink / raw)
To: The development of GRUB 2
On Sun, Feb 15, 2009 at 3:32 PM, Vesa Jääskeläinen <chaac@nic.fi> wrote:
> Bean wrote:
>> On Sat, Feb 14, 2009 at 11:11 PM, Felix Zielcke <fzielcke@z-51.de> wrote:
>>> A. Am Samstag, den 14.02.2009, 22:46 +0800 schrieb Bean:
>>>
>>>> If there is no objection, I'd commit this patch in a few days.
>>> Hello Bean,
>>>
>>> if you want to drop termin_input and terminal_output command then please
>>> don't forget to update util/grub.d/00_header.in
>>>
>>> +GRUB_MOD_INIT(handler)
>>> +{
>>> + (void)mod; /* To stop warning. */
>>> + grub_register_command ("handler", grub_cmd_handler,
>>> GRUB_COMMAND_FLAG_BOTH,
>>> + "handler [class [handler]]",
>>> + "List or select a handler", 0);
>>> +}
>>> +
>>> +GRUB_MOD_FINI(handler)
>>> +{
>>> + grub_unregister_command ("hello");
>>> +}
>>>
>>> This should probable be grub_unregister_command ("handler").
>>
>> Hi,
>>
>> Thanks for pointing out, this new patch should fix the problem.
>
> Hi,
>
> Ok. I a way this functionality could be used. I just don't like how it
> is visible to the user.
>
>> +if handler output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
>> + # For backward compatibility with versions that uses terminal.mod instead
>> + # of handler.mod
>> + if terminal_output ${GRUB_TERMINAL_OUTPUT} ; then true ; else
>> + # For backward compatibility with versions of terminal.mod that don't
>> + # understand terminal_output
>> + terminal ${GRUB_TERMINAL_OUTPUT}
>> + fi
>
> If we look at this snippet, for me keyword handler doesn't say a thing.
> where it could be terminal for terminal handlers.
>
> So I would propose to change it in following ways:
>
> 1. Do not register handler command unless you need to enumerate those or
> allow more flexibility to configuration
> 2. Register command functions/alias to more understandable grub commands.
>
> So following could be:
>
> terminal output <whatever>
>
> or keep it what it is (I would prefer above line)
>
> terminal_output
>
> Good idea with this handler stuff would be that if someone writes following:
>
> terminal console
>
> It would lookup if this console provides input and output service and
> would use them out of the box.
>
> Now if some-one writes something like:
>
> terminal --input usbkbd --input console --output console
>
> or:
>
> terminal --input usbkbd
> terminal --input console
> terminal --output console
>
> or
>
> terminal_input usbkbd
> terminal_input console
> terminal_output console
>
> or
>
> terminal_input usbkbd console
> terminal_output console
>
> or
>
> terminal_input console
> terminal_output console
> termianl_input --add usbkbd
>
> User would now get two input sources like ps2 keyboard and usb keyboard
> and then output to console.
>
> Anyway... my point being... handler does not say anything to me in a
> sens what does it logically give to user. It hinders the understanding
> of the user for grub 2 usage...
Hi,
Good point. However, currently this can't be implemented in a generic
way. The main obstacle is that the command function doesn't allow
custom parameter, so one function can only serve one command, it's not
possible to use a single function, such as grub_cmd_handler, to handle
multiple command with slightly different behavior.
One quick fix is to use more descriptive class name, such as
terminal_input and terminal_output, so the command looks like this:
handler terminal_input console
In a long term, it would be better to improve the command interface,
which is my next goal. I'm planning to merge the normal and rescue
command into one single command set, so that any command can be used
in both environment. This also eliminates commands like linux, chain,
etc, whose function is simply to call the underlying command _linux
and _chain.
--
Bean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-15 8:58 ` Bean
@ 2009-02-15 15:14 ` Bean
2009-02-22 19:40 ` Bean
2009-02-27 19:54 ` Robert Millan
0 siblings, 2 replies; 13+ messages in thread
From: Bean @ 2009-02-15 15:14 UTC (permalink / raw)
To: The development of GRUB 2
[-- Attachment #1: Type: text/plain, Size: 928 bytes --]
Hi,
The new version contains the following changes:
1, The handler module register commands terminal_input and
terminal_output. This is for backward compatible of grub.cfg.
Currently, the commands are registered manually, but this process
could be automated with a new command interface design.
2, Add a new class, grub_named_list, which represents a named list:
struct grub_named_list
{
struct grub_named_list *next;
const char *name;
};
it also introduce a new function, grub_named_list_find, which can be
used to lookup a object by name.
The relationship between different class:
list - named list + - handler + - terminal input
| |
| + - terminal output
+ - handler class
You can use macros like GRUB_AS_LIST, GRUB_AS_NAMED_LIST and
GRUB_AS_HANDLER to cast pointer of a certain class to its ancestors.
--
Bean
[-- Attachment #2: handler_3.diff --]
[-- Type: text/x-patch, Size: 29988 bytes --]
diff --git a/commands/handler.c b/commands/handler.c
new file mode 100644
index 0000000..d6c9b70
--- /dev/null
+++ b/commands/handler.c
@@ -0,0 +1,132 @@
+/* handler.c - test module for dynamic loading */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/normal.h>
+#include <grub/dl.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/term.h>
+#include <grub/handler.h>
+
+static grub_err_t
+grub_cmd_handler_generic (int argc, char **args, char *class_name)
+{
+ char *find_name;
+ void *find_result;
+ void *curr_item = 0;
+ grub_handler_class_t head;
+
+ auto int list_item (grub_named_list_t item);
+ int list_item (grub_named_list_t item)
+ {
+ if (item == curr_item)
+ grub_putchar ('*');
+
+ grub_printf ("%s\n", item->name);
+
+ return 0;
+ }
+
+ head = grub_handler_class_get_head ();
+ if ((argc == 0) && (class_name == 0))
+ {
+ grub_list_iterate (head, (grub_list_hook_t) list_item);
+ }
+ else
+ {
+ grub_handler_class_t class;
+
+ if (class_name == 0)
+ {
+ class_name = args[0];
+ argc--;
+ args++;
+ }
+
+ class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
+ if (! class)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
+
+ if (argc == 0)
+ {
+ curr_item = class->cur_handler;
+ grub_list_iterate (class->handler_list,
+ (grub_list_hook_t) list_item);
+ }
+ else
+ {
+ grub_handler_t handler;
+
+ handler =
+ grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
+ args[0]);
+
+ if (! handler)
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
+
+ grub_handler_set_current (class, handler);
+ }
+ }
+
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_handler (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ return grub_cmd_handler_generic (argc, args, 0);
+}
+
+static grub_err_t
+grub_cmd_terminal_input (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ return grub_cmd_handler_generic (argc, args, "terminal_input");
+}
+
+static grub_err_t
+grub_cmd_terminal_output (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ return grub_cmd_handler_generic (argc, args, "terminal_output");
+}
+
+GRUB_MOD_INIT(handler)
+{
+ (void)mod; /* To stop warning. */
+ grub_register_command ("handler", grub_cmd_handler, GRUB_COMMAND_FLAG_BOTH,
+ "handler [class [handler]]",
+ "List or select a handler", 0);
+ grub_register_command ("terminal_input", grub_cmd_terminal_input,
+ GRUB_COMMAND_FLAG_BOTH,
+ "terminal_input [handler]",
+ "List or select a handler", 0);
+ grub_register_command ("terminal_output", grub_cmd_terminal_output,
+ GRUB_COMMAND_FLAG_BOTH,
+ "terminal_output [handler]",
+ "List or select a handler", 0);
+}
+
+GRUB_MOD_FINI(handler)
+{
+ grub_unregister_command ("terminal_input");
+ grub_unregister_command ("terminal_output");
+ grub_unregister_command ("handler");
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index dfd481a..9a62ac3 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -330,7 +330,7 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS)
scsi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Commands.
-pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod \
+pkglib_MODULES += hello.mod boot.mod handler.mod ls.mod \
cmp.mod cat.mod help.mod search.mod \
loopback.mod fs_uuid.mod configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
@@ -346,10 +346,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index b97483b..4938665 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -17,7 +17,7 @@ kernel_elf_SOURCES = kern/i386/coreboot/startup.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
@@ -30,7 +30,7 @@ kernel_elf_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/boot.h machine/console.h machine/init.h \
- machine/memory.h machine/loader.h
+ machine/memory.h machine/loader.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic
@@ -57,7 +57,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 3814abb..7ae9c5e 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -34,7 +34,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -88,14 +88,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
term/efi/console.c disk/efi/efidisk.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/rtc_get_time_ms.c \
kern/generic/millisleep.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h
+ efi/efi.h efi/time.h efi/disk.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 903113e..16a3fba 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -20,7 +20,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/i386/dl.c kern/parser.c kern/partition.c \
kern/env.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/generic/millisleep.c \
kern/ieee1275/ieee1275.c \
term/ieee1275/ofconsole.c \
@@ -29,7 +29,8 @@ kernel_elf_SOURCES = kern/i386/ieee1275/startup.S kern/i386/ieee1275/init.c \
kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h
+ ieee1275/ieee1275.h machine/kernel.h machine/loader.h machine/memory.h \
+ list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x10000,-Bstatic
@@ -55,7 +56,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index 3ef351e..9e83bda 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -42,7 +42,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,7C00
kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
kern/parser.c kern/partition.c \
kern/i386/tsc.c kern/i386/pit.c \
@@ -56,7 +56,7 @@ kernel_img_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
machine/biosdisk.h machine/boot.h machine/console.h machine/init.h \
machine/memory.h machine/loader.h machine/vga.h machine/vbe.h \
- machine/kernel.h machine/pxe.h
+ machine/kernel.h machine/pxe.h list.h handler.h
kernel_img_CFLAGS = $(COMMON_CFLAGS)
kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
kernel_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS) -Wl,-Ttext,$(GRUB_MEMORY_MACHINE_LINK_ADDR) $(COMMON_CFLAGS)
@@ -114,7 +114,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/echo.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/i386/cpuid.c \
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 51e7c07..bedd4e0 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -40,7 +40,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/search.c commands/terminal.c commands/test.c \
+ commands/search.c commands/handler.c commands/test.c \
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
disk/loopback.c \
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index 640ceda..18c108e 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -44,7 +44,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
# For grub-emu
#grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
# commands/configfile.c commands/default.c commands/help.c \
-# commands/search.c commands/terminal.c commands/ls.c \
+# commands/search.c commands/handler.c commands/ls.c \
# commands/timeout.c commands/test.c \
# commands/halt.c commands/reboot.c \
# disk/loopback.c \
@@ -76,8 +76,8 @@ kernel_elf_SOURCES = kern/sparc64/ieee1275/init.c kern/ieee1275/ieee1275.c \
kern/sparc64/ieee1275/openfw.c disk/ieee1275/ofdisk.c \
kern/partition.c kern/env.c kern/sparc64/dl.c symlist.c \
kern/generic/millisleep.c kern/generic/get_time_ms.c \
- kern/sparc64/cache.S kern/parser.c
-kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h
+ kern/sparc64/cache.S kern/parser.c kern/list.c kern/handler.c
+kernel_elf_HEADERS = grub/sparc64/ieee1275/ieee1275.h list.h handler.h
kernel_elf_CFLAGS = $(COMMON_CFLAGS)
kernel_elf_ASFLAGS = $(COMMON_ASFLAGS)
kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-melf64_sparc
@@ -86,7 +86,7 @@ kernel_elf_LDFLAGS = -mno-app-regs -nostdlib -Wl,-N,-Ttext,0x200000,-Bstatic,-me
#_linux.mod linux.mod
pkglib_MODULES = fat.mod ufs.mod ext2.mod minix.mod \
hfs.mod jfs.mod normal.mod hello.mod font.mod ls.mod \
- boot.mod cmp.mod cat.mod terminal.mod fshelp.mod amiga.mod apple.mod \
+ boot.mod cmp.mod cat.mod handler.mod fshelp.mod amiga.mod apple.mod \
pc.mod suspend.mod loopback.mod help.mod reboot.mod halt.mod sun.mod \
configfile.mod search.mod gzio.mod xfs.mod \
affs.mod sfs.mod acorn.mod
@@ -187,10 +187,10 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
-# For terminal.mod.
-terminal_mod_SOURCES = commands/terminal.c
-terminal_mod_CFLAGS = $(COMMON_CFLAGS)
-terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For handler.mod.
+handler_mod_SOURCES = commands/handler.c
+handler_mod_CFLAGS = $(COMMON_CFLAGS)
+handler_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ls.mod.
ls_mod_SOURCES = commands/ls.c
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index 5b108d2..07bf1a6 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -36,7 +36,7 @@ grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/misc.c
util/grub-emu.c_DEPENDENCIES = grub_emu_init.h
grub_emu_SOURCES = commands/boot.c commands/cat.c commands/cmp.c \
commands/configfile.c commands/help.c \
- commands/terminal.c commands/ls.c commands/test.c \
+ commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
@@ -90,14 +90,14 @@ kernel_mod_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
kern/x86_64/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
- kern/time.c \
+ kern/time.c kern/list.c kern/handler.c \
kern/i386/tsc.c kern/i386/pit.c \
kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c \
term/efi/console.c disk/efi/efidisk.c
kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
- efi/efi.h efi/time.h efi/disk.h machine/loader.h
+ efi/efi.h efi/time.h efi/disk.h machine/loader.h list.h handler.h
kernel_mod_CFLAGS = $(COMMON_CFLAGS)
kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/include/grub/handler.h b/include/grub/handler.h
new file mode 100644
index 0000000..3808116
--- /dev/null
+++ b/include/grub/handler.h
@@ -0,0 +1,60 @@
+/* handler.h - header for grub handler */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_HANDLER_HEADER
+#define GRUB_HANDLER_HEADER 1
+
+#include <grub/list.h>
+#include <grub/err.h>
+
+struct grub_handler
+{
+ struct grub_handler *next;
+ const char *name;
+ grub_err_t (*init) (void);
+ grub_err_t (*fini) (void);
+};
+typedef struct grub_handler *grub_handler_t;
+
+struct grub_handler_class
+{
+ struct grub_handler_class *next;
+ const char *name;
+ grub_handler_t handler_list;
+ grub_handler_t cur_handler;
+};
+typedef struct grub_handler_class *grub_handler_class_t;
+
+grub_handler_class_t EXPORT_FUNC(grub_handler_class_get_head) (void);
+
+void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class,
+ grub_handler_t handler);
+void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class,
+ grub_handler_t handler);
+grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class,
+ grub_handler_t handler);
+
+#define GRUB_AS_HANDLER(ptr) \
+ ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \
+ GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \
+ (grub_handler_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_HANDLER_HEADER */
diff --git a/include/grub/list.h b/include/grub/list.h
new file mode 100644
index 0000000..b2af3b8
--- /dev/null
+++ b/include/grub/list.h
@@ -0,0 +1,69 @@
+/* list.h - header for grub list */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LIST_HEADER
+#define GRUB_LIST_HEADER 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+struct grub_list
+{
+ struct grub_list *next;
+};
+typedef struct grub_list *grub_list_t;
+
+typedef int (*grub_list_hook_t) (grub_list_t item);
+
+void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item);
+void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head);
+void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item);
+void EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook);
+
+/* This function doesn't exist, so if assertion is false for some reason, the
+ linker would fail. */
+extern void* grub_assert_fail (void);
+
+#define GRUB_FIELD_MATCH(ptr, type, field) \
+ ((char *) &(ptr)->field == (char *) &((type) (ptr))->field)
+
+#define GRUB_AS_LIST(ptr) \
+ (GRUB_FIELD_MATCH (ptr, grub_list_t, next) ? \
+ (grub_list_t) ptr : grub_assert_fail ())
+
+#define GRUB_AS_LIST_P(pptr) \
+ (GRUB_FIELD_MATCH (*pptr, grub_list_t, next) ? \
+ (grub_list_t *) (void *) pptr : grub_assert_fail ())
+
+struct grub_named_list
+{
+ struct grub_named_list *next;
+ const char *name;
+};
+typedef struct grub_named_list *grub_named_list_t;
+
+void * EXPORT_FUNC(grub_named_list_find) (grub_named_list_t head,
+ const char *name);
+
+#define GRUB_AS_NAMED_LIST(ptr) \
+ ((GRUB_FIELD_MATCH (ptr, grub_named_list_t, next) && \
+ GRUB_FIELD_MATCH (ptr, grub_named_list_t, name))? \
+ (grub_named_list_t) ptr : grub_assert_fail ())
+
+#endif /* ! GRUB_LIST_HEADER */
diff --git a/include/grub/term.h b/include/grub/term.h
index 13835bb..8ac8bc5 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -38,6 +38,7 @@
#include <grub/err.h>
#include <grub/symbol.h>
#include <grub/types.h>
+#include <grub/handler.h>
/* These are used to represent the various color states we use. */
typedef enum
@@ -139,6 +140,9 @@ grub_term_color_state;
struct grub_term_input
{
+ /* The next terminal. */
+ struct grub_term_input *next;
+
/* The terminal name. */
const char *name;
@@ -153,14 +157,14 @@ struct grub_term_input
/* Get a character. */
int (*getkey) (void);
-
- /* The next terminal. */
- struct grub_term_input *next;
};
typedef struct grub_term_input *grub_term_input_t;
struct grub_term_output
{
+ /* The next terminal. */
+ struct grub_term_output *next;
+
/* The terminal name. */
const char *name;
@@ -208,9 +212,6 @@ struct grub_term_output
/* The feature flags defined above. */
grub_uint32_t flags;
-
- /* The next terminal. */
- struct grub_term_output *next;
};
typedef struct grub_term_output *grub_term_output_t;
@@ -218,8 +219,6 @@ void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
-void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
-void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
diff --git a/kern/handler.c b/kern/handler.c
new file mode 100644
index 0000000..b271702
--- /dev/null
+++ b/kern/handler.c
@@ -0,0 +1,70 @@
+/* handler.c - grub handler function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/handler.h>
+
+static grub_handler_class_t grub_handler_class_list;
+
+grub_handler_class_t
+grub_handler_class_get_head (void)
+{
+ return grub_handler_class_list;
+}
+
+void
+grub_handler_register (grub_handler_class_t class, grub_handler_t handler)
+{
+ int first_handler = (class->handler_list == 0);
+
+ grub_list_push (GRUB_AS_LIST_P (&class->handler_list),
+ GRUB_AS_LIST (handler));
+
+ if (first_handler)
+ {
+ grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list),
+ GRUB_AS_LIST (class));
+ grub_handler_set_current (class, handler);
+ }
+}
+
+void
+grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler)
+{
+ grub_list_remove (GRUB_AS_LIST_P (&class->handler_list),
+ GRUB_AS_LIST (handler));
+
+ if (class->handler_list == 0)
+ grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list),
+ GRUB_AS_LIST (class));
+}
+
+grub_err_t
+grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler)
+{
+ if (class->cur_handler && class->cur_handler->fini)
+ if ((class->cur_handler->fini) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (handler->init)
+ if ((handler->init) () != GRUB_ERR_NONE)
+ return grub_errno;
+
+ class->cur_handler = handler;
+ return GRUB_ERR_NONE;
+}
diff --git a/kern/list.c b/kern/list.c
new file mode 100644
index 0000000..b22218e
--- /dev/null
+++ b/kern/list.c
@@ -0,0 +1,84 @@
+/* list.c - grub list function*/
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/list.h>
+#include <grub/misc.h>
+
+void
+grub_list_push (grub_list_t *head, grub_list_t item)
+{
+ item->next = *head;
+ *head = item;
+}
+
+void *
+grub_list_pop (grub_list_t *head)
+{
+ grub_list_t item;
+
+ item = *head;
+ if (item)
+ *head = item->next;
+
+ return item;
+}
+
+void
+grub_list_remove (grub_list_t *head, grub_list_t item)
+{
+ grub_list_t *p, q;
+
+ for (p = head, q = *p; q; p = &(q->next), q = q->next)
+ if (q == item)
+ {
+ *p = q->next;
+ break;
+ }
+}
+
+void
+grub_list_iterate (grub_list_t head, grub_list_hook_t hook)
+{
+ grub_list_t p;
+
+ for (p = head; p; p = p->next)
+ if (hook (p))
+ break;
+}
+
+void *
+grub_named_list_find (grub_named_list_t head, const char *name)
+{
+ grub_named_list_t result = 0;
+
+ auto int list_find (grub_named_list_t item);
+ int list_find (grub_named_list_t item)
+ {
+ if (! grub_strcmp (item->name, name))
+ {
+ result = item;
+ return 1;
+ }
+
+ return 0;
+ }
+
+ grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find);
+ return result;
+}
diff --git a/kern/term.c b/kern/term.c
index 8d5a23b..b23a00e 100644
--- a/kern/term.c
+++ b/kern/term.c
@@ -22,14 +22,6 @@
#include <grub/misc.h>
#include <grub/env.h>
-/* The list of terminals. */
-static grub_term_input_t grub_term_list_input;
-static grub_term_output_t grub_term_list_output;
-
-/* The current terminal. */
-static grub_term_input_t grub_cur_term_input;
-static grub_term_output_t grub_cur_term_output;
-
/* The amount of lines counted by the pager. */
static int grub_more_lines;
@@ -39,98 +31,58 @@ static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
+static struct grub_handler_class grub_term_input_class =
+ {
+ .name = "terminal_input"
+ };
+
+static struct grub_handler_class grub_term_output_class =
+ {
+ .name = "terminal_output"
+ };
+
+#define grub_cur_term_input \
+ ((grub_term_input_t) grub_term_input_class.cur_handler)
+
+#define grub_cur_term_output \
+ ((grub_term_output_t) grub_term_output_class.cur_handler)
+
void
grub_term_register_input (grub_term_input_t term)
{
- term->next = grub_term_list_input;
- grub_term_list_input = term;
- if (! grub_cur_term_input)
- grub_term_set_current_input (term);
+ grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_register_output (grub_term_output_t term)
{
- term->next = grub_term_list_output;
- grub_term_list_output = term;
- if (! grub_cur_term_output)
- grub_term_set_current_output (term);
+ grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_input (grub_term_input_t term)
{
- grub_term_input_t *p, q;
-
- for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
+ grub_handler_unregister (&grub_term_input_class, GRUB_AS_HANDLER (term));
}
void
grub_term_unregister_output (grub_term_output_t term)
{
- grub_term_output_t *p, q;
-
- for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
- if (q == term)
- {
- *p = q->next;
- break;
- }
-}
-
-void
-grub_term_iterate_input (int (*hook) (grub_term_input_t term))
-{
- grub_term_input_t p;
-
- for (p = grub_term_list_input; p; p = p->next)
- if (hook (p))
- break;
-}
-
-void
-grub_term_iterate_output (int (*hook) (grub_term_output_t term))
-{
- grub_term_output_t p;
-
- for (p = grub_term_list_output; p; p = p->next)
- if (hook (p))
- break;
+ grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_input (grub_term_input_t term)
{
- if (grub_cur_term_input && grub_cur_term_input->fini)
- if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_input = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_input_class,
+ GRUB_AS_HANDLER (term));
}
grub_err_t
grub_term_set_current_output (grub_term_output_t term)
{
- if (grub_cur_term_output && grub_cur_term_output->fini)
- if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
- return grub_errno;
-
- if (term->init)
- if ((term->init) () != GRUB_ERR_NONE)
- return grub_errno;
-
- grub_cur_term_output = term;
- return GRUB_ERR_NONE;
+ return grub_handler_set_current (&grub_term_output_class,
+ GRUB_AS_HANDLER (term));
}
grub_term_input_t
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-15 15:14 ` Bean
@ 2009-02-22 19:40 ` Bean
2009-02-27 19:54 ` Robert Millan
1 sibling, 0 replies; 13+ messages in thread
From: Bean @ 2009-02-22 19:40 UTC (permalink / raw)
To: The development of GRUB 2
Hi,
Any comment about this ?
On Sun, Feb 15, 2009 at 11:14 PM, Bean <bean123ch@gmail.com> wrote:
> Hi,
>
> The new version contains the following changes:
>
> 1, The handler module register commands terminal_input and
> terminal_output. This is for backward compatible of grub.cfg.
> Currently, the commands are registered manually, but this process
> could be automated with a new command interface design.
>
> 2, Add a new class, grub_named_list, which represents a named list:
>
> struct grub_named_list
> {
> struct grub_named_list *next;
> const char *name;
> };
>
> it also introduce a new function, grub_named_list_find, which can be
> used to lookup a object by name.
>
> The relationship between different class:
>
> list - named list + - handler + - terminal input
> | |
> | + - terminal output
> + - handler class
>
> You can use macros like GRUB_AS_LIST, GRUB_AS_NAMED_LIST and
> GRUB_AS_HANDLER to cast pointer of a certain class to its ancestors.
>
> --
> Bean
>
--
Bean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-15 15:14 ` Bean
2009-02-22 19:40 ` Bean
@ 2009-02-27 19:54 ` Robert Millan
2009-02-28 5:41 ` Bean
1 sibling, 1 reply; 13+ messages in thread
From: Robert Millan @ 2009-02-27 19:54 UTC (permalink / raw)
To: The development of GRUB 2
On Sun, Feb 15, 2009 at 11:14:18PM +0800, Bean wrote:
> diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
> index 640ceda..18c108e 100644
> --- a/conf/sparc64-ieee1275.rmk
> +++ b/conf/sparc64-ieee1275.rmk
Don't bother updating sparc64-ieee1275.rmk, it's completely broken by now.
> void
> grub_term_register_input (grub_term_input_t term)
> {
> - term->next = grub_term_list_input;
> - grub_term_list_input = term;
> - if (! grub_cur_term_input)
> - grub_term_set_current_input (term);
> + grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
> }
Is grub_handler_register() always used this way? Perhaps it should be
inline.
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-27 19:54 ` Robert Millan
@ 2009-02-28 5:41 ` Bean
2009-03-01 17:52 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-02-28 5:41 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Feb 28, 2009 at 3:54 AM, Robert Millan <rmh@aybabtu.com> wrote:
> On Sun, Feb 15, 2009 at 11:14:18PM +0800, Bean wrote:
>> diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
>> index 640ceda..18c108e 100644
>> --- a/conf/sparc64-ieee1275.rmk
>> +++ b/conf/sparc64-ieee1275.rmk
>
> Don't bother updating sparc64-ieee1275.rmk, it's completely broken by now.
>
>> void
>> grub_term_register_input (grub_term_input_t term)
>> {
>> - term->next = grub_term_list_input;
>> - grub_term_list_input = term;
>> - if (! grub_cur_term_input)
>> - grub_term_set_current_input (term);
>> + grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
>> }
>
> Is grub_handler_register() always used this way? Perhaps it should be
> inline.
Hi,
Good point. In fact, I change all occurrence of
grub_term_register_input to grub_handler_register previously, but
considered the amount of code to change, I decide to provide the
wrapper function grub_term_register_input. Using inline function would
utilize the new handler infrastructure while retaining code
compatibility.
--
Bean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-02-28 5:41 ` Bean
@ 2009-03-01 17:52 ` Bean
2009-03-04 20:55 ` Robert Millan
0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-03-01 17:52 UTC (permalink / raw)
To: The development of GRUB 2
On Sat, Feb 28, 2009 at 1:41 PM, Bean <bean123ch@gmail.com> wrote:
> On Sat, Feb 28, 2009 at 3:54 AM, Robert Millan <rmh@aybabtu.com> wrote:
>> On Sun, Feb 15, 2009 at 11:14:18PM +0800, Bean wrote:
>>> diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
>>> index 640ceda..18c108e 100644
>>> --- a/conf/sparc64-ieee1275.rmk
>>> +++ b/conf/sparc64-ieee1275.rmk
>>
>> Don't bother updating sparc64-ieee1275.rmk, it's completely broken by now.
>>
>>> void
>>> grub_term_register_input (grub_term_input_t term)
>>> {
>>> - term->next = grub_term_list_input;
>>> - grub_term_list_input = term;
>>> - if (! grub_cur_term_input)
>>> - grub_term_set_current_input (term);
>>> + grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
>>> }
>>
>> Is grub_handler_register() always used this way? Perhaps it should be
>> inline.
>
> Hi,
>
> Good point. In fact, I change all occurrence of
> grub_term_register_input to grub_handler_register previously, but
> considered the amount of code to change, I decide to provide the
> wrapper function grub_term_register_input. Using inline function would
> utilize the new handler infrastructure while retaining code
> compatibility.
Hi,
Fixed and committed.
--
Bean
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-03-01 17:52 ` Bean
@ 2009-03-04 20:55 ` Robert Millan
2009-03-05 5:34 ` Bean
0 siblings, 1 reply; 13+ messages in thread
From: Robert Millan @ 2009-03-04 20:55 UTC (permalink / raw)
To: The development of GRUB 2
On Mon, Mar 02, 2009 at 01:52:21AM +0800, Bean wrote:
>
> Hi,
>
> Fixed and committed.
So what happened to the terminal module? Is there a new way to change
terminals? :-)
--
Robert Millan
The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
how) you may access your data; but nobody's threatening your freedom: we
still allow you to remove your data and not access it at all."
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Handler support
2009-03-04 20:55 ` Robert Millan
@ 2009-03-05 5:34 ` Bean
0 siblings, 0 replies; 13+ messages in thread
From: Bean @ 2009-03-05 5:34 UTC (permalink / raw)
To: The development of GRUB 2
On Thu, Mar 5, 2009 at 4:55 AM, Robert Millan <rmh@aybabtu.com> wrote:
> On Mon, Mar 02, 2009 at 01:52:21AM +0800, Bean wrote:
>>
>> Hi,
>>
>> Fixed and committed.
>
> So what happened to the terminal module? Is there a new way to change
> terminals? :-)
Hi,
Handler is the new generic handler manipulation command, for example:
handler terminal_output gfxterm
is the same as:
terminal_output gfxterm
The handler module also export command terminal_input and
terminal_output for backward compatibility, so you can also use the
old command.
--
Bean
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-03-05 5:34 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-12 12:01 [PATCH] Handler support Bean
2009-02-14 14:46 ` Bean
2009-02-14 15:11 ` Felix Zielcke
2009-02-14 15:28 ` Bean
2009-02-15 7:32 ` Vesa Jääskeläinen
2009-02-15 8:58 ` Bean
2009-02-15 15:14 ` Bean
2009-02-22 19:40 ` Bean
2009-02-27 19:54 ` Robert Millan
2009-02-28 5:41 ` Bean
2009-03-01 17:52 ` Bean
2009-03-04 20:55 ` Robert Millan
2009-03-05 5:34 ` Bean
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.