Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/lib5/stdio/fopen.c
There are 8 other files named fopen.c in the archive. Click here to see a list.
/*
* FOPEN - open a file
*
* Copyright (c) 1986 by Ian Macky, SRI International
*/
#include "stdio.h"
/*
* this is initial FILE-block storage for std streams (stdin, stdout,
* and stderr, the first three slots respectively), plus extra storage
* for user files. this is a static array so that storage for the
* first n FILE blocks is pre-allocated, so there is no chance of
* not having enough memory to allocate space for one.
*/
#include "sys/usysio.h" /* Get defs for STDIN_CH etc */
FILE _sios[SYS_OPEN] = {
{_SIOF_OPEN,0,0,0,0,(_SIOF_READ |_SIOF_AUTOBUF), STDIN_CH},
{_SIOF_OPEN,0,0,0,0,(_SIOF_WRITE|_SIOF_AUTOBUF|_SIOF_LINEBUF), STDOUT_CH},
{_SIOF_OPEN,0,0,0,0,(_SIOF_WRITE), STDERR_CH}
};
/*
* this is the head of the linked list of FILE blocks beyond those
* in the previous static array. when that array is filled, new
* blocks are allocated dynamically and added to this linklist.
*/
FILE *_FILE_head = NULL;
FILE *fopen(pathname, type)
char *pathname, *type;
{
FILE *f;
if (f = _makeFILE()) { /* get a FILE block */
if (freopen(pathname, type, f)) /* if can open file */
return f; /* return FILE ptr */
_freeFILE(f); /* lose, release it */
}
return NULL; /* barf return */
}
/*
* allocate a FILE block. first check to see if there are any free
* blocks in the static array. if there are none, then make a new
* block, flag it as dynamically allocated, and add it to the linked
* list.
*/
FILE *_makeFILE()
{
int i;
FILE *f;
extern char *calloc();
/*
* look for a free spot in the static _sios[] array of FILE blocks.
* DON'T check the first three slots, which are reserved for stdin,
* stdout, and stderr respectively.
*/
for (f = stderr+1; f < &_sios[SYS_OPEN]; f++)
if (!(f->sioflgs & _SIOF_OPEN)) {
f->siocheck = _SIOF_FILE; /* mark as valid FILE block */
return f;
}
/*
* no free slots, so allocate a new FILE block
*/
if ((f = (FILE *) calloc(1, sizeof(FILE))) == NULL)
return NULL; /* lost, couldn't make one */
else {
f->sioflgs |= _SIOF_DYNAMFILE; /* success, splice this new block */
f->siopFILE = NULL; /* into the linklist of dynamically */
f->sionFILE = _FILE_head; /* allocated blocks, to keep track */
f->siocheck = _SIOF_FILE; /* mark as valid FILE block */
return _FILE_head = f; /* of them. */
}
}
/*
* release a FILE block. if it was dynamically allocated, then
* remove it from the linked list of FILE blocks and release it,
* else it was a static block, so zero the flag word so we will
* see it as available in _makeFILE()
*/
void _freeFILE(f)
FILE *f;
{
if (f->sioflgs & _SIOF_DYNAMFILE) {
/*
* if there's no previous pointer then this is the first block in the
* linklist, so "previous" is the head pointer.
*/
if (f->siopFILE)
f->siopFILE->sionFILE = f->sionFILE;
else _FILE_head = f->sionFILE;
if (f->sionFILE)
f->sionFILE->siopFILE = f->siopFILE;
free((char *) f);
} else {
f->siocheck = f->sioflgs = 0; /* nuke the open flag! */
f->siofd = -1; /* is this really necessary? */
}
}