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.
* http://hanoi.kernelthread.com
*
* 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
};