home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 1.ddi / CLIB1.ZIP / FOPEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-07  |  10.9 KB  |  329 lines

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