/* from Dale Schumacher's dLibs */ #include #include #include #include #include __EXTERN void _getbuf __PROTO((FILE *)); static FILE *_fopen __PROTO((const char *, const char *, FILE *)); /* lowest character device handle # */ #define LAST_DEVICE __SMALLEST_VALID_HANDLE extern int __default_mode__; static FILE *_fopen(filename, mode, fp) const char *filename; const char *mode; FILE *fp; /* * INTERNAL FUNCTION. Attempt to open in the given * and attach it to the stream */ { register int h, i, iomode = 0, f = __default_mode__; while(*mode) { switch(*mode++) { case 'r': f |= _IOREAD; break; case 'w': f |= _IOWRT; iomode |= (O_CREAT | O_TRUNC); break; case 'a': f |= _IOWRT; iomode |= (O_CREAT | O_APPEND); break; case '+': f &= ~(_IOREAD | _IOWRT); f |= _IORW; break; case 'b': f |= _IOBIN; break; case 't': f &= ~_IOBIN; break; default: return(NULL); } } if((i = (f & (_IORW | _IOREAD | _IOWRT))) == 0) return(NULL); else if(i == _IOREAD) iomode |= O_RDONLY; else if(i == _IOWRT) iomode |= O_WRONLY; else iomode |= O_RDWR; h = open(filename, iomode, 0644); if(h < __SMALLEST_VALID_HANDLE) { return(NULL); /* file open/create error */ } if(isatty(h)) f |= (_IODEV | _IOLBF); else f |= _IOFBF; fp->_file = h; /* file handle */ fp->_flag = f; /* file status flags */ return(fp); } FILE *fopen(filename, mode) const char *filename, *mode; { register int i; register FILE *fp = NULL; for(i=0; (!fp && (i < _NFILE)); ++i) if(!(_iob[i]._flag & (_IORW | _IOREAD | _IOWRT))) fp = &_iob[i]; /* empty slot */ if(fp != NULL) { if(_fopen(filename, mode, fp) == NULL) return NULL; _getbuf(fp); return fp; } else { errno = EMFILE; return NULL; } } /* * re-coded, foobared code deleted * * ++jrb */ FILE *freopen(filename, mode, fp) const char *filename, *mode; FILE *fp; { unsigned int f; if(fp == NULL) return NULL; f = fp->_flag; if((f & (_IORW | _IOREAD | _IOWRT)) != 0) { /* file not closed, close it */ #if 0 if(fflush(fp) != 0) return NULL; /* flush err */ if(close(fp->_file) != 0) return NULL; /* close err */ #else fflush(fp); close(fp->_file); /* ANSI says ignore errors */ #endif } /* save buffer discipline and setbuf settings, and _IOWRT just for determinining line buffering after the next _fopen */ f &= (_IOFBF | _IOLBF | _IONBF | _IOMYBUF | _IOWRT); /* open the new file according to mode */ if((fp = _fopen(filename, mode, fp)) == NULL) return NULL; if(fp->_flag & _IODEV) { /* we are re-opening to a tty */ if((f & _IOFBF) && (f & _IOWRT) && (f & _IOMYBUF)) { /* was a FBF & WRT & !setvbuff'ed */ /* reset to line buffering */ f &= ~_IOFBF; f |= _IOLBF; } } f &= ~_IOWRT; /* get rid of saved _IOWRT flag */ /* put buffering and discipline flags in new fp->_flag */ fp->_flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOMYBUF); fp->_flag |= f; return fp; }