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