fopen的实现

来源:互联网 发布:黑马程序员 android 编辑:程序博客网 时间:2024/06/05 08:12

/***   
  *fopen.c   -   open   a   file   
  *   
  *               Copyright   (c)   1985-1997,   Microsoft   Corporation.   All   rights   reserved.   
  *   
  *Purpose:   
  *               defines   fopen()   and   _fsopen()   -   open   a   file   as   a   stream   and   open   a   file   
  *               with   a   specified   sharing   mode   as   a   stream   
  *   
  *******************************************************************************/   
    
  #include    <cruntime.h>   
  #include    <stdio.h>   
  #include    <share.h>   
  #include    <dbgint.h>   
  #include    <internal.h>   
  #include    <mtdll.h>   
  #include    <file2.h>   
  #include    <tchar.h>   
    
  /***   
  *FILE   *_fsopen(file,   mode,   shflag)   -   open   a   file   
  *   
  *Purpose:   
  *               Opens   the   file   specified   as   a   stream.     mode   determines   file   mode:   
  *               "r":   read               "w":   write             "a":   append   
  *               "r+":   read/write                                 "w+":   open   empty   for   read/write   
  *               "a+":   read/append   
  *               Append   "t"   or   "b"   for   text   and   binary   mode.   shflag   determines   the   
  *               sharing   mode.   Values   are   the   same   as   for   sopen().   
  *   
  *Entry:   
  *               char   *file   -   file   name   to   open   
  *               char   *mode   -   mode   of   file   access   
  *   
  *Exit:   
  *               returns   pointer   to   stream   
  *               returns   NULL   if   fails   
  *   
  *Exceptions:   
  *   
  *******************************************************************************/   
    
  FILE   *   __cdecl   _tfsopen   (   
                  const   _TSCHAR   *file,   
                  const   _TSCHAR   *mode   
                  ,int   shflag   
                  )   
  {   
                  REG1   FILE   *stream;   
                  REG2   FILE   *retval;   
    
                  _ASSERTE(file   !=   NULL);   
                  _ASSERTE(*file   !=   _T('/0'));   
                  _ASSERTE(mode   !=   NULL);   
                  _ASSERTE(*mode   !=   _T('/0'));   
    
                  /*   Get   a   free   stream   */   
                  /*   [NOTE:   _getstream()   returns   a   locked   stream.]   */   
    
                  if   ((stream   =   _getstream())   ==   NULL)   
                                  return(NULL);   
    
                  /*   open   the   stream   */   
  #ifdef   _UNICODE   
                  retval   =   _wopenfile(file,mode,shflag,stream);   
  #else     /*   _UNICODE   */   
                  retval   =   _openfile(file,mode,shflag,stream);   
  #endif     /*   _UNICODE   */   
    
                  /*   unlock   stream   and   return.   */   
                  _unlock_str(stream);   
                  return(retval);   
  }   
    
    
  /***   
  *FILE   *fopen(file,   mode)   -   open   a   file   
  *   
  *Purpose:   
  *               Opens   the   file   specified   as   a   stream.     mode   determines   file   mode:   
  *               "r":   read               "w":   write             "a":   append   
  *               "r+":   read/write                                 "w+":   open   empty   for   read/write   
  *               "a+":   read/append   
  *               Append   "t"   or   "b"   for   text   and   binary   mode   
  *   
  *Entry:   
  *               char   *file   -   file   name   to   open   
  *               char   *mode   -   mode   of   file   access   
  *   
  *Exit:   
  *               returns   pointer   to   stream   
  *               returns   NULL   if   fails   
  *   
  *Exceptions:   
  *   
  *******************************************************************************/   
    
  FILE   *   __cdecl   _tfopen   (   
                  const   _TSCHAR   *file,   
                  const   _TSCHAR   *mode   
                  )   
  {   
                  return(   _tfsopen(file,   mode,   _SH_DENYNO)   );   
  }   
    *_open.c   -   open   a   stream,   with   string   mode   
  *   
  *               Copyright   (c)   1985-1997,   Microsoft   Corporation.   All   rights   reserved.   
  *   
  *Purpose:   
  *               defines   _openfile()   -   opens   a   stream,   with   string   arguments   for   mode   
  *   
  *******************************************************************************/   
    
  #ifdef   _WIN32   
    
    
  #include    <cruntime.h>   
  #include    <stdio.h>   
  #include    <fcntl.h>   
  #include    <file2.h>   
  #include    <io.h>   
  #include    <dbgint.h>   
  #include    <internal.h>   
  #include    <tchar.h>   
    
  #define   CMASK       0644         /*   rw-r--r--   */   
  #define   P_CMASK   0666         /*   different   for   Posix   */   
    
  /***   
  *FILE   *_openfile(filename,   mode,   shflag,   stream)   -   open   a   file   with   string   
  *               mode   and   file   sharing   flag.   
  *   
  *Purpose:   
  *               parse   the   string,   looking   for   exactly   one   of   {rwa},   at   most   one   '+',   
  *               at   most   one   of   {tb},   at   most   one   of   {cn},   at   most   one   of   {SR},   at   most   
  *               one   'T',   and   at   most   one   'D'.   pass   the   result   on   as   an   int   containing   
  *               flags   of   what   was   found.   open   a   file   with   proper   mode   if   permissions   
  *               allow.   buffer   not   allocated   until   first   i/o   call   is   issued.   intended   
  *               for   use   inside   library   only   
  *   
  *Entry:   
  *               char   *filename   -   file   to   open   
  *               char   *mode   -   mode   to   use   (see   above)   
  *               int   shflag   -   file   sharing   flag   
  *               FILE   *stream   -   stream   to   use   for   file   
  *   
  *Exit:   
  *               set   stream's   fields,   and   causes   system   file   management   by   system   calls   
  *               returns   stream   or   NULL   if   fails   
  *   
  *Exceptions:   
  *   
  *******************************************************************************/
FILE   *   __cdecl   _openfile   (   
                  const   char   *filename,   
                  REG3   const   char   *mode,   
                  int   shflag,   
                  FILE   *str   
                  )   
  {   
                  REG2   int   modeflag;   
                  int   streamflag   =   _commode;   
                  int   commodeset   =   0;   
                  int   whileflag;   
                  int   filedes;   
                  REG1   FILE   *stream;   
    
                  _ASSERTE(filename   !=   NULL);   
                  _ASSERTE(mode   !=   NULL);   
                  _ASSERTE(str   !=   NULL);   
    
                  /*   Parse   the   user's   specification   string   as   set   flags   in   
                                (1)   modeflag   -   system   call   flags   word   
                                (2)   streamflag   -   stream   handle   flags   word.   */   
    
                  /*   First   mode   character   must   be   'r',   'w',   or   'a'.   */   
    
                  switch   (*mode)   {   
                  case   'r':   
                                  modeflag   =   _O_RDONLY;   
                                  streamflag    ¦=   _IOREAD;   
                                  break;   
                  case   'w':   
                                  modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_TRUNC;   
                                  streamflag    ¦=   _IOWRT;   
                                  break;   
                  case   'a':   
                                  modeflag   =   _O_WRONLY    ¦   _O_CREAT    ¦   _O_APPEND;   
                                  streamflag    ¦=   _IOWRT;   
                                  break;   
                  default:   
                                  return(NULL);   
                                  break;   
                  }   
    
                  /*   There   can   be   up   to   three   more   optional   mode   characters:   
                        (1)   A   single   '+'   character,   
                        (2)   One   of   't'   and   'b'   and   
                        (3)   One   of   'c'   and   'n'.   
                  */   
    
                  whileflag=1;   
    
                  while(*++mode   &&   whileflag)   
                                  switch(*mode)   {   
    
                                  case   '+':   
                                                  if   (modeflag   &   _O_RDWR)   
                                                                  whileflag=0;   
                                                  else   {   
                                                                  modeflag    ¦=   _O_RDWR;   
                                                                  modeflag   &=   ~(_O_RDONLY    ¦   _O_WRONLY);   
                                                                  streamflag    ¦=   _IORW;   
                                                                  streamflag   &=   ~(_IOREAD    ¦   _IOWRT);   
                                                  }   
                                                  break;   
                                  case   't':   
                                                  if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))   
                                                                  whileflag=0;   
                                                  else   
                                                                  modeflag    ¦=   _O_TEXT;   
                                                  break;   
    
                                  case   'b':   
                                                  if   (modeflag   &   (_O_TEXT    ¦   _O_BINARY))   
                                                                  whileflag=0;   
                                                  else   
                                                                  modeflag    ¦=   _O_BINARY;   
                                                  break;   
                                  case   'c':   
                                                  if   (commodeset)   
                                                                  whileflag=0;   
                                                  else   {   
                                                                  commodeset   =   1;   
                                                                  streamflag    ¦=   _IOCOMMIT;   
                                                  }   
                                                  break;   
    
                                  case   'n':   
                                                  if   (commodeset)   
                                                                  whileflag=0;   
                                                  else   {   
                                                                  commodeset   =   1;   
                                                                  streamflag   &=   ~_IOCOMMIT;   
                                                  }   
                                                  break;   
                                  default:   
                                                  whileflag=0;   
                                                  break;   
                                  }   
    
                  /*   Try   to   open   the   file.     Note   that   if   neither   't'   nor   'b'   is   
                        specified,   _sopen   will   use   the   default.   */   
    
                  if   ((filedes   =   _sopen(filename,   modeflag,   shflag,   CMASK))    <   0)   
                                  return(NULL);   
    
                  /*   Set   up   the   stream   data   base.   */   
    
  #ifndef   CRTDLL   
                  /*   force   library   pre-termination   procedure   */   
                  _cflush++;   
  #endif     /*   CRTDLL   */   
    
                  /*   Init   pointers   */   
                  stream   =   str;   
    
                  stream->_flag   =   streamflag;   
                  stream->_cnt   =   0;   
                  stream->_tmpfname   =   stream->_base   =   stream->_ptr   =   NULL;   
                  stream->_file   =   filedes;   
    
                  return(stream);   
  }

原创粉丝点击