GNU bash Dynamically Loadable Built-in

The Towers of Hanoi as a loadable module (extension) for GNU bash. Loading this module causes a new built-in called hanoi to be introduced in the shell.

According to the bash home page:

Bash is the shell, or command language interpreter, that will appear in the GNU operating system. Bash is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification.

/* * The Towers Of Hanoi * GNU bash dynamically loadable built-in command * Copyright (C) 1998 Amit Singh. All Rights Reserved. * * * Tested under GNU bash 2.02.1 */ /* This module should be dynamically loaded with enable -f * which would create a new builtin named hanoi. You'll need * the source code for GNU bash to recompile this module. * * Compilation directions: * Assuming that you have bash source unpacked and residing in * /tmp/bash-2.02.1, then copy this file as * /tmp/bash-2.02.1/examples/loadables/hanoi.c * Then cd to /tmp/bash-2.02.1/examples/loadables and issue the * following commands: * * gcc -fpic -I. -I.. -I../.. -I../../lib -I../../builtins\ * -I/tmp/bash-2.02.1 -I/tmp/bash-2.02.1/lib\ * -I/tmp/bash-2.02.1/builtins -c -o hanoi.o hanoi.c * * ld -x -Bshareable -o hanoi hanoi.o * * Then, from within bash, enable -f ./hanoi hanoi, where ./hanoi * is the binary obtained from running ld above. Hereafter, `hanoi' * is a shell builtin. */ #include <stdio.h> #include "builtins.h" #include "shell.h" #ifndef errno extern int errno; #endif extern char *strerror(); extern char **make_builtin_argv(); void dohanoi(int N, int from, int to, int using); hanoi_main(int argc, char **argv) { long int N; if (argc != 2) { fprintf(stderr, "usage: %s N\n", argv[0]); return(1); } N = strtol(argv[1], (char **)NULL, 10); /* a bit of error checking, LONG_XXX should be there in limits.h */ if (N == LONG_MIN || N == LONG_MAX || N <= 0) { fprintf(stderr, "illegal value for number of disks\n"); return(1); } dohanoi(N, 3, 1, 2); return(0); } hanoi_builtin(WORD_LIST *list) { char **v; int c, r; v = make_builtin_argv(list, &c); r = hanoi_main(c, v); free(v); return r; } void dohanoi(int N, int from, int to, int using) { if (N > 0) { dohanoi(N-1, from, using, to); printf ("move %d --> %d\n", from, to); dohanoi(N-1, using, to, from); } } char *hanoi_doc[] = { "The Towers Of Hanoi implemented as a shell builtin. The command", "expects a single (and mandatory) integer argument.", (char *)0 }; struct builtin hanoi_struct = { "hanoi", hanoi_builtin, BUILTIN_ENABLED, hanoi_doc, "hanoi N", 0 };