* * * * * 99 ways to program a hex, Part 28: K&R C, system calls, full buffering So, how would the version based on system calls [1] have looked in the 80s? You know, probably before the mmap() system call existed [2]? Probably like this, vowel impairments, sorry, vwlmprmnts and all. > /************************************************************************* > * > * Copyright 2012 by Sean Conner. All Rights Reserved. > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License > * as published by the Free Software Foundation; either version 2 > * of the License, or (at your option) any later version. > * > * This program is distributed in the hope that it will be useful, > * but WITHOUT ANY WARRANTY; without even the implied warranty of > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > * GNU General Public License for more details. > * > * You should have received a copy of the GNU General Public License > * along with this program; if not, write to the Free Software > * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > * > * Comments, questions and criticisms can be sent to: sean@conman.org > * > *************************************************************************/ > > /* Style: K&R, system calls, full buffering */ > > #include > #include > #include > > #include > #include > #include > #include > > #define LINESIZE 16 > > /********************************************************************/ > > main(argc,argv) > char **argv; > { > int i,fhin; > > if (argc == 1) { > hexdmp(0,1); > } else { > for (i = 1 ; i < argc ; i++) { > fhin = open(argv[i],O_RDONLY); > if (fhin == -1) { > myperr(argv[i]); > continue; > } > > mywrt(1,"-----",5); > mywrt(1,argv[i],strlen(argv[i])); > mywrt(1,"-----\n",6); > > hexdmp(fhin,1); > if (close(fhin) < 0) { > myperr(argv[i]); > } > } > } > > return 0; > } > > /************************************************************************/ > > char buffer[4096],outbuf[75 * 109]; > > hexdmp(fhin,fhout) > { > int off,bytes,count,amount; > char *pout,*p; > > memset(outbuf,' ',sizeof(outbuf)); > off = count = 0; > pout = outbuf; > > while((bytes = myread(fhin,(char *)buffer,sizeof(buffer))) > 0) { > p = buffer; > for (p = buffer ; bytes > 0 ; ) { > amount = hexln(&pout,p,bytes,off); > p += amount; > bytes -= amount; > off += amount; > count++; > > if (count == 109) { > mywrt(fhout,outbuf,pout - outbuf); > memset(outbuf,' ',sizeof(outbuf)); > count = 0; > pout = outbuf; > } > } > } > > if (pout - outbuf > 0) { > mywrt(fhout,outbuf,pout - outbuf); > } > } > > /********************************************************************/ > > hexln(pline,p,bytes,off) > char **pline,*p; > { > char *line,*dh,*da; > int count; > > line = *pline; > > hexout(line,off,8,':'); > if (bytes > LINESIZE) { > bytes = LINESIZE; > } > > p += bytes; > dh = &line[10 + bytes * 3]; > da = &line[58 + bytes]; > > for (count = 0 ; count < bytes ; count++) { > p --; > da --; > dh -= 3; > > if ((*p >= ' ') && (*p <= '~')) { > *da = *p; > } else { > *da = '.'; > } > > hexout(dh,(unsigned long)*p,2,' '); > } > > line[58 + count] = '\n'; > *pline = &line[59 + count]; > return count; > } > > /**********************************************************************/ > > hexout(dest,value,size,padding) > char *dest; > { > dest[size] = padding; > while(size--) { > dest[size] = (char)((value & 0x0F) + '0'); > if (dest[size] > '9') { > dest[size] += 7; > } > value >>= 4; > } > } > > /************************************************************************/ > > myperr(s) > char *s; > { > extern char **sys_errlist; > extern int sys_nerr; > int err = errno; > > mywrt(2,s,strlen(s)); > mywrt(2,": ",2); > > if (err > sys_nerr) { > mywrt(2,"(unknown)",9); > } else { > mywrt(2,sys_errlist[err],strlen(sys_errlist[err])); > } > mywrt(2,"\n",1); > } > > /************************************************************************/ > > myread(fh,buf,size) > char *buf; > { > int amount = 0,bytes; > > while(size > 0) { > bytes = read(fh,buf,size); > if (bytes < 0) { > myperr("read()"); > exit(1); > } > if (bytes == 0) { > break; > } > amount += bytes; > size -= bytes; > buf += bytes; > } > return amount; > } > > /*********************************************************************/ > > mywrt(fh,msg,size) > char *msg; > { > if (write(fh,msg,size) < size) { > if (fh != 2) { > myperr("output"); > } > exit(1); > } > } > > /***********************************************************************/ > Actually, the [DELETED-vowel impairment-DELETED] vwlmprmnt code was due to linker strictions at the time—linkers at the time were fairly limited, and one of the limits was the length of identifiers it could handle, a limit of around 6 characters (some might have handled more, but the first C standard in 1989 set the limit to six, so that's probably the smallest size at the time). With only six characters (makes you wonder where that limit comes from [3]) and vowels typically being redundant (“f y cn rd ths y t cn wrt prgrms”) is it any wonder early code was typically vwlmprd? * Part 27: C♯, binary stream [4] * Part 29: K&R, system calls, full buffering, obfuscated [5] [1] gopher://gopher.conman.org/0Phlog:2012/01/30.1 [2] gopher://gopher.conman.org/0Phlog:2012/02/03.1 [3] http://en.wikipedia.org/wiki/DEC_Radix-50 [4] gopher://gopher.conman.org/0Phlog:2012/02/04.1 [5] gopher://gopher.conman.org/0Phlog:2012/02/06.1 Email Sean Conner at sean@conman.org .