[syslinux] Patch sensible callback framework
Sebastian Herbszt
herbszt at gmx.de
Fri Apr 30 12:12:41 PDT 2010
Ayvaz, James wrote:
[snip]
> diff -uprN syslinux-3.86-vanilla/com32/modules/linux.c syslinux-3.86/com32/modules/linux.c
> --- syslinux-3.86-vanilla/com32/modules/linux.c 2010-03-31 11:24:25.000000000 -0500
> +++ syslinux-3.86/com32/modules/linux.c 2010-04-29 10:17:19.000000000 -0500
> @@ -43,11 +43,13 @@
> #include <stdio.h>
> #include <string.h>
> #include <console.h>
> +#include <syslinux/callback.h>
> #include <syslinux/loadfile.h>
> #include <syslinux/linux.h>
> #include <syslinux/pxe.h>
>
> const char *progname = "linux.c32";
> +callback_record *CB_LOADFILE = NULL;
>
> /* Find the last instance of a particular command line argument
> (which should include the final =; do not use for boolean arguments) */
> @@ -108,6 +110,53 @@ static char *make_cmdline(char **argv)
> return cmdline;
> }
>
> +void linux_percent_progress_cb(va_list ap) {
> + char *file = va_arg(ap, char*);
> + size_t cur = va_arg(ap, size_t);
> + size_t total = va_arg(ap, size_t);
> + int percent = 0;
> +
> + if (total > 0) {
> + percent = (int)(((float)cur / (float)total) * 100.0);
> + }
> + clear_line();
> + move_cursor_to_column(0);
> + printf("Loading: %s %d%%", file, percent);
Strip the colon here - it's not used below.
> +}
> +
> +void linux_dot_progress_cb(va_list ap) {
> + char *file = va_arg(ap, char*);
> + size_t cur = va_arg(ap, size_t);
> + size_t total = va_arg(ap, size_t);
> + int percent = 0;
> + int i = 0;
> + if (total > 0) {
> + percent = (int)(((float)cur / (float)total) * 100.0);
> + }
> +
> + clear_line();
> + move_cursor_to_column(0);
> +
> + printf("Loading %s", file);
> + while(i < percent) {
> + printf(".");
> + i += 5;
> + }
> +}
> +
> +void linux_done_progress_cb(va_list ap) {
> + char *file = va_arg(ap, char*);
> + size_t cur = va_arg(ap, size_t);
> + size_t total = va_arg(ap, size_t);
> + int percent = 0;
> + if (total > 0) {
> + percent = (int)(((float)cur / (float)total) * 100.0);
> + }
> +
> + if (percent >= 100)
> + printf(" OK\n");
> +}
I think "total" can never be 0, because syslinux handles 0 byte files as non existent.
If that is correct "total" can be > 0 or -1 for unknown size. In the latter case "OK" is never printed.
That printf() can be put after the calls to loadfile() and initramfs_load_archive() if those succeed and
opt_quiet is false. This callback can then be removed.
> +
> int main(int argc, char *argv[])
> {
> const char *kernel_name;
> @@ -118,11 +167,14 @@ int main(int argc, char *argv[])
> size_t kernel_len;
> bool opt_dhcpinfo = false;
> bool opt_quiet = false;
> + bool opt_percent = false;
> void *dhcpdata;
> size_t dhcplen;
> char **argp, *arg, *p;
> + callback_record *progress_cb, *complete_cb;
> +
>
> - openconsole(&dev_null_r, &dev_stdcon_w);
> + console_ansi_raw();
>
> (void)argc;
> argp = argv + 1;
> @@ -130,7 +182,11 @@ int main(int argc, char *argv[])
> while ((arg = *argp) && arg[0] == '-') {
> if (!strcmp("-dhcpinfo", arg)) {
> opt_dhcpinfo = true;
> + }
> + else if (!strcmp("-percent", arg)) {
> + opt_percent = true;
> } else {
> +
Strip this introduced new line.
> fprintf(stderr, "%s: unknown option: %s\n", progname, arg);
> return 1;
> }
> @@ -157,16 +213,21 @@ int main(int argc, char *argv[])
> if (find_boolean(argp, "quiet"))
> opt_quiet = true;
>
> - if (!opt_quiet)
> - printf("Loading %s... ", kernel_name);
> + if (!opt_quiet) {
A printf("Loading %s ", kernel_name); is needed here in case loadfile() fails and opt_quiet is false.
Else we just get a line with "failed!".
> + if (opt_percent) {
> + progress_cb = register_callback(&CB_LOADFILE, &linux_percent_progress_cb);
> + }
> + else {
> + progress_cb = register_callback(&CB_LOADFILE, &linux_dot_progress_cb);
> + }
> + complete_cb = register_callback(&CB_LOADFILE, &linux_done_progress_cb);
> + }
> if (loadfile(kernel_name, &kernel_data, &kernel_len)) {
> if (opt_quiet)
> printf("Loading %s ", kernel_name);
> printf("failed!\n");
> goto bail;
> }
> - if (!opt_quiet)
> - printf("ok\n");
>
> cmdline = make_cmdline(argp);
> if (!cmdline)
> @@ -183,22 +244,23 @@ int main(int argc, char *argv[])
> if (p)
> *p = '\0';
>
> - if (!opt_quiet)
> - printf("Loading %s... ", arg);
> if (initramfs_load_archive(initramfs, arg)) {
> if (opt_quiet)
> printf("Loading %s ", kernel_name);
> printf("failed!\n");
> goto bail;
> }
printf("Loading %s ", arg); should be kept here before initramfs_load_archive() if opt_quiet is false.
> - if (!opt_quiet)
> - printf("ok\n");
>
> if (p)
> *p++ = ',';
> } while ((arg = p));
> }
>
> + if (!opt_quiet) {
> + unregister_callback(&CB_LOADFILE, progress_cb);
> + unregister_callback(&CB_LOADFILE, complete_cb);
> + }
> +
> /* Append the DHCP info */
> if (opt_dhcpinfo &&
> !pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
>
Sebastian
More information about the Syslinux
mailing list