Files
2024-02-19 00:25:23 -05:00

80 lines
1.8 KiB
C

/* _ f i l e
*
* Allocate a stream descriptor
*
* Allocate and initialise a FILE structure. If the pointer passed
* to the function is NULL, a FILE will be allocated, otherwise
* the one specified will be used. The function will return
* a pointer to the FILE structure, or NULL if it fails.
*/
#include "stdiolib.h"
/*LINTLIBRARY*/
#if _IOREAD != 1 || _IOWRITE != 2
_IOREAD == 1 and _IOWRITE == 2 assumed
#endif
static int (*filtable[]) P((FILE *)) =
{__brdupdate, __brdonly, __bffil};
static int (*flstable[]) P((int, FILE *)) =
{__bwrupdate, __bffls, __bwronly};
FILE *__file F3(register FILE *, fp, int, fd, register short, flags)
{
/* Retain flags and insert if necessary */
if (fp != NULL) {
if (TESTFLAG(fp, _IOINSERT)) {
CLEARFLAG(fp, _IOINSERT);
FINSERT(fp);
}
flags |= GETFLAG(fp, _IORETAIN);
}
/* Allocate or find a file structure */
else {
for (fp = __iop; fp != NULL && TESTFLAG(fp, ~_IORETAIN); fp = fp->__next) {
if (fileno(fp) == fd) {
/* Multiple fdopen() on a file descriptor is debatable */
/* Error return here breaks too many broken programs! */
/* return NULL; */
__freebuf(fp);
break;
}
}
/* Retain flags on existing descriptors */
if (fp != NULL)
flags |= GETFLAG(fp, _IORETAIN);
/* No existing descriptor */
else {
if ((fp = (FILE *) malloc(sizeof(*fp))) == NULL)
return NULL;
FINSERT(fp);
}
}
/* Stream descriptor needs to be initialised */
fp->__rend = NULL;
fp->__rptr = NULL;
fp->__wend = NULL;
fp->__wptr = NULL;
fp->__base = NULL;
fp->__flag = flags;
fp->__file = fd;
fp->__bufsiz = __allocbuf(fp);
flags &= _IOREAD | _IOWRITE;
fp->__filbuf = filtable[flags];
fp->__flsbuf = flstable[flags];
fp->__flush = __btfls;
return fp;
}