Notes for programmers --------------------- Status: The C library has had various bugs fixed and deficiencies corrected since version 3.50 (see below). The library version string returned by _clib_version()) is: "{Shared }C Library vsn 310/R [Jul 30 1990]" The SharedCLibrary module version is: C Library 3.66 (30 Jul 1990) In outline: - reported bugs have been fixed; - reported deficiencies have been addressed; - the library has been brought closer to the ANSI standard; - some small improvements have been made. Fixes: fputc() sometimes wrote 1 byte beyond the end of an I/O buffer in the event of an I/O error such as disc full. This is fixed in release 3.66 * The release 3.50 C library installed no exit handler, causing, e.g., *quit typed to ObjAsm's interactive prompt, _kernel_swi(OS_Exit,...) and system("*quit") all to crash the machine. This is fixed in 3.66 - the exit handler now closes down the library cleanly. * In 3.50, stack overflow caused the enigmatic message "no stack for trap handler" to appear. In 3.66, SIGSTAK is raised and can be handled by a user-supplied signal handler. * In 3.50, a program with a sufficiently deep stack would hang when events were enabled. This is fixed in release 3.66. * In 3.50, fopen(, "w...") created files of size 32KB and failed if less than 32KB was available. In 3.66 the initial size has been reduced to 16KB and if this fails it is repeatedly halved until using 1KB fails (N.B. BUFSIZ is 4KB so any write will fail if less than this is allocated unless you have used setvbuf() - see 'Notes' below). * y-umlaut and beta (German sz) were wrongly categorised by isupper(), islower(), etc. in the ISO8859-1 locale. This is fixed in release 3.66. * In release 3.50, "\a" is printed as ||G unless the output stream is (re)opened with mode "wb". In release 3.66, an audible BEL results. * The installation/de-installation of handlers by the C library is now RISC_OS-compliant (obeys the rules for handlers stated in the RISC OS Programmer's Reference Manual). * remove() now returns non-0 if does not exist. * (f)printf(...) now retuns EOF if an I/O error occurs while printing (in 3.50, the number of characters offered for printing was returned). * (f)printf("%.s", s) no longer requires s to be properly terminated (it now inspects at most chars). * If both '-' and '0' flags appear in a printf format the '0' is now ignored (as required by the definition of printf). * SIG_IGN, SIG_DFL and SIG_ERR now have fixed definitions. Using Shared C Library 3.50, the library and the client could each have different values for these macros, violating the ANSI standard. * setvbuf(f, NULL, mode, size) now sets the size of the buffer to be allocated by the system when the first I/O operation occurs. In release 3.50, this call did not work. * In release 3.50, the overlay manager could lose return handlers when returning from a call to a segment which had overlaid the caller. This is fixed in release 3.66. * The profiling support _mapstore() and _fmapstore(file) which, in release 3.50 could access bad addresses, has been fixed not to do so. * A bug in command line stream re-direction has been fixed. Previously, if 2 streams shared the same file descriptor (via, e.g. >& file) and one of the was closed, the file descriptor was closed. * system() used to corrupt the OS_ChangeEnvironment value for MemoryLimit (but does so no longer). Changes: memmove and memcpy are now hand-coded for speed. * An open mode may have a trailing 't', requesting that the file's time- stamp be updated. For example, fopen (file, "r+t") causes file to have its time-stamp updated when it is opened (previously, a file opened "r+" would not have its time-stamp updated, even if written to). The open is guaranteed to fail if the medium containing it is write- protected. Unless requested using mode modifier 't', file time stamps are only updated on opening with modes "w", "w+" or "a". * The C backtrace has been tidied up marginally (now says "in shared library function", when appropriate). * setlocale(..., "") (selecting the native locale) is now an equivalent (but better) way to do setlocale(..., "ISO8859-1"). * strcoll() now works in the "ISO8859-1" (RISC OS native) locale (i.e. it correctly collates top-bit-set characters in the native locale). In release 3.50 it was meaningful only in the "C" locale. * setlocale(LC_COLLATE, "ISO8859-1") is now understood (previously, only LC_CTYPE had any effect). * strftime(..., "%X", ...) now prints the time in a more useful format. * In release 3.50, the catch-all signal to which all un-recognised host errors were mapped was SIGFPE. In release 3.66, SIGOSERROR has been introduced for this purpose and SIGFPE now means "erroneous arithmetic operation", as it should. * A longjmp() will now deallocate any trailing stack chunks allocated to extend the stack between the setjmp() and the longjmp(). This is particularly vital to the handling of SIGSTAK (stack overflow) by longjmp'ing out of the signal handler. * The heuristics governing heap extension (via malloc) have been modified in favour of keeping the heap more compact (may cause more coalesce operations when the heap is small - but they are fast then). * A program running under the wimp can now extend it's wimp slot in order to grab more heap (for malloc) or stack. This is only done for programs linked with the new (release 3.66) stubs or AnsiLib. Old binaries (which may rely on malloc failing when the wimp slot is exhausted) running under the 3.66 SharedCLibrary are not affected. * Wimp slot extension can now collude with RISC_OSLib's flex module (or anything else for that matter) so that heap extension is not blocked if the slot has already been extended by something prepared to move out of the way (by extending the slot and moving into the extension). * The default root stack size and stack extension chunk is now 4KB rather than 16KB. Again, this only affects code linked with the 3.66 stubs or AnsiLib; old binaries running under the 3.66 shared library continue to get a 16KB root chunk. * An application may now set its own root stack size by using, for example, int __root_stack_size = 10*1024; (to get a 10KB root). * _kernel_swi() now always does an 'X'-bit SWI unless asked not to by orring _kernel_NONX with the SWI number. * _kernel_swi_c() has been added for calling SWIs which return a status value via the processor's carry flag. * The C library's RISC OS error handler now treats all errors as being fatal (in the RISC OS sense). * _kernel_raise_error() has been added to allow an application or module written in C to raise (or pass on) a RISC OS error. * A (previously fatal) direct call to SWI OS_CLI now has the same effect as system("CHAIN:..."). * The program's argument string is now copied in SVC mode so that C programs can be run with page 0 read-protected (causing the de- referencing of NULL pointers to trap...). Notes: Although BUFSIZ is defined in to be 4KB, any value can be used by making a suitable call to setvbuf() between opening a file and first performing an I/O operation on it. Thus the amount of memory used by stdin, stdout and any streams you open yourself, can be closely controlled. The relevant sequences are as follows: f = fopen(file, ...); ... setvbuf(f, NULL, _IOFBF, size); /* to set the size of the */ ... /* file buffer allocated */ use f... /* automatically. */ or setvbuf(f, mybuf, _IOFBF, size); /* to use 'mybuf' of size */ /* 'size'. */ ****************************************************************************