80 lines
1.8 KiB
C
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;
|
|
}
|