home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mntlib18 / fopen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-03  |  3.6 KB  |  162 lines

  1. /* from Dale Schumacher's dLibs */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8.  
  9. __EXTERN void _getbuf __PROTO((FILE *));
  10.  
  11. /* lowest character device handle # */
  12. #define    LAST_DEVICE    __SMALLEST_VALID_HANDLE
  13.  
  14. extern int __default_mode__;
  15.  
  16. static FILE *_fopen(filename, mode, fp)
  17.     const char *filename;
  18.     const register char *mode;
  19.     register FILE *fp;
  20. /*
  21.  *    INTERNAL FUNCTION.  Attempt to open <filename> in the given
  22.  *    <mode> and attach it to the stream <fp>
  23.  */
  24.     {
  25.     register int h, i, iomode = 0, f = __default_mode__;
  26.  
  27.     while(*mode)
  28.         {
  29.         switch(*mode++)
  30.             {
  31.             case 'r':
  32.                 f |= _IOREAD;
  33.                 break;
  34.             case 'w':
  35.                 f |= _IOWRT;
  36.                 iomode |= (O_CREAT | O_TRUNC);
  37.                 break;
  38.             case 'a':
  39.                 f |= _IOWRT;
  40.                 iomode |= (O_CREAT | O_APPEND);
  41.                 break;
  42.             case '+':
  43.                 f &= ~(_IOREAD | _IOWRT);
  44.                 f |= _IORW;
  45.                 break;
  46.             case 'b':
  47.                 f |= _IOBIN;
  48.                 break;
  49.             case 't':
  50.                 f &= ~_IOBIN;
  51.                 break;
  52.             default:
  53.                 return(NULL);
  54.             }
  55.         }
  56.     if((i = (f & (_IORW | _IOREAD | _IOWRT))) == 0)
  57.         return(NULL);
  58.     else if(i == _IOREAD)
  59.         iomode |= O_RDONLY;
  60.     else if(i == _IOWRT)
  61.         iomode |= O_WRONLY;
  62.     else
  63.         iomode |= O_RDWR;
  64.     h = open(filename, iomode, 0644);
  65.     if(h < __SMALLEST_VALID_HANDLE)
  66.         {
  67.         return(NULL);        /* file open/create error */
  68.         }
  69.     if(isatty(h))
  70.         f |= (_IODEV | _IOLBF);
  71.     else
  72.         f |= _IOFBF;
  73.     fp->_file = h;            /* file handle */
  74.     fp->_flag = f;            /* file status flags */
  75.  
  76.     return(fp);
  77.     }
  78.  
  79. FILE *fopen(filename, mode)
  80.     const char *filename, *mode;
  81.     {
  82.     register int i;
  83.     register FILE *fp = NULL;
  84.  
  85.     for(i=0; (!fp && (i < _NFILE)); ++i)
  86.         if(!(_iob[i]._flag & (_IORW | _IOREAD | _IOWRT))) 
  87.             fp = &_iob[i]; /* empty slot */
  88.     if(fp != NULL)
  89.     {
  90.         if(_fopen(filename, mode, fp) == NULL)
  91.             return NULL;
  92.         _getbuf(fp);
  93.         return fp;
  94.     }
  95.     else
  96.       {
  97.         errno = EMFILE;
  98.         return NULL;
  99.       }
  100.     }
  101.  
  102. /*
  103.  * re-coded,  foobared code ifdef'ed below
  104.  *
  105.  *    ++jrb
  106.  */
  107. FILE *freopen(filename, mode, fp)
  108.     const char *filename, *mode;
  109.     FILE *fp;
  110. {
  111.     unsigned int f;
  112.     
  113.     if(fp == NULL) return NULL;
  114.     
  115.     f = fp->_flag;
  116.     if((f & (_IORW | _IOREAD | _IOWRT)) != 0)
  117.     { /* file not closed, close it */
  118. #if 0
  119.         if(fflush(fp) != 0) return NULL;            /* flush err */
  120.         if(close(fp->_file) != 0) return NULL;        /* close err */
  121. #else
  122.     fflush(fp); close(fp->_file);        /* ANSI says ignore errors */
  123. #endif
  124.     }
  125.     /* save buffer discipline and setbuf settings, and _IOWRT just for
  126.        determinining line buffering after the next _fopen */
  127.     f &= (_IOFBF | _IOLBF | _IONBF | _IOMYBUF | _IOWRT);
  128.  
  129.     /* open the new file according to mode */
  130.     if((fp = _fopen(filename, mode, fp)) == NULL)
  131.     return NULL;
  132.     if(fp->_flag & _IODEV)
  133.     { /* we are re-opening to a tty */
  134.     if((f & _IOFBF) && (f & _IOWRT) && (f & _IOMYBUF))
  135.     {   /* was a FBF & WRT & !setvbuff'ed  */
  136.         /* reset to line buffering */
  137.         f &= ~_IOFBF;
  138.         f |=  _IOLBF;
  139.     }
  140.     }
  141.     f &= ~_IOWRT; /* get rid of saved _IOWRT flag */
  142.     
  143.     /* put buffering and discipline flags in new fp->_flag */
  144.     fp->_flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOMYBUF);
  145.     fp->_flag |= f;
  146.     
  147.     return fp;
  148.     
  149. #ifdef FOOBAR
  150.         /* this was old incorrect coding */
  151. /* the problem: apart from the requirement that freopen return the
  152. same file descriptor that the code below meets, it should also preserve
  153. the same buffering discipline, and the same buffer (because the
  154. user may have done a setbuf/setvbuf).
  155.  */
  156.     if(fclose(fp))
  157.         return(NULL);
  158.     else
  159.         return(_fopen(filename, mode, fp));
  160. #endif /* FOOBAR */
  161.     }
  162.