home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 2.ddi / CLIBSRC3.ZIP / FOPEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-10  |  9.3 KB  |  283 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - fopen.c
  3.  *
  4.  * function(s)
  5.  *        fopen         - opens a stream
  6.  *        __openfp      - opens a file
  7.  *        __getfp       - gets a file pointer
  8.  *        CheckOpenType - returns the FILE's flags value, zero if type
  9.  *                        string was invalid.
  10.  *-----------------------------------------------------------------------*/
  11.  
  12. /*
  13.  *      C/C++ Run Time Library - Version 5.0
  14.  *
  15.  *      Copyright (c) 1987, 1992 by Borland International
  16.  *      All Rights Reserved.
  17.  *
  18.  */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <fcntl.h>
  23. #include <sys\stat.h>
  24. #include <io.h>
  25. #include <RtlData.h>
  26.  
  27. /*---------------------------------------------------------------------*
  28.  
  29. Name            CheckOpenType - examines file open type
  30.  
  31. Usage           static unsigned pascal near
  32.                   CheckOpenType (const char *type, unsigned *oflagsP,
  33.                                  unsigned *modeP)
  34.  
  35. Prototype in    _stdio.h
  36.  
  37. Description
  38.  
  39.   The function returns the FILE's flags value, zero if type string was
  40.   invalid.
  41.  
  42.   The type string contains characters with the following meanings:
  43.  
  44.                 oflags                  mode                    f->flags
  45. r       O_RDONLY                        don't care              _F_READ
  46. w       O_CREAT | O_WRONLY | O_TRUNC    S_IWRITE                _F_WRIT
  47. a       O_CREAT | O_WRONLY | O_APPEND   S_IWRITE                _F_WRIT
  48. r+      O_RDWR                          don't care              _F_RDWR
  49. w+      O_RDWR | O_CREAT | O_TRUNC      S_IWRITE | S_IREAD      _F_RDWR
  50. a+      O_RDWR | O_CREAT | O_APPEND     S_IWRITE | S_IREAD      _F_RDWR
  51.  
  52. where "oflags" and "mode" are the second and third parameters to the
  53. open() function.  Please consult open() documentation for details.
  54.  
  55. A further character is optional:
  56.  
  57.         ..t     - text mode             oflags, f->flags |= O_TEXT,
  58.         ..b     - binary mode           oflags, f->flags |= O_BINARY, _F_BIN
  59.  
  60. We require the first char of the type string to be r, w, or a, but after
  61. that we just stop on mismatch and don't care if the string is junk.
  62.  
  63. Return value    see description above
  64.  
  65. *---------------------------------------------------------------------*/
  66. static unsigned pascal near
  67. CheckOpenType (register const char *type, unsigned *oflagsP, unsigned *modeP)
  68.  
  69. {
  70.         extern void     (*_exitfopen)();
  71.         extern void     _xfclose();
  72.  
  73.         unsigned        oflags = 0;
  74.         unsigned        mode   = 0;
  75.         unsigned        flags  = 0;
  76.         char    c;
  77.  
  78.     if ((c = *type++) == 'r')
  79.     {
  80.                 oflags =  O_RDONLY;
  81.                 flags  = _F_READ;
  82.         }
  83.     else if (c == 'w')
  84.     {
  85.                 oflags = O_CREAT | O_WRONLY | O_TRUNC;
  86.                 mode   = S_IWRITE;
  87.                 flags  = _F_WRIT;
  88.         }
  89.     else if (c == 'a')
  90.     {
  91.                 oflags = O_WRONLY | O_CREAT | O_APPEND;
  92.                 mode   = S_IWRITE;
  93.                 flags  = _F_WRIT;
  94.         }
  95.         else
  96.                 return 0;
  97.  
  98.         c  = *type++;
  99.  
  100.         if (c == '+' || (*type == '+' && (c == 't' || c == 'b')))
  101.         {
  102.         if (c == '+')
  103.                     c = *type;
  104.         /* same modes, but both read and write */
  105.                 oflags = (oflags & ~(O_WRONLY | O_RDONLY)) | O_RDWR;
  106.                 mode   = S_IREAD | S_IWRITE;
  107.                 flags  = _F_READ | _F_WRIT;
  108.         }
  109.  
  110.     if ('t' == c)
  111.     {
  112.                 oflags |= O_TEXT;
  113.         }
  114.     else if ('b' == c)
  115.     {
  116.                 oflags |= O_BINARY;
  117.                 flags |= _F_BIN;
  118.         }
  119.         else
  120.         {
  121.         if ((oflags |= (_RTLInstanceData(_fmode) & (O_TEXT | O_BINARY))) & O_BINARY)
  122.               flags |= _F_BIN;
  123.         }
  124.         _exitfopen = _xfclose;
  125.         *oflagsP = oflags;
  126.         *modeP = mode;
  127.         return flags;
  128. }
  129.  
  130.  
  131. /*---------------------------------------------------------------------*
  132.  
  133. Name            __openfp - opens a file
  134.  
  135. Usage           static FILE * pascal near __openfp (FILE *fp,
  136.                         const char *filename, const char *type, int shflag);
  137.  
  138. Prototype in    _stdio.h
  139.  
  140. Description     opens a file
  141.  
  142. Return value    On successful completion, each function returns the
  143.                 newly open stream. freopen returns the argument stream.
  144.                 In the event of error, each function returns NULL.
  145.  
  146. *---------------------------------------------------------------------*/
  147. FILE     *pascal near __openfp (FILE *fp, const char *filename,
  148. const char *type, int shflag)
  149. {
  150.         unsigned        oflag, mode;
  151.  
  152.     if (((fp->flags = CheckOpenType (type, &oflag, &mode)) == 0) ||
  153.                 ((fp->fd < 0) &&
  154.         (fp->fd = open (filename, oflag|shflag, mode)) < 0))
  155.     {
  156.                 fp->fd = -1;
  157.                 fp->flags = 0;
  158.                 return NULL;
  159.         }
  160.  
  161.         if (isatty (fp->fd))
  162.                 fp->flags |= _F_TERM;
  163.  
  164.         if (setvbuf (fp, NULL, (fp->flags & _F_TERM) ? _IOLBF : _IOFBF, BUFSIZ))
  165.         {
  166.                 fclose (fp);
  167.                 return NULL;
  168.         }
  169.         else {
  170.                 fp->istemp = 0;
  171.                 return fp;
  172.         }
  173. }
  174.  
  175.  
  176. /*---------------------------------------------------------------------*
  177.  
  178. Name            __getfp - gets a file pointer
  179.  
  180. Usage           static FILE  * pascal near  __getfp(void)
  181.  
  182. Prototype in    _stdio.h
  183.  
  184. Description     gets a file pointer
  185.  
  186. *---------------------------------------------------------------------*/
  187. FILE *pascal near __getfp(void)
  188. {
  189.     register FILE *fp;
  190.     _QRTLDataBlock;
  191.     fp = _QRTLInstanceData(_streams);
  192.  
  193.     while (fp->fd >= 0 &&
  194.            fp++ < _QRTLInstanceData(_streams) + _QRTLInstanceData(_nfile))
  195.                 continue;
  196.  
  197.     if (fp->fd >= 0)
  198.             return NULL;
  199.     else
  200.             return fp;
  201. }
  202.  
  203.  
  204. /*---------------------------------------------------------------------*
  205.  
  206. Name            fopen - opens a stream
  207.  
  208. Usage           #include <stdio.h>
  209.                 FILE *fopen(const char *filename, const char *type);
  210.  
  211. Related
  212. functions usage FILE *fdopen(int handle, char *type);
  213.                 FILE *freopen(const char *filename, const char *type,
  214.                               FILE *stream);
  215.  
  216. Prototype in    stdio.h
  217.  
  218. Description     fopen opens the file named by filename and
  219.                 associates a stream with it. fopen returns a pointer to be
  220.                 used to identify the stream in subsequent operations.
  221.  
  222.                 fdopen associates a stream with a file handle obtained from
  223.                 creat, dup, dup2, or open. The type of stream must match the
  224.                 mode of the open handle.
  225.  
  226.                 freopen substitutes the named file in place of the open
  227.                 stream. The original stream is closed, regardless of
  228.                 whether the open succeeds. freopen is useful for changing the
  229.                 file attached to stdin, stdout, or stderr.
  230.  
  231.                 The type string used in each of these calls is one of the
  232.                 following values:
  233.  
  234.                         r       Open for reading only.
  235.  
  236.                         w       Create for writing.
  237.  
  238.                         a       Append; open for writing at end of file or
  239.                                 create for writing if the file does not exist.
  240.  
  241.                         r+      Open an existing file for update (reading and
  242.                                 writing).
  243.  
  244.                         w+      Create a new file for update.
  245.  
  246.                         a+      Open for append; open (or create if the file
  247.                                 does not exist) for update at the end of the
  248.                                 file.
  249.  
  250.                 To specify that a file is being opened or created in text
  251.                 mode, you can append a t to the value of type (rt, w+t, etc.);
  252.                 similarly, to specify binary mode, you can append a b to the
  253.                 type value (wb, a+b, etc.)
  254.  
  255.                 If a t or b is not given in type, the mode is governed by the
  256.                 global variable _fmode. If _fmode is set to O_BINARY, files
  257.                 will be opened in binary mode. If _fmode is set to O_TEXT,
  258.                 they will be opened in text mode. These O_... constants are
  259.                 defined in fcntl.h.
  260.  
  261.                 When a file is opened for update, both input and output may be
  262.                 done on the resulting stream. However, output may not be
  263.                 directly followed by input without an intervening fseek or
  264.                 rewind, and input may not be directly followed by output
  265.                 without an intervening fseek, rewind, or an input which
  266.                 encounters end-of-file.
  267.  
  268. Return value    On successful completion, each function returns the
  269.                 newly open stream. freopen returns the argument stream.
  270.                 In the event of error, each function returns NULL.
  271.  
  272. *---------------------------------------------------------------------*/
  273. FILE    * _FARFUNC fopen (const char *filename, const char *type)
  274. {
  275.         register FILE   *fp;
  276.  
  277.         if ((fp = __getfp()) == NULL)
  278.                 return NULL;
  279.         else
  280.                 return __openfp (fp, filename, type, 0);
  281.  
  282. }
  283.