Commit 0d936eec authored by Kevin Bracey's avatar Kevin Bracey
Browse files

* Improved stdio to allocate extra FILE objects beyond the static array of 16....

* Improved stdio to allocate extra FILE objects beyond the static array of 16. Number of open files now only limited by memory and the OS.

* FOPEN_MAX in <stdio.h> increased from 8 to 16 to reflect reality.
* Minor corrections to comments in <stdio.h>.
* Library shutdown tidied for modules. In particular, shutdown of I/O was
  broken for modules which had been entered as applications.

Version 5.53. Tagged as 'RISC_OSLib-5_53'
parent 72dac353
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.52"
Module_Version SETA 552
Module_MajorVersion SETS "5.53"
Module_Version SETA 553
Module_MinorVersion SETS ""
Module_Date SETS "07 Mar 2005"
Module_ApplicationDate SETS "07-Mar-05"
Module_Date SETS "14 Mar 2005"
Module_ApplicationDate SETS "14-Mar-05"
Module_ComponentName SETS "RISC_OSLib"
Module_ComponentPath SETS "RiscOS/Sources/Lib/RISC_OSLib"
Module_FullVersion SETS "5.52"
Module_HelpVersion SETS "5.52 (07 Mar 2005)"
Module_FullVersion SETS "5.53"
Module_HelpVersion SETS "5.53 (14 Mar 2005)"
END
/* (5.52)
/* (5.53)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.2.
*
*/
#define Module_MajorVersion_CMHG 5.52
#define Module_MajorVersion_CMHG 5.53
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 07 Mar 2005
#define Module_Date_CMHG 14 Mar 2005
#define Module_MajorVersion "5.52"
#define Module_Version 552
#define Module_MajorVersion "5.53"
#define Module_Version 553
#define Module_MinorVersion ""
#define Module_Date "07 Mar 2005"
#define Module_Date "14 Mar 2005"
#define Module_ApplicationDate "07-Mar-05"
#define Module_ApplicationDate "14-Mar-05"
#define Module_ComponentName "RISC_OSLib"
#define Module_ComponentPath "RiscOS/Sources/Lib/RISC_OSLib"
#define Module_FullVersion "5.52"
#define Module_HelpVersion "5.52 (07 Mar 2005)"
#define Module_LibraryVersionInfo "5:52"
#define Module_FullVersion "5.53"
#define Module_HelpVersion "5.53 (14 Mar 2005)"
#define Module_LibraryVersionInfo "5:53"
......@@ -20,8 +20,6 @@
/* Incorporate _sys_tmpnam_ idea from WGD */
/* __pos of a file is now a long, and we avoid warnings by two casts */
/* of this to (int) in the calls to _sys_seek(). */
/* N.B. I am trying to factor out machine dependence via calls to */
/* routines like _sys_read_ which can be implemented as _osgbpb or */
/* NIOP as required. This file SHOULD therefore be machine independent */
......@@ -102,6 +100,42 @@ typedef struct __extradata {
static _extradatap _extra;
/* 14-Mar-2005 - upgraded to handle more files beyond _SYS_OPEN; extra */
/* handles stored in a linked list. For simplicity, these structures are */
/* never freed until terminateio is called. Need to take care that all */
/* code directly referencing __iob also considers this list. */
typedef struct _FILElist {
struct _FILElist *next;
FILE file;
_extradata extra;
} _FILElist, *_FILElistp;
static _FILElistp _flist;
static FILE *_getFILE(void)
{ _FILElistp fp;
int i;
/* First try __iob array */
for (i=3; i<_SYS_OPEN; i++)
{ FILE *stream = &__iob[i];
if (!(stream->__flag & _IOREAD+_IOWRITE))
return stream;
}
/* Then try linked list */
for (fp = _flist; fp; fp = fp->next)
if (!(fp->file.__flag & _IOREAD+_IOWRITE))
return &fp->file;
/* Then try to allocate a new one */
fp = calloc(1, sizeof(_FILElist));
if (fp)
{ fp->file.__extrap = &fp->extra;
fp->next = _flist;
_flist = fp;
return &fp->file;
}
return 0;
}
#ifdef SUPPORT_WIDE
#define O_NONE 0
#define O_BYTE (-1)
......@@ -176,7 +210,7 @@ static _extradatap _extra;
int (fgetc)(FILE *stream) { return getc(stream); }
int (fputc)(int ch, FILE *stream) { return putc(ch, stream); }
int (getc)(FILE *stream) { return getc(stream); }
int (getchar)() { return getchar(); }
int (getchar)(void) { return getchar(); }
int (putc)(int ch, FILE *stream) { return putc(ch, stream); }
int (putchar)(int ch) { return putchar(ch); }
int (feof)(FILE *stream) { return feof(stream); }
......@@ -267,7 +301,7 @@ dbmsg("_IOSHARED so zoom to end %d\n", (int)stream->__pos);
if (flag & _IOSEEK+_IOBUFREAD)
{
dbmsg("_writebuf seeking to %d\n", (int)stream->__pos);
if (_sys_seek(fh, (int)stream->__pos) < 0)
if (_sys_seek(fh, stream->__pos) < 0)
{ seterr(stream);
return EOF;
}
......@@ -485,7 +519,7 @@ dbmsg("fillbuf seeking to %d\n", (int)stream->__pos);
_sys_ensure(fh);
stream->__flag &= ~_IOADFSBUG;
}
if (_sys_seek(fh, (int)stream->__pos) < 0)
if (_sys_seek(fh, stream->__pos) < 0)
{ seterr(stream);
return EOF;
}
......@@ -508,7 +542,7 @@ dbmsg("fillbuf dirty buffer, read into end,seeking to %d\n",(int) stream->__pos+
_sys_ensure(fh);
stream->__flag &= ~_IOADFSBUG;
}
if (_sys_seek(fh, (int) stream->__pos + extent) < 0)
if (_sys_seek(fh, stream->__pos + extent) < 0)
{ seterr(stream);
return EOF;
} else stream->__flag |= _IOBUFREAD;
......@@ -582,7 +616,9 @@ int fclose(FILE *stream)
{ int fd = _SYS_OPEN;
res = fflush(stream);
if (flag & _IOSHARED)
{ for (fd = 0; fd < _SYS_OPEN; ++fd)
{ /* No need to check FILElist, as only FILEs in __iob can be */
/* shared by __dup(). */
for (fd = 0; fd < _SYS_OPEN; ++fd)
{ FILE *f = &__iob[fd];
if ((f != stream) &&
(f->__flag & _IOREAD+_IOWRITE) && /* f is open */
......@@ -647,12 +683,9 @@ FILE *freopen(const char *name, const char *mode, FILE *iob)
}
FILE *fopen(const char *name, const char *mode)
{ int i;
for (i=3; i<_SYS_OPEN; i++)
{ FILE *stream = &__iob[i];
if (!(stream->__flag & _IOREAD+_IOWRITE)) /* if not open then try it */
return (freopen(name, mode, stream));
}
{ FILE *stream = _getFILE();
if (stream)
return (freopen(name, mode, stream));
return 0; /* no more i/o channels allowed for */
}
......@@ -674,17 +707,13 @@ FILE *_fopen_string_file(const char *data, int length)
/* The declaration of this function in #include "hostsys.h" suggests */
/* that this function is of type (void *), so this definition will lead */
/* to a warning message. */
int i;
for (i=3; i<_SYS_OPEN; i++)
{ FILE *stream = &__iob[i];
if (!(stream->__flag & _IOREAD+_IOWRITE)) /* if not open then try it */
{
fclose(stream);
stream->__flag = _IOSTRG+_IOREAD+_IOACTIVE;
stream->__ptr = stream->__base = (unsigned char *)data;
stream->__icnt = length;
return stream;
}
FILE *stream = _getFILE();
if (stream)
{ fclose(stream);
stream->__flag = _IOSTRG+_IOREAD+_IOACTIVE;
stream->__ptr = stream->__base = (unsigned char *)data;
stream->__icnt = length;
return stream;
}
return 0; /* no more i/o channels allowed for */
}
......@@ -717,13 +746,18 @@ void _initio(char *f1,char *f2,char *f3)
_sprintf_lf(v,_kernel_getmessage("Couldn't write %s", "C46"), f2), _sys_msg(v), exit(1);
}
void _terminateio()
void _terminateio(void)
{ int i;
int closeall = !_kernel_client_is_module();
_FILElistp fp;
for (i=3; i<_SYS_OPEN; i++) {
FILE *f = &__iob[i];
if (closeall || (f->__flag & _IOUSERFILE)) fclose(f);
}
for (fp = _flist; fp; fp = fp->next) {
FILE *f = &fp->file;
if (closeall || (f->__flag & _IOUSERFILE)) fclose(f);
}
/* for cowardice do stdin, stdout, stderr last (in that order) */
for (i=0; i<3; i++) {
FILE *f = &__iob[i];
......@@ -732,7 +766,13 @@ void _terminateio()
if (!closeall) freopen(TTYFILENAME, (f == stdin ? "r" : "w"), f);
}
}
if (_extra) {
if (closeall) {
_FILElistp fpnext;
for (fp = _flist; fp; fp = fpnext) {
fpnext = fp->next;
free(fp);
}
_flist = 0;
free(_extra);
_extra = 0;
}
......@@ -1066,8 +1106,11 @@ int fflush(FILE *stream)
res =_do_fflush(stream);
else
{ int i;
_FILElistp fp;
for (i=0; i<_SYS_OPEN; i++)
if (_do_fflush(&__iob[i]) != 0) res = EOF;
for (fp=_flist; fp; fp=fp->next)
if (_do_fflush(&fp->file) != 0) res = EOF;
}
return res;
}
......@@ -1119,7 +1162,7 @@ char *__old_tmpnam(char *a)
return tmpnam(a);
}
FILE *tmpfile()
FILE *tmpfile(void)
{
char name[L_tmpnam];
FILE *f;
......
......@@ -30,7 +30,7 @@
static unsigned long int next = 1;
int _ANSI_rand() /* This is the ANSI suggested portable code */
int _ANSI_rand(void) /* This is the ANSI suggested portable code */
{
next = next * 1103515245 + 12345;
return (unsigned int) (next >> 16) % 32768;
......@@ -63,7 +63,7 @@ static unsigned _random_number_seed[55] =
static int _random_j = 23, _random_k = 54;
int rand()
int rand(void)
{
/* See Knuth vol 2 section 3.2.2 for a discussion of this random
number generator.
......@@ -108,7 +108,7 @@ static struct {
char alloc_finalised, io_finalised, getenv_finalised;
} exit_s;
void _exit_init()
void _exit_init(void)
{
if (_kernel_client_is_module()) {
/* leave SWI mode exit handlers in place. number_of_exit_functions
......@@ -130,19 +130,28 @@ int atexit(vprocp func)
return 0; /* success */
}
void _lib_shutdown()
void _lib_shutdown(void)
{
int mode = ((_kernel_processor_mode() & 0xF) != 0);
int ismodule = _kernel_client_is_module(); /* ie is module app, so not */
/* total shutdown */
while (exit_s.number_of_exit_functions!=0) {
vprocp fn = _exitvector[--exit_s.number_of_exit_functions].p;
int flags = _exitvector[exit_s.number_of_exit_functions].i;
if ((flags & 3) != mode) { ++exit_s.number_of_exit_functions; break; };
/* Take extra care with fn ptr - consider Thumb */
fn = (vprocp) ((unsigned) fn &~ 3);
_call_client_0(fn);
}
/* ensure no recursion if finalisation fails */
if (!exit_s.getenv_finalised) { exit_s.getenv_finalised = 1; _terminate_getenv(); }
if (!exit_s.alloc_finalised) { exit_s.alloc_finalised = 1; _terminate_user_alloc(); }
if (!exit_s.io_finalised) { exit_s.io_finalised = 1; _terminateio(); }
if (!exit_s.getenv_finalised && !ismodule)
{ exit_s.getenv_finalised = 1; _terminate_getenv(); }
if (!exit_s.alloc_finalised)
{ exit_s.alloc_finalised = 1; _terminate_user_alloc(); }
if (!exit_s.io_finalised)
{ exit_s.io_finalised = 1; _terminateio(); }
if (ismodule) /* Want terminateio again for module part */
exit_s.io_finalised = 0;
}
......@@ -166,7 +175,7 @@ void _Exit(int n)
_exit(n);
}
void abort()
void abort(void)
{
raise(SIGABRT);
exit(1);
......
......@@ -96,9 +96,7 @@ typedef struct __FILE_struct
* negative integral constant, indicates end-of-file, that is, no more input
* from a stream.
*/
/* It is not clear to me what value FOPEN_MAX should have, so I will
err in the cautious direction - ANSI requires it to be at least 8 */
#define FOPEN_MAX 8 /* check re arthur/unix/mvs */
#define FOPEN_MAX _SYS_OPEN
/*
* an integral constant expression that is the minimum number of files that
* this implementation guarantees can be open simultaneously.
......@@ -203,20 +201,24 @@ int fclose(FILE * /*stream*/);
* causes the stream pointed to by stream to be flushed and the associated
* file to be closed. Any unwritten buffered data for the stream are
* delivered to the host environment to be written to the file; any unread
* buffered data are discarded. The stream is disassociated from the file.
* If the associated buffer was automatically allocated, it is deallocated.
* Returns: zero if the stream was succesfully closed, or nonzero if any
* buffered data are discarded. Whether or not the call succeeds, the stream
* is disassociated from the file and any buffer set by the setbuf or
* setvbuf function is disassociated from the stream (and deallocated if it
* was automatically allocated).
* Returns: zero if the stream was succesfully closed, or EOF if any
* errors were detected or if the stream was already closed.
*/
int fflush(FILE * /*stream*/);
/*
* If the stream points to an output or update stream in which the most
* recent operation was output, the fflush function causes any unwritten
* data for that stream to be delivered to the host environment to be
* written to the file. If the stream points to an input or update stream,
* the fflush function undoes the effect of any preceding ungetc operation
* on the stream.
* Returns: nonzero if a write error occurs.
* If the stream points to an output stream or an update stream in which
* the most recent operation was not input, the fflush function causes any
* unwritten data for that stream to be delivered to the host environment to
* be written to the file. If the stream points to an input or update
* stream, the fflush function undoes the effect of any preceding ungetc
* operation on the stream.
* If stream is a null pointer, the fflush function performs this flushing
* action on all streams for which the behaviour is defined above.
* Returns: EOF if a write error occurs.
*/
FILE *fopen(const char * restrict /*filename*/,
const char * restrict /*mode*/);
......
......@@ -25,7 +25,7 @@
EXPORT |CLib_data_end|
% 124*4
% 123*4
|CLib_data_end|
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment