188  Programming  7.  Why  should  the  debugger  do  that?  Why  not  write  some  “tool”  that  does  it  instead?  6.  If  the  debugger  dumps  core,  you  should  forget  about  debugging  your  application  and  debug  the  debugger.  5.  It’s  too  hard  to  understand.  4.  Where  are  the  Twinkies?  3.  Why  fix  things  now?  2.  Unix  can’t  do  everything  right.  1.  What’s  the  problem?  The  statement  “fixing  bugs  would  break  existing  code”  is  a  powerful  excuse  for  Unix  programmers  who  don’t  want  to  fix  bugs.  But  there  might  be  a  hidden  agenda  as  well.  More  than  breaking  existing  code,  fixing  bugs  would  require  changing  the  Unix  interface  that  zealots  consider  so  simple  and  easy-to-understand.  That  this  interface  doesn’t  work  is  irrelevant.  But  instead  of  buckling  down  and  coming  up  with  something  better,  or  just  fix-  ing  the  existing  bugs,  Unix  programmers  chant  the  mantra  that  the  Unix  interface  is  Simple  and  Beautiful.  Simple  and  Beautiful.  Simple  and  Beau-  tiful!  (It’s  got  a  nice  ring  to  it,  doesn’t  it?)  Unfortunately,  programming  around  bugs  is  particularly  heinous  since  it  makes  the  buggy  behavior  part  of  the  operating  system  specification.  The  longer  you  wait  to  fix  a  bug,  the  harder  it  becomes,  because  countless  pro-  grams  that  have  the  workaround  now  depend  on  the  buggy  behavior  and  will  break  if  it  is  fixed.  As  a  result,  changing  the  operating  system  interface  has  an  even  higher  cost  since  an  unknown  number  of  utility  programs  will  need  to  be  modified  to  handle  the  new,  albeit  correct,  interface  behavior.  (This,  in  part,  explains  why  programs  like  ls  have  so  many  different  options  to  accomplish  more-or-less  the  same  thing,  each  with  its  own  slight  variation.)  If  you  drop  a  frog  into  briskly  boiling  water  it  will  immediately  jump  out.  Boiling  water  is  hot,  you  know.  However,  if  you  put  a  frog  into  cold  water  and  slowly  bring  it  to  a  boil,  the  frog  won’t  notice  and  will  be  boiled  to  death.  The  Unix  interface  is  boiling  over.  The  complete  programming  interface  to  input/output  used  to  be  open,  close,  read,  and  write.  The  addition  of  net-  working  was  more  fuel  for  the  fire.  Now  there  are  at  least  five  ways  to  send  data  on  a  file  descriptor:  write,  writev,  send,  sendto,  and  sendmsg.  Each  involves  a  separate  code  path  through  the  kernel,  meaning  there  are  five  times  as  many  opportunities  for  bugs  and  five  different  sets  of  performance  characteristics  to  remember.  The  same  holds  true  for  reading  data  from  a  file  descriptor  (read,  recv,  recvfrom,  and  recvmsg).  Dead  frog.  
“It  Can’t  Be  a  Bug,  My  Makefile  Depends  on  It!”  189  Filename  Expansion  There  is  one  exception  to  Unix’s  each-program-is-self-contained  rule:  file-  name  expansion.  Very  often,  one  wants  Unix  utilities  to  operate  on  one  or  more  files.  The  Unix  shells  provide  a  shorthand  for  naming  groups  of  files  that  are  expanded  by  the  shell,  producing  a  list  of  files  that  is  passed  to  the  utility.  For  example,  say  your  directory  contains  the  files  A,  B,  and  C.  To  remove  all  of  these  files,  you  might  type  rm  *.  The  shell  will  expand  “*”  to  “A  B  C”  and  pass  these  arguments  to  rm.  There  are  many,  many  problems  with  this  approach,  which  we  discussed  in  the  previous  chapter.  You  should  know,  though,  that  using  the  shell  to  expand  filenames  is  not  an  historical  accident:  it  was  a  carefully  reasoned  design  decision.  In  “The  Unix  Pro-  gramming  Environment”  by  Kernighan  and  Mashey  (IEEE  Computer,  April  1981),  the  authors  claim  that,  “Incorporating  this  mechanism  into  the  shell  is  more  efficient  than  duplicating  it  everywhere  and  ensures  that  it  is  available  to  programs  in  a  uniform  way.”3  Excuse  me?  The  Standard  I/O  library  (stdio  in  Unix-speak)  is  “available  to  programs  in  a  uniform  way.”  What  would  have  been  wrong  with  having  library  functions  to  do  filename  expansion?  Haven’t  these  guys  heard  of  linkable  code  libraries?  Furthermore,  the  efficiency  claim  is  completely  vacuous  since  they  don't  present  any  performance  numbers  to  back  it  up.  They  don’t  even  explain  what  they  mean  by  “efficient.”  Does  having  file-  name  expansion  in  the  shell  produce  the  most  efficient  system  for  program-  mers  to  write  small  programs,  or  does  it  simply  produce  the  most  efficient  system  imaginable  for  deleting  the  files  of  untutored  novices?  Most  of  the  time,  having  the  shell  expand  file  names  doesn’t  matter  since  the  outcome  is  the  same  as  if  the  utility  program  did  it.  But  like  most  things  in  Unix,  it  sometimes  bites.  Hard.  Say  you  are  a  novice  user  with  two  files  in  a  directory,  A.m  and  B.m.  You’re  used  to  MS-DOS  and  you  want  to  rename  the  files  to  A.c  and  B.c.  Hmm.  There’s  no  rename  command,  but  there’s  this  mv  command  that  looks  like  it  does  the  same  thing.  So  you  type  mv  *.m  *.c.  The  shell  expands  this  to  mv  A.m  B.m  and  mv  overwrites  B.m  with  A.m.  This  is  a  bit  of  a  shame  since  you  had  been  working  on  B.m  for  the  last  couple  of  hours  and  that  was  your  only  copy.  3Note  that  this  decision  flies  in  the  face  of  the  other  lauded  Unix  decision  to  let  any  user  run  any  shell.  You  can’t  run  any  shell:  you  have  to  run  a  shell  that  performs  star-name  expansion.—Eds.  
            
            






































































































































































































































































































































































