home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / misc / lib / dlibssrc / fopen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-10-03  |  4.1 KB  |  154 lines

  1. #include <osbind.h>
  2. #include <stdio.h>
  3. #include <io.h>
  4.  
  5. #define    LAST_DEVICE    -3        /* lowest character device handle # */
  6.  
  7. extern    FILE    _iob[];
  8.  
  9. static FILE *_fopen(filename, mode, fp)
  10. char *filename;
  11. register char *mode;
  12. register FILE *fp;
  13. /*
  14.  *    INTERNAL FUNCTION.  Attempt to open <filename> in the given
  15.  *    <mode> and attach it to the stream <fp>
  16.  */
  17. {
  18.     register char *p = NULL;
  19.     register int h, i, j = FALSE, f = 0;
  20.     char *malloc();
  21.  
  22.     while(*mode) {
  23.         switch(*mode++) {
  24.             case 'r':
  25.                 f |= F_READ;
  26.                 break;
  27.             case 'w':
  28.                 f |= F_WRITE;
  29.                 break;
  30.             case 'a':
  31.                 f |= F_WRITE;
  32.                 j = TRUE;
  33.                 break;
  34.             case '+':
  35.                 f |= (F_READ | F_WRITE);
  36.                 break;
  37.             case 'b':
  38.                 f |= F_BINARY;
  39.                 break;
  40.             case 't':
  41.                 f &= ~F_BINARY;
  42.                 break;
  43.             default:
  44.                 fputs(stderr, "Illegal file mode.\n");
  45.                 return(NULL);
  46.         }
  47.     }
  48.     if((i = (f & (F_READ | F_WRITE))) == 0)
  49.         return(NULL);
  50.     if(i == F_READ)
  51.         h = open(filename, _OPNr);
  52.     else if(!j && (i == F_WRITE))
  53.         h = creat(filename, _CRErw);
  54.     else {
  55.         i = ((i == F_WRITE) ? _OPNw : _OPNrw);
  56.         if ((h = open(filename, i)) < LAST_DEVICE)
  57.             h = creat(filename, _CRErw);
  58.     }
  59.     if(h < 0) {
  60.         if (h < LAST_DEVICE)
  61.             return(NULL);        /* file open/create error */
  62.         else
  63.             f |= F_DEVICE;        /* character device handles */
  64.     }
  65.     else {
  66.         if((p=malloc(BUFSIZ)) != NULL)    /* set up file buffer */
  67.             f |= F_BUFFER;
  68.         if(j)                /* append mode. move to eof. */
  69.             lseek(h, 0L, _LSKend);
  70.     }
  71.     fp->F_h = h;            /* file handle */
  72.     fp->F_stat = f;            /* file status flags */
  73.     fp->F_buf = p;            /* base of file buffer */
  74.     fp->F_bp = p;            /* current buffer pointer */
  75.     fp->F_bsiz = (p ? BUFSIZ : 0);    /* buffer size */
  76.     fp->F_cnt = 0;            /* # of bytes in buffer */
  77.     fp->F_unc1 = '\0';        /* primary ungotten character */
  78.     fp->F_unc2 = '\0';        /* secondary ungotten character */
  79.     return(fp);
  80. }
  81.  
  82. FILE *fopen(filename, mode)
  83. char *filename;
  84. char *mode;
  85. /*
  86.  *    Open <filename> as a stream file.  This is the normal open way
  87.  *    to open a file.  The <mode> is a string specifying the mode(s)
  88.  *    that are relevent to the file open.  Valid <mode> characters are:
  89.  *        r        read mode
  90.  *        w        write mode
  91.  *        a        append mode
  92.  *        b        binary mode
  93.  *        t        text (translated) mode
  94.  *    At least one of "r", "w" or "a" must be specified.  "t" is assumed
  95.  *    and indicates that <nl> is translated to <cr><lf> on output and
  96.  *    vica-versa on input.  "b" overides "t" and indicated that characters
  97.  *    are not translated during i/o operations.  "a" represents append
  98.  *    mode and means that the file pointer will initially be placed at
  99.  *    the end of the file.  "w" mode will create a file if it doesn't
  100.  *    exists, or zero an existing file.  If "r" is the only mode specified,
  101.  *    the file must already exist.  A (FILE *) is returned if the open
  102.  *    succeeds, or NULL if it fails.
  103.  */
  104. {
  105.     register int i;
  106.     register FILE *fp = NULL;
  107.  
  108.     for(i=0; (!fp && (i < MAXFILES)); ++i)
  109.         if(!(_iob[i].F_stat & (F_READ | F_WRITE)))   /* empty slot? */
  110.             fp = &_iob[i];
  111.     if(fp)
  112.         return(_fopen(filename, mode, fp));
  113.     else
  114.         return(NULL);
  115.     /* return(fp ? _fopen(filename, mode, fp) : NULL); */
  116. }
  117.  
  118. FILE *freopen(filename, mode, fp)
  119. char *filename;
  120. char *mode;
  121. FILE *fp;
  122. /*
  123.  *    Closes the file associated with <fp> and opens the new file as with
  124.  *    fopen(), except that a new FILE structure is not created.  The
  125.  *    existing FILE structure pointed to by <fp> is re-initialized with
  126.  *    the new file information.  This is typically used to redirect i/o
  127.  *    to standard streams "stdin", "stdout", "stderr", "stdprn", "stdaux".
  128.  *    <fp> is returned for success, or NULL for failure.
  129.  */
  130. {
  131.     if(fclose(fp))
  132.         return(NULL);
  133.     else
  134.         return(_fopen(filename, mode, fp));
  135.     /* return(fclose(fp) ? NULL : _fopen(filename, mode, fp)); */
  136. }
  137.  
  138. int fclose(fp)
  139. register FILE *fp;
  140. /*
  141.  *    Close the stream <fp>, flushing the buffer.  Returns 0 on success.
  142.  */
  143. {
  144.     if((fp->F_stat & (F_READ | F_WRITE)) == 0)
  145.         return(ERROR);                /* file not open! */
  146.     fflush(fp);
  147.     if(fp->F_stat & F_BUFFER)
  148.         free(fp->F_buf);            /* free buffer */
  149.     fp->F_stat = 0;                    /* clear status */
  150.     fp->F_buf = NULL;
  151.     fp->F_bsiz = 0;
  152.     return(close(fp->F_h) ? EOF : 0);
  153. }
  154.