home *** CD-ROM | disk | FTP | other *** search
- /* from Dale Schumacher's dLibs */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
-
- __EXTERN void _getbuf __PROTO((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 register char *mode;
- register FILE *fp;
- /*
- * INTERNAL FUNCTION. Attempt to open <filename> in the given
- * <mode> and attach it to the stream <fp>
- */
- {
- 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
- return NULL;
- }
-
- /*
- * re-coded, foobared code ifdef'ed below
- *
- * ++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;
-
- #ifdef FOOBAR
- /* this was old incorrect coding */
- /* the problem: apart from the requirement that freopen return the
- same file descriptor that the code below meets, it should also preserve
- the same buffering discipline, and the same buffer (because the
- user may have done a setbuf/setvbuf).
- */
- if(fclose(fp))
- return(NULL);
- else
- return(_fopen(filename, mode, fp));
- #endif /* FOOBAR */
- }
-