MacOS Xã§Thompson Shellãåãã
Thompson Shellã¨ãã£ã¦ãè³é¦´æã¿ãªã人ãå¤ããã¨æãããBourne Shellã«ãªãåã®ç±ç·æ£ããUNIXã·ã§ã«ã§ãããThompsonã¨ã¯ããã¡ããKen Thompsonã®ãã¨ãWikipediaã®ãBourne Shellã®ãã¼ã¸ã«ããã¨ã
Bourne Shell(ãã¼ã³ã·ã§ã«)ã¯ãUnix Version 7ã®ã·ã§ã«ã§ãããããã¾ã§ã®Thompson Shellãç½®ãæãã(ããããã³ãã³ãå㯠sh ã§ãã)ã
ãã®å¾ãï¼å¾ã«Sun Microsystemsãèããã¨ã«ãªãï¼Bill Joyã¯Thompson ShellããC Shellãæ´¾çããããããã¦ãBourne ShellãC Shellã®ææãåæ ãããå½¢ã§ãUNIX V10ã«ç»å ´ããã®ãrcã§ããã
rc ã¯ãã«ç 究æã® Tom Duff ã Version 10 Unixï¼Plan 9 ã®å¾ç¶ï¼ã§ Bourne sh ã®ä»£æ¿ã¨ãã¦éçºãããã®ã§ãããPlan 9 ã Inferno ã§ã®ããã©ã¼ã«ãã·ã§ã«ã§ããããUNIXç³»OSã«ã移æ¤ããã¦ããï¼Plan 9 from User Spaceï¼ã
温æ ç¥æ°ã¨ãããã¨ã§ï¼ï¼ï¼ãUNIX V6ã®Thompson ShellãMacOS Xã«ç§»æ¤ãã¦ã¿ãã1ãã¡ã¤ã«ã®é常ã«ã·ã³ãã«ãªä½ãã§ãããcdã¯builtinãããªãã¦ãchdirã¨ããbuiltinãæä¾ããã¦ããã®ããã
ã¨ããããåãããã«ãªã£ãã®ã§ããããæãã¦ã¿ãã
ã¾ã注æãå¿ è¦ãªã®ã¯ããã¼ã¿ãã«Cã³ã³ãã¤ã©ä»¥åã®PDP-11 Cã³ã³ãã¤ã©ãªã®ã§ãCã®æ§æãå¾®å¦ã«éããã¨ã"=|"ã"=+"ãªã©æ¼ç®åã=ã®åç½®ãããªãã¦å¾ç½®ã«ãªããã¾ããsetexit/resetã£ã¦é¢æ°ããããã©ãããã¯setjmp/longjmpã«ç¸å½ããããã ãã¸ã£ã³ããããã¡ã¯ã°ãã¼ãã«ã«ä¸ã¤ã¨ããæãã«è¦åããããããã¨ãintã¯16ããããªã®ã§ã32ãããã®æéæ å ±ãæ±ãã®ã«ãint[2]ã使ã£ã¦ããé¨åã¯é©å½ã«ç´ããããã¡ããã¨åä½ã¯ç¢ºèªãã¦ããªãã
--- sh.orig.c 2008-09-12 20:02:12.000000000 +0900 +++ sh.c 2008-09-12 20:43:39.000000000 +0900 @@ -1,5 +1,8 @@ /* + * Thompson shell (UNIX V6) */ +#include <stdio.h> +#include <stdlib.h> #define INTR 2 #define QUIT 3 @@ -49,7 +52,7 @@ char *arginp; int onelflg; -char *mesg[] { +char *mesg[] = { 0, "Hangup", 0, @@ -73,21 +76,28 @@ }; struct stime { - int proct[2]; - int cputim[2]; - int systim[2]; + int proct; + int cputim; + int systim; } timeb; char line[LINSIZ]; char *args[ARGSIZ]; int trebuf[TRESIZ]; +/* Emulate setexit/reset by using setjmp/longjmp. */ +#include <setjmp.h> +jmp_buf jbuf; +#define setexit() setjmp(jbuf) +#define reset() longjmp(jbuf, 1) + main(c, av) int c; char **av; { register f; register char *acname, **v; + div_t a; for(f=2; f<15; f++) close(f); @@ -95,7 +105,8 @@ close(f); dolc = getpid(); for(f=4; f>=0; f--) { - dolc = ldiv(0, dolc, 10); + a = div(dolc, 10); + dolc = a.quot; pidp[f] = ldivr+'0'; } v = av; @@ -132,7 +143,7 @@ loop: if(promp != 0) prs(promp); - peekc = getc(); + peekc = xgetc(); main1(); goto loop; } @@ -174,7 +185,7 @@ *argp++ = linep; loop: - switch(c = getc()) { + switch(c = xgetc()) { case ' ': case '\t': @@ -211,7 +222,7 @@ pack: for(;;) { - c = getc(); + c = xgetc(); if(any(c, " '\"\t;&<>()|^\n")) { peekc = c; if(any(c, "\"'")) @@ -229,7 +240,7 @@ register *t; t = treep; - treep =+ n; + treep += n; if (treep>treeend) { prs("Command line overflow\n"); error++; @@ -238,7 +249,7 @@ return(t); } -getc() +xgetc() { register char c; @@ -248,17 +259,17 @@ return(c); } if(argp > eargp) { - argp =- 10; - while((c=getc()) != '\n'); - argp =+ 10; + argp -= 10; + while((c=xgetc()) != '\n'); + argp += 10; err("Too many args"); gflg++; return(c); } if(linep > elinep) { - linep =- 10; - while((c=getc()) != '\n'); - linep =+ 10; + linep -= 10; + while((c=xgetc()) != '\n'); + linep += 10; err("Too many characters"); gflg++; return(c); @@ -299,7 +310,7 @@ if (arginp) { if (arginp == 1) - exit(); + exit(1); if ((c = *arginp++) == 0) { arginp = 1; c = '\n'; @@ -307,9 +318,9 @@ return(c); } if (onelflg==1) - exit(); + exit(1); if(read(0, &cc, 1) != 1) - exit(); + exit(1); if (cc=='\n' && onelflg) onelflg--; return(cc); @@ -372,7 +383,7 @@ t[DFLG] = 0; if(l == '&') { t1 = t[DLEF]; - t1[DFLG] =| FAND|FPRS|FINT; + t1[DFLG] |= FAND|FPRS|FINT; } t[DRIT] = syntax(p+1, p2); return(t); @@ -437,7 +448,7 @@ flg = 0; if(**p2 == ')') - flg =| FPAR; + flg |= FPAR; lp = 0; rp = 0; i = 0; @@ -465,7 +476,7 @@ case '>': p++; if(p!=p2 && **p=='>') - flg =| FCAT; else + flg |= FCAT; else p--; case '<': @@ -628,14 +639,14 @@ if(i < 0) { prs(t[DLEF]); err(": cannot open"); - exit(); + exit(1); } } if(t[DRIT] != 0) { if((f&FCAT) != 0) { i = open(t[DRIT], 1); if(i >= 0) { - seek(i, 0, 2); + lseek(i, 0, 2); goto f1; } } @@ -643,7 +654,7 @@ if(i < 0) { prs(t[DRIT]); err(": cannot create"); - exit(); + exit(1); } f1: close(1); @@ -672,9 +683,9 @@ } if(t[DTYP] == TPAR) { if(t1 = t[DSPR]) - t1[DFLG] =| f&FINT; + t1[DFLG] |= f&FINT; execute(t1); - exit(); + exit(1); } close(acctf); gflg = 0; @@ -683,7 +694,7 @@ t[DSPR] = "/etc/glob"; execv(t[DSPR], t+DSPR); prs("glob: cannot execute\n"); - exit(); + exit(1); } scan(t, &trim); *linep = 0; @@ -698,26 +709,26 @@ texec(linep, t); prs(t[DCOM]); err(": not found"); - exit(); + exit(1); case TFIL: f = t[DFLG]; pipe(pv); t1 = t[DLEF]; - t1[DFLG] =| FPOU | (f&(FPIN|FINT|FPRS)); + t1[DFLG] |= FPOU | (f&(FPIN|FINT|FPRS)); execute(t1, pf1, pv); t1 = t[DRIT]; - t1[DFLG] =| FPIN | (f&(FPOU|FINT|FAND|FPRS)); + t1[DFLG] |= FPIN | (f&(FPOU|FINT|FAND|FPRS)); execute(t1, pv, pf2); return; case TLST: f = t[DFLG]&FINT; if(t1 = t[DLEF]) - t1[DFLG] =| f; + t1[DFLG] |= f; execute(t1); if(t1 = t[DRIT]) - t1[DFLG] =| f; + t1[DFLG] |= f; execute(t1); return; @@ -738,12 +749,12 @@ t[DSPR] = "/bin/sh"; execv(t[DSPR], t+DSPR); prs("No shell!\n"); - exit(); + exit(1); } if (errno==ENOMEM) { prs(t[DCOM]); err(": too large"); - exit(); + exit(1); } } @@ -754,8 +765,8 @@ prs(s); prs("\n"); if(promp == 0) { - seek(0, 0, 2); - exit(); + lseek(0, 0, 2); + exit(1); } } @@ -766,10 +777,10 @@ s = as; while(*s) - putc(*s++); + xputc(*s++); } -putc(c) +xputc(c) { write(2, &c, 1); @@ -778,11 +789,12 @@ prn(n) int n; { - register a; + register div_t a; - if(a=ldiv(0,n,10)) + a = div(n,10); + if(a.quot) prn(a); - putc(lrem(0,n,10)+'0'); + xputc(a.rem+'0'); } any(c, as) @@ -862,10 +874,10 @@ char cname[14]; char shf; char uid; - int datet[2]; - int realt[2]; - int bcput[2]; - int bsyst[2]; + int datet; + int realt; + int bcput; + int bsyst; } tbuf; register i; register char *np, *s; @@ -873,9 +885,9 @@ s = as; times(&timbuf); time(timbuf.proct); - lsub(tbuf.realt, timbuf.proct, timeb.proct); - lsub(tbuf.bcput, timbuf.cputim, timeb.cputim); - lsub(tbuf.bsyst, timbuf.systim, timeb.systim); + tbuf.realt = timbuf.proct - timeb.proct; + tbuf.bcput = timbuf.cputim - timeb.cputim; + tbuf.bsyst = timbuf.systim - timeb.systim; do { np = s; while (*s != '\0' && *s != '/') @@ -886,12 +898,11 @@ if (*np) np++; } - tbuf.datet[0] = timbuf.proct[0]; - tbuf.datet[1] = timbuf.proct[1]; + tbuf.datet = timbuf.proct; tbuf.uid = uid; tbuf.shf = 0; if (promp==0) tbuf.shf = 1; - seek(acctf, 0, 2); + lseek(acctf, 0, 2); write(acctf, &tbuf, sizeof(tbuf)); }
ãããæãã°ã30年以ä¸åã®ããã°ã©ã ãã¡ãã£ã¨ããä¿®æ£ã§åãã®ã ãããæ¹ãã¦C & UNIXã®ç§»æ¤æ§ã®é«ããæããã
ä½è«ã ããBourne Shellã®ç¹å¾´ã¨ãã¦ã
Bourne Shell ã¯ã¾ããã¨ã©ã¼ã¡ãã»ã¼ã¸ã®ããã« 2çªã®ãã¡ã¤ã«è¨è¿°åã使ãã¨ããè¦å®ãæåã«æ¡ç¨ããããã°ã©ã ã§ããããããã«ãããã¨ã©ã¼ã¡ãã»ã¼ã¸ããã¼ã¿ã¨åé¢ãã¦ã¹ã¯ãªããã§å¶å¾¡ãããã¨ã容æã«ãªã£ãã
ã¨ããã確ãã«ãThompson shellã¯fd 2ãã¾ã£ããã±ã¢ãã¦ããªãã
æã®ã¨ã³ããªãæ¤ç´¢ãã¦ã¿ããããBourne shellãã«é¢ãããã®ããã£ãããããBourne shellã®ã³ã¼ãã¯ç¡çãéãã¨ããããã¯ã£ããè¨ã£ã¦èªã¿ã«ãããã¡ãªã¿ã«ãOpenSolarisã®Bourne shellï¼Hairloom Bourne Shellï¼ã¯ALGOL 68風ã®ã³ã¼ãã§ã¯ãªãã