Evolution of shells in Linux (developerWorks)
Posted Dec 8, 2011 0:37 UTC (Thu) by
lkundrak (subscriber, #43452)
Parent article:
Evolution of shells in Linux (developerWorks)
One of interesting things about early UNIX shells (Thomson's, up to sixth edition) was that exit and goto were not built-ins, but simple programs that seeked a file descriptor open for the running script appropriately, either to the beginning proceeding to given label or to the end.
Also, Bourne's seventh edition shell is almost universally considered to be one of the most horrible C code ever written. From its mac.h source file:
#define LOCAL static
#define PROC extern
#define TYPE typedef
#define STRUCT TYPE struct
#define UNION TYPE union
#define REG register
#define IF if(
#define THEN ){
#define ELSE } else {
#define ELIF } else if (
#define FI ;}
#define BEGIN {
#define END }
#define SWITCH switch(
#define IN ){
#define ENDSW }
#define FOR for(
#define WHILE while(
#define DO ){
#define OD ;}
#define REP do{
#define PER }while(
#define DONE );
#define LOOP for(;;){
#define POOL }
#define SKIP ;
#define DIV /
#define REM %
#define NEQ ^
#define ANDF &&
#define ORF ||
#define TRUE (-1)
#define FALSE 0
Thankfully, many of the macros, such as DIV are not actually used anywhere. This is what the code actually looks like:
VOID fault(sig)
REG INT sig;
{
REG INT flag;
signal(sig,fault);
IF sig==MEMF
THEN IF setbrk(brkincr) == -1
THEN error(nospace);
FI
Also, the code quoted is another rather creative technique used by the shell: it's the signal handler for memory faults, that simply enlarges heap with setbrk() when an out-of-bounds memory is signalled by kernel. Needless to say, there are not many calls to malloc() in the source...
(
Log in to post comments)