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 >
Wrap
C/C++ Source or Header
|
1993-08-03
|
4KB
|
158 lines
/* 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 */
}