Re: Smallest Unix Shell
Article: 8667 of alt.hackers Newsgroups: alt.hackers From: mrs@netcom.com (Morgan Schweers) Subject: Re: Smallest Unix Shell Message-ID: mrsDFArxq.DJ8@netcom.com Organization: Foxsoft Cyberware Date: Fri, 22 Sep 1995 08:08:14 GMT Approved: Yah, youbetcha. Lines: 71 Sender: mrs@netcom17.netcom.com Status: RO
Some time ago wkt@dolphin.cs.adfa.oz.au (Warren Toomey) happily mumbled: >ObHack: A challenge with a friend to come up with the smallest Unix shell >in C. >Here's the results, the smallest being 123 characters (124 with a \n): (I've also split all of them across two lines. For optimal use, recombine on one line. All of them SHOULD be, however, split on 'safe' splits, all identically (so you can compare the second line for size...) so even as is, the code should compile.) Interesting. I'm not familiar with the 'strsep' function... My preferred version is this one (*K&R* C legal... Yep. Disgusting, ain't it? No, the lack of 'char' at the beginning isn't a typo.): My smallest at offhand at 121 bytes: a,b[99],*c,d[99];main(){while(printf(">"),c=d,*c=a=gets(b)){ for(;*++c=strtok(a," ");a=0);fork()?wait(0):execvp(*d,d+1);}} Your smallest (so far) at 122 bytes: char*c,b[99],*v[99],i;main(){while(putchar(62),gets(b)){for( c=b,i=0;v[i++]=strsep(&c," "););fork()?wait(0):execvp(*v,v);}} has three bugs: o Enter an invalid command (like hitting ENTER) and the fork goes back and prompts you, thus going another level down... o It requires that you add a 'spare' parameter (which gets ignored). o The first 'parameter' passed (as argv[1]) is the same as the name of the program. (This is a function/problem of execv and execvp, at least under SunOS 4.1.3.) o (And, though not a bug, I've not found a machine that recognizes 'strsep' yet...) My code still has the first bug, but not the remaining two, and uses 'strtok'. The first bug is fixed by the following code (127 bytes): a,b[99],*c,d[99];main(){while(printf(">"),c=d,*c=a=gets(b)){ for(;*++c=strtok(a," ");a=0);fork()?wait(0):exit(execvp(*d,d+1));}} Now... What bugs remain, that aren't feature enhancements? (Note: You can shrink it by another byte by making it call 'execv' instead of execvp, and entering the path for each program you want to execute entirely by hand.) (Presuming that 'strsep' returns a pointer into the string being modified at the point of the latest 'seperator', while placing a 0 just before it in the string, returning NULL when there are no more seperators...) The following is a 'strsep' version with bugs 2 and 3 fixed. (Bug #1 still takes an additional 6 bytes to fix.) This is down to 119 bytes, but I don't know of any platforms that work with 'strsep', so I can't test it...: a,*c,b[99],v[99];main(){while(printf(">"),c=v,*c=a=gets(b)){ for(;*++c=strsep(&a," "););fork()?wait(0):execvp(*v,v+1);}} >I've broken them into 2 lines each for easier reading. Fixing the small bug >that all four versions have would increase the size by at least 10 characters. > > Warren Which small bug...? (One I've missed?) -- Morgan Schweers -- Morgan Schweers | New Chrome Grass! Finger mrs@netcom.com for my PGP key | Live fast, die \ B1 S4 a b g j++! k l? p r- s t+ u v- w+ x y- z, approx.__/ old, and leave a smouldering pile of metal as a corpse... It's never enough, until your heart stops beating, the deeper you get, the sweeter the pain...