diff --git a/Doc/LFSv1,5 b/Doc/LFSv1,5
new file mode 100644
index 0000000000000000000000000000000000000000..fb7c0bd3b6949ebd55ca3996a56f81c64ff93920
--- /dev/null
+++ b/Doc/LFSv1,5
@@ -0,0 +1,2638 @@
+Adding Support for Arbitrary File Sizes to the Single UNIX Specification
+
+Last Update: 20Mar96
+----------------------------------------------------------------------------
+
+Table of Contents
+
+Adding Support for Arbitrary File Sizes to the Single UNIX Specification
+1.0 Overview
+1.1 The Large File Problem
+1.2 Requirements
+1.3 Importance
+1.4 Concepts
+1.5 Changes and Additions
+1.6 Conformance
+2.0 Changes to the Single UNIX Specification
+2.1 Changes to CAE Specification System Interface Definitions, Issue 4,
+Version 2
+2.2 Changes to CAE Specification System Interfaces and Headers, Issue 4,
+Version 2
+2.2.1 Changes to System Interfaces
+2.2.2 Changes to Headers
+2.3 Changes to CAE Specification Commands and Utilities, Issue 4, Version 2
+3.0 Transitional Extensions to the Single UNIX Specification
+3.1 Transitional Extensions to CAE Specification System Interfaces and
+Headers, Issue 4, Version 2
+3.1.1 Transitional Extensions to System Interfaces
+3.1.2 Transitional Extensions to Headers
+3.2 Transitional Extensions to the mount Utility
+3.3 Accessing the Extensions to the SUS
+
+Appendix A: Rationale and Notes
+A.1 Overview
+A.1.1 Guiding Principles
+A.1.2 Concepts
+A.2 Changes to the Single UNIX Specification
+A.2.1 Changes to CAE Specification System Interfaces and Headers, Issue 4,
+Version 2
+A.2.1.1 Changes to System Interfaces
+A.2.2 Changes to CAE Specification Commands and Utilities, Issue 4, Version
+2
+A.3 Transitional Extensions to the Single UNIX Specification
+A.3.1 Transitional Extensions to CAE Specification System Interfaces and
+Headers, Issue 4, Version 2
+A.3.1.1 Transitional Extensions to System Interfaces
+A.3.1.2 Transitional Extensions to Headers
+A.3.2 Accessing the Transitional Extensions to the SUS
+
+Acknowledgements
+
+Revision Information
+23Feb96 Version 1.1
+24Feb96 Version 1.2
+01Mar96 Version 1.3
+05Mar96 Version 1.4
+20Mar96 Version 1.5
+----------------------------------------------------------------------------
+
+Acknowledgements
+
+Even with the rise of 64-bit systems, the 32-bit operating system will be
+with us for a while yet. However, the need for interoperability with 64-bit
+systems, large applications, large databases, and cheap disks has created a
+market imperative for the UNIX industry: support large files on 32-bit
+systems. Most current UNIX systems support file sizes of at most 2^31-1
+bytes. This is not enough for today's applications, which include files
+containing videos, sounds, images, and large databases. Today's 32-bit
+systems are quite capable of handling the computational needs of these
+applications, but they need to be able to support maximum file sizes that
+are many orders of magnitude larger.
+
+This support must be compatible with the existing Single UNIX Specification,
+and provide a path to conformance with following versions. It must allow
+system vendors a cost effective approach to adding these features to their
+existing products, and provide system vendors, software vendors, and users
+with a clear path for future products. The independent software vendors
+(ISVs) listed below gathered in a set of meetings with the UNIX systems
+vendors to develop a common set of APIs and modifications to the Single UNIX
+Specification to allow support for large files. We called these meetings the
+Large File Summit. For details of the meetings, how the proposals were
+developed, and the ISV requirements document, see
+http://www.sas.com/standards/large.file.
+
+This work is being sent to the X/Open Base System Working Group so they can
+consider the changes that are suggested for the next generation of the
+Single UNIX Specification.
+
+The individuals who participated in the Large File Summit meetings and
+on-line discussions were:
+
+Amdahl Corp.:  Dennis Chapman, John Haines
+Convex Computer Corp.:  Mike Carl, Peter Poorman, Tom White
+Cray Research, Inc.:  Rick Matthews
+Data General Corp.:  Dean Herington
+Digital Equipment Corp.:  Fred Glover, Ray Lanza, Peter Smith
+Fujitsu:  Chris Seabrook
+HAL Computer Systems, Inc.:  Prashant Dholakia, Howard Gayle,
+     David H. Yamada
+Hewlett-Packard Co.:  Larry Dwyer, Hal Prince
+IBM Corp.:  Bill Baker, Mark Brown
+MacNeal-Schwendler Corp.:  David Lombard
+NCR:  Kevin Brasche, Shawn Shealy
+NEC Systems Laboratory, Inc.:  Jeff Forys
+Novell:  Bill Cox, John Kiger, Seth Rosenthal
+NOVON Research Inc.:  Brian Boyle
+Oracle:  Mark Johnson
+Programmed Logic Corp.:  Tim Williams, Steve Rago
+Pyramid Technology Corporation:  Ralph Campbell, Henry Robinson
+SAS Institute Inc.:  Mark Cates, Leigh Ihnen, Tom Truscott,
+     Kelly Wyatt
+Sequent Computer Systems:  Gerrit Huizenga, Mike Spitzer
+Siemens Nixdorf Inc.:  Ralf Nolting, Klaus Thon
+Silicon Graphics:  Steve Cobb, Adam Sweeney
+Stratus Computer Inc.:  Tony Luck
+Sun Microsystems, Inc.:  Steve Chessin
+SunSoft Inc.:  Karen Barnes, Don Cragun, Karl Danz, Andy Roach,
+     Glenn Skinner, Peter Van der Linden,
+     Srinivasan Viswanathan
+Sybase Inc.:  Marc Sugiyama
+Syncsort Inc.:   Asokan
+Tandem Computers:  David M. VomLehn
+The Santa Cruz Operation, Inc.:  John Farley, Kurt Gollhardt,
+     Art Herzog, Danielle Lahmani, Wen-Ling Lu, Dave Prosser
+Unisoft:  Guy Hadland
+Unisys Corp.:  Steve Beck, Bruce Jones, Scott Lurndal,
+     Jim Soddy
+UTG Inc.:  Michael Dortch, Mark Hatch, Larry Lytle
+Veritas:  Craig Harmer, Michael Schmitz
+
+Special thanks go to SAS Institute Inc., SunSoft, Silicon Graphics, and
+Convex Computer (now HP) for providing meeting rooms and logistics support.
+Hal Prince and Don Cragun provided technical guidance and kept us aware of
+the details. Mark Brown helped us understand how important it was to comply
+with existing standards. Bill Baker and Tom White worked hard typing early
+drafts and providing alternative ways to organize the document. Adam Sweeney
+and Howard Gayle kept us within reason. David VomLehn and Tom Truscott kept
+good notes and provided the minutes. Ray Lanza gave us rousing encouragement
+("Just make everything 64 bits!!"). Mark Johnson quipped excellent
+summaries. Kelly Wyatt did the final edits and provided an excellent sanity
+check during the endgame. And special thanks go to Mark Hatch (now with
+Integrated Computer Solutions, Inc.) who organized the first meetings and
+got this effort going.
+
+I really enjoyed participating and would like to express my gratitude to the
+members of the large file summit. In particular, I enjoyed participating
+with people who were so honestly motivated to make the right technical
+decisions. This was a great lesson in UNIX file system semantics and how the
+Open Systems Process works.
+
+There are a couple of interesting features of this specification. First, it
+contains a method of supporting an industry wide transition to full 64-bit
+APIs. Second, it specifies a set of changes to the Single UNIX Specification
+that will allow unlimited file offsets. The transition includes a way to add
+64-bit file indexing without breaking current compliance to standards, and
+allow software developers to migrate existing sources and binaries to
+systems that support 64-bit file indexing.
+
+This document is the result of a collaborative process that was open to all
+participants. The efforts of those who participated will best be rewarded by
+having this work accepted and used. I believe that this specification is an
+example of how well the industry can work together to solve problems that
+affect our ability to produce products that compete in the market.
+
+John Carl Zeigler, jcz@utg.org
+VP Technology, UTG Inc.
+Cary, NC
+----------------------------------------------------------------------------
+
+1.0 Overview
+
+1.1 The Large File Problem
+
+As UNIX systems have become increasingly powerful, a number of system
+vendors and UNIX independent software vendors have developed a requirement
+to access files that contain more information than can be addressed using a
+signed long integer. One possible solution could be to convert every program
+using files to a larger size for long integers, including the operating
+system. However, the work to do this is undesirable for many vendors. A
+number of major system vendors and users have been meeting at the "Large
+File Summit" (LFS) for over a year to develop a set of changes to the
+existing Single UNIX Specification (SUS) that allow both new and converted
+programs to address files of arbitrary sizes. This set of changes will be
+provided to X/Open for inclusion into the next version of the SUS. In
+addition, a set of transitional extensions intended to permit users to
+immediately implement large file support on typical 32-bit UNIX operating
+systems is proposed. Both the changes and transitional extensions and the
+rationale behind their definition is included in this document.
+
+1.2 Requirements
+
+The LFS has worked to develop a solution to the large file problem meeting
+the following requirements:
+
+Be implementable at a reasonable cost
+     Several of the LFS members are leading efforts to develop and implement
+     solutions. Results from their experiences have guided our decisions.
+Protect existing programs
+     This proposal allows for protection of existing programs. Many of the
+     solutions considered would have caused existing programs to fail
+     unexpectedly and silently. This proposal has been carefully crafted to
+     reduce this possibility.
+Provide access to files much larger than 2 gigabytes on 32-bit operating
+systems
+     This is the requirement that first motivated the LFS activity. The
+     proposed changes implement a solution that allows file size and related
+     sizes to be uncoupled from the size of the C language data types chosen
+     for an operating environment. As a result, systems conforming to the
+     proposed changes to the SUS can support files of arbitrary sizes.
+Be fully compliant to the SUS
+     Systems modified to support the proposed extensions can be configured
+     to strictly conform to the existing SUS. These same systems will
+     normally be configured to fully meet the proposed changes supporting
+     arbitrary file sizes and remain compliant to the SUS with extensions.
+     In addition, conforming systems can also support a transitional API
+     extension designed to substantially reduce the difficulty of conversion
+     to this proposed standard while remaining compliant to the existing
+     SUS. This transitional interface is contained in section 3.0
+     Transitional Extensions to the Single UNIX Specification.
+Provide an extension to the SUS
+     While the LFS would like to see this proposal included in the next
+     version of the SUS, this specification provides extensions that system
+     vendors and independent software vendors need to support this
+     functionality in their current compliant products.
+
+1.3 Importance
+
+As noted earlier, several vendors have already begun or completed
+implementation because of substantial market pressures. Independent software
+vendors are already writing software dependent on large file functionality.
+Rapid inclusion into the SUS is necessary to avoid repeating the existing
+situation where over 20 different implementations of asynchronous I/O are
+available on various UNIX systems. The LFS has chosen design alternatives to
+facilitate the needed rapid process of standardization. We believe the
+proposed changes will substantially enhance the value of the next revision
+of the SUS if they are included.
+
+1.4 Concepts
+
+The proposed changes are motivated by a consistent implementation of a few
+very basic technical concepts.
+
+Mixed sizes of off_t
+     During a period of transition from existing systems to systems able to
+     support an arbitrarily large file size, most systems will need to
+     support binaries with two or more sizes of the off_t data type (and
+     related data types). This mixed off_t environment may occur on a system
+     with an ABI that supports different sizes of off_t. It may occur on a
+     system which has both a 64-bit and a 32-bit ABI. Finally, it may occur
+     when using a distributed system where clients and servers have
+     differing sizes of off_t. In effect, the period of transition will not
+     end until we need 128-bit file sizes, requiring yet another transition!
+     The proposed changes may also be used as a model for the 64 to 128-bit
+     file size transition.
+Offset maximum
+     Most, but unfortunately not all, of the numeric values in the SUS are
+     protected by opaque type definitions. In theory this allows programs to
+     use these types rather than the underlying C language data types to
+     avoid issues like overflow. However, most existing code maps these
+     opaque data types like off_t to long integers that can overflow for the
+     values needed to represent the offsets possible in large files.
+
+     To protect existing binaries from arbitrarily large files, a new value
+     (offset maximum) will be part of the open file description. An offset
+     maximum is the largest offset that can be used as a file offset.
+     Operations attempting to go beyond the offset maximum will return an
+     error. The offset maximum is normally established as the size of the
+     off_t "extended signed integral type" used by the program creating the
+     file description.
+
+     The open() function and other interfaces establish the offset maximum
+     for a file description, returning an error if the file size is larger
+     than the offset maximum at the time of the call. Returning errors when
+     the offset maximum is (or is likely to be) exceeded protects existing
+     binaries effectively.
+EOVERFLOW
+     In a system with binaries compiled to support different sizes of off_t,
+     operations such as read() or write() can attempt to reach parts of a
+     large file beyond the range of an off_t or other limit. The existing
+     SUS does not define an error for this case. EOVERFLOW is an existing
+     error type that must be added to a number of system interfaces to
+     communicate the new error condition to applications.
+Development models
+     In addition to supporting environments requiring mixed sizes of off_t,
+     the LFS also considered the development model. To maintain older
+     programs that have not been converted to support arbitrary file sizes,
+     it is necessary to specify the size of off_t and related data types.
+     Two compilation models and the means to control them are specified in
+     section 3.3 Accessing the Extensions to the SUS. A new set of
+     transitional extensions will probably be needed when the next jump to
+     larger file sizes occurs. The changes specified for the SUS, however,
+     are size neutral.
+     Selectable off_t
+          In this model, the size of off_t is specified at compile time, and
+          the appropriate set of libraries, headers and data types is chosen
+          during the compilation and linking process. All existing binaries
+          default to an off_t the size of a long integer.
+     Explicit off_t
+          In this model, the size of off_t is specified during application
+          design. The system interface specified explicitly uses an off_t of
+          a particular length. On a 32-bit system, for example, use of
+          open() implies an off_t of 32 bits and use of open64() implies an
+          off64_t of 64 bits. While the model is very useful for supporting
+          incremental conversions and writing system software, it is not
+          directly supported in the SUS. A proposed set of transitional
+          extensions is described in section 3.0 Transitional Extensions to
+          the Single UNIX Specification. These transitional interfaces
+          support only the 32-bit to 64-bit file offset transition.
+
+1.5 Changes and Additions
+
+The requirements and concepts defined above have been consistently and
+completely applied to the SUS to generate the changes and additions
+specified in sections 2.0 Changes to the Single UNIX Specification and 3.0
+Transitional Extensions to the Single UNIX Specification. The changes are
+classified as:
+
+Changes to System Interface Definitions
+     The terms extended signed integral type, extended unsigned integral
+     type, offset maximum and saved resource limits have been defined.
+Changes to System Interfaces and Headers
+     EOVERFLOW, EFBIG and EINVAL are added or updated wherever needed.
+
+     The open() and fcntl() functions have been changed to support the
+     offset maximum.
+
+     The fseeko() and ftello() functions have been added because the
+     existing fseek() and ftell() do not use the required opaque types.
+
+     Data types, declarations and symbolic constants were added to or
+     changed in headers.
+Changes to Commands and Utilities
+     Utilities needed to establish a minimally complete system that can
+     support large files which require conversion are defined. A complete
+     conversion is both expensive and unnecessary for effective use of large
+     files.
+Transitional Extensions
+     The proposed transitional extensions including interfaces, macros and
+     data types have been defined.
+
+1.6 Conformance
+
+A conforming implementation will supply all the interfaces that are
+specified in 2.0 Changes to the Single UNIX Specification (except that
+implementations need not provide the asynchronous I/O interfaces:
+aio_read(), aio_write(), and lio_listio()) and will define _LFS_LARGEFILE to
+be 1 (see 3.1.2.12 <unistd.h>).
+
+A conforming implementation that provides asynchronous I/O interfaces and
+the extensions to them specified in 2.0 Changes to the Single UNIX
+Specification will define _LFS_ASYNCHRONOUS_IO to be 1 (see 3.1.2.12
+<unistd.h>).
+
+A conforming implementation that provides the explicit 64-bit interfaces
+will provide at least those interfaces specified in 3.1.1.1.3 Other
+Interfaces, 3.1.1.2 fcntl(), 3.1.1.3 open(), and 3.1.2 Transitional
+Extensions to Headers (except that changes specified in 3.1.2.2 <aio.h> and
+3.1.2.6 <stdio.h> need not be supported) and will define _LFS64_LARGEFILE to
+be 1 (see 3.1.2.12 <unistd.h>).
+
+A conforming implementation that defines _LFS64_LARGEFILE to be 1 and
+provides the explicit 64-bit interfaces for asynchronous I/O specified in
+3.1.1.1.1 Asynchronous I/O Interfaces will define _LFS64_ASYNCHRONOUS_IO to
+be 1 (see 3.1.2.12 <unistd.h>).
+
+A conforming implementation that defines _LFS64_LARGEFILE to be 1 and
+provides the explicit 64-bit STDIO interfaces specified in 3.1.1.1.2 STDIO
+Interfaces and 3.1.2.6 <stdio.h> will define _LFS64_STDIO to be 1 (see
+3.1.2.12 <unistd.h>).
+
+2.0 Changes to the Single UNIX Specification
+
+2.1 Changes to CAE Specification System Interface Definitions, Issue 4,
+Version 2
+
+The following definitions will be added to System Interface Definitions,
+Chapter 2, Glossary:
+
+extended signed integral type
+     a signed integral type or an implementation-specific type with similar
+     properties.
+extended unsigned integral type
+     an unsigned integral type or an implementation-specific type with
+     similar properties.
+offset maximum
+     an attribute of an open file description representing the largest value
+     that can be used as a file offset.
+saved resource limits
+     an attribute of a process that provides some flexibility in the
+     handling of unrepresentable resource limits, as described in the exec
+     family of functions and setrlimit().
+
+     (Note the attribute "resource limits" as used in the SUS is not
+     defined.)
+
+2.2 Changes to CAE Specification System Interfaces and Headers, Issue 4,
+Version 2
+
+2.2.1 Changes to System Interfaces
+
+The following changes will be made to System Interfaces and Headers, Chapter
+3, System Interfaces. The Asynchronous I/O interfaces (aio_read(),
+aio_write() and lio_listio()) should be included when POSIX.1b is added in a
+future revision to the SUS.
+
+2.2.1.1 aio_read()
+
+DESCRIPTION
+
+     For regular files, no data transfer will occur past the offset
+     maximum established in the open file description associated with
+     aiocbp->aio_fildes.
+
+ERRORS
+
+     The following is an additional condition which may be detected
+     synchronously or asynchronously:
+
+     [EOVERFLOW]
+          The file is a regular file, aiocbp->aio_nbytes is greater
+          than 0 and the starting offset in aiocbp->aio_offset is
+          before the end-of-file and is at or beyond the offset maximum
+          in the open file description associated with
+          aiocbp->aio_fildes.
+
+     Note: This is a new error condition.
+
+2.2.1.2 aio_write()
+
+DESCRIPTION
+
+     For regular files, no data transfer will occur past the offset
+     maximum established in the open file description associated with
+     aiocbp->aio_fildes.
+
+ERRORS
+
+     The following is an additional condition which may be detected
+     synchronously or asynchronously:
+
+     [EFBIG]
+          The file is a regular file, aiocbp->aio_nbytes is greater
+          than 0 and the starting offset in aiocbp->aio_offset is at or
+          beyond the offset maximum in the open file description
+          associated with aiocbp->aio_fildes.
+
+     Note: This is an additional EFBIG error condition.
+
+2.2.1.3 exec
+
+DESCRIPTION
+
+     The saved resource limits in the new process image are set to be a
+     copy of the process's corresponding hard and soft resource limits.
+
+2.2.1.4 fclose(), fflush(), fputwc(), fputws(), fseek(), putwc(), putwchar()
+
+ERRORS
+
+     These functions will fail if:
+
+     [EFBIG]
+          The file is a regular file and an attempt was made to write
+          at or beyond the offset maximum associated with the
+          corresponding stream.
+
+     Note: This is an additional EFBIG error condition.
+
+2.2.1.5 fcntl()
+
+DESCRIPTION
+
+     An unlock (F_UNLCK) request in which l_len is non-zero and the
+     offset of the last byte of the requested segment is the maximum
+     value for an object of type off_t, when the process has an
+     existing lock in which l_len is 0 and which includes the last byte
+     of the requested segment, will be treated as a request to unlock
+     from the start of the requested segment with an l_len equal to 0.
+     Otherwise an unlock (F_UNLCK) request will attempt to unlock only
+     the requested segment.
+
+ERRORS
+
+     The fcntl() function will fail if:
+
+     [EOVERFLOW]
+          One of the values to be returned cannot be represented
+          correctly.
+     [EOVERFLOW]
+          The cmd argument is F_GETLK, F_SETLK or F_SETLKW and the
+          smallest or, if l_len is non-zero, the largest, offset of any
+          byte in the requested segment cannot be represented correctly
+          in an object of type off_t.
+
+     Note: These are new error conditions.
+
+2.2.1.6 fdopen()
+
+DESCRIPTION
+
+     The fdopen() function will preserve the offset maximum previously
+     set for the open file description corresponding to fildes.
+
+2.2.1.7 fgetc(), fgets(), fgetwc(), fgetws(), fread(), fscanf(), getc(),
+getchar(), gets(), getw(), getwc(), getwchar(), scanf()
+
+ERRORS
+
+     These functions will fail if data needs to be read and:
+
+     [EOVERFLOW]
+          The file is a regular file and an attempt was made to read at
+          or beyond the offset maximum associated with the
+          corresponding stream.
+
+     Note: This is a new error condition.
+
+2.2.1.8 fgetpos()
+
+ERRORS
+
+     The fgetpos() function will fail if:
+
+     [EOVERFLOW]
+          The current value of the file position cannot be represented
+          correctly in an object of type fpos_t.
+
+     Note: This is a new error condition.
+
+2.2.1.9 fopen(), freopen(), tmpfile()
+
+DESCRIPTION
+
+     The largest value that can be represented correctly in an object
+     of type off_t will be established as the offset maximum in the
+     open file description.
+
+ERRORS
+
+     The fopen() and freopen() functions will fail if:
+
+     [EOVERFLOW]
+          The named file is a regular file and the size of the file
+          cannot be represented correctly in an object of type off_t.
+
+     Note: This is a new error condition.
+
+2.2.1.10 fpathconf() and pathconf()
+
+DESCRIPTION
+
+  Variable          Value of name          Notes
+  FILESIZEBITS      _PC_FILESIZEBITS       3,4
+
+2.2.1.11 fprintf(), fputc(), fputs(), fwrite(), printf(), putc(), putchar(),
+puts(), putw(), vfprintf(), vprintf()
+
+ERRORS
+
+     These functions will fail if either the stream is unbuffered or
+     the stream's buffer needed to be flushed and:
+
+     [EFBIG]
+          The file is a regular file and an attempt was made to write
+          at or beyond the offset maximum.
+
+     Note: This is an additional EFBIG error condition.
+
+2.2.1.12 fseek()
+
+ERRORS
+
+     The fseek() function will fail if:
+
+     [EOVERFLOW]
+          The resulting file offset would be a value which cannot be
+          represented correctly in an object of type long.
+
+     Note: This is a new error condition.
+
+2.2.1.13 fseeko()
+
+DESCRIPTION
+
+     The fseeko() function is identical to the modified fseek() except
+     that the offset argument is of type off_t and the EOVERFLOW error
+     is changed as follows:
+
+ERRORS
+
+     [EOVERFLOW]
+          The resulting file offset would be a value which cannot be
+          represented correctly in an object of type off_t.
+
+     Note: This is a new function.
+
+2.2.1.14 fstat(), lstat() and stat()
+
+ERRORS
+
+     These functions will fail if:
+
+     [EOVERFLOW]
+          The file size in bytes or the number of blocks allocated to
+          the file or the file serial number cannot be represented
+          correctly in the structure pointed to by buf.
+
+     Note: This is an additional EOVERFLOW error condition.
+
+2.2.1.15 fstatvfs() and statvfs()
+
+ERRORS
+
+     These functions will fail if:
+
+     [EOVERFLOW]
+          One of the values to be returned cannot be represented
+          correctly in the structure pointed to by buf.
+
+     Note: This is a new error condition.
+
+2.2.1.16 ftell()
+
+ERRORS
+
+     The ftell() function will fail if:
+
+     [EOVERFLOW]
+          The current file offset cannot be represented correctly in an
+          object of type long.
+
+     Note: This is a new error condition.
+
+2.2.1.17 ftello()
+
+DESCRIPTION
+
+     The ftello() function is identical to the modified ftell() except
+     that the return value is of type off_t and the EOVERFLOW error is
+     changed as follows:
+
+ERRORS
+
+     [EOVERFLOW]
+          The current file offset cannot be represented correctly in an
+          object of type off_t.
+
+     Note: This is a new function.
+
+2.2.1.18 ftruncate()
+
+ERRORS
+
+     The ftruncate() function will fail if:
+
+     [EFBIG]
+          The file is a regular file and length is greater than the
+          offset maximum established in the open file description
+          associated with fildes.
+
+     Note: This is an additional EFBIG error condition.
+
+2.2.1.19 getrlimit() and setrlimit()
+
+DESCRIPTION
+
+     When using the getrlimit() function, if a resource limit can be
+     represented correctly in an object of type rlim_t then its
+     representation is returned; otherwise if the value of the resource
+     limit is equal to that of the corresponding saved hard limit the
+     value returned is RLIM_SAVED_MAX; otherwise the value returned is
+     RLIM_SAVED_CUR.
+
+     When using the setrlimit() function, if the requested new limit is
+     RLIM_INFINITY the new limit will be "no limit"; otherwise if the
+     requested new limit is RLIM_SAVED_MAX the new limit will be the
+     corresponding saved hard limit; otherwise if the requested new
+     limit is RLIM_SAVED_CUR the new limit will be the corresponding
+     saved soft limit; otherwise the new limit will be the requested
+     value. In addition, if the corresponding saved limit can be
+     represented correctly in an object of type rlim_t then it will be
+     overwritten with the new limit.
+
+     The result of setting a limit to RLIM_SAVED_MAX or RLIM_SAVED_CUR
+     is unspecified unless a previous call to getrlimit() returned that
+     value as the soft or hard limit for the corresponding resource
+     limit.
+
+     The determination of whether a limit can be correctly represented
+     in an object of type rlim_t is implementation-dependent. For
+     example, some implementations permit a limit whose value is
+     greater than RLIM_INFINITY and others do not.
+
+     The exec family of functions also cause resource limits to be
+     saved. (See 2.2.1.3 exec).
+
+2.2.1.20 lio_listio()
+
+DESCRIPTION
+
+     For regular files, no data transfer will occur past the offset
+     maximum established in the open file description associated with
+     aiocbp->aio_fildes.
+
+ERRORS
+
+     The following are additional error codes which may be set for each
+     aiocb control block:
+
+     [EOVERFLOW]
+          The aiocbp->aio_lio_opcode is LIO_READ, the file is a regular
+          file, aiocbp->aio_nbytes is greater than 0, and the
+          aiocbp->aio_offset is before the end-of-file and is greater
+          than or equal to the offset maximum in the open file
+          description associated with aiocbp->aio_fildes.
+     [EFBIG]
+          The aiocbp->aio_lio_opcode is LIO_WRITE, the file is a
+          regular file, aiocbp->aio_nbytes is greater than 0, and the
+          aiocbp->aio_offset is greater than or equal to the offset
+          maximum in the open file description associated with
+          aiocbp->aio_fildes.
+
+     Note: These are additional EFBIG and EOVERFLOW error conditions.
+
+2.2.1.21 lockf()
+
+DESCRIPTION
+
+     An F_ULOCK request in which size is non-zero and the offset of the
+     last byte of the requested section is the maximum value for an
+     object of type off_t, when the process has an existing lock in
+     which size is 0 and which includes the last byte of the requested
+     section, will be treated as a request to unlock from the start of
+     the requested section with a size equal to 0. Otherwise an F_ULOCK
+     request will attempt to unlock only the requested section.
+
+ERRORS
+
+     The lockf() function will fail if:
+
+     [EINVAL]
+          The function argument is not one of F_LOCK, F_TLOCK, F_TEST
+          or F_ULOCK; or size plus the current file offset is less than
+          0.
+     [EOVERFLOW]
+          The offset of the first, or if size is not 0 then the last,
+          byte in the requested section cannot be represented correctly
+          in an object of type off_t.
+
+     Note: This is a clarification of the EINVAL error condition.
+     Note: EOVERFLOW is a new error condition.
+
+2.2.1.22 lseek()
+
+ERRORS
+
+     The lseek() function will fail if:
+
+     [EOVERFLOW]
+          The resulting file offset would be a value which cannot be
+          represented correctly in an object of type off_t.
+
+     Note: This is a new error condition.
+
+2.2.1.23 mmap()
+
+ERRORS
+
+     The mmap() function will fail if:
+
+     [EOVERFLOW]
+          The file is a regular file and the value of off plus len
+          exceeds the offset maximum established in the open file
+          description associated with fildes.
+
+     Note: This is a new error condition.
+
+2.2.1.24 open()
+
+DESCRIPTION
+
+     The largest value that can be represented correctly in an object
+     of type off_t will be established as the offset maximum in the
+     open file description.
+
+ERRORS
+
+     The open() function will fail if:
+
+     [EOVERFLOW]
+          The named file is a regular file and the size of the file
+          cannot be represented correctly in an object of type off_t.
+
+     Note: This is a new error condition.
+
+2.2.1.25 read() and readv()
+
+DESCRIPTION
+
+     For regular files, no data transfer will occur past the offset
+     maximum established in the open file description associated with
+     fildes.
+
+ERRORS
+
+     The read() and readv() functions will fail if:
+
+     [EOVERFLOW]
+          The file is a regular file, nbyte is greater than 0, the
+          starting position is before the end-of-file and the starting
+          position is greater than or equal to the offset maximum
+          established in the open file description associated with
+          fildes.
+
+     Note: This is a new error condition.
+
+2.2.1.26 readdir()
+
+ERRORS
+
+     The readdir() function will fail if:
+
+     [EOVERFLOW]
+          One of the values in the structure to be returned cannot be
+          represented correctly.
+
+     Note: This is a new error condition.
+
+2.2.1.27 write() and writev()
+
+DESCRIPTION
+
+     For regular files, no data transfer will occur past the offset
+     maximum established in the open file description associated with
+     fildes.
+
+ERRORS
+
+     These functions will fail if:
+
+     [EFBIG]
+          The file is a regular file, nbyte is greater than 0 and the
+          starting position is greater than or equal to the offset
+          maximum established in the open file description associated
+          with fildes.
+
+     Note: This is an additional EFBIG error condition.
+
+2.2.2 Changes to Headers
+
+The following changes will be made to System Interfaces and Headers, Chapter
+4, Headers.
+
+2.2.2.1 <limits.h>
+
+The following symbolic constant is defined as a Pathname Variable Value:
+
+Name             Description                Acceptable Value
+FILESIZEBITS     Minimum number of bits             *
+                 needed to represent,
+                 as a signed integer
+                 value, the maximum size
+                 of a regular file
+                 allowed in the
+                 specified directory.
+
+2.2.2.2 <stdio.h>
+
+The following are declared as functions and may also be defined as macros:
+
+int         fseeko(FILE *stream, off_t offset, int whence);
+off_t       ftello(FILE *stream);
+
+The type off_t is defined through typedef as described in <sys/types.h>.
+
+2.2.2.3 <sys/resource.h>
+
+The following symbolic constants are defined:
+
+RLIM_SAVED_MAX     A value of type rlim_t indicating an
+                   unrepresentable saved hard limit.
+RLIM_SAVED_CUR     A value of type rlim_t indicating an
+                   unrepresentable saved soft limit.
+
+On implementations where all resource limits are representable in an object
+of type rlim_t, RLIM_SAVED_MAX and RLIM_SAVED_CUR need not be distinct from
+RLIM_INFINITY.
+
+2.2.2.4 <sys/stat.h>
+
+The type of st_blocks in the stat structure will be changed to:
+
+blkcnt_t    st_blocks   number of blocks allocated for this
+                        object.
+
+2.2.2.5 <sys/statvfs.h>
+
+The types of the fields below in the statvfs structure will be changed to:
+
+fsblkcnt_t  f_blocks    total number of blocks in the file
+                        system in units of f_frsize.
+fsblkcnt_t  f_bfree     total number of free blocks.
+fsblkcnt_t  f_bavail    number of free blocks available to
+                        non-privileged process.
+fsfilcnt_t  f_files     total number of file serial numbers.
+fsfilcnt_t  f_ffree     total number of free file serial
+                        numbers.
+fsfilcnt_t  f_favail    number of free file serial numbers
+                        available to non-privileged process.
+
+2.2.2.6 <sys/types.h>
+
+The following data types will be defined:
+
+blkcnt_t                Used for file block counts.
+fsblkcnt_t              Used for file system block counts.
+fsfilcnt_t              Used for file system file counts.
+
+The types blkcnt_t and off_t are defined as extended signed integral types.
+
+The types fsblkcnt_t, fsfilcnt_t, and ino_t are defined as extended unsigned
+integral types.
+
+2.2.2.7 <unistd.h>
+
+The following symbolic constant is defined for pathconf():
+
+     _PC_FILESIZEBITS
+
+2.3 Changes to CAE Specification Commands and Utilities, Issue 4, Version 2
+
+The following changes will be made to Commands and Utilities, Chapter 3,
+Utilities.
+
+2.3.1 Considerations for Utilities in Support of Files of Arbitrary Size
+
+Note: This is a new section and should be added to Commands and Utilities,
+Issue 4, Version 2, Chapter 3 after section 1.2.1, Symbolic Links.
+
+The following utilities will support files of any size up to the maximum
+that can be created by the implementation. This support includes correct
+writing of file size related values (such as file sizes and offsets, line
+numbers, and block counts) and correct interpretation of command line
+arguments that contain such values.
+
+basename   return non-directory portion of pathname
+cat        concatenate and print files
+cd         change working directory
+chgrp      change file group ownership
+chmod      change file modes
+chown      change file ownership
+cksum      write file checksums and sizes
+cmp        compare two files
+cp         copy files
+dd         convert and copy a file
+df         report free disk space
+dirname    return directory portion of pathname
+du         estimate file space usage
+find       find files
+ln         link files
+ls         list directory contents
+mkdir      make directories
+mv         move files
+pathchk    check pathnames
+pwd        return working directory name
+rm         remove directory entries
+rmdir      remove directories
+sh         shell, the standard command language interpreter
+sum        print checksum and block or byte count of a file
+test       evaluate expression
+touch      change file access and modification times
+ulimit     set or report file size limit
+
+Exceptions to the requirement that utilities support files of any size up to
+the maximum are:
+
+  1. Utilities such as tar and cpio cannot support arbitrary file sizes due
+     to limitations imposed by fixed file formats.
+  2. Uses of files as command scripts, or for configuration or control, are
+     exempt. For example, it is not required that sh be able to read an
+     arbitrarily large ".profile".
+  3. Shell input and output redirection are exempt. For example, it is not
+     required that the redirections sum < file or echo foo > file succeed
+     for an arbitrarily large existing file.
+
+2.3.2 The sh Utility
+
+DESCRIPTION:
+
+     Pathname expansion will not fail due to the size of a file.
+
+     Shell input and output redirections will have an
+     implementation-specific offset maximum that will be established in
+     the open file description.
+
+2.3.3 The pax Utility
+
+APPLICATION USAGE
+
+     The pax utility is not able to handle arbitrary file sizes. There
+     is currently a proposal in ballot in IEEE Project 1003.2b to
+     address this issue.
+
+3.0 Transitional Extensions to the Single UNIX Specification
+
+The interfaces, macros and data types in this section are explicitly 64-bit
+instances of the corresponding SUS and POSIX.1b interfaces, macros and data
+types. The function prototype and semantics of a transitional interface will
+be equivalent to those of the SUS version of the call. Version test macros
+announcing extensions to the SUS are also defined.
+
+The transitional extensions in this section are intended to be temporary.
+While an application using this specification may be using non-POSIX
+conforming transitional extensions to operating system functions, this does
+not require that system vendors break their POSIX compliance. This
+specification is intended to be compatible with the standards. The
+transitional extensions are provided so that system vendors may define a
+common set of large file capable extensions to their current compliant
+systems without violating that compliance.
+
+3.1 Transitional Extensions to CAE Specification System Interfaces and
+Headers, Issue 4, Version 2
+
+3.1.1 Transitional Extensions to System Interfaces
+
+3.1.1.1 64-bit Versions of Interfaces
+
+The following interfaces are explicitly 64-bit versions of the corresponding
+Single UNIX Specification and POSIX.1b interfaces. There is no functional
+difference between these and the corresponding Single UNIX Specification and
+POSIX.1b interfaces.
+
+3.1.1.1.1 Asynchronous I/O Interfaces
+
+aio_cancel64()         aio_error64()
+aio_fsync64()          aio_read64()
+aio_return64()         aio_suspend64()
+aio_write64()          lio_listio64()
+
+3.1.1.1.2 STDIO Interfaces
+
+fgetpos64()            fopen64()
+freopen64()            fseeko64()
+fsetpos64()            ftello64()
+tmpfile64()
+
+3.1.1.1.3 Other Interfaces
+
+creat64()             fstat64()
+fstatvfs64()          ftruncate64()
+ftw64()               getrlimit64()
+lockf64()             lseek64()
+lstat64()             mmap64()
+nftw64()              open64()
+readdir64()           setrlimit64()
+stat64()              statvfs64()
+truncate64()
+
+3.1.1.2 fcntl()
+
+DESCRIPTION
+
+     The following additional value may be used in constructing oflag:
+
+     O_LARGEFILE
+          If set, the offset maximum in the open file description will
+          be the largest value that can be represented correctly in an
+          object of type off64_t.
+
+     The behavior of the following additional values is equivalent to
+     the corresponding Single UNIX Specification value (FGETLK, FSETLK,
+     FSETLKW), but they take a struct flock64 argument rather than a
+     struct flock argument.
+
+     FGETLK64
+     FSETLK64
+     FSETLKW64
+
+3.1.1.3 open()
+
+DESCRIPTION
+
+     The following additional value may be used in constructing oflag:
+
+     O_LARGEFILE
+          If set, the offset maximum in the open file description will
+          be the largest value that can be represented correctly in an
+          object of type off64_t.
+
+ERRORS
+
+     The open() function will fail if:
+
+     [EOVERFLOW]
+          The named file is a regular file and either O_LARGEFILE is
+          not set and the size of the file cannot be represented
+          correctly in an object of type off_t or O_LARGEFILE is set
+          and the size of the file cannot be represented correctly in
+          an object of type off64_t.
+
+APPLICATION USAGE
+
+     Note that using open64() is equivalent to using open() with
+     O_LARGEFILE set in oflag.
+
+Note: For the transitional extensions these changes to open() are in place
+of the changes described in 2.2.1.24 open() relating to the changes to the
+SUS.
+
+3.1.2 Transitional Extensions to Headers
+
+The modifications to the headers in this section are necessary to implement
+the transitional extensions as described in 3.0 Transitional Extensions to
+the Single UNIX Specification.
+
+3.1.2.1 64-bit Versions of Headers
+
+In summary, the changes to the headers involve the following data types,
+structures and symbolic constants:
+
+3.1.2.1.1 Data Types
+
+blkcnt_t               fsblkcnt_t
+fsfilcnt_t             fpos_t
+ino_t                  off_t
+rlim_t
+
+3.1.2.1.2 Structures
+
+struct dirent          struct flock
+struct rlimit          struct stat
+struct statvfs
+
+3.1.2.1.3 Symbolic Constants
+
+F_GETLK                F_SETLK
+F_SETLKW               RLIM_INFINITY
+RLIM_SAVED_MAX         RLIM_SAVED_CUR
+
+3.1.2.2 <aio.h>
+
+The aiocb64 structure is defined in the same way as the aiocb structure in
+the POSIX.1b with the exception of the following member:
+
+off64_t        aio_offset
+
+The following are declared as functions and may be defined as macros.
+
+int     aio_read64(struct aiocb64 *aiocbp);
+int     aio_write64(struct aiocb64 *aiocbp);
+int     lio_listio64(int mode, struct aiocb64 *const list[],
+            int nent, struct sigevent *sig);
+int     aio_error64(const struct aiocb64 *aiocbp);
+ssize_t aio_return64(struct aiocb64 *aiocbp);
+int     aio_cancel64(int fildes, struct aiocb64 *aiocbp);
+int     aio_suspend64(const struct aiocb64 *const list[],
+            int nent, const struct timespec *timeout);
+int     aio_fsync64(int op, struct aiocb64 *aiocbp);
+
+3.1.2.3 <dirent.h>
+
+The dirent64 structure is defined in the same way as the dirent structure in
+the Single UNIX Specification with the exception of the following member:
+
+ino64_t       d_ino     file serial number.
+
+The following is declared as a function and may also be defined as a macro:
+
+struct dirent64 *readdir64(DIR *dirp);
+
+3.1.2.4 <fcntl.h>
+
+The flock64 structure is defined in the same way as the flock structure in
+the Single UNIX Specification with the exception of the following members:
+
+off64_t       l_start relative offset in bytes.
+off64_t       l_len   size.
+
+Additional values for cmd used by fcntl():
+
+F_GETLK64     Get record locking information using struct
+              flock64.
+F_SETLK64     Establish a record lock using struct flock64.
+F_SETLKW64    Establish a record lock, blocking, using struct
+              flock64.
+
+An additional file status flag, used by open() and fcntl(), is defined:
+
+O_LARGEFILE     The offset maximum in the open file description
+                is the largest value that can be represented
+                correctly in an object of type off64_t.
+
+The following are declared as functions and may also be defined as macros:
+
+int     creat64(const char *path, mode_t mode);
+int     open64(const char *path, int oflag, ...);
+
+3.1.2.5 <ftw.h>
+
+The following are declared as functions and may also be defined as macros:
+
+int ftw64(const char *path,
+    int (*fn)(const char *, const struct stat64 *, int),
+    int ndirs);
+int nftw64(const char *path,
+    int (*fn)(const char *, const struct stat64 *, int,
+               struct FTW *),
+    int depth, int flags);
+
+3.1.2.6 <stdio.h>
+
+The following data type is defined through typedef:
+
+fpos64_t  Type containing all information needed to specify
+          uniquely every position within a file in which the
+          largest offset can be represented in an object of type
+          off64_t.
+
+The following are declared as functions and may also be defined as macros:
+
+int       fgetpos64(FILE *stream, fpos64_t *pos);
+FILE     *fopen64(const char *filename, const char *mode);
+FILE     *freopen64(const char *filename, const char *mode,
+               FILE *stream);
+int       fseeko64(FILE *stream, off64_t offset, int whence);
+int       fsetpos64(FILE *stream, const fpos64_t *pos);
+off64_t   ftello64(FILE *stream);
+FILE     *tmpfile64(void);
+
+3.1.2.7 <sys/mman.h>
+
+The following is declared as a function and may also be defined as a macro:
+
+void     *mmap64(void *addr, size_t len, int prot, int flags,
+                int fd, off64_t offset);
+
+3.1.2.8 <sys/resource.h>
+
+The following data type is defined through typedef:
+
+rlim64_t    type used for limit values.
+
+The type rlim64_t must be an extended unsigned arithmetic type that can
+represent correctly any non-negative value of an off64_t.
+
+The following symbolic constants are defined:
+
+RLIM64_INFINITY    A value of type rlim64_t indicating no limit.
+RLIM64_SAVED_MAX   A value of type rlim64_t indicating an
+                   unrepresentable saved hard limit.
+RLIM64_SAVED_CUR   A value of type rlim64_t indicating an
+                   unrepresentable saved soft limit.
+
+On implementations where all resource limits are representable in an object
+of type rlim64_t, RLIM64_SAVED_MAX and RLIM64_SAVED_CUR need not be distinct
+from RLIM64_INFINITY.
+
+The rlimit64 structure is defined in the same way as the rlimit structure in
+the Single UNIX Specification with the exception of the following members:
+
+rlim64_t  rlim_cur      the current (soft) limit.
+rlim64_t  rlim_max      the hard limit.
+
+The following are declared as functions and may also be defined as macros:
+
+int       getrlimit64(int resource, struct rlimit64 *rlp);
+int       setrlimit64(int resource, const struct rlimit64 *rlp);
+
+3.1.2.9 <sys/stat.h>
+
+The stat64 structure is defined in the same way as the stat structure in the
+Single UNIX Specification with the exception of the following members:
+
+ino64_t     st_ino      file serial number.
+off64_t     st_size     file size in bytes.
+blkcnt64_t  st_blocks   number of blocks allocated for this
+                        object.
+
+The following are declared as functions and may also be defined as macros:
+
+int         fstat64(int fildes, struct stat64 *buf);
+int         lstat64(const char *, struct stat64 *buf);
+int         stat64(const char *, struct stat64 *buf);
+
+3.1.2.10 <sys/statvfs.h>
+
+The statvfs64 structure is defined in the same way as the statvfs structure
+in the Single UNIX Specification with the exception of the following
+members:
+
+fsblkcnt64_t  f_blocks  total number of blocks in the file
+                        system in units of f_frsize.
+fsblkcnt64_t  f_bfree   total number of free blocks.
+fsblkcnt64_t  f_bavail  number of free blocks available to
+                        non-privileged process.
+fsfilcnt64_t  f_files   total number of file serial numbers.
+fsfilcnt64_t  f_ffree   total number of free file serial
+                        numbers.
+fsfilcnt64_t  f_favail  number of free file serial numbers
+                        available to non-privileged process.
+
+The following are declared as functions and may also be defined as macros:
+
+int         statvfs64(const char *path, struct statvfs64 *buf);
+int         fstatvfs64(int fildes, struct statvfs64 *buf);
+
+3.1.2.11 <sys/types.h>
+
+The following data types are defined through typedef:
+
+blkcnt64_t      Used for file block counts.
+fsblkcnt64_t    Used for file system block counts.
+fsfilcnt64_t    Used for file system file counts.
+ino64_t         Used for file serial numbers.
+off64_t         Used for file sizes.
+
+The types blkcnt64_t and off64_t are defined as extended signed integral
+types.
+
+The types fsblkcnt64_t, fsfilcnt64_t, and ino64_t are defined as extended
+unsigned integral types.
+
+3.1.2.12 <unistd.h>
+
+The following are declared as functions and may also be defined as macros:
+
+int         lockf64(int fildes, int function, off64_t size);
+off64_t     lseek64(int fildes, off64_t offset, int whence);
+int         ftruncate64(int fildes, off64_t length);
+int         truncate64(const char *path, off64_t length);
+
+Version Test Macros:
+_LFS_LARGEFILE   is defined to be 1 if the implementation
+                 supports the interfaces as specified in
+                 2.2.1 Changes to System Interfaces
+                 except that implementations need not provide
+                 the asynchronous I/O interfaces: aio_read(),
+                 aio_write(), and lio_listio().
+_LFS_ASYNCHRONOUS_IO
+                 is defined to be 1 if the implementation
+                 supports the asynchronous IO interfaces:
+                 aio_read(), aio_write(), and lio_listio() as
+                 specified in 2.2.1 Changes to
+                 System Interfaces.
+_LFS64_ASYNCHRONOUS_IO
+                 is defined to be 1 if the implementation
+                 supports all the transitional extensions
+                 listed in 3.1.1.1.1 Asynchronous I/O Interfaces
+                 and 3.1.2.2 <aio.h>.
+_LFS64_LARGEFILE is defined to be 1 if the implementation
+                 supports all the transitional extensions
+                 listed in 3.1.1.1.3 Other Interfaces,
+                 3.1.1.2 fcntl(), 3.1.1.3 open() and
+                 3.1.2 Transitional Extensions to Headers,
+                 except changes specified in 3.1.2.2 <aio.h>
+                 and 3.1.2.6 <stdio.h> need not be supported.
+_LFS64_STDIO     is defined to be 1 if the implementation
+                 supports all the transitional extensions
+                 listed in 3.1.1.1.2 STDIO Interfaces
+                 and 3.1.2.6 <stdio.h>.
+
+                 If _LFS64_STDIO is not defined to be 1 and the
+                 underlying file description associated with
+                 stream has O_LARGEFILE set then the behavior
+                 of the Standard I/O functions is unspecified.
+
+Constants for Functions:
+    _CS_LFS_CFLAGS       for confstr().
+    _CS_LFS_LDFLAGS      for confstr().
+    _CS_LFS_LIBS         for confstr().
+    _CS_LFS_LINTFLAGS    for confstr().
+
+    _CS_LFS64_CFLAGS     for confstr().
+    _CS_LFS64_LDFLAGS    for confstr().
+    _CS_LFS64_LIBS       for confstr().
+    _CS_LFS64_LINTFLAGS  for confstr().
+
+3.2 Transitional Extensions to the mount Utility
+
+3.2.1 Optional Additional Option for the mount utility
+
+If the -o nolargefiles option is specified and is supported by the file
+system, then for the duration of the mount it is guaranteed that all regular
+files in the file system have a file size that will fit in the smallest
+object of type off_t supported by the system performing the mount. The mount
+will fail if there are any files in the file system not meeting this
+criterion.
+
+If -o largefiles is specified then there is no such guarantee.
+
+The default behavior is implementation-dependent.
+
+3.3 Accessing the Extensions to the SUS
+
+3.3.1 Compilation Environment - Visibility of Additions to the API
+
+Applications which define the macro _LARGEFILE_SOURCE to be 1 before
+inclusion of any header will enable at least the functionality described in
+2.0 Changes to the Single UNIX Specification on implementations that support
+these features. Implementations that support these features will define
+_LFS_LARGEFILE to be 1 in <unistd.h>, as described in 3.1.2.12 <unistd.h>.
+
+3.3.2 Compilation Environment - Visibility of Transitional API
+
+Applications which define the macro _LARGEFILE64_SOURCE to be 1 before
+inclusion of any header will enable at least the fseeko(), ftello()
+extensions to the SUS (see 2.2.1.13 fseeko(), 2.2.1.17 ftello() and 2.2.2.2
+<stdio.h>) and the transitional extensions described in 3.1 Transitional
+Extensions to CAE Specification System Interfaces and Headers, Issue 4,
+Version 2 on implementations that support these features. Implementations
+that support these features will define _LFS64_LARGEFILE,
+_LFS64_ASYNCHRONOUS_IO and _LFS64_STDIO to be 1 in <unistd.h>, as described
+in 3.1.2.12 <unistd.h>.
+
+3.3.3 Mixed API and Compile Environments Within a Single Process
+
+It is permitted to use both the Single UNIX Specification and the
+transitional APIs within the same executable, including within the same
+source file, and to use both on the same file descriptor whether in the same
+process or in different processes (when an open file descriptor is passed or
+inherited).
+
+3.3.4 Utilities: Optional Method for Specifying the Size of an off_t
+
+For programs to take advantage of different environments, it is necessary to
+compile them for each particular environment. For programs to make use of
+the features described in this section they must be compiled with new
+compiler and linker options. The getconf utility called with the new
+arguments can be used to generate compiler and linker options.
+
+Example 1:
+
+An example of compiling a program with a "large" off_t and that uses
+fseeko() and ftello() and uses yacc:
+
+   c89 -D_LARGEFILE_SOURCE     -o foo      \
+        $(getconf LFS_CFLAGS)  y.tab.c b.o \
+        $(getconf LFS_LDFLAGS)             \
+        -ly $(getconf LFS_LIBS)
+
+Example 2:
+
+An example of compiling a program with a "large" off_t and that does not use
+fseeko() and ftello() and has no application specific libraries:
+
+   c89  $(getconf LFS_CFLAGS)  a.c         \
+        $(getconf LFS_LDFLAGS)             \
+        $(getconf LFS_LIBS)
+
+Example 3:
+
+An example of compiling a program with a "default" off_t and that uses
+fseeko() and ftello():
+
+   c89 -D_LARGEFILE_SOURCE     a.c
+
+Example 4:
+
+An example of compiling a program using transitional versions of SUS
+interfaces such as lseek64() and fopen64():
+
+   c89  -D_LARGEFILE64_SOURCE              \
+        $(getconf LFS64_CFLAGS)  a.c       \
+        $(getconf LFS64_LDFLAGS)           \
+        $(getconf LFS64_LIBS)
+
+Example 5:
+
+An example of running lint on a program with a "large" off_t:
+
+   lint -D_LARGEFILE_SOURCE                \
+        $(getconf LFS_LINTFLAGS) ...       \
+        $(getconf LFS_LIBS)
+
+Example 6: An example of running lint on a program using the transitional
+API:
+
+   lint -D_LARGEFILE64_SOURCE              \
+        $(getconf LFS64_LINTFLAGS) ...     \
+        $(getconf LFS64_LIBS)
+
+These examples show the need for the additional variables LFS_CFLAGS,
+LFS_LDFLAGS, LFS_LIBS, LFS_LINTFLAGS, LFS64_CFLAGS, LFS64_LDFLAGS,
+LFS64_LIBS and LFS64_LINTFLAGS to be reported by getconf.
+
+Implementations may permit the linking of object files that are compiled
+with differing off_t environments. For example, an object module compiled
+with a 32-bit off_t can be linked with an object module compiled with a
+64-bit off_t. In such a case, both 32-bit off_t and 64-bit off_t API calls
+may be used on the same file descriptor. Implementations may instead
+disallow this linking.
+
+Appendix A: Rationale and Notes
+
+In a mixed environment the size of an off_t (and other types) might differ
+from program to program, and in a transitional environment (see 3.0
+Transitional Extensions to the Single UNIX Specification) it might differ
+even from routine to routine within a single program. Each specific use of
+an off_t has an invariant size that is determined by the compilation
+environment. This is referred to below as the size which is "in use".
+
+A.1 Overview
+
+A.1.1 Guiding Principles
+
+A.1.1.1 "No Lies" Rule
+
+An error will be returned whenever a function cannot return the correct
+result of an operation.
+
+Returning a "lie" to allow for common uses of a function (e.g. use of stat()
+to determine if a file exists) could inadvertently cause a correctly written
+application to operate incorrectly.
+
+It is conceivable that returning a "lie" could keep an incorrectly written
+application from malfunctioning in a way that creates a serious problem, but
+no such applications are known to exist. (Of course it would be easy to
+contrive one.)
+
+PASC Interpretation reference 1003.1-90 #38 completed by the POSIX.1
+interpretations committee confirms that POSIX.1 conforming implementations
+are not allowed to lie to applications. This interpretation explicitly
+states that if the file size will not fit in an object of type off_t,
+fstat() must fail. In addition, PASC Interpretation reference 1003.1-90 #75
+went on to clarify that EOVERFLOW would be a legal extension to report this
+condition.
+
+A.1.1.2 "Open Protection" Rule
+
+An open() will fail if the size of the (regular) file cannot be represented
+correctly in an object of type off_t.
+
+The size of file on which a program is able to operate is determined by the
+off_t in use for the open(). The open protection rule ensures that old
+binaries do not operate on files that are too large to handle correctly, and
+prevents the binaries from generating incorrect results or corrupting the
+data in the file.
+
+An argument against open protection is that requiring opens to fail will
+break some binaries that would have worked perfectly well otherwise. For
+example, a cat program does a loop of open(), read()/write() pairs, and
+close() for each input file. This program would unnecessarily break due to
+open protection. But this "Let it Run" argument is flawed in that there is
+no known utility which fails due to open protection but would work
+"perfectly well" if only we "let it run". Real versions of the cat program
+use fstat() to determine whether the input and output files are the same,
+have a -n option (count newlines) which will fail on sufficiently large
+files and so on.
+
+Another argument against open protection is that it is unnecessary because
+an error will be returned as soon as a function cannot return the correct
+result of an operation ("No Lies" rule). However, most programs check for
+the success of the open() call, but many do not check for overflow or error
+after lseek() and other calls. An audit of the standard utilities uncovered
+numerous examples.
+
+An argument for open protection is that it increases the likelihood of an
+immediate and informative error message. The error message is likely to
+include the name of the file that could not be opened. It is much less
+likely that an lseek() error message will be as immediate or as informative.
+The delay in, or complete lack of, reporting such errors may result in
+"silent failure".
+
+Another argument for open protection is that there are numerous plausible
+scenarios in which this rule avoids serious harm. It prevents typical
+implementations of the touch utility from truncating large files to 0 length
+(see A.2.1.1.4 creat()). It can prevent silent failure, which has been
+demonstrated to occur in at least one commercial data management system.
+With open protection a commercial backup/restore system will report errors
+on files that might otherwise result in a corrupted backup tape. It prevents
+typical implementations of dbm/ndbm from returning incorrect results from a
+database whose size exceeds the off_t in use for the dbm routines.
+
+A.1.1.3 "Read/Write Limit" Rule
+
+For regular files, no data transfer will occur past the offset maximum
+established in the open file description.
+
+There are two separate issues for this rule, which are that there is an
+application-dependent limit on read() and write(), and that the limit is
+"the offset maximum established in the open file description". The second
+issue is deferred to A.1.2.1 Offset Maximum. The first issue, that there be
+an application-dependent limit, is considered here.
+
+There are two assertions upon which many applications rely:
+
+  1. A file can be read until end-of-file and written until the file system
+     is full or some other implementation limit is reached.
+  2. The current file offset can be stored correctly in an object of type
+     off_t, and any file position that can be reached with read() and write
+     can also be reached with lseek().
+
+In a mixed off_t environment these assertions are true only for the largest
+supported size of off_t. An audit of typical applications revealed that most
+check return codes from read() and write() in order to guard against
+end-of-file, full file systems, and the like, but that most do not check for
+overflow of file offsets or errors returned by lseek(). This suggests that
+it is more important to maintain the truth of the second assertion. In order
+to maintain the second assertion, read() and write() must not be permitted
+to move the file offset past the largest offset representable by the
+application's off_t.
+
+The write limit avoids the unintuitive situation in which a program could
+create a file too large for it to open (due to open protection). This could
+result in a serious problem. "Can you imagine the reaction of someone who
+has 1.9G of data, and all of a sudden, the DBMS can no longer open the file?
+I wouldn't want to be working in tech support that day."
+
+An argument for the write limit is that it keeps a program from creating a
+file too large for it to handle properly. An argument for the read limit is
+that it is a simple way to cover the hole where a file grows after it is
+opened.
+
+An argument for the read/write limit rule is that generating an error at
+this limit provides the earliest possible warning of an incompatibility
+problem that could result in lost or corrupted data if the application was
+to continue.
+
+An argument against the read/write limit rule is that it results in
+unnecessary breakage of binaries that would have worked perfectly well
+otherwise. This is the "Let it Run" argument, but as noted earlier few if
+any such programs exist.
+
+Another argument against the read/write limit rule is that implementing it
+is expensive and complex. But it has already been implemented and found not
+to be either expensive or complex (an analysis appears in A.1.2.1 Offset
+Maximum).
+
+Another argument against the read/write limit rule is that it can result in
+a truncated log file record (hence corrupting the log file). But this
+truncation and corruption can also occur due to insufficient disk space or
+RLIMIT_FSIZE, and indeed the standards require that this occur.
+
+Another argument against the read/write limit rule is that instead one can
+use the existing file size resource limit (RLIMIT_FSIZE). But this is not a
+useful defense in a mixed off_t environment because it unnecessarily
+restricts the size of files created by programs which support a larger
+off_t. The practical effect will be that use of RLIMIT_FSIZE in this way
+will inconvenience users and they will unlimit themselves and then there
+will be no write limit. So this is a false, although attractive, argument.
+
+Another argument against the read/write limit rule is that instead there can
+be a mount option which limits the maximum size of a file created in the
+file system. But regardless of other merits for such an option, it does not
+provide a useful defense in a mixed off_t environment because it
+unnecessarily restricts the size of files created by programs which support
+a larger off_t. The practical effect will be that the system administrator
+will be pressured into remounting the file system with no limit and then
+there will be no write limit. So this is another false, although attractive,
+argument.
+
+A.1.1.4 Holes in the Protection Mechanism
+
+The following holes in the protection mechanism are discussed in other
+sections of this document:
+
+   * While a "small" application has a file open another "large" application
+     can extend the file (see A.1.2.1 Offset Maximum).
+   * The fcntl() function may inadvertently clear O_LARGEFILE (see A.3.1.1.1
+     fcntl()).
+   * The lseek() failure may result in corruption of log file or database
+     (see A.2.1.1.6 fgetpos(), fseek(), ftell(), lseek()).
+   * An open file description with a "large" offset maximum may be inherited
+     by a "small" application (see A.1.2.2 Inheritance).
+
+A.1.2 Concepts
+
+A.1.2.1 Offset Maximum
+
+The offset maximum is used to implement the read/write limit (see A.1.1.3
+"Read/Write Limit" Rule). It is basically a hack to avoid the need to
+provide transitional versions of read()/write() and the numerous routines
+which call them (getchar(), putchar(), printf(), etc.). For consistency it
+also affects the semantics of ftruncate() and mmap().
+
+The offset maximum is an unusual part of this specification as it is
+associated with the file description whereas in all other cases the limit is
+determined by the size of the type that is used for the call. But
+determining the latter for read/write would be extremely difficult in an
+environment in which a single process contains calls with differing sizes of
+off_t in use (this environment is not part of this section of the
+specification, but it is part of the transitional specification). In such an
+environment it would be necessary to determine the size of off_t for every
+function that might result in a read() or write(). That would include
+putchar(), fwrite(), fputs(), fprintf(), puts(), etc. The number of the
+routines that might potentially do a read() or write() is too large for such
+an implementation to be practical.
+
+It is possible that while a "small" application has a file open another
+application with a larger off_t can extend the file beyond the size of the
+small application's off_t. This leads to a situation where the small
+application has a file descriptor which refers to a file too large for it to
+be able to process correctly. That is, open protection has been lost. The
+application will still have some protection due to "No Lies" and the
+"Read/Write Limit", but these are less effective protections. It is believed
+that this case is sufficiently unlikely that it may be safely ignored.
+
+As an added protection, it has been suggested that all file calls should
+fail whenever the size of the file cannot be represented correctly in an
+object of type off_t. This would defend against the file growth scenario
+described above. But checking file size on each read/write might hurt
+performance in some cases and also it was not considered an important
+defense. It would also have the putchar(), fwrite(), etc. implementation
+problem.
+
+It has been suggested that a file should not be permitted to be extended
+beyond the size of the smallest offset maximum in any open file description
+that refers to the file. It is believed that this is an unnecessary
+complication, cannot be enforced for some distributed file systems and
+applies only to a situation that it is believed may be safely ignored.
+
+The value of the offset maximum in an open file description will not affect
+the semantics of operations related to other open file descriptions or of
+operations which create new open file descriptions, including other open
+file descriptions which refer to the same file.
+
+An argument against offset maximum is that it is expensive and complex. But
+that is not the case. The only implementation that will matter for years is
+for 64-bit off_t which
+
+   * can be implemented as a open file flag (O_LARGEFILE -- see 3.1.2.4
+     <fcntl.h>).
+   * will require about 5 lines in headers (e.g. <sys/fcntl.h>).
+   * will require about 0 lines to set it during a 64-bit open().
+   * will require about 5 lines of code to check and enforce it in each of
+     the kernel implementations of read() and write().
+   * will require about 2 lines of code to display it in each of the
+     programs which display file flags (e.g. pstat utility).
+
+Documentation would add a dozen or so lines of text, but this part of the
+specification does not require such documentation.
+
+A.1.2.1.1 Offset Maximum and the 2G-1 File Size Limit
+
+On implementations where type off_t is a 32-bit two's complement integer,
+the maximum value that can be correctly represented in an object of type
+off_t is 2^31-1 (2G-1). Because of this, the maximum file size and maximum
+file offset of a small file are 2G-1, but the maximum offset of any byte
+contained in a small file is 2G-2. An illustration of the offsets (0, 1,
+...) of a file, with the bytes (b, B and L) shown as small boxes and the
+offset shown as "^" is:
+
+        <- "small" -> | <- "large" >-
+    ----------   -----------------------
+    | b | b | ::: | b | B | L | L | L | :::
+    ^---^---^-   -^---^---^---^---^---^-
+    0   1   2     2G  2G  2G
+                  -2  -1
+
+Although an lseek() can be done to the 2G-1 offset, a read() or write()
+cannot be performed at that position because when B (counting number 2G, but
+offset 2G-1) is read or written, the resulting pointer to the next offset
+address and the file size itself would overflow.
+
+A.1.2.2 Inheritance
+
+The offset maximum will be inherited via fork(), the exec family of
+functions, dup(), and fcntl() called with F_DUPFD, and its value will not be
+altered by them. The value of the offset maximum will not affect any
+semantics related to inheritance.
+
+An application can inherit, via the exec family of functions, a file
+descriptor that is associated with a file whose size exceeds the largest
+value that can be represented correctly by the off_t that is in use by the
+application. An example is if a shell that was compiled with a 64-bit off_t
+does input or output redirection of a 10 gigabyte file and then executes a
+program which was compiled with a 32-bit off_t. In such a case the large
+file unaware application will function until attempting an operation from
+which the results cannot be correctly returned.
+
+Most inherited files are due to shell redirection, the other cases are rare
+and typically under the complete control of a single application provider.
+The cases that are of primary concern are:
+
+     old_binary < large_file
+
+and
+
+     old_binary > large_file
+
+In these cases a pre-existing application binary, old_binary, is given a
+file descriptor to a file that it would not have been able to open for
+itself and would be able to read and write past the limit that would have
+been established by the open(). The concern is that the application will do
+something destructive or generate incorrect results since it is not
+expecting a file to be so large.
+
+In comparison, consider the following cases:
+
+     a.out | old_binary
+
+and
+
+     old_binary | a.out
+
+There is no limit to the amount of data that may be passed through a pipe.
+In the first case the application named a.out may push more data through the
+pipe than can be contained in a small file. In the second case a.out may be
+willing to read more data than can be contained in a small file. If a
+pre-existing application binary has problems with inherited file descriptors
+that refer to large files then it is likely to have a pre-existing problem
+when using a pipe for large amounts of data. While it is true that the two
+sets of cases are not completely equivalent, the above examples show that
+pre-existing binaries have had the potential to see data streams larger than
+the amount of data that can be contained in a small file.
+
+Another reason it is believed that the inheritance of file descriptors does
+not cause problems is that the majority of existing applications do not
+perform seek operations on standard input or standard output.
+
+A.1.2.3 Non-Requirements
+
+Open protection and the read/write limit apply only to regular files, and
+are not specified to apply to block or character special files such as raw
+disk partitions.
+
+A.1.2.4 Non-Changes
+
+The following are to clarify, not to change, existing practice: Different
+files may have different maximum permitted sizes even when they are on the
+same system, or are on the same type of file system, or are on the same file
+system. The maximum permitted file sizes are independent of the offset
+maximum. The maximum permitted file sizes do not have specified minimum or
+maximum values. Attempts to grow a file via write(), writev(), or truncate()
+may fail even when statvfs() reports that space is available.
+
+A.1.2.5 NFS Quality of Implementation Issue
+
+NFS does not fall within the confines of this specification since there are
+no relevant NFS interfaces. However, here are some suggestions for NFS
+implementations.
+
+The NFS version 2 protocol is effectively a 32-bit application since it
+cannot handle file sizes larger than 2^31-1 bytes. Any attempt by an NFS V2
+client to access a large file (read(), write(), stat(), etc.) should be
+rejected by the server since the server knows the file is large and knows
+the application (NFS V2) is not "large file aware". This test is trivial and
+requires no more performance penalty than the tests for any other file
+system type.
+
+The NFS version 3 protocol is "large file aware" since it can handle file
+sizes up to 2^63-1 bytes. An NFS V3 server would handle all requests without
+change, even if the request involves a large file. It is up to the NFS V3
+client code to determine if the application accessing a file is "large file
+aware" or not. This should be handled in the standard fashion in the OS on
+the client side machine using the attributes returned by the NFS operation
+or the cached file attributes. While this does not provide perfect
+protection or immediate detection of files that have grown beyond 2^31-1
+bytes since being opened, it is no more broken than the rest of NFS. (See
+below for more discussion of cached file attributes).
+
+This does not address the issue of NFS V3 clients that are not prepared to
+handle "large files". If they are carefully written and obey the NFS V3
+protocol they should realize that files can be larger than 2^31-1 bytes and
+handle this condition appropriately, probably by failing the operation (they
+would know this when a stat(), read(), write(), etc. operation returned a
+file size larger than 2^31). However, there are probably NFS V3 clients that
+are not carefully written. We really can't do much about that.
+
+Cached Attributes: with the NFS V3 protocol, clients are not required to
+cache the file attributes, and servers are not required to return the file
+attributes with each operation. If the file attributes are returned with
+each operation, it is easy to determine if the file has grown past the large
+file limit. If not, the cached attributes can be consulted.
+
+If the client does not cache attributes, then it will either have to request
+the attributes from the server over the wire (adversely affecting
+performance) or assume the file has not grown in size since it was opened.
+This specification pretty much requires the client code to check the file
+size at open.
+
+Because of the stateless nature of NFS, it is difficult to ensure that a
+large-file unaware application cannot operate on a file that has grown from
+small to large. This is for the same reasons that NFS cannot implement
+standard UNIX file semantics. However, it is easy to ensure that a
+large-file unaware application does not grow a small file to become large
+(since the offset and length of each write are determined at the client, the
+client can fail any operation where the offset plus length exceeds the small
+file limit). It is also easy to insure that a large-file unaware application
+does not read past the small file limit.
+
+A.2 Changes to the Single UNIX Specification
+
+A.2.1 Changes to CAE Specification System Interfaces and Headers, Issue 4,
+Version 2
+
+A.2.1.1 Changes to System Interfaces
+
+A.2.1.1.1 Notes on Functions not Modified by this Proposal
+
+The following functions do not require modification to meet the terms of
+this proposal:
+
+aio_error(), aio_cancel(), aio_return() and aio_suspend()
+     No large file implications were identified for these functions.
+aio_fsync()
+     It is possible that an aio_fsync() could try to write out file blocks
+     that are beyond the offset maximum, just as fsync() could. There is no
+     compelling reason for either to fail. Clearly, the original write
+     request had to be within the offset maximum for the file description
+     used. The aio_fsync() function will not enforce the offset maximum on
+     the blocks which it writes out.
+glob() and wordexp()
+     The subroutines that expand file name wild cards need to be large file
+     capable.
+
+A.2.1.1.2 aio_read()
+
+The aio_read() function enforces the offset maximum rules for consistency
+with read() and readv().
+
+A.2.1.1.3 aio_write()
+
+The aio_write() function enforces the offset maximum rules for consistency
+with write() and writev().
+
+A.2.1.1.4 creat()
+
+The creat() function will fail if the named file is a regular file and the
+size of the file cannot be represented correctly in an object of type off_t
+(see 2.2.1.24 open()). This offers protection from the following coding
+style:
+
+     if (stat(path, ...) < 0) {
+         /* assume file does not exist, so create it */
+         if ((fd = creat(path, ...)) < 0) {
+            /* print out error text */
+         }
+     }
+
+In this example the stat() function is being used to determine the existence
+of a file. But if the file size cannot be represented correctly in an object
+of type off_t then stat() will fail (see 2.2.1.14 fstat(), lstat() and
+stat()) and if creat() did not then fail it would have the unintended effect
+of truncating the file to 0 length. Many applications and standard utilities
+have code similar to this example, including typical implementations of the
+touch utility.
+
+A.2.1.1.5 fcntl() and lockf()
+
+Unlock requests are sometimes "rounded to infinity" so that a process can
+create a whole-file lock and then successfully issue a request to clip off
+the beginning of the lock without leaving behind an unrepresentable lock.
+This is to avoid breaking any existing 32-bit applications which might
+happen to do this.
+
+Several existing implementations of fcntl() permit locking the byte whose
+offset is the maximum value that can be represented correctly in a object of
+type off_t, even though write() cannot write to that offset. This
+specification permits that behavior.
+
+The fcntl() function will fail if the cmd argument is F_GETLK and the first
+lock which blocks the lock description has a starting offset or length which
+cannot be represented correctly in an object of type off_t. Information
+about such a lock cannot be correctly returned.
+
+Discussion of the semantics of fcntl() locks that cross the off_t boundary
+resulted in six competing proposals:
+
+  1. An unlock request fails if it would create an unrepresentable lock.
+  2. If any lock request includes the byte whose offset is the maximum value
+     that fits in an off_t, then the request is equivalent to a request
+     where l_len is 0 and l_start refers to the first byte of the affected
+     area.
+  3. (proposal was dropped)
+  4. If l_len is 0 then the lock is through and including the maximum value
+     of off_t (and not beyond).
+  5. Just no lies.
+  6. If an unlock request includes the byte whose offset is the maximum
+     value that fits in an off_t, and there is an existing lock with l_len
+     equal to 0 which also includes that byte, then the request is
+     equivalent to a request where l_len is 0 and l_start refers to the
+     first byte of the affected area.
+
+An advantage of 2, 4, and 6 is that they do not change existing behavior of
+a 32-bit application.
+
+Proposals 1 and 5 can result in a new type of failure in the case where the
+program creates a lock with l_len equal to 0 and then clips off the
+beginning leaving behind an unrepresentable lock.
+
+Proposal 4 precludes truly "whole file" locking.
+
+Proposal 6 was adopted because as it preserves existing 32-bit behavior and
+is less disruptive than proposal 2 (which extends lock requests in addition
+to unlock requests).
+
+The fcntl() and lockf() functions will fail if the offset of the first byte
+in the region, or if l_len (size) is non-zero then the offset of last byte
+in the region, exceeds the largest possible value in an object of type
+off_t. Otherwise the process could create a lock which would be "beyond" the
+ability of the program to represent.
+
+A.2.1.1.6 fgetpos(), fseek(), ftell(), lseek()
+
+These functions will fail if the resulting file offset would exceed the
+largest value that can be represented correctly in the related type which is
+in use for the call, and will set errno to EOVERFLOW (permitted by PASC
+Interpretation 1003.1-90 #75).
+
+Programs typically, but incorrectly, fail to check the return value of these
+functions, which renders the error return less useful. On the other hand,
+returning an incorrect offset can result in serious malfunction as well.
+
+An lseek() to the end of a file using
+
+     lseek(fd, 0, SEEK_END);
+
+is quite common. It is unfortunate that these fail on a too-large file since
+the return value is usually ignored. One alternative that was considered was
+for lseek() to move the file offset for all valid requests and then return
+an error if the resulting offset is too large. That is, the call would
+succeed for applications that do not check the return code, but also fail
+for applications that do check. This option was deemed too bizarre to adopt.
+For example, it might be difficult to implement using a remote procedure
+call system that was constructed to return either results or an error, but
+not both. In addition, the POSIX 1003.1 standard requires the file offset to
+remain unchanged if an error is returned by lseek(). It was felt that the
+open protection (see A.1.1.2 "Open Protection" Rule) and the read/write
+limit (see A.1.1.3 "Read/Write Limit" Rule) are more effective defenses
+against this problem.
+
+Another potentially serious consequence of ignoring the return value of
+lseek() is that programs which extend data files by attempting to seek
+beyond the end-of-file and then writing may instead overwrite existing data.
+
+For example, typical implementations of the dbm and ndbm libraries contain
+code such as:
+
+     (void) lseek(db->dbm_pagf, blkno*PBLKSIZ, L_SET);
+     if (write(db->dbm_pagf, pagebuf, PBLKSIZ) != PBLKSIZ)
+                ... error handling ...
+
+The problem is that the return code of lseek() is not checked and so if
+"blkno*PBLKSIZ" overflows the lseek() will fail (or will seek to an
+unintended offset) and the data will be written to an unintended offset.
+
+A.2.1.1.7 fpathconf() and pathconf()
+
+The reference "See Note 3,4" refers to notes in the X/Open specification for
+fpathconf() and pathconf(). These notes indicate that this option
+(_PC_FILESIZEBITS) is valid only for a directory, and the results are for
+files that exist or may be created in that directory.
+
+The _PC_FILESIZEBITS option makes it possible for a process to determine how
+large a file can be created in a given directory. It takes into account
+implementation limitations in the file system (e.g. due to the size of file
+size and block count variables), and it takes into account long term policy
+limitations (e.g. due to the mount utility's -o nolargefiles option). It
+does not take into account dynamic restrictions such as the RLIM_FSIZE
+resource limit or the number of available file blocks, so the process must
+perform appropriate checks.
+
+When the current directory is on a typical large file capable file system
+and is mounted with the -o nolargefiles option,
+
+     pathconf(".", _PC_FILESIZEBITS);
+
+will return 32. In general, if the maximum size file that could ever exist
+on the mounted file system is maxsize then the returned value is 2 plus the
+floor of the base 2 logarithm of maxsize.
+
+A.2.1.1.8 fseeko() and ftello()
+
+These functions are needed because fseek() and ftell() are limited by the
+long offset type required by ISO C. The fsetpos() and fgetpos() functions,
+although they do use an opaque offset type, are not complete replacements
+for fseek() and ftell() because they do not allow relative seeks or
+arithmetic on fpos_t values.
+
+A.2.1.1.9 fsetpos()
+
+Since fsetpos() sets an absolute file position, which is always legal
+regardless of the implementation-supported sizes of off_t, there are no new
+error returns or other new semantics.
+
+A.2.1.1.10 fstatvfs() and statvfs()
+
+These functions will fail if the total, or free, or available number of
+blocks or files cannot be represented correctly in the structure to be
+returned (f_blocks, f_bfree, f_bavail, f_files, f_ffree, f_favail).
+
+A.2.1.1.11 ftruncate(), truncate(), unlink()
+
+These functions are used only on pre-existing files and so do not have the
+potential programming hazard as does creat() (see A.2.1.1.4 creat()).
+
+When ftruncate() is used to increase the size of a file, the semantics are
+similar to a write() of zeroes to the file. For consistency with write(),
+the ftruncate() function will fail when the request is beyond the offset
+maximum (even if the effect of the request would be to shorten the file).
+
+A.2.1.1.12 ftw() and nftw()
+
+The ftw() and nftw() functions may fail if a stat() in the underlying
+implementation fails with EOVERFLOW. This is unfortunate because "small"
+binaries using these functions cannot reasonably be used on file trees
+containing "large" files. Some systems have a non-standard extension to
+nftw() which permits it to continue when stat() fails (typical failures also
+include ESTALE and ELOOP).
+
+A.2.1.1.13 getrlimit() and setrlimit()
+
+These functions map limits that they cannot represent correctly to and from
+RLIM_SAVED_MAX and RLIM_SAVED_CUR. These values do not require any special
+handling by programs. They may be thought of as tokens that the kernel hands
+out to programs that can't handle the real answer, and that remind the
+kernel, when the tokens come back from the user, of what value is really
+meant.
+
+If setrlimit() fails for any reason (for example, EPERM), the resource
+limits and saved resource limits remain unchanged.
+
+This proposal does not specify any particular value for RLIM_INFINITY,
+RLIM_SAVED_MAX or RLIM_SAVED_CUR. Typical current implementations use the
+value 0x7FFFFFFF for RLIM_INFINITY, and it is recommended that
+RLIM_SAVED_MAX and RLIM_SAVED_CUR have similar large values.
+
+Few, if any, programs will need to refer explicitly to RLIM_SAVED_MAX or
+RLIM_SAVED_CUR. Those that do should not use them in C-language switch cases
+since they may have the same value in some implementations (see 2.2.2.3
+<sys/resource.h>).
+
+A limit that can be represented correctly in an object of type rlim_t is
+either "no limit", which is represented with RLIM_INFINITY, or has a value
+not equal to any of RLIM_INFINITY or RLIM_SAVED_MAX or RLIM_SAVED_CUR and
+which can be represented correctly in an object of type rlim_t and which
+meets any additional implementation-specific criteria for correct
+representation.
+
+A rejected alternative proposal was to map limits that could not be
+represented to and from RLIM_INFINITY. This would avoid the need for the new
+symbols RLIM_SAVED_MAX and RLIM_SAVED_CUR. But such mapping would arguably
+be a lie, and the resulting information loss would cause unintuitive program
+behavior, especially in programs running with appropriate privileges needed
+to raise hard limits.
+
+A rejected alternative proposal was that if getrlimit() could not correctly
+return a current limit then it should instead return -1 and set errno to
+EOVERFLOW. But that would result in unnecessary breakage of programs. (Note
+that this breakage occurs even when no large files are present.) It would
+also result in malfunction of programs that assume that they are calling
+getrlimit() properly and so failure "cannot happen". For example, in the 4.4
+BSD-Lite distribution, there are at least 15 unchecked calls to getrlimit().
+When the 4.4 BSD csh limit function is used to report the current limits,
+there is no check of the return code and so the reported results can be
+entirely incorrect. Also, non-superuser programs typically unlimit
+themselves with:
+
+     getrlimit(RLIMIT_STACK, &rl);
+     rl.rlim_cur = rl.rlim_max;
+     setrlimit(RLIMIT_STACK, &rl);
+
+If the getrlimit() fails then garbage is passed to setrlimit() which may
+result in an unwanted and extremely restricted limit. Several utilities that
+are part of the GNU C compiler have this problem.
+
+A.2.1.1.14 lio_listio()
+
+The lio_list() function enforces the offset maximum rules since they are
+logically equivalent to aio_read() and aio_write() which enforce it.
+
+A.2.1.1.15 mmap()
+
+For consistency with read() and write(), the mmap() function will fail when
+the request extends beyond the offset maximum.
+
+A.2.1.1.16 open()
+
+The open() function called with O_TRUNC set will fail without truncation if
+the named file is a regular file and the size of the file cannot be
+represented correctly in an object of type off_t. (See A.2.1.1.4 creat()).
+
+A.2.1.1.17 read(), readv(), write() and writev()
+
+These functions may do a "partial read or write" due to the offset maximum.
+That is, the value returned may be less than nbyte if the number of bytes
+remaining which may be transferred is less than nbyte.
+
+A.2.1.1.18 ulimit()
+
+The ulimit() function will return an unspecified result if the result cannot
+be represented correctly in an object of type long. As this function is
+already obsolescent, the use of getrlimit() and setrlimit() is recommended
+for getting and setting process limits.
+
+A.2.2 Changes to CAE Specification Commands and Utilities, Issue 4, Version
+2
+
+A.2.2.1 General Porting Suggestions
+
+When porting a program to be large file capable, general areas of concern in
+addition to the issues mentioned in A.1.1.4 Holes in the Protection
+Mechanism include:
+
+   * command line arguments
+   * API conversion
+   * type conversion
+   * output formatting
+   * fixed format media issues
+   * other languages
+
+A.2.2.1.1 Command Line Arguments
+
+Numeric arguments which are file size related, such as a file offset or
+block count, need to be handled as an appropriately large type. Converting
+arguments into an off_t that is larger than a long may need to be
+accomplished with non-standard scanf() formats, if available, or with
+portable user-written functions that convert ASCII to a large off_t
+analogous to the strtol() function.
+
+A.2.2.1.2 API Conversion
+
+The program should be recompiled in a large off_t environment or,
+alternatively, should be converted to use the transitional API. In either
+case the source must be scanned for the functions listed in 3.1.1.1 64-bit
+Versions of Interfaces and the data types listed in 3.1.2.1 64-bit Versions
+of Headers to ensure that all types are properly converted.
+
+A.2.2.1.3 Type Conversion
+
+Whenever a new 64-bit function is used, the argument types and function
+result will need to be converted as appropriate. Whenever a variable's type
+is converted (whether via the large off_t compilation environment or the
+transitional API), all uses of the variable must be checked to determine if
+further type conversions are warranted. For example, wherever there is a
+struct stat, all uses of st_size must be checked. If the st_size value is
+assigned or compared with a variable "v" the variable "v" must be converted
+if necessary and all uses of "v" must in turn be checked. This is also true
+of type conversions required for command line arguments.
+
+In addition, the program needs to be checked for file size related variables
+such as offsets, line numbers, and block counts that must be converted to a
+large off_t or related type. These variables typically appear inside loops
+that are performing input and/or output.
+
+A.2.2.1.4 Output Formatting
+
+Output of types that have been converted will probably involve using a
+different printf() format or using a revised user-written conversion
+routine. Since there is a larger range of values which take up more space,
+revision of the output layout may be required.
+
+A.2.2.1.5 Fixed Format Media Issues
+
+Current implementations of the tar and cpio utilities are defective in their
+support of arbitrarily large files. The pax utility is also equally
+defective, but is the subject of a proposal in ballot. (See 2.3.3 The pax
+Utility for discussion of this topic.)
+
+Vendor and third-party backup software is also unable to support large files
+and will require modification in order to do so.
+
+A.2.2.1.6 Other Languages
+
+This specification is for the C language only. Other languages have
+different support requirements. For example, the Fortran I/O API has a limit
+on the number of records, not bytes.
+
+A.2.2.2 Considerations for Utilities in Support of Files of Arbitrary Size
+
+The utilities listed in 2.3.1 Considerations for Utilities in Support of
+Files of Arbitrary Size are utilities which are used to perform
+administrative tasks such as to create, move, copy, remove, change the
+permissions, or measure the resources of a file. They are useful both as
+end-user tools and as utilities invoked by applications during software
+installation and operation.
+
+Typical core utilities must be compiled in a "large" off_t compilation
+environment or must use the transitional APIs. Using the compilation
+environment reduces the number of editing changes required to port a
+program, but it does not reduce the effort required to ensure the
+correctness of the port.
+
+The chgrp, chmod, chown, ln, and rm utilities probably require use of large
+file capable versions of stat(), lstat(), ftw(), and the stat structure.
+
+The cat, cksum, cmp, cp, dd, mv, sum, and touch utilities probably require
+use of large file capable versions of creat(), open(), and fopen().
+
+The cat, cksum, cmp, dd, df, du, ls, and sum utilities may require writing
+large integer values. For example,
+
+   * The cat utility might have a -n option which counts newlines.
+   * The cksum and ls utilities report file sizes.
+   * The cmp utility reports the line number at which the first difference
+     occurs, and also has a -l option which reports file offsets.
+   * The dd, df, du, ls, and sum utilities report block counts.
+
+The dd, find and test utilities may need to interpret command arguments that
+contain 64-bit values. For dd the arguments include skip=n, seek=n, and
+count=n. For find the arguments include -size n. For test the arguments are
+those associated with algebraic comparisons.
+
+The df utility might need to access large file systems with statvfs().
+
+The ulimit utility will need to use large file capable versions of
+getrlimit() and setrlimit() and be able to read and write large integer
+values.
+
+Conversion between off_t (or other derived types) and ASCII is unspecified,
+which is a significant practical deficiency. This is being considered by
+other groups. For example, see:
+ftp://ftp.dmk.com/DMK/sc22wg14/c9x/extended-integers/
+
+A.2.2.3 Additional Requirements for the sh Utility - Porting Recommendations
+
+Pathname expansion (e.g. expanding */foo.c to a/foo.c b/foo.c c/foo.c) and
+pathname completion might in some cases use the stat() function which would
+need to be large file capable.
+
+The offset maximum used for shell input and output redirections is
+implementation-specific. Some vendors prefer to use the smallest supported
+off_t, others prefer the largest.
+
+A.3 Transitional Extensions to the Single UNIX Specification
+
+A.3.1 Transitional Extensions to CAE Specification System Interfaces and
+Headers, Issue 4, Version 2
+
+Prior experience with transitional access is reported by SGI, Convex,
+(http://www.sas.com/standards/large.file/background) and Programmed Logic
+Corporation
+(http://www.sas.com/standards/large.file/proposals).
+
+A.3.1.1 Transitional Extensions to System Interfaces
+
+A.3.1.1.1 fcntl()
+
+The O_LARGEFILE flag may be set or cleared with F_SETFL. An incorrectly
+written program may inadvertently clear this flag. For example, some
+programs put a file into append mode with:
+
+      fcntl(fd, F_SETFL, O_APPEND);
+
+This is incorrect because it turns off all the other open flags, including
+O_LARGEFILE. Instead, to turn on append mode one should first use F_GETFL to
+get the current flags:
+
+     int oflag = fcntl(fd, F_GETFL, 0);
+
+then include O_APPEND in the flags:
+
+     oflag |= O_APPEND;
+
+and then set the new flags:
+
+     fcntl(fd, F_SETFL, oflag);
+
+A more complete example would also check for fcntl() failures.
+
+A.3.1.1.2 No fcntl64()
+
+A rejected alternative to extending fcntl() with F_GETLK64 (and so on) would
+be to specify fcntl64() with F_GETLK (and so on). The former has prior art
+and less functional redundancy, whereas the latter is more consistent with
+other transitional functions. This specification does not preclude vendors
+from supplying an fcntl64().
+
+A.3.1.2 Transitional Extensions to Headers
+
+A.3.1.2.1 <aio.h>
+
+The aio control block has an embedded offset which is of type off_t. A large
+file enabled aio control block needs a 64-bit offset. For consistency with
+the other transitional interfaces, a new control block with a 64-bit offset
+is defined. The offset is of the type off64_t.
+
+Since a new control block is needed, new interfaces are required for all of
+the existing aio interfaces since every one takes a pointer to the control
+block as an argument.
+
+A.3.1.2.2 <sys/resource.h>
+
+This proposal does not specify any particular value for RLIM64_INFINITY,
+RLIM64_SAVED_MAX or RLIM64_SAVED_CUR. Typical implementations should use the
+value 0x7FFFFFFFFFFFFFFF or 0xFFFFFFFFFFFFFFFF for RLIM_INFINITY, and it is
+recommended that RLIM64_SAVED_MAX and RLIM64_SAVED_CUR have similar large
+values. Even though all limit values will be represented in 64-bit types for
+a few years, specifying them as distinct values now will reduce
+compatibility problems in the future when the next transition to a still
+larger type occurs.
+
+A.3.1.2.3 <sys/types.h>
+
+It is not required that ino64_t be a 64-bit type. However, the NFS version 3
+protocol allows for 64-bit file serial numbers. For NFS interoperability
+with systems making use of 64-bit file serial numbers, 64-bit ino_t support
+is necessary. DCE also may make use of 64-bit file serial numbers.
+
+A.3.2 Accessing the Transitional Extensions to the SUS
+
+A.3.2.1 Compilation Environment - Visibility of Additions to the API
+
+Applications which use the fseeko() and ftello() interfaces should define
+_LARGEFILE_SOURCE to be 1, then include <unistd.h> and then test that
+_LFS_LARGEFILE is 1 to determine if the additional functionality is indeed
+available. This additional functionality may be available even when
+_LARGEFILE_SOURCE is not defined, but it will not be available to strictly
+conforming X/Open programs.
+
+This macro does not affect the size of off_t (see 3.3.3 Mixed API and
+Compile Environments Within a Single Process).
+
+A.3.2.2 Visibility of Transitional API
+
+Applications which wish to use this transitional functionality should define
+_LARGEFILE64_SOURCE to be 1, then include <unistd.h>, and then test that
+_LFS64_LARGEFILE, _LFS64_ASYNCHRONOUS_IO and _LFS64_STDIO are set to 1 to
+determine if the corresponding transitional functionality is indeed
+available. This transitional functionality may be available even when
+_LARGEFILE64_SOURCE is not defined, but it will not be available to strictly
+conforming X/Open programs.
+
+This macro does not affect the size of off_t (see 3.3.3 Utilities: Optional
+Method for Specifying the Size of an off_t).
+
+If _LARGEFILE64_SOURCE is defined then _LARGEFILE_SOURCE is implied so it
+need not also be defined (see 3.3.1 Compilation Environment - Visibility of
+Additions to the API). Similarly, if _LFS64_LARGEFILE is defined then
+_LFS_LARGEFILE will be defined so it need not also be tested.
+
+A.3.2.3 Mixed API and Compile Environments within a Single Process
+
+Mixing objects from differing compile environments can be dangerous, since
+some types have different sizes in the differing environments. The types
+might be used in a way where the size difference causes problems. A system
+may disallow this mixing. To avoid these problems, don't mix such objects in
+the same executable, or at least ensure that data shared between files
+compiled differently does not use any of the types whose meaning may change.
+
+Mixing the standard and transitional APIs is relatively safe, since data
+types have the same meaning in every file. This mixing permits a smoother
+and faster migration to a larger off_t environment, because it permits
+asynchronous upgrades. For example, it permits libraries to be made large
+file aware without requiring large file awareness in all the programs which
+use the library or in all the libraries which the library uses. (This is
+true both for static and for shared libraries.) This is particularly
+beneficial for situations in which the system vendor, one or more
+third-party suppliers, and the end user may all be supplying libraries or
+other objects that are components of a complete program.
+
+A.3.2.4 Utilities: Optional Method for Specifying the Size an off_t
+
+The LFS_CFLAGS variable is used to obtain implementation- specific compiler
+options, such as flags and preprocessor variable definitions, so that the
+compiled program will be using a "large" off_t. Similarly the LFS_LDFLAGS
+variable supplies link editor options, the LFS_LIBS variable supplies link
+library names, and the LFS_LINTFLAGS variable supplies lint options.
+
+If the size of off_t is controlled by a preprocessor macro variable then it
+is recommended that the macro be named _FILE_OFFSET_BITS and be supported as
+follows:
+
+   * If this symbol is not defined then an implementation-defined default
+     size will be used.
+   * Otherwise, if this symbol has a decimal value equal to the number of
+     bits in one of the implementation-supported sizes of off_t then that
+     size of off_t will be used.
+   * Otherwise, an error message will be written to the standard error and
+     compilation will terminate with a non-zero status.
+
+For POSIX compatibility this method must not be affected by the #undef
+preprocessor or directive. For example:
+
+     #undef lseek
+
+must not alter the size of type off_t in use for a call to lseek().
+
+The functions that might be affected by this option are listed in 3.1.1.1
+64-bit Versions of Interfaces.
+
+The types, structures and symbolic constants that might be affected by this
+option are listed in 3.1.2.1 64-bit Versions of Headers.
+
+It has been argued that there should be a new mode bit (or "magic number")
+on executable images to indicate whether or not the application is large
+file aware. This is not precluded by this specification. However, an
+argument against it is that it requires significant work. Specifically,
+kernel, compiler, loader, and library changes are needed. It is unclear how
+the mode bit would support a large file aware application that makes calls
+to a non-aware shared library.
+
+----------------------------------------------------------------------------
+
+Revision Information
+
+23Feb96 Version 1.1
+
+The 23Feb96 changes include:
+
+  1. Unix changed to UNIX throughout
+  2. Section 1.5 (Changes and Additions) second bullet (Changes to System
+     Interfaces and Headers) added EFBIG
+  3. Section 2.2.1 (Changes to System Interfaces) changed "as a future" to
+     "in a future".
+  4. Section 2.2.1.1 (aio_read), 2.2.1.1 (aio_write) and 2.2.1.20
+     (lio_listio) changed nbyte to aiocbp->aio_nbytes; added "is before the
+     end-of-file and" before "is at or beyond" in the EOVERFLOW error.
+  5. Section 2.2.1.1 (aio_read), 2.2.1.1 (aio_write) and 2.2.1.20
+     (lio_listio) changed "greater than or equal to" to "greater than".
+  6. Section 2.2.1.4 (fclose, etc.), 2.2.1.7 (fgetc, etc.) and 2.2.1.11
+     (fprintf, etc.) changed "write beyond" to "write at or beyond".
+  7. Section 2.2.1.20 (lio_listio) prefixed lio_opcode with aiocbp->;
+     changed order of phrases in EOVERFLOW and EFBIG (moved "the
+     aiocbp->aio_lio_opcode is LIO_READ" to the front of the sentences);
+     removed "before EOF" in the EOVERFLOW error condition; added "is before
+     the end-of-file and" before "is greater than or equal to the offset
+     maximum".
+  8. Section 2.2.2.6 (sys/types.h) and 3.1.2.11 (sys/types.h) changed "must
+     be" to "are defined as" in the sentences starting "The types..".
+  9. Section 3.1.1.1 (64-bit Versions of SUS Interfaces) changed title of
+     section to "64-bit Versions of Interfaces". Changed titles in
+     references to match.
+ 10. Section A.1.1.4.1 (fcntl) moved into A.3.1.1.1 (fcntl).
+ 11. Section A.1.1.4 (Holes in the Protection Mechanism) body added.
+ 12. Section A.1.2.1.1 (Offset Maximum and the 2G-1 File Size Limit)
+     boldfaced "B" in "byte line"; changed "a lseek" to "an lseek"; changed
+     "the resulting pointer to the next offset address will overflow" to
+     "the resulting pointer to the next offset address and the file size
+     itself would overflow"; changed title from "Offset Maximum - 2G-1 File
+     Size Limit" to "Offset Maximum and the 2G-1 File Size Limit"; changed
+     "cannot be performed because" to "cannot be performed at that position
+     because" in the last paragraph.
+ 13. Section A.2.1.1.4 (creat) changed sample code from if (creat(path, ...)
+     < 0) { to if ((fd = creat(path, ...)) < 0) {.
+ 14. Section A.2.1.1.6 (fgetpos, etc.) changed "this function" to "these
+     functions" in second paragraph; added paragraph beginning "Another
+     potentially serious..." and all that follows to the end of the section.
+ 15. Section A.3.1.1 (Transitional Extensions...) changed "B.3.1.1.2" to
+     "A.3.1.1.2" in subsection.
+ 16. Section A.3.1.1.1 (fcntl) Merged sentence "The O_LARGEFILE flag may be
+     set..." with the sentence "The O_LARGEFILE flag can expose..." moved in
+     from A.1.1.4.1 (fcntl).
+ 17. Section A.3.2.2 (Visibility of Transitional API) changed "Note that if"
+     to "If" in fourth paragraph.
+ 18. Section A.3.2.4 (Utilities:...) corrected reference to 3.1.2 in the
+     second to the last paragraph to 3.1.2.1 64-bit Version of Headers.
+ 19. Table of Contents corrected A.3 and A.3.1 heading titles.
+
+24Feb96 Version 1.2
+
+The 24Feb96 changes include:
+
+  1. Added link to Foreword and section.
+  2. Section 1.6 (Conformance) removed list, added text for section.
+  3. Section 2.2.1.11 (fprintf) changed "needs" to "needed" in the error
+     text.
+  4. Section 3.1.2.12 (unistd.h) added LFS_ASYNCHRONOUS_IO version test
+     macro.
+
+01Mar96 Version 1.3
+
+The 01Mar96 changes include:
+
+  1. Changed "Foreword" to "Acknowledgements".
+  2. Added body of Acknowledgements.
+  3. Section 1.6 (Conformance) 1st paragraph changed "may fail to" to "need
+     not".
+  4. Section 3.3.4, Example 2 changed "had" to "has".
+  5. Section A.1.2.1.1 (Offset Maximum...) swapped "-" and ">" in top line.
+  6. Section A.2.1.1.4 (creat) corrected reference for fstat.
+  7. Section 3.3.3 (Utilities:...) corrected reference for Compilation
+     Environment...
+
+05Mar96 Version 1.4
+
+The 05Mar96 changes include:
+
+  1. Changed Version 1.2 in 01Mar96 revision section to Version 1.3
+  2. Added additional contributors in the Acknowledgements.
+
+20Mar96 Version 1.5
+
+The 20Mar96 changes include:
+
+  1. Back by popular demand.... Larger fonts in the PostScript Version!
+  2. Section 1.2 (Requirements) In the text for "Be fully compliant to the
+     SUS" changed "conversion to the proposed standard" to "conversion to
+     this proposed standard" in the second from the last paragraph.
+  3. Section 1.4 (Concepts) Changed "file is larger" to "file size is
+     larger" and changed "only support" to "support only".
+  4. Section 1.6 (Conformance) LOTS of changes. In summary: each statement
+     of conformance ("A conforming implementation...") was separated into
+     individual paragraph and in each the phrases "described in" and "listed
+     in" were changed to "specified in"; the version test macro required for
+     each statement of conformance was added along with a reference to the
+     section where the changes to the interfaces and/or headers is
+     described; in the first statement of conformance parenthesis were added
+     around "except...lio_listio()" for clarity. Also deleted the last
+     paragraph (beginning "Implementations which provide...").
+  5. Section 2.2.1.7 (fgetc) Removed extra period at end of EOVERFLOW
+     description.
+  6. Section 2.2.1.19 (getrlimit) Changed commas before "otherwise" to
+     semicolons in first and second paragraphs; changed "permit" to "might
+     permit" and "do not" to "might not" in the fourth paragraph.
+  7. Section 3.0 (Transitional Extensions...) first paragraph: Added
+     sentence beginning "Version test macros..." after the first sentence
+     ("The interfaces...").
+  8. Section 3.1.2.8 (sys/resource.h) Added period after description of
+     RLIM64_INFINITY.
+  9. Section 3.1.2.12 (unistd.h) In Version Test Macros section added to
+     description of _LFS_ASYNCHRONOUS_IO beginning with "as specified
+     in..."; added "and 3.1.2.2..." to description of
+     _LFS64_ASYNCHRONOUS_IO; added "3.1.1.2 fcntl()..." to description of
+     _LFS64_LARGEFILE; added "and 3.1.2.6..." to description of
+     _LFS64_STDIO. The last paragraph of A.3.2.2 ("If _LFS64_STDIO...") was
+     moved to 3.1.2.12 as a new paragraph in the description of
+     _LFS64_STDIO. In the description of _LFS_LARGEFILE the phrase "the
+     fseeko() and ftello()" was removed and the text beginning with "as
+     specified in..." through the end of the sentence was added.
+ 10. Section 3.2.1 (Optional Additional...) Changed criteria to criterion
+     (last word of first paragraph).
+ 11. Section A.1.1.2 (Open Protection...) Removed comma before "and so on"
+     in the third paragraph.
+ 12. Section A.1.2.1 (Offset Maximum) Added "it" between "that" and "is
+     believed" in last sentence of the fifth paragraph. Also in the fifth
+     paragraph, changed "only applies" to "applies only".
+ 13. Section A.2.1.1.13 (getrlimit()...) Added text beginning "These values
+     do not..." through "...is really meant." to the end of the first
+     paragraph.
+ 14. Section A.2.2.1 (General Porting...) In the first paragraph removed the
+     phrase "there are four" and added "include" at then end of the
+     sentence.
+ 15. Section A.2.2.3 (Type Conversion...) Removed the last sentence of the
+     last paragraph ("Utilities not directly...").
+ 16. Section A.3.2.2 (Visibility of...) Second paragraph: added missing
+     parenthesis at end of the sentence. Also moved last paragraph ("If
+     _LFS64_STDIO is not defined...") to section 3.1.2.12 (unistd.h) as an
+     additional paragraph in the _LFS64_STDIO description.
+ 17. Acknowledgements first paragraph: changed "files sizes" to "file sizes"
+     in two places and changed "at least 2**32-1" to "at most 2^31-1". In
+     the list of contributors changed "Hewlett-Packard Inc." to
+     "Hewlett-Packard Co."; changed "Sun Microsystems Corp." to "Sun
+     Microsystems, Inc."; changed "Srimivasam" to "Srinivasan"; removed Art
+     Herzog from Novell list; removed Carl Zeigler from SAS list; added The
+     Santa Cruz Operation, Inc. contributors. Added "(now with Integrated
+     Computer Solutions, Inc.)" after "Mark Hatch".
+ 18. General: Changed "define[s,d] XXX as 1" to "define[s,d] XXX to be 1".
diff --git a/Makefile b/Makefile
index eea2e192c7450888669229dcd05791afcea5d251..12439ad5aeb78edba128bd9847c125edaace13ed 100644
--- a/Makefile
+++ b/Makefile
@@ -63,7 +63,7 @@ DIFF    = gnu.diff -df >null:
 
 AFLAGS  = -depend !Depend
 # The zz switch stops library static data being placed in a zero-init area
-CFLAGS  = -c -depend !Depend ${INCLUDES} -DDDE -fK -zz10000000
+CFLAGS  = -c -depend !Depend ${INCLUDES} -DDDE -fK -zz10000000 -jC:
 CPFLAGS = ~cfr~v
 WFLAGS  = ~c~r~v
 
diff --git a/SWIOptions,feb b/SWIOptions,feb
index a235472f24beb6b9ca221991b12cd7b6debbd97d..2230277d727ba2e2d082beb9460d976648487a62 100644
--- a/SWIOptions,feb
+++ b/SWIOptions,feb
@@ -60,6 +60,8 @@ IfThere Hdr:ScrBlank     Then Echo <32> GET Hdr:ScrBlank     { >> s.swioptions }
 IfThere Hdr:ScrModes     Then Echo <32> GET Hdr:ScrModes     { >> s.swioptions }
 IfThere Hdr:SCSI         Then Echo <32> GET Hdr:SCSI         { >> s.swioptions }
 IfThere Hdr:SCSIFS       Then Echo <32> GET Hdr:SCSIFS       { >> s.swioptions }
+IfThere Hdr:SDFS         Then Echo <32> GET Hdr:SDFS         { >> s.swioptions }
+IfThere Hdr:SDIO         Then Echo <32> GET Hdr:SDIO         { >> s.swioptions }
 IfThere Hdr:SharedCLib   Then Echo <32> GET Hdr:SharedCLib   { >> s.swioptions }
 IfThere Hdr:Shell        Then Echo <32> GET Hdr:Shell        { >> s.swioptions }
 IfThere Hdr:Sound        Then Echo <32> GET Hdr:Sound        { >> s.swioptions }
diff --git a/VersionASM b/VersionASM
index 031b990a204e3fb1a210b5a9064afb6470d886de..20a3c5db87a4ddabe1c4af12250a0917090c97e4 100644
--- a/VersionASM
+++ b/VersionASM
@@ -11,13 +11,13 @@
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
                         GBLS    Module_ComponentPath
-Module_MajorVersion     SETS    "5.63"
-Module_Version          SETA    563
+Module_MajorVersion     SETS    "5.64"
+Module_Version          SETA    564
 Module_MinorVersion     SETS    ""
 Module_Date             SETS    "28 Oct 2011"
 Module_ApplicationDate  SETS    "28-Oct-11"
 Module_ComponentName    SETS    "RISC_OSLib"
 Module_ComponentPath    SETS    "castle/RiscOS/Sources/Lib/RISC_OSLib"
-Module_FullVersion      SETS    "5.63"
-Module_HelpVersion      SETS    "5.63 (28 Oct 2011)"
+Module_FullVersion      SETS    "5.64"
+Module_HelpVersion      SETS    "5.64 (28 Oct 2011)"
                         END
diff --git a/VersionNum b/VersionNum
index f4dd74a58dbfae70039e8d8069bbf8cd4c7db7e0..455f2300d7e0943c5fd48be21b3de5f358393b2c 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,15 +1,15 @@
-/* (5.63)
+/* (5.64)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  * Last processed by srccommit version: 1.1.
  *
  */
-#define Module_MajorVersion_CMHG        5.63
+#define Module_MajorVersion_CMHG        5.64
 #define Module_MinorVersion_CMHG        
 #define Module_Date_CMHG                28 Oct 2011
 
-#define Module_MajorVersion             "5.63"
-#define Module_Version                  563
+#define Module_MajorVersion             "5.64"
+#define Module_Version                  564
 #define Module_MinorVersion             ""
 #define Module_Date                     "28 Oct 2011"
 
@@ -18,6 +18,6 @@
 #define Module_ComponentName            "RISC_OSLib"
 #define Module_ComponentPath            "castle/RiscOS/Sources/Lib/RISC_OSLib"
 
-#define Module_FullVersion              "5.63"
-#define Module_HelpVersion              "5.63 (28 Oct 2011)"
-#define Module_LibraryVersionInfo       "5:63"
+#define Module_FullVersion              "5.64"
+#define Module_HelpVersion              "5.64 (28 Oct 2011)"
+#define Module_LibraryVersionInfo       "5:64"
diff --git a/c/armsys b/c/armsys
index c808a43f47718a1356c10f8466c183e7d98d6088..335d6dad7a53b40ab3a9b791f4fdc561de632ba8 100644
--- a/c/armsys
+++ b/c/armsys
@@ -20,6 +20,7 @@
 /* version 11 */
 
 #define __system_io 1                           /* to get at flag bits */
+#define _LARGEFILE64_SOURCE /* define 64-bit file pointer stuff in stdio.h */
 
 #include "VersionNum"
 
@@ -80,13 +81,13 @@ struct bbctime {unsigned int l,h;};
 
 static clock_t _time0;
 
-static clock_t _clock()
+static clock_t _clock(void)
 {   struct bbctime bt;
     _bbctime(&bt);
     return bt.l;
 }
 
-static void _clock_init()   /* private - for initialisation */
+static void _clock_init(void)   /* private - for initialisation */
 {   _time0 = _clock();
 }
 
@@ -97,7 +98,7 @@ static void _clock_ignore(clock_t t)
 
 /* Exported... */
 
-clock_t clock()
+clock_t clock(void)
 {   return _clock() - _time0;     /* clock runs even if date not set */
 }
 
@@ -106,7 +107,7 @@ clock_t clock()
 time_t time(time_t *timer)
 /* this version gives the UNIX result of secs since 1-Jan-1970 */
 { time_t result;
-  int mctype;
+  /*int mctype;*/
   struct bbctime bt, w, w2;
   unsigned v;
   _kernel_swi_regs r;
@@ -159,7 +160,7 @@ time_t time(time_t *timer)
  * and Wimp_ReadSysInfo 3 says we're in the desktop, and Wimp_ReadSysInfo 5 gives us a
  * task handle.
  */
-int _desktop_task()
+int _desktop_task(void)
 {
     _kernel_swi_regs r;
     if (_kernel_processor_mode() & 0xF) return 0;
@@ -381,20 +382,49 @@ int _sys_istty(FILE *stream)
     return istty(stream->__file);
 }
 
-int _sys_seek(FILEHANDLE fh, long pos)
+int _sys_seek(FILEHANDLE fh, off64_t pos)
 {
     if istty(fh) return 0;
+#if 1
+    /* Can't use _kernel_osargs, even for 32-bit file pointers, because it can't handle files of size 4G-2 .*/
+    /* Use _kernel_swi instead so that _kernel_last_oserror is set up on failure like it always was. */
+    _kernel_swi_regs r;
+    r.r[0] = 1;
+    r.r[1] = fh;
+    r.r[2] = (unsigned int) pos;
+    if (_kernel_swi(OS_Args, &r, &r) != NULL)
+    {
+        errno = -1;
+        return _kernel_ERROR;
+    }
+    return 0;
+#else
     {   int rc = _kernel_osargs(1, fh, (int)pos);
         if (rc == _kernel_ERROR) errno = -1;
         return rc;
     }
+#endif
 }
 
-long _sys_flen(FILEHANDLE fh)
+off64_t _sys_flen(FILEHANDLE fh)
 {
+#if 1
+    /* Can't use _kernel_osargs, even for 32-bit file pointers, because it can't handle files of size 4G-2 .*/
+    /* Use _kernel_swi instead so that _kernel_last_oserror is set up on failure like it always was. */
+    _kernel_swi_regs r;
+    r.r[0] = 2;
+    r.r[1] = fh;
+    if (_kernel_swi(OS_Args, &r, &r) != NULL)
+    {
+        errno = -1;
+        return _kernel_ERROR;
+    }
+    return (unsigned int) r.r[2];
+#else
     int rc = _kernel_osargs(2, fh, 0);
     if (rc == _kernel_ERROR) errno = -1;
     return rc;
+#endif
 }
 
 int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
@@ -698,6 +728,7 @@ void _armsys_lib_init(void)
 {   char *stdinfile  = TTYFILENAME,
          *stdoutfile = TTYFILENAME,
          *stderrfile = TTYFILENAME;
+    (void) unused;
     _getenv_value = NULL;
     _error_recursion = 0;
     _ctype_init();          /* C locale */
diff --git a/c/ctype b/c/ctype
index 2a2841d899ac8c2c2235c0bbe9db59e626525bb8..24292de40a649a800c0434d444b8dd7e408bb53c 100644
--- a/c/ctype
+++ b/c/ctype
@@ -320,7 +320,7 @@ void _set_ctype(int territory)
   }
 }
 
-void _ctype_init()
+void _ctype_init(void)
 {
   __ctype[-1] = IL; /* for ctype(EOF) */
   _set_ctype(0);
diff --git a/c/locale b/c/locale
index fa02a4fa9ab74f080d940040d8cbab941eadf98d..72b929eeddde87261b290a9bced535321ca63801 100644
--- a/c/locale
+++ b/c/locale
@@ -48,6 +48,7 @@
 
 extern int _sprintf_lf(char *buff, const char *fmt, ...);
 
+extern int __locales[5];
 int __locales[5] = {0, 0, 0, 0, 0};
 
 /* lc initialised to C for default */
diff --git a/c/math b/c/math
index 594463de3f0a423c61ffce44683f77cc000f4f16..e87d0472fef834c2a001e5cce0fc5d810f36261b 100644
--- a/c/math
+++ b/c/math
@@ -962,11 +962,13 @@ float modff(float value, float *iptr)
 
 double nan(const char *s)
 {
+    (void) s;
     return (double) NAN;
 }
 
 float nanf(const char *s)
 {
+    (void) s;
     return NAN;
 }
 
diff --git a/c/printf b/c/printf
index 73db8e4c3bb25a1dc2a20fd12ebbb6005f23469a..5fcc54dbb3fc1757624927f7d4e2c4be5c47e785 100644
--- a/c/printf
+++ b/c/printf
@@ -117,7 +117,7 @@ static int printf_display(FILE *p, int flags, int ch, int precision, int width,
                 }
                 break;
     case 'o':   while(v!=0)
-                {   buff[len++] = '0' + (v & 07);
+                {   buff[len++] = '0' + (char)(v & 07);
                     v = v >> 3;
                 }
                 break;
@@ -125,7 +125,7 @@ static int printf_display(FILE *p, int flags, int ch, int precision, int width,
     case 'i':
     case 'd':   while (v != 0)
                 {   unsigned long long vDiv10 = v / 10U;
-                    buff[len++] = '0' + v - vDiv10 * 10U;
+                    buff[len++] = '0' + (char)(v - vDiv10 * 10U);
                     v = vDiv10;
                 }
                 break;
diff --git a/c/scanf b/c/scanf
index d5dca1e8c2dd0056d54a7d8fb48c8e883c57af8c..5050ea36062695a500e36875d166ac81a82e72dd 100644
--- a/c/scanf
+++ b/c/scanf
@@ -842,6 +842,10 @@ typedef struct __extradata {
   int __d;
   int __e;
   int __f;
+#ifdef SUPPORT_WIDE
+  int __g;
+  mbstate_t __h;
+#endif
 } _extradata, *_extradatap;
 
 int vsscanf(const char *buff, const char *fmt, va_list a)
diff --git a/c/signal b/c/signal
index 89469380d74977e569ce911a2d51394607525cd7..dc06d8b69cf3ff7d70aeea623f393bcf2a47ddd8 100644
--- a/c/signal
+++ b/c/signal
@@ -49,7 +49,7 @@ extern void __ignore_signal_handler(int sig)
 
 static void _real_default_signal_handler(int sig)
 {
-    char *s, v[128];
+    char *s = NULL, v[128];
     _kernel_oserror *e = _kernel_peek_last_oserror();
 
     if (((sig == SIGSEGV || sig == SIGILL) && _SignalNumber(e->errnum) == sig) ||
@@ -179,7 +179,7 @@ void (*signal(int sig, void (*func)(int)))(int)
     return oldf;
 }
 
-void _signal_init()
+void _signal_init(void)
 {
     int i;
     /* do the following initialisation explicitly so code restartable */
diff --git a/c/stdio b/c/stdio
index 759613cd77f80e47dbfaef37a5c383a3dd0bccd5..e444a60ac1b0136197d30ea21e260cf6a91f854a 100644
--- a/c/stdio
+++ b/c/stdio
@@ -30,6 +30,7 @@
 */
 
 #define __system_io 1      /* makes stdio.h declare more */
+#define _LARGEFILE64_SOURCE /* define 64-bit file pointer stuff in stdio.h */
 
 #include "hostsys.h"   /* _sys_alloc() etc */
 #include <stdio.h>     /* macros for putc, getc, putchar, getchar */
@@ -62,6 +63,20 @@ int __backspace(FILE *stream);  /* strict right inverse of getc() */
 
 #define NO_DEBUG
 
+/* Maximum allowable file pointers for the 32 and 64-bit APIs. */
+#define OFF32_MAX (0x7fffffffL)
+#if 1 /* change this once FileSwitch has a 64-bit API */
+#define OFF64_MAX (0x00000000ffffffffLL)
+#else
+#define OFF64_MAX (0x7fffffffffffffffLL)
+#endif
+
+/* The maximum buffer size to permit via setvbuf().
+ * Previous limit of 16MB-1 was maybe a bit stingy, given the amount of
+ * RAM in machines these days.
+ */
+#define MAX_BUF_SIZE (1u<<30)
+
 /* This macro is part of the fwrite performance improvement.  It selects
  * which strategy is being used for large block writes.  If this macro
  * is defined, then _writebuf is asked to write n*buffersize bytes in one
@@ -86,8 +101,9 @@ typedef struct __extradata {
    * it, alter sscanf's view of it.
    */
   unsigned char __lilbuf[2]; /* single byte buffer for them that want it  */
-                            /* plus an unget char is put in __lilbuf[1]   */
-  long _lspos;              /* what __pos should be (set after lazy seek) */
+                             /* plus an unget char is put in __lilbuf[1]  */
+  off64_t __pos;             /* position in file corresponding to start of buffer */
+  off64_t _lspos;            /* what __pos should be (set after lazy seek)*/
   unsigned char *__extent;   /* extent of writes into the current buffer  */
   int __buflim;              /* used size of buffer                       */
   int __savedicnt;           /* after unget contains old icnt             */
@@ -203,8 +219,9 @@ static FILE *_getFILE(void)
 #define _IOUSERFILE 0x00200000     /* set if should be closed by user    */
                                    /* terminateio in a module            */
 #define _IOACTIVE   0x00400000     /* some IO operation already performed*/
-#define _IODEL      0xad800000     /* for safety check 9 bits            */
-#define _IODELMSK   0xff800000
+#define _IO64       0x00800000     /* stream ok for 64-bit file pointers */
+#define _IODEL      0xad000000     /* for safety check 8 bits            */
+#define _IODELMSK   0xff000000
 
 /* first functions for macros in <stdio.h>  */
 int (fgetc)(FILE *stream) { return getc(stream); }
@@ -217,15 +234,15 @@ int (feof)(FILE *stream) { return feof(stream); }
 int (ferror)(FILE *stream) { return ferror(stream); }
 #define STDOUT stderr
 #ifdef DEBUG
-#define dbmsg(m, m2) if (stream > STDOUT || stream == stdin) {int last=0 ;int iw; char v[128]; \
-        sprintf(v, m, m2); \
+#define dbmsg(m, ...) if (stream > STDOUT || stream == stdin) {int last=0 ;int iw; char v[128]; \
+        sprintf(v, m, __VA_ARGS__); \
         for(iw=0;v[iw];_kernel_oswrch(last=v[iw++])); \
         if (last == 10)_kernel_oswrch(13);}
 #define dbmsg_noNL(m, m2) if (stream > STDOUT || stream == stdin) {int last=0 ;int iw; char v[128]; \
         sprintf(v, m, m2); \
         for(iw=0;v[iw];_kernel_oswrch(last=v[iw++]));}
 #else
-#define dbmsg(m, m2)
+#define dbmsg(m, ...)
 #define dbmsg_noNL(m, m2)
 #endif
 /* put this here too */
@@ -251,7 +268,7 @@ int setvbuf(FILE *stream, char *buf, int type, size_t size)
             break;
         case _IOLBF:
         case _IOFBF:
-            if (size-1 >= 0xffffff) return 1;  /* unsigned! */
+            if (size-1 >= MAX_BUF_SIZE) return 1;  /* unsigned! */
             break;
     }
     stream->__ptr = stream->__base = ubuf;
@@ -289,37 +306,54 @@ int ungetc(int c,FILE *stream)
     return c;
 }
 
-static int _writebuf(unsigned char *buf, int len, FILE *stream)
+static int _writebuf(unsigned char *buf, unsigned int len, FILE *stream)
 {   int w;
     FILEHANDLE fh = stream->__file;
+    off64_t over_limit;
     int flag = stream->__flag;
     if (flag & _IOSHARED) /* this is really gross */
     {   flag |= _IOSEEK;
-        stream->__pos = _sys_flen(fh);
-dbmsg("_IOSHARED so zoom to end %d\n", (int)stream->__pos);
+        stream->__extrap->__pos = _sys_flen(fh);
+dbmsg("_IOSHARED so zoom to end %lld\n", stream->__extrap->__pos);
     }
     if (flag & _IOSEEK+_IOBUFREAD)
     {
-dbmsg("_writebuf seeking to %d\n", (int)stream->__pos);
-        if (_sys_seek(fh, stream->__pos) < 0)
+dbmsg("_writebuf seeking to %lld\n", stream->__extrap->__pos);
+        if (_sys_seek(fh, stream->__extrap->__pos) < 0)
         {   seterr(stream);
             return EOF;
         }
         stream->__flag = (flag &= ~(_IOSEEK+_IOBUFREAD));
     }
 dbmsg_noNL("_writebuf pop goes the stoat %i, ", fh);
-dbmsg_noNL("%X, ", buf);
+dbmsg_noNL("%X, ", (int)buf);
 dbmsg_noNL("%d, ", len);
 dbmsg("%X\n", flag);
-    w = _sys_write(fh, buf, len, flag);
-    stream->__flag |= _IOADFSBUG;
+    over_limit = stream->__extrap->__pos + len - ((stream->__flag & _IO64) ? OFF64_MAX : OFF32_MAX);
+    if (over_limit < 0) over_limit = 0;
+dbmsg("over_limit %lld\n", over_limit);
+    len -= (unsigned int) over_limit;
+    if (len == 0)
+        w = 0;
+    else
+    {
+        w = _sys_write(fh, buf, len, flag);
+        stream->__flag |= _IOADFSBUG;
 dbmsg("_sys_write_ returned %d\n", w);
-    stream->__pos += len - (w & 0x7fffffffL);
+    }
+    if (w < (unsigned int) _kernel_ERROR)
+        stream->__extrap->__pos += (off64_t) len - (w & 0x7fffffffLL);
     if (w!=0)    /* AM: was (w<0) but trap unwritten chars as error too */
     {   seterr(stream);
         return(EOF);
     }
-dbmsg("filelen = %d\n",_sys_flen(fh));           /* length of this file      */
+    if (over_limit)
+    {
+        seterr(stream);
+        errno = EFBIG;
+        return(EOF);
+    }
+dbmsg("filelen = %lld\n",_sys_flen(fh));           /* length of this file      */
     return 0;
 }
 
@@ -358,7 +392,7 @@ else dbmsg("%s\n", "not a dirty buffer");
       stream->__flag = stream->__flag & ~(_IOEOF|_IONOWRITES|_IOREADS|_IOPEOF)
                                                                    |_IOSEEK;
       stream->__icnt = stream->__ocnt = 0;
-      stream->__pos += (extent - buff);
+      stream->__extrap->__pos += (extent - buff);
       stream->__ptr = buff;
     }
 */
@@ -368,15 +402,15 @@ else dbmsg("%s\n", "not a dirty buffer");
 
 static void _deferredlazyseek(FILE *stream)
 {
-dbmsg("deferredlazyseek to %d\n", (int)stream->__extrap->_lspos);
+dbmsg("deferredlazyseek to %lld\n", stream->__extrap->_lspos);
     /* only here because of a seek */
     stream->__flag &= ~_IOLAZY;
-    if (stream->__pos != stream->__extrap->_lspos) {
+    if (stream->__extrap->__pos != stream->__extrap->_lspos) {
       _fflush(stream);
       /* clear EOF condition */
 dbmsg("%s\n", "clear IODIRTIED");
       stream->__flag = stream->__flag & ~(_IONOWRITES | _IONOREADS) | _IOSEEK;
-      stream->__pos = stream->__extrap->_lspos;
+      stream->__extrap->__pos = stream->__extrap->_lspos;
       stream->__ptr = stream->__extrap->__extent = stream->__base;
     }
 else dbmsg("%s\n", ".....already there");
@@ -421,7 +455,7 @@ dbmsg("%s\n", "!= _IOWRITE");
 /* Will somebody please help ACN remember/understand what was going on here!*/
     {   /* first write to APPEND file after FFLUSH, but not FSEEK nor       */
         /* fopen (does its own FSEEK)                                       */
-        fseek(stream, 0L, SEEK_END);
+        fseeko64(stream, 0LL, SEEK_END);
         if (stream->__flag & _IOLAZY) _deferredlazyseek(stream);
         flag = stream->__flag;
     }
@@ -441,7 +475,7 @@ dbmsg("%s\n", "set IODIRTIED");
     }
     if (flag & _IOFBF)               /* system or user buffer */
     {   unsigned char *buff = stream->__base;
-        int count = EXTENT(stream) - buff;
+        unsigned int count = EXTENT(stream) - buff;
         if (count != 0) {
             if (_writebuf(buff, count, stream)) return EOF;
         }
@@ -452,7 +486,7 @@ dbmsg("%s\n", "set IODIRTIED");
     }
     else     /* no buffer (i.e. 1 char private one) or line buffer */
     {   unsigned char *buff = stream->__base;
-        int count;
+        unsigned int count;
         *stream->__ptr++ = ch;   /* always room */
         count = EXTENT(stream) - buff;
         stream->__extrap->__buflim = stream->__bufsiz;
@@ -470,7 +504,8 @@ extern int __filbuf(FILE *stream)
 {   int w;
     unsigned char *buff;
     FILEHANDLE fh;
-    int request;
+    off64_t over_limit;
+    unsigned int request;
 dbmsg("%s\n", "__filbuf");
     stream->__flag |= _IOACTIVE;
     if (stream->__flag & _IOUNGET) {
@@ -514,12 +549,12 @@ dbmsg("fillbuf negative icnt = %d\n", stream->__icnt);
     if (stream->__flag & _IOSEEK) {
       if (stream->__flag & _IODIRTIED) _fflush(stream);
       else {
-dbmsg("fillbuf seeking to %d\n", (int)stream->__pos);
+dbmsg("fillbuf seeking to %lld\n", stream->__extrap->__pos);
         if (stream->__flag & _IOADFSBUG) {
           _sys_ensure(fh);
           stream->__flag &= ~_IOADFSBUG;
         }
-        if (_sys_seek(fh, stream->__pos) < 0)
+        if (_sys_seek(fh, stream->__extrap->__pos) < 0)
         {   seterr(stream);
             return EOF;
         }
@@ -529,7 +564,7 @@ dbmsg("fillbuf seeking to %d\n", (int)stream->__pos);
     stream->__flag |= _IONOWRITES;           /* we are reading */
 
     if (stream->__flag & _IODIRTIED) {
-      int extent = (int) (EXTENT(stream) - stream->__base);
+      unsigned int extent = (int) (EXTENT(stream) - stream->__base);
       request = stream->__bufsiz - extent;
       if (request == 0) {
         _fflush(stream);
@@ -537,12 +572,12 @@ dbmsg("fillbuf seeking to %d\n", (int)stream->__pos);
       } else {
 dbmsg("fillbuf flag %X\n", stream->__flag);
         if ((stream->__flag & (_IOBUFREAD+_IOSEEK)) == 0) {
-dbmsg("fillbuf dirty buffer, read into end,seeking to %d\n",(int) stream->__pos+extent);
+dbmsg("fillbuf dirty buffer, read into end,seeking to %lld\n", stream->__extrap->__pos+extent);
           if (stream->__flag & _IOADFSBUG) {
             _sys_ensure(fh);
             stream->__flag &= ~_IOADFSBUG;
           }
-          if (_sys_seek(fh, stream->__pos + extent) < 0)
+          if (_sys_seek(fh, stream->__extrap->__pos + extent) < 0)
           {   seterr(stream);
               return EOF;
           } else stream->__flag |= _IOBUFREAD;
@@ -554,19 +589,41 @@ dbmsg("at buff %X\n", (int)buff);
     } else {
       request = stream->__bufsiz;
       buff = stream->__base;
-      stream->__pos += stream->__ptr - buff;     /* add buf size for ftell() */
+      stream->__extrap->__pos += stream->__ptr - buff;     /* add buf size for ftell() */
     }
     stream->__flag &= ~_IOSEEK;
 
+    /* At this point, we are attempting to fill the buffer with data read from the
+     * file, with no knowledge of where EOF might be. If the file pointer
+     * corresponding to the start of the read is already at the maximum file pointer,
+     * it's time to report EOVERFLOW. Since RISC OS is treated as a 'late' eof OS,
+     * we can't detect EOF coinciding with the maximum file pointer - at least, not
+     * without extending the armsys.c API, since polling the EOF flag requires a
+     * separate OS_Args call which it would not be desirable to do on every call to
+     * _sys_read(). If the file pointer corresponding to the end of the read lies
+     * beyond the maximum file pointer, we need to truncate the read so as not to
+     * cause FileSwitch to exceed the limit. If the C library client uses up this
+     * truncated buffer, __filbuf will be called again, and we can report EOVERFLOW
+     * at that time.
+     */
+    over_limit = stream->__extrap->__pos + stream->__bufsiz - request - ((stream->__flag & _IO64) ? OFF64_MAX : OFF32_MAX);
+    if (over_limit >= 0) /* shouldn't actually ever be > 0, but just in case */
+    {
+        seterr(stream);
+        errno = EOVERFLOW;
+        return EOF;
+    }
+    else if (request > -over_limit)
+        request = (unsigned int) -over_limit;
 
 dbmsg("READING FROM FILE REQUEST = %d\n", request);
-dbmsg("filelen = %d\n",_sys_flen(fh));             /* length of this file */
+dbmsg("filelen = %lld\n",_sys_flen(fh));             /* length of this file */
     stream->__icnt = 0;
     w = _sys_read(fh, buff, request, stream->__flag);
     stream->__flag &= ~_IOADFSBUG;
 dbmsg("_sys_read_ returned %d\n", w);
     if (w<0) {
-      if (w == _kernel_ERROR) { seterr(stream); return EOF; }
+      if (w >= (unsigned int) _kernel_ERROR) { seterr(stream); return EOF; }
       /* this deals with operating systems with 'early' eof */
       stream->__flag |= _IOPEOF;
       w = w & 0x7fffffff;
@@ -645,7 +702,7 @@ int fclose(FILE *stream)
     return res;
 }
 
-FILE *freopen(const char *name, const char *mode, FILE *iob)
+static FILE *freopen_common(const char *name, const char *mode, FILE *iob, int flag64, off64_t limit)
 {
 /* The use of modes "r+", "w+" and "a+" is not fully thought out   */
 /* yet, in that calls to __flsbuf may write back stuff that was    */
@@ -674,14 +731,31 @@ FILE *freopen(const char *name, const char *mode, FILE *iob)
         break;
     }
     if ((fh = _sys_open(name, openmode)) == NONHANDLE) return NULL;
+    if (_sys_flen(fh) > limit)
+    {
+        errno = EOVERFLOW;
+        _sys_close(fh);
+        return NULL;
+    }
+    flag |= flag64;
     if (_kernel_client_is_module()) flag |= _IOUSERFILE;
     iob->__ptr = iob->__base = NULL; iob->__bufsiz = BUFSIZ;
     iob->__flag = flag;
     iob->__file = fh;
-    if (openmode & OPEN_A) fseek(iob, 0L, SEEK_END);  /* a or a+             */
+    if (openmode & OPEN_A) fseeko64(iob, 0LL, SEEK_END);  /* a or a+             */
     return iob;
 }
 
+FILE *freopen(const char *name, const char *mode, FILE *iob)
+{
+    return freopen_common(name, mode, iob, 0, OFF32_MAX);
+}
+
+FILE *freopen64(const char *name, const char *mode, FILE *iob)
+{
+    return freopen_common(name, mode, iob, _IO64, OFF64_MAX);
+}
+
 FILE *fopen(const char *name, const char *mode)
 {   FILE *stream = _getFILE();
     if (stream)
@@ -689,6 +763,13 @@ FILE *fopen(const char *name, const char *mode)
     return 0;   /* no more i/o channels allowed for */
 }
 
+FILE *fopen64(const char *name, const char *mode)
+{   FILE *stream = _getFILE();
+    if (stream)
+        return (freopen64(name, mode, stream));
+    return 0;   /* no more i/o channels allowed for */
+}
+
 FILEHANDLE __dup(int new, int old)
 {   FILE *s_new, *s_old;
     (void) fclose(&__iob[new]);
@@ -701,6 +782,7 @@ FILEHANDLE __dup(int new, int old)
     return s_new->__file;
 }
 
+#if 0
 FILE *_fopen_string_file(const char *data, int length)
 {
 /* open a file that will read data from the given string argument        */
@@ -717,6 +799,7 @@ FILE *_fopen_string_file(const char *data, int length)
     }
     return 0;   /* no more i/o channels allowed for */
 }
+#endif
 
 int _fisatty(FILE *stream)  /* not in ANSI, but related needed for ML */
 {   if ((stream->__flag & _IOREAD) && _sys_istty(stream)) return 1;
@@ -830,7 +913,7 @@ int puts(const char *s)
 }
 
 /* _read improved to use __filbuf and block moves.  Optimisation
-   to memcpy too if word move.  Still possible improvments avoiding copy
+   to memcpy too if word move.  Still possible improvements avoiding copy
    but I don't want to do these yet because of interactions
    (e.g. __pos of a file).   N.B.  _read is not far from unix 'read' */
 static int _read(char *ptr, int nbytes, FILE *stream)
@@ -876,15 +959,15 @@ dbmsg("fread %d\n", count);
                          : _read(ptr, itemsize*count, stream) / itemsize;
 }
 
-static int _write(const char *ptr, int nbytes, FILE *stream)
-{   int i;
+static int _write(const char *ptr, unsigned int nbytes, FILE *stream)
+{   unsigned int i;
     if (_sys_istty(stream) || (stream->__flag & _IONBF)) {
       for(i=0; i<nbytes; i++)
         if (putc(*ptr++, stream) == EOF) return 0;
         /* H&S say 0 on error */
     }
     else if (nbytes > 0) {
-      int so_far = 0;
+      unsigned int so_far = 0;
 
       if (stream->__ocnt < 0) {
         /* Not ready for writes, so do one putc to force it into a nice state. */
@@ -914,7 +997,7 @@ static int _write(const char *ptr, int nbytes, FILE *stream)
          * OR non-existant.  We need to write (nbytes - so_far) bytes, at ptr to 'stream'.
          * Buffer does exist if __ocnt is zero.  Thus the call to __flsbuf will flush any
          * filled buffers AND/OR initialise the data structures to accept written data,
-         * so we can legally check __ocnt, __flags and __bufsiz.  This call to __flsbuf is
+         * so we can legally check __ocnt, __flags and __bufsiz.  This call to __flsbuf is
          * basically simulating putc, so it MUST always decrement __ocnt before the call.
          */
         --stream->__ocnt;
@@ -926,8 +1009,8 @@ static int _write(const char *ptr, int nbytes, FILE *stream)
          */
         if (stream->__ocnt > 0 && (stream->__flag & _IOFBF) && stream->__bufsiz > 0) {
           /* Looks like it is worth attempting a direct write to the file */
-          int nblocks, count, loop;
-          nblocks = (nbytes - so_far - 1) / stream->__bufsiz;
+          unsigned int nblocks, count, loop;
+          nblocks = (nbytes == so_far) ? 0 : (nbytes - so_far - 1) / stream->__bufsiz;
           if (nblocks > 0) {
             /* There cannot be any _IOLAZY pending as __flsbuf will have taken care of it.
              * We want _writebuf to simply pass this data directly to _sys_write (and under
@@ -990,22 +1073,37 @@ dbmsg("itemsize %d (decimal)\n", itemsize);
 
 #define _ftell(stream) (  (stream)->__flag & _IOLAZY \
                         ? (stream)->__extrap->_lspos \
-                        : (stream)->__pos + (stream)->__ptr - (stream)->__base)
+                        : (stream)->__extrap->__pos + (stream)->__ptr - (stream)->__base)
 
-long int ftell(FILE *stream)
-{  long pos;
+static off64_t ftell_common(FILE * stream, off64_t limit)
+{  off64_t pos;
    if (!(stream->__flag & _IOREAD+_IOWRITE))     /* already closed        */
    { errno = EDOM;
-     return -1L;
+     return -1LL;
    }
    pos = _ftell(stream);
    if (stream->__flag & _IOUNGET && pos > 0) --pos;
+   if ((unsigned long long) pos > limit)
+   {
+       errno = EOVERFLOW;
+       return -1LL;
+   }
    return pos;
 }
 
+long int ftell(FILE *stream)
+{
+    return (long int) ftell_common(stream, OFF32_MAX);
+}
+
+off64_t ftello64(FILE * stream)
+{
+    return ftell_common(stream, OFF64_MAX);
+}
+
 /* The treatment of files that can be written to seems complicated in fseek */
 
-int fseek(FILE *stream, long int offset, int whence)
+static int fseek_common(FILE *stream, off64_t offset, int whence, off64_t limit)
 {
     FILEHANDLE fh = stream->__file;
     int flag = stream->__flag;
@@ -1019,17 +1117,17 @@ dbmsg_noNL("%s ", "SEEK ENTRY");
 case SEEK_SET:
         break;                                  /* relative to file start */
 case SEEK_CUR:
-        offset += ftell(stream);                /* relative seek */
+        offset += ftello64(stream);             /* relative seek */
         break;
 case SEEK_END:
-        {   long int filelen, filepos;
+        {   off64_t filelen, filepos;
             filelen = _sys_flen(fh);           /* length of this file      */
-dbmsg("filelen in seek = %d\n", (int)filelen);
+dbmsg("filelen in seek = %lld\n", filelen);
             if (filelen<0)                      /* failed to read length    */
             {   seterr(stream);
                 return 1;
             }
-            filepos = stream->__pos + EXTENT(stream) - stream->__base;
+            filepos = stream->__extrap->__pos + EXTENT(stream) - stream->__base;
             if (stream->__flag & _IOLAZY && filepos < stream->__extrap->_lspos)
               filepos = stream->__extrap->_lspos;
             if (filepos>filelen)                /* only possible on write   */
@@ -1044,11 +1142,18 @@ default:
 
     if (offset < 0) { seterr(stream); return 2; } /* fseek impossible  */
 
+    if (offset > limit)
+    {
+        seterr(stream);
+        errno = EOVERFLOW;
+        return 2;
+    }
+
     if ((flag & _IONOREADS) && stream->__extrap->__extent < stream->__ptr)
       stream->__extrap->__extent = stream->__ptr;
 
 dbmsg_noNL("%s ", "SEEK");
-dbmsg_noNL("__pos %d", (int)stream->__pos);
+dbmsg_noNL("__pos %lld", stream->__extrap->__pos);
 dbmsg_noNL(" offset %d", (int)offset);
 dbmsg_noNL(" buflim %d", stream->__extrap->__buflim);
 dbmsg_noNL(" __ptr %X", (int)stream->__ptr);
@@ -1056,9 +1161,9 @@ dbmsg_noNL(" __icnt %d", stream->__icnt);
 dbmsg_noNL(" __ocnt %d", stream->__ocnt);
 dbmsg_noNL(" __base %X", (int)stream->__base);
 
-    if (offset < stream->__pos ||
-      offset > stream->__pos + EXTENT(stream) - stream->__base ||
-      offset >= stream->__pos + stream->__extrap->__buflim)
+    if (offset < stream->__extrap->__pos ||
+      offset > stream->__extrap->__pos + EXTENT(stream) - stream->__base ||
+      offset >= stream->__extrap->__pos + stream->__extrap->__buflim)
 
       { /* outside buffer */
 dbmsg("%s\n", " outside buffer");
@@ -1067,7 +1172,7 @@ dbmsg("%s\n", " outside buffer");
       stream->__extrap->_lspos = offset;
     } else { /* inside buffer */
 dbmsg("%s\n", " inside buffer");
-      offset -= stream->__pos;
+      offset -= stream->__extrap->__pos;
       if (flag & _IOWRITE)
         stream->__ocnt = -(stream->__extrap->__buflim - (int)offset);
       if (flag & _IOREAD)
@@ -1083,17 +1188,27 @@ dbmsg(" __ocnt %d\n", stream->__ocnt);
     return 0;
 }
 
+int fseek(FILE *stream, long int offset, int whence)
+{
+    return fseek_common(stream, offset, whence, OFF32_MAX);
+}
+
+int fseeko64(FILE *stream, off64_t offset, int whence)
+{
+    return fseek_common(stream, offset, whence, OFF64_MAX);
+}
+
 static int _do_fflush(FILE *stream)
 { /* ignore the effect of a previous unget on the file position indicator by
      using _ftell rather than ftell */
   if (stream->__flag & _IOREAD+_IOWRITE)   /* not open */
-  { long offset = _ftell(stream);
+  { off64_t offset = _ftell(stream);
     int res;
 dbmsg("%s\n", "fflush");
     if (stream->__flag & _IOLAZY) _deferredlazyseek(stream);
     stream->__flag &= ~(_IONOREADS+_IONOWRITES);
     res =_fflush(stream);
-    fseek(stream, offset, SEEK_SET);
+    fseeko64(stream, offset, SEEK_SET);
     return res;
   } else return 0;
 }
@@ -1117,18 +1232,29 @@ int fflush(FILE *stream)
 
 void rewind(FILE *stream)
 {
-   fseek(stream, 0L, SEEK_SET);
+   fseeko64(stream, 0LL, SEEK_SET);
    clearerr(stream);
 }
 
 /* the following routines need to become the main entry I suppose          */
 int fgetpos(FILE *stream, fpos_t *pos)
-{  pos->__lo = ftell(stream);
+{  *pos = ftell(stream);
+   return 0;
+}
+
+int fgetpos64(FILE *stream, fpos64_t *pos)
+{  *pos = ftello64(stream);
    return 0;
 }
 
 int fsetpos(FILE *stream, const fpos_t *pos)
-{  int res = fseek(stream, pos->__lo, SEEK_SET);
+{  int res = fseek(stream, *pos, SEEK_SET);
+   if (res) errno = EDOM;
+   return res;
+}
+
+int fsetpos64(FILE *stream, const fpos64_t *pos)
+{  int res = fseeko64(stream, *pos, SEEK_SET);
    if (res) errno = EDOM;
    return res;
 }
@@ -1157,6 +1283,7 @@ char *tmpnam(char *a)
     return a;
 }
 
+extern char *__old_tmpnam(char *a);
 char *__old_tmpnam(char *a)
 {
     return tmpnam(a);
@@ -1174,6 +1301,18 @@ FILE *tmpfile(void)
     return f;
 }
 
+FILE *tmpfile64(void)
+{
+    char name[L_tmpnam];
+    FILE *f;
+    f = fopen64(tmpnam(name), "w+b");
+    if (f)
+    {   f->__flag |= _IODEL;
+        f->__signature = _tmp_file_sig;
+    }
+    return f;
+}
+
 void perror(const char *s)
 {   char b[256];
     if (s != 0 && *s != 0) fprintf(stderr, "%s: ", s);
diff --git a/c/string b/c/string
index bf3e024140d5dc3fd46d2f633cf8db2fce6f1de3..860b7221bd6094da2685374b55eee57a65aaf49d 100644
--- a/c/string
+++ b/c/string
@@ -536,6 +536,12 @@ char *_strerror(int n, char *v)
             return _kernel_getmessage2("ERANGE - function result not representable", "C37", v, 80);
         case ESIGNUM:
             return _kernel_getmessage2("ESIGNUM - illegal signal number to signal() or raise()", "C66", v, 80);
+        case EILSEQ:
+            return _kernel_getmessage2("EILSEQ - character encoding error", "C74", v, 80);
+        case EOVERFLOW:
+            return _kernel_getmessage2("EOVERFLOW - too large for data structure", "C75", v, 80);
+        case EFBIG:
+            return _kernel_getmessage2("EFBIG - data written to file lost due to exceeding file size limit", "C76", v, 80);
         default:
             return _hostos_error_string(n, v);
     }
diff --git a/clib/Resources/UK/Messages b/clib/Resources/UK/Messages
index 12d79117a1aa04edb21495605ba8c8a4d50d520d..48cf40478c39df092b746a82fbe34d463bca1599 100644
Binary files a/clib/Resources/UK/Messages and b/clib/Resources/UK/Messages differ
diff --git a/clib/h/errno b/clib/h/errno
index ff628b613b79f119aa78bdfe33287efdbcc544d5..20987b50c63e29b338b614ca559c37a3bb9a1e94 100644
--- a/clib/h/errno
+++ b/clib/h/errno
@@ -57,6 +57,7 @@ extern volatile int errno;
     * acquires the value of the macro EDOM and HUGE_VAL is returned. EDOM may
     * be used by non-mathematical functions.
     */
+
 #define ERANGE 2
    /*
     * a range error occurs if the result of a function can not be represented
@@ -70,7 +71,33 @@ extern volatile int errno;
     * integer expression errno acquires the value of the macro ERANGE. ERANGE
     * may be used by non-mathematical functions.
     */
+
 #define ESIGNUM 3
+   /*
+    * a signal number error occurs if an unrecognised signal number is passed
+    * to signal() or raise().
+    */
+
+#define EILSEQ 4
+   /*
+    * an illegal sequence error indicates that a multibyte character encoding
+    * error has been detected.
+    */
+
+#define EOVERFLOW 5
+   /*
+    * an overflow error occurs if one or more fields of a data structure is
+    * not large enough to hold the values required - for example, if you
+    * attempt to open a file with fopen() whose size cannot be expressed using
+    * an object of type off_t.
+    */
+
+#define EFBIG 6
+   /*
+    * a big file error occurs if a file is unbuffered or the file's buffer
+    * needs to be flushed, and this would have resulted in a write occurring
+    * at or beyond the maximum file pointer for this file descriptor.
+    */
 
 #endif
 
diff --git a/clib/h/stdio b/clib/h/stdio
index 9aeb0a5b724280b35b80054a5b6bdec24f359605..0071ed9c64c19331da43e2862885cb919e33c1cb 100644
--- a/clib/h/stdio
+++ b/clib/h/stdio
@@ -44,14 +44,45 @@ typedef char *__va_list[1];       /* keep in step with <stdarg.h> */
 #  define NULL 0                /* see <stddef.h> */
 #endif
 
-typedef struct __fpos_t_struct
-{ unsigned long __lo;             /* add hi one day */
-} fpos_t;
+typedef long int _off_t;
+#ifdef __STDC__
+typedef long long int _off64_t;
+#endif
+
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 32
+#endif
+#if defined(__STDC__) && _FILE_OFFSET_BITS == 64
+typedef _off64_t fpos_t;
+#elif _FILE_OFFSET_BITS == 32
+typedef _off_t fpos_t;
+#else
+#error Unsupported _FILE_OFFSET_BITS value
+#endif
    /*
     * fpos_t is an object capable of recording all information needed to
     * specify uniquely every position within a file.
     */
 
+#if defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)
+typedef fpos_t off_t;
+#endif
+   /*
+    * off_t is an object capable of recording the offset from any position
+    * within a file to any other position within that file, and is used by
+    * the LFS extension functions fseeko() and fello().
+    */
+
+#if defined(__STDC__) && defined(_LARGEFILE64_SOURCE)
+typedef _off64_t fpos64_t, off64_t;
+#endif
+   /*
+    * fpos64_t and of64_t are the equivalent of fpos_t and off_t respectively,
+    * and are used in their place when an application explicitly uses the
+    * 64-bit LFS extension functions fgetpo64(), fseeko64(), fsetpos64() and
+    * ftello64().
+    */
+
 typedef struct __FILE_struct
 { unsigned char *__ptr;
   int __icnt;      /* two separate _cnt fields so we can police ...        */
@@ -61,7 +92,7 @@ typedef struct __FILE_struct
   /* are invisible in an ANSI-conforming program.                          */
   unsigned char *__base; /* buffer base */
   int __file;            /* RISCOS/Arthur/Brazil file handle */
-  long __pos;            /* position in file */
+  long __unused;         /* used to contain 32-bit file pointer */
   int __bufsiz;          /* maximum buffer size */
   int __signature;       /* used with temporary files */
   struct __extradata *__extrap; /* pointer to information about stream */
@@ -172,6 +203,15 @@ int rename(const char * /*old*/, const char * /*new*/);
     *          original name.
     */
 FILE *tmpfile(void);
+#ifdef __STDC__
+FILE *_tmpfile64(void);
+#if _FILE_OFFSET_BITS == 64
+#define tmpfile _tmpfile64
+#endif
+#ifdef _LARGEFILE64_SOURCE
+#define tmpfile64 _tmpfile64
+#endif
+#endif
    /*
     * creates a temporary binary file that will be automatically removed when
     * it is closed or at program termination. The file is opened for update.
@@ -222,6 +262,16 @@ int fflush(FILE * /*stream*/);
     */
 FILE *fopen(const char * restrict /*filename*/,
             const char * restrict /*mode*/);
+#ifdef __STDC__
+FILE *_fopen64(const char * restrict /*filename*/,
+               const char * restrict /*mode*/);
+#if _FILE_OFFSET_BITS == 64
+#define fopen _fopen64
+#endif
+#ifdef _LARGEFILE64_SOURCE
+#define fopen64 _fopen64
+#endif
+#endif
    /*
     * opens the file whose name is the string pointed to by filename, and
     * associates a stream with it.
@@ -267,6 +317,17 @@ FILE *fopen(const char * restrict /*filename*/,
 FILE *freopen(const char * restrict /*filename*/,
               const char * restrict /*mode*/,
               FILE * restrict /*stream*/);
+#ifdef __STDC__
+FILE *_freopen64(const char * restrict /*filename*/,
+                 const char * restrict /*mode*/,
+                 FILE * restrict /*stream*/);
+#if _FILE_OFFSET_BITS == 64
+#define freopen _freopen64
+#endif
+#ifdef _LARGEFILE64_SOURCE
+#define freopen64 _freopen64
+#endif
+#endif
    /*
     * opens the file whose name is the string pointed to by filename and
     * associates the stream pointed to by stream with it. The mode argument is
@@ -659,7 +720,16 @@ size_t fwrite(const void * restrict /*ptr*/,
     *          than nmemb only if a write error is encountered.
     */
 
-int fgetpos(FILE * restrict /*stream*/, fpos_t * restrict /*pos*/);
+int fgetpos(FILE * restrict /*stream*/, _off_t * restrict /*pos*/);
+#ifdef __STDC__
+int _fgetpos64(FILE * restrict /*stream*/, _off64_t * restrict /*pos*/);
+#if _FILE_OFFSET_BITS == 64
+#define fgetpos _fgetpos64
+#endif
+#ifdef _LARGEFILE64_SOURCE
+#define fgetpos64 _fgetpos64
+#endif
+#endif
    /*
     * stores the current value of the file position indicator for the stream
     * pointed to by stream in the object pointed to by pos. The value stored
@@ -671,6 +741,20 @@ int fgetpos(FILE * restrict /*stream*/, fpos_t * restrict /*pos*/);
     *          nonzero value (under RISCOS/Arthur/Brazil fgetpos cannot fail).
     */
 int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/);
+int _fseeko(FILE * /*stream*/, _off_t /*offset*/, int /*whence*/);
+#if defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)
+#if _FILE_OFFSET_BITS == 64
+#define fseeko _fseeko64
+#else
+#define fseeko _fseeko
+#endif
+#endif
+#ifdef __STDC__
+int _fseeko64(FILE * /*stream*/, _off64_t /*offset*/, int /*whence*/);
+#ifdef _LARGEFILE64_SOURCE
+#define fseeko64 _fseeko64
+#endif
+#endif
    /*
     * sets the file position indicator for the stream pointed to by stream.
     * For a binary stream, the new position is at the signed number of
@@ -687,7 +771,16 @@ int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/);
     * the next operation on an update stream may be either input or output.
     * Returns: nonzero only for a request that cannot be satisfied.
     */
-int fsetpos(FILE * /*stream*/, const fpos_t * /*pos*/);
+int fsetpos(FILE * /*stream*/, const _off_t * /*pos*/);
+#ifdef __STDC__
+int _fsetpos64(FILE * /*stream*/, const _off64_t * /*pos*/);
+#if _FILE_OFFSET_BITS == 64
+#define fsetpos _fsetpos64
+#endif
+#ifdef _LARGEFILE64_SOURCE
+#define fsetpos64 _fsetpos64
+#endif
+#endif
    /*
     * sets  the file position indicator for the stream pointed to by stream
     * according to the value of the object pointed to by pos, which shall be a
@@ -702,6 +795,20 @@ int fsetpos(FILE * /*stream*/, const fpos_t * /*pos*/);
     *          in math.h).
     */
 long int ftell(FILE * /*stream*/);
+_off_t _ftello(FILE * /*stream*/);
+#if defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)
+#if _FILE_OFFSET_BITS == 64
+#define ftello _ftello64
+#else
+#define ftello _ftello
+#endif
+#endif
+#ifdef __STDC__
+_off64_t _ftello64(FILE * /*stream*/);
+#ifdef _LARGEFILE64_SOURCE
+#define ftello64 _ftello64
+#endif
+#endif
    /*
     * obtains the current value of the file position indicator for the stream
     * pointed to by stream. For a binary stream, the value is the number of
diff --git a/clib/h/string b/clib/h/string
index 00c42b4881503184f68f8c127a404fdaf1d415ff..8d865634ff9d81e9ce80983797521d0eb47b4c0d 100644
--- a/clib/h/string
+++ b/clib/h/string
@@ -255,6 +255,10 @@ char *strerror(int /*errnum*/);
     *          EDOM    "EDOM - function argument out of range"
     *          ERANGE  "ERANGE - function result not representable"
     *          ESIGNUM "ESIGNUM - illegal signal number to signal() or raise()"
+    *          EILSEQ  "EILSEQ - character encoding error"
+    *          EOVERFLOW "EOVERFLOW - too large for data structure"
+    *          EFBIG   "EFBIG - data written to file lost due to exceeding
+    *                  file size limit"
     *          -1      Error message from _kernel_lastoserror(), if any,
     *                  else "unspecified error"
     *          others  "unknown error"
diff --git a/clib/s/cl_body b/clib/s/cl_body
index 82d9872c47032e80eb3ca4bc4303b02835c2b001..ae7ad9a340c1591f37fdf17f70b8f041bbf8060f 100644
--- a/clib/s/cl_body
+++ b/clib/s/cl_body
@@ -150,12 +150,12 @@ $Label
         EXPORT  |_ldfp|
         EXPORT  |_stfp|
 
-        EXPORT  |__fpclassifyf|
-        EXPORT  |__fpclassifyd|
-        EXPORT  |__signbitf|
-        EXPORT  |__signbitd|
-        EXPORT  |__copysignf|
-        EXPORT  |__copysignd|
+        EXPORT  |__fpclassifyf| [FPREGARGS]
+        EXPORT  |__fpclassifyd| [FPREGARGS]
+        EXPORT  |__signbitf| [FPREGARGS]
+        EXPORT  |__signbitd| [FPREGARGS]
+        EXPORT  |__copysignf| [FPREGARGS]
+        EXPORT  |__copysignd| [FPREGARGS]
         EXPORT  copysign
         EXPORT  copysignf
         EXPORT  nextafter
@@ -237,7 +237,7 @@ $Label
         BL      |_lib_shutdown|
         MOV     a1, #0
         BL      |_exit|
-        LDMFD   sp!, {r1}               ; free the RMA block addressed by
+        LDR     r1, [sp], #4            ; free the RMA block addressed by
         MOV     r0, #Module_Free        ; our private word.
         LDR     r2, [r1]
         MOV     r3, #0
@@ -267,9 +267,9 @@ EventHandler Keep
         MOV     a1, #SIGINT
         STRNE   a1, [ip, #O__saved_interrupt]
         BNE     %FT01
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
         BL      raise
-        LDMFD   sp!, {r14}
+        LDR     r14, [sp], #4
 01      MOV     a1, #1          ; we wish to handle it, but not just yet
         Return  ,LinkNotStacked
 
@@ -284,9 +284,9 @@ UnhandledEventHandler Keep
         MOV     a1, #SIGINT
         STRNE   a1, [ip, #O__saved_interrupt]
         BNE     %FT02
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
         BL      raise
-        LDMFD   sp!, {r14}
+        LDR     r14, [sp], #4
 02      MOV     a1, #1          ; we wish to handle it, but not just yet
         Return  ,LinkNotStacked
 
@@ -343,7 +343,7 @@ TrapHandler Keep
         MOV     a4, a1
         STMFD   sp!, {a2, a4, r14}
         BL      SignalNumber
-        STMFD   sp!, {a1}
+        STR     a1, [sp, #-4]!
         BL      |_signal_real_handler|
         CMP     a1, #0
         LDMFD   sp!, {a1, a2, a4, r14}
@@ -403,7 +403,7 @@ llabs
 ; test for division by zero (used when division is voided)
         TEQS    a1, #0
         Return  ,LinkNotStacked, NE
-        STMFD   sp!, {r0}
+        STR     r0, [sp, #-4]!
         ADR     r0, E_DivideByZero
         B       |_kernel_fault|
 
@@ -482,14 +482,14 @@ llabs
         Return  ,,CC
         ; and drop into writefail
 writefail
-        LDMFD   sp!, {lr}
-        STMFD   sp!, {r0}
+        LDR     lr, [sp], #4
+        STR     r0, [sp, #-4]!
         ADR     r0, E_WriteFail
         B       |_kernel_fault|
 
 readfail
-        LDMFD   sp!, {lr}
-        STMFD   sp!, {r0}
+        LDR     lr, [sp], #4
+        STR     r0, [sp, #-4]!
         ADR     r0, E_ReadFail
         B       |_kernel_fault|
 
@@ -523,8 +523,8 @@ readfail
         Return  "v1"
         NOOP
 
-        LDMIA   a2!, {a4}
-        STMIA   a1!, {a4}
+        LDR     a4, [a2], #4
+        STR     a4, [a1], #4
         Return  "v1"
 
 ; Note that the number of instructions is critical for the SUBLT
@@ -545,7 +545,7 @@ readfail
         STMIA   a1!, {a2, a4}
         Return
 
-        STMIA   a1!, {a4}
+        STR     a4, [a1], #4
         Return
 
 mesg    DCB     "mesg"
@@ -598,7 +598,7 @@ postmortem1
 postmortem2
         LDMFD   sp!, {r0-r5}
         BL      |_kernel_fpavailable|
-        LDMFD   sp!, {r14}
+        LDR     r14, [sp], #4
         CMP     a1, #0
         MOV     ip, sp
         SUBEQ   sp, sp, #12*4
@@ -731,7 +731,13 @@ sj_f7   #       3*4
         STMIA   a1, {sl, lr}
         SUB     v1, a1, #sj_sl
   |
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   a1, {v1-v6, sl, fp, sp, lr}
+      |
+        STMIA   a1!, {v1-v6, sl, fp}
+        STR     lr, [a1, #sj_pc - sj_sp]
+        STR     sp, [a1], #-sj_sp
+      ]
         MOV     v1, a1
   ]
         MOV     v2, lr
@@ -775,7 +781,13 @@ sj_f7   #       3*4
         LDMFD   sp, {sl, fp, sp}
  |
         LFMNE   f4, 4, [v1, #sj_f4-sj_f4]
+      [ {FALSE} ; this instruction is now deprecated
         LDMDB   v1!, {sl, fp, sp, lr}
+      |
+        LDR     lr, [v1, #sj_pc - sj_f4]!
+        LDR     sp, [v1, #sj_sp - sj_pc]!
+        LDMDB   v1!, {sl, fp}
+      ]
         MOV     v5, lr
  ]
 
@@ -829,12 +841,12 @@ chunks_deallocated
 
 |_osgbpb|
         STMFD   sp!, {a3, a4, v1, v2, v3} ; v1-v3 just to reserve space
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
         ADD     a3, sp, #4
         BL      |_kernel_osgbpb|
         CMP     a1, #-2
         LDRNE   a1, [sp, #8]            ; new value of len
-        LDMFD   sp!, {r14}
+        LDR     r14, [sp], #4
         ADD     sp, sp, #5*4
         Return  ,LinkNotStacked
 
@@ -852,10 +864,10 @@ chunks_deallocated
 
 |_osfile|
         STMFD   sp!, {a3, a4, v1, v2}  ; v1,v2 just to reserve space
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
         ADD     a3, sp, #4
         BL      |_kernel_osfile|
-        LDMFD   sp!, {r14}
+        LDR     r14, [sp], #4
         ADD     sp, sp, #4*4
         Return  ,LinkNotStacked
 
@@ -1199,7 +1211,7 @@ fmax
         BVS     fcmpnan
         Return  ,LinkNotStacked,NE
         ; Values are equal. Anding the sign bits will give nice behaviour
-        ; for fmax(±0, ±0).
+        ; for fmax(�0, �0).
         [ FloatingPointArgsInRegs
         STFD    f1, [sp, #-8]!
         STFD    f0, [sp, #-8]!
@@ -1252,7 +1264,7 @@ fmin
         BVS     fcmpnan
         Return  ,LinkNotStacked,NE
         ; Values are equal. Oring the sign bits will give nice behaviour
-        ; for fmin(±0, ±0).
+        ; for fmin(�0, �0).
         [ FloatingPointArgsInRegs
         STFD    f1, [sp, #-8]!
         STFD    f0, [sp, #-8]!
diff --git a/clib/s/cl_entries b/clib/s/cl_entries
index 127d1e6f6b3133b131d95a4e06aa2b119eda98d6..61addbaaf4da3f82b943c5981aa8b51ce9b8984b 100644
--- a/clib/s/cl_entries
+++ b/clib/s/cl_entries
@@ -142,9 +142,9 @@
         Entry   fread, imported    , , , 4
         Entry   fwrite, imported   , , , 4
         Entry   fgetpos, imported  , , , 2
-        Entry   fseek, imported    , , , 3
+        Entry2  fseek, imported    , , , 3, , _fseeko
         Entry   fsetpos, imported  , , , 2
-        Entry   ftell, imported    , , , 1
+        Entry2  ftell, imported    , , , 1, , _ftello
         Entry   rewind, imported   , , , 1
         Entry   clearerr, imported , , , 1
         Entry   feof, imported     , , , 1
diff --git a/clib/s/cl_entry2 b/clib/s/cl_entry2
index b9bca55e9bb9e9e7e5175e05f7865d6bf41e889f..28c8b8d60f6caf972a0d79653aa981c08e2f73f5 100644
--- a/clib/s/cl_entry2
+++ b/clib/s/cl_entry2
@@ -19,12 +19,12 @@
 ; Add new entries ONLY AT THE END of the list
 ;
 
-        Entry   __fpclassifyf, , , unveneered
-        Entry   __fpclassifyd, , , unveneered
-        Entry   __signbitf, , , unveneered
-        Entry   __signbitd, , , unveneered
-        Entry   __copysignd, , , unveneered
-        Entry   __copysignf, , , unveneered
+        Entry   __fpclassifyf, , , unveneered, , , [FPREGARGS]
+        Entry   __fpclassifyd, , , unveneered, , , [FPREGARGS]
+        Entry   __signbitf, , , unveneered, , , [FPREGARGS]
+        Entry   __signbitd, , , unveneered, , , [FPREGARGS]
+        Entry   __copysignd, , , unveneered, , , [FPREGARGS]
+        Entry   __copysignf, , , unveneered, , , [FPREGARGS]
         Entry   nan, imported, , unveneered
         Entry   nanf, imported, , unveneered
         Entry   nextafter, , , unveneered
@@ -153,12 +153,12 @@
         Entry   llround, imported, , unveneered
         Entry   llroundf, imported, , unveneered
 
-        Entry   _cxd_mul, imported, , unveneered
-        Entry   _cxf_mul, imported, , unveneered
-        Entry   _cxd_div, imported, , unveneered
-        Entry   _cxf_div, imported, , unveneered
-        Entry   _cxd_rdv, imported, , unveneered
-        Entry   _cxf_rdv, imported, , unveneered
+        Entry   _cxd_mul, imported, , unveneered, , , [FPREGARGS]
+        Entry   _cxf_mul, imported, , unveneered, , , [FPREGARGS]
+        Entry   _cxd_div, imported, , unveneered, , , [FPREGARGS]
+        Entry   _cxf_div, imported, , unveneered, , , [FPREGARGS]
+        Entry   _cxd_rdv, imported, , unveneered, , , [FPREGARGS]
+        Entry   _cxf_rdv, imported, , unveneered, , , [FPREGARGS]
 
         Entry   cacos, imported, , unveneered
         Entry   cacosf, imported, , unveneered
@@ -205,4 +205,12 @@
         Entry   creal, imported, , unveneered
         Entry   crealf, imported, , unveneered
 
+        Entry   _fgetpos64, imported, , unveneered
+        Entry   _fopen64, imported, , unveneered
+        Entry   _freopen64, imported, , unveneered
+        Entry   _fseeko64, imported, , unveneered
+        Entry   _fsetpos64, imported, , unveneered
+        Entry   _ftello64, imported, , unveneered
+        Entry   _tmpfile64, imported, , unveneered
+
         END
diff --git a/clib/s/cl_stub b/clib/s/cl_stub
index af500812153b5dfd289383ba62bf0d7e6ddac88b..6cb16f8d5bbc741641a4691b34c02f562fab7243 100644
--- a/clib/s/cl_stub
+++ b/clib/s/cl_stub
@@ -207,7 +207,7 @@ LookupError
         ; (statics need copying) - if so, we must allocate RMA to hold them.
         ; Note that finalise always discards the RMA (whether fatal or not)
         ; so initialise always acquires it.  Is this reasonable?
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
    [ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM" :LAND: :LNOT::DEF:AnsiLib
         BL      EnsureCLib
 ;        LDMVSFD sp!, {pc}
@@ -234,7 +234,7 @@ LookupError
         ADDNE   r3, r3, #fixedwssize
         MOV     r0, #Module_Claim
         SWI     Module
-        LDMVSIA sp!, {pc}
+        LDRVS   pc, [sp], #4
         STR     r2, [r12]               ; set private word to address our data
         STR     r3, [r2]                ; first word is size
 
@@ -333,7 +333,7 @@ LookupError
       |
         CMP     r0, #&80000000
         CMNVC   r0, #&80000000          ; Set V bit
-        LDMIA   sp!, {pc}
+        LDR     pc, [sp], #4
       ]
 
    [ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM" :LAND: :LNOT::DEF:AnsiLib
@@ -375,10 +375,10 @@ RMEnsure6
 
         EXPORT  |_clib_initialisemodule|
 |_clib_initialisemodule|
-        STMFD   sp!, {r14}
+        STR     r14, [sp, #-4]!
         BL      |_kernel_moduleentry|
-        LDMVSIA sp!, {pc}
-        STMFD   sp!, {r9}               ; save preserved private word ptr
+        LDRVS   pc, [sp], #4
+        STR     r9, [sp, #4]!           ; save preserved private word ptr
         BL      |_clib_initialise|
       [ {CONFIG}=26
         LDMFD   sp!, {r0, pc}^          ; return saved private word ptr
diff --git a/h/hostsys b/h/hostsys
index e8c990414b03ade2307f0bdae9c4bd86f44ef789..5060716a45725c49209a3ffdd24594bdd1a2348f 100644
--- a/h/hostsys
+++ b/h/hostsys
@@ -198,7 +198,7 @@ extern int _sys_istty(FILE *);
 /*           setbuf call).                                               */
 /*           disallow seek                                               */
 
-extern int _sys_seek(FILEHANDLE fh, long pos);
+extern int _sys_seek(FILEHANDLE fh, _off64_t pos);
 /* Position the file at offset pos from its beginning.                   */
 /* Result is >= 0 if OK, negative for an error.                          */
 
@@ -207,7 +207,7 @@ extern int _sys_ensure(FILEHANDLE fh);
 /* up to date on disc.  (Only required if HOSTOS_NEEDSENSURE; see above) */
 /* Result is >= 0 if OK, negative for an error.                          */
 
-extern long _sys_flen(FILEHANDLE fh);
+extern _off64_t _sys_flen(FILEHANDLE fh);
 /* Return the current length of the file fh (or a negative error         */
 /* indicator).  Required to convert fseek(, SEEK_END) into (, SEEK_START)*/
 /* as required by _sys_seek.                                             */
@@ -318,6 +318,7 @@ typedef union {struct {unsigned mlo; int s:1, x:11, mhi:20; } i;
         high = temp.d;                                                    \
     }
 
+#if 0
 /* The next line is not very nice, but since I want to declare a      */
 /* function of type (FILE *) is seems to be needed. If you do not     */
 /* want <stdio.h> included, tough luck!                               */
@@ -325,6 +326,7 @@ typedef union {struct {unsigned mlo; int s:1, x:11, mhi:20; } i;
 /* revealed by <stdio.h>.                                             */
 #include <stdio.h>
 extern FILE *_fopen_string_file(const char *data, int length);
+#endif
 
 
 #if defined __ARM && defined SHARED_C_LIBRARY
diff --git a/kernel/s/k_body b/kernel/s/k_body
index 6cef10e737fd3c9b173e56f6d89b344b11124ffc..29036d573bde7e5c97519f81ecbda0ba364481fd 100644
--- a/kernel/s/k_body
+++ b/kernel/s/k_body
@@ -198,7 +198,7 @@ uwb_size        #       0
         STR     r0, [ip, #O_allocProc]  ; default alloc proc
         ADR     r0, |_kernel_RMAfree|
         STR     r0, [ip, #O_freeProc]   ; and no dealloc proc
-        LDMFD   sp!, {pc}
+        LDR     pc, [sp], #4
  ]
 
 |_kernel_irqs_disabled|
@@ -585,7 +585,7 @@ RSI6_List
         BEQ     |_kernel_user_exit|
         MOV     ip, sp
         SUB     sp, sp, #4*12              ; set up an unwind block
-        STMFD   sp!, {sl}
+        STR     sl, [sp, #-4]!
         STMFD   sp!, {a1, r3-r9, fp, ip, r14}  ; r3 to reserve an extra word
         BL      |_kernel_exittraphandler|
 01      ADD     a1, sp, #8
@@ -597,14 +597,20 @@ RSI6_List
         SWI     XOS_ReadDynamicArea
         MOVVC   r14, r0
         MOVVS   r14, #&01800000         ; default to fixed base if SWI fails
-        LDMFD   sp!, {a1}
+        LDR     a1, [sp], #4
         CMP     a1, r14
         ADRCC   a1, E_Exit
         BLCC    |_kernel_copyerror|     ; BL<cond> 32-bit OK
         [ {CONFIG}=26
         LDMIB   sp, {r4-r9, fp, sp, pc}^
         |
+      [ {FALSE} ; this instruction is now deprecated
         LDMIB   sp, {r4-r9, fp, sp, pc}
+      |
+        LDMIB   sp, {r4-r9, fp, ip, lr}
+        MOV     sp, ip
+        MOV     pc, lr
+      ]
         ]
 
         ALIGN
@@ -648,9 +654,9 @@ KernelExit1
         CMPNE   r2, r3
         LDR     r1, ABEXString
         SWICC   Exit
-        STMDB   sp!, {r0}
+        STR     r0, [sp, #-4]!
         BL      Finalise
-        LDMIA   sp!, {r0}
+        LDR     r0, [sp],  #4
         SWI     GenerateError
 
 ; Generate an external error. Re-init the stack to the root stack chunk.
@@ -676,13 +682,13 @@ KernelExit1
         ADD     sp, sl, sp
         ADD     sl, sl, #SC_SLOffset
         MOV     fp, #0
-        STMFD   sp!, {a1}
+        STR     a1, [sp, #-4]!
         BL      Finalise
-        LDMFD   sp!, {a1}
+        LDR     a1, [sp], #4
         SWI     GenerateError
 
 Finalise
-        STMFD   sp!, {lr}
+        STR     lr, [sp, #-4]!
         LDMIB   v6, {v2, v3}
 CallFinaliseProcs
         CMP     v2, v3
@@ -741,7 +747,7 @@ NoFinaliseProc_SL
         B       CallFinaliseProcs_SL
 EndFinaliseProcs_SL
  ]
-        LDMFD   sp!, {lr}
+        LDR     lr, [sp], #4
         B       RestoreOSHandlers
 
 
@@ -1326,7 +1332,7 @@ FCH_Unwind  Keep
         [ {CONFIG}=26
         LDMFD   sp!, {pc}^
         |
-        LDMFD   sp!, {pc}
+        LDR     pc, [sp], #4
         ]
 
         ErrorBlock UncaughtTrap, "Uncaught trap", C57
@@ -1414,7 +1420,7 @@ UpCallHandler
 ; down.
 ; The register state is undefined, except that r13 must be the SWI stack
 ; pointer.
-        STMFD   sp!, {r0-r3, v1-v6, fp, sl, lr}
+        STMFD   sp!, {r0-r3, v1-v6, sl, fp, lr}
         MOV     v6, r12
         WritePSRc PSRUSRMode, r0
         NOP
@@ -1425,13 +1431,13 @@ UpCallHandler
         MOV     fp, #0
         BL      Finalise
         SWI     EnterSVC
-        LDMFD   sp!, {r0-r3, v1-v6, fp, sl, pc}
+        LDMFD   sp!, {r0-r3, v1-v6, sl, fp, pc}
 
 InstallHandlers Keep
         ; r0 is zero for the initial call (previous values for the handlers
         ; to be saved).
         ; If non-zero, it is the value memoryLimit should be set to.
-        STMFD   sp!, {r0}
+        STR     r0, [sp, #-4]!
         MOV     r8, r0
         MOV     r0, #0
         MOV     r1, #0
@@ -1453,9 +1459,9 @@ InstallHandlers Keep
         STMEQIA r8!, {r1, r2}
 
         MOV     r0, #Env_MemoryLimit
-        LDMFD   sp!, {r1}
+        LDR     r1, [sp], #4
         SWI     ChangeEnv
-        STMEQIA r8!, {r1}
+        STREQ   r1, [r8], #4
 
         MOV     r0, #Env_ErrorHandler
         ADR     r1, ErrorHandler
@@ -1511,7 +1517,7 @@ InstallCallersHandlers Keep
         SWI     ChangeEnv
 
         MOV     r0, #Env_MemoryLimit
-        LDMIA   r8!, {r1}
+        LDR     r1, [r8], #4
         SWI     ChangeEnv
         MOV     r4, r1
 
@@ -1618,7 +1624,12 @@ EventHandler Keep
         STMFD   r13!, {r11, r14}
         STR     r0, [r12, #O_eventCode]
         ADD     r11, r12, #O_eventRegisters
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   r11, {r0-r10, r13}
+      |
+        STMIA   r11, {r0-r10}
+        STR     r13, [r11, #11*4]
+      ]
 
         STMDB   r11, {r13}^
         MOV     v6, r12
@@ -1654,16 +1665,16 @@ EndFastEventHandlers
 EscapeHandler Keep
         TSTS    r11, #&40
         BNE     haveEscape
-        STMFD   r13!, {r0}
+        STR     r0, [r13, #-4]!
         MOV     r0, #0
         STRB    r0, [r12, #O_hadEscape]
-        LDMFD   r13!, {r0}
+        LDR     r0, [r13], #4
         MOV     pc, r14         ; ignore flag going away
 
 haveEscape
         ; In Arthur, it is NEVER safe to call a handler now: we always have to
         ; wait for CallBack.
-        STMFD   r13!, {r0}
+        STR     r0, [r13, #-4]!
         MOV     r0, #-1
         STRB    r0, [r12, #O_hadEscape]
         LDRB    r0, [r12, #O_eventCode]
@@ -1672,7 +1683,7 @@ haveEscape
         LDRB    r11, [r12, #O_callbackInactive]
         CMP     r11, #0
         MOVNE   r12, #1
-        LDMFD   r13!, {r0}
+        LDR     r0, [r13], #4
         MOV     pc, r14
 
 ; Callback handler - entered in either SWI or IRQ mode, interrupts disabled,
@@ -2235,7 +2246,12 @@ ErrorExitV6Stacked
         ; (otherwise possible) case of v6 < 0.
         CMP     r14, #1024
         MOVLT   r14, #0
+      [ {FALSE} ; this instruction is now deprecated
         STMFD   sp!, {a2, v2-v5, r14, r15}   ; save them away
+      |
+        SUB     sp, sp, #4
+        STMFD   sp!, {a2, v2-v5, r14}        ; save them away
+      ]
                                         ;subr/chain, len, base, top, limit, gap
                                         ; hole for memoryLimit
 
@@ -2250,12 +2266,12 @@ ErrorExitV6Stacked
         MOV     r1, #0
         SWINE   ChangeEnv
 
-        STMFD   sp!, {r1}               ; remember slot size
+        STR     r1, [sp, #-4]!          ; remember slot size
         ; All registers must be preserved whose values are wanted afterwards.
         ; v1 to v6 are already on the stack.
         ADD     ip, sp, r14
         ADD     r5, v6, #O_languageEnvSave
-        STMIA   r5, {fp, ip, sl}        ; save ptr to moved stack
+        STMIA   r5, {sl, fp, ip}        ; save ptr to moved stack
         ADD     v6, v6, r14             ; now points to the to be copied data
 
 ; The following loop copies the image up memory. It avoids overwriting
@@ -2339,7 +2355,12 @@ s_Exit
         MOV     r0, #0
 s_Exit2
         ADD     r5, v6, #O_languageEnvSave
-        LDMIA   r5, {fp, sp, sl}
+      [ {FALSE} ; this instruction is now deprecated
+        LDMIA   r5, {sl, fp, sp}
+      |
+        LDMIA   r5, {sl, fp}
+        LDR     sp, [r5, #2*4]
+      ]
         LDMFD   sp!, {a2, a3, v1-v5}    ; slotsize,
                                         ;subr/chain, Len, Base, Top, Limit, Gap
         STR     r0, [sp, #4]            ; ... over prev saved r0...
@@ -2392,7 +2413,7 @@ CopyDnDone
     MOV    r0, #0
     SWI    XOS_SynchroniseCodeAreas
   ]
-        LDMFD   sp!, {r0}               ; old memoryLimit
+        LDR     r0, [sp], #4            ; old memoryLimit
         BL      InstallHandlers
 
         LDMFD   sp!, {a1, v5}
@@ -2413,8 +2434,8 @@ CopyErrorV6OK
         ADD     a2, v6, #O_errorNumber
 CopyError2
         STR     pc, [a2, #-4]           ; mark as valid
-        LDMIA   a4!, {a3}
-        STMIA   a2!, {a3}
+        LDR     a3, [a4], #4
+        STR     a3, [a2], #4
 CopyErrorString
 01      LDRB    a3, [a4], #+1
         STRB    a3, [a2], #+1
@@ -2641,7 +2662,13 @@ alloc_return_block
         LoadStaticBase ip, a1
         LDR     lr, [sp], #4
         ADD     ip, ip, #O_registerDump
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   ip, {a1 - r14}
+      |
+        STMIA   ip, {a1 - r12}
+        STR     r13, [ip, #13*4]
+        STR     r14, [ip, #14*4]
+      ]
         ADR     r0, E_StackOverflow
         BL      |_kernel_copyerror|
         SWI     GenerateError
@@ -2911,7 +2938,12 @@ StkOvfGetNewChunk Keep
         LDR     a2, [v2, #O_extendChunk]
         LDR     a3, [a2, #SC_size]
         ADD     a3, a2, a3                ; new sp
+      [ {FALSE} ; this instruction is now deprecated
         STMFD   a3!, {sl, fp, sp}         ; save old stack description
+      |
+        STR     sp, [a3, #-4]!
+        STMFD   a3!, {sl, fp}             ; save old stack description
+      ]
         MOV     sp, a3
         ADD     sl, a2, #SC_SLOffset
         MOV     fp, #0
@@ -2930,7 +2962,12 @@ StkOvfGetNewChunk Keep
         MOVS    v2, a1
         LDMFD   sp!, {v3, ip}           ; size in bytes, dealloc
 01
+      [ {FALSE} ; this instruction is now deprecated
         LDMFD   sp, {sl, fp, sp}        ; back to old chunk
+      |
+        LDMFD   sp!, {sl, fp}           ; back to old chunk
+        LDR     sp, [sp]
+      ]
         MOV     a1, #1
         STR     a1, [lr, #O_extendChunkNotInUse]
         BEQ     StkOvfError
@@ -2968,7 +3005,13 @@ StackOverflowFault Keep
         MOV     sp, v1
         LDMDA   v1, {a1, a2, v1-v6, lr}
         ADD     ip, ip, #O_registerDump
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   ip, {a1 - r14}
+      |
+        STMIA   ip, {a1 - r12}
+        STR     r13, [ip, #13*4]
+        STR     r14, [ip, #14*4]
+      ]
         ADR     r0, E_StackOverflow
         BL      |_kernel_copyerror|
         SWI     GenerateError
@@ -3188,12 +3231,17 @@ dividebyzero
         ; the link from the stack).
         LoadStaticBase ip, a3
         ADD     ip, ip, #O_registerDump
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   ip, {r0-r13}
+      |
+        STMIA   ip, {r0-r12}
+        STR     r13, [ip, #13*4]
+      ]
         RemovePSRFromReg r14, r1, r0            ; == BIC r0, r14, #PSRBits  IFF 26bit
         SUBS    r1, pc, r0
         ADRGE   r1, |_kernel_udiv|
         CMPGE   r0, r1
-        LDMGEFD sp!, {r14}
+        LDRGE   r14, [sp], #4
         STR     r14, [ip, #r14*4]
         ADR     r0, E_DivideByZero
 10
@@ -3207,7 +3255,7 @@ dividebyzero
         LDMIB   ip, {r1-r14}^
         NOP
         STMDB   sp!, {r10, r11, r12}
-        STMDB   sp!, {r14}
+        STR     r14, [sp, #-4]!
         SWI     GenerateError
 
         EXPORT  |_kernel_fault|
@@ -3218,7 +3266,13 @@ dividebyzero
         STMFD   sp!, {r1, ip}
         LoadStaticBase ip, r1
         ADD     ip, ip, #O_registerDump
+      [ {FALSE} ; this instruction is now deprecated
         STMIA   ip, {r0-r14}
+      |
+        STMIA   ip, {r0-r12}
+        STR     r13, [ip, #13*4]
+        STR     r14, [ip, #14*4]
+      ]
         LDMFD   sp!, {r1, r2, r3}
         STR     r3, [ip]
         STR     r2, [ip, #ip*4]
diff --git a/kernel/s/k_init b/kernel/s/k_init
index 7730c9704252dc4737195e4fe7d6eea06555c973..cd85f07560840a500930b809d6f4ae8c11994f35 100644
--- a/kernel/s/k_init
+++ b/kernel/s/k_init
@@ -88,7 +88,7 @@ ZeroInitClientStatics
         SUBS    r5, r5, r3
         BLE     DoneClientStatics
         MOV     r6, #0
-01      STMIA   r1!, {r6}
+01      STR     r6, [r1], #4
         SUBS    r5, r5, #4
         BGT     %B01
 
diff --git a/rlib/s/poll b/rlib/s/poll
index 357d259eea86fa17139aee2cb70ab0c18fb5b36d..f056b69ca9f843c0766d889173d266fd70095939 100644
--- a/rlib/s/poll
+++ b/rlib/s/poll
@@ -111,7 +111,7 @@ wimp_pollidle
 ; can corrupt a2-a4
 save_fp_state
         RFS     a2                      ; read FP status
-        STMFD   sp!, {a2}
+        STR     a2, [sp, #-4]!
         MOV     a2, #0
         WFS     a2
         SUB     sp, sp, #4*12           ; emulated a lot faster than writeback
@@ -130,7 +130,7 @@ restore_fp_state
         LDFE    f6, [sp, #2*12]
         LDFE    f7, [sp, #3*12]
         ADD     sp, sp, #4*12           ; emulated a lot faster than writeback
-        LDMFD   sp!, {v1}
+        LDR     v1, [sp], #4
         WFS     v1
         MOV     pc, lr
 
diff --git a/rlib/s/swi b/rlib/s/swi
index f40a7543d4f9824832032699b572407a3bb68ee5..2e63ef4879a95e6431f699b4833ecb98332e9b21 100644
--- a/rlib/s/swi
+++ b/rlib/s/swi
@@ -128,10 +128,10 @@ os_swi
         MOV     r12, r0
         CMP     r1, #0
         BEQ     os_swi_noregset
-        STMDB   sp!, {r1}
+        STR     r1, [sp, #-4]!
         LDMIA   r1, {r0-r9}
         SWI     XOS_CallASWIR12
-        LDMIA   sp!, {ip}
+        LDR     ip, [sp], #4
         STMIA   ip, {r0-r9}
         Return  "v1-v6"
 os_swi_noregset
@@ -149,10 +149,10 @@ os_swix
         MOV     r12, r0
         CMP     r1, #0
         BEQ     os_swix_noregset
-        STMDB   sp!, {r1}
+        STR     r1, [sp, #-4]!
         LDMIA   r1, {r0-r9}
         SWI     XOS_CallASWIR12
-        LDMIA   sp!, {ip}
+        LDR     ip, [sp], #4
         STMIA   ip, {r0-r9}
         MOVVC   a1, #0
         Return  "v1-v6"
diff --git a/s/cxsupport b/s/cxsupport
index 7a6d8a604365d6ce0ff3c5fc3eb89630875ff584..415cc322f3d1b2b7e2fce7c58e34acd7a31ea4a5 100644
--- a/s/cxsupport
+++ b/s/cxsupport
@@ -16,12 +16,12 @@
 
         CodeArea
 
-        EXPORT  _cxd_mul
-        EXPORT  _cxf_mul
-        EXPORT  _cxd_div
-        EXPORT  _cxf_div
-        EXPORT  _cxd_rdv
-        EXPORT  _cxf_rdv
+        EXPORT  _cxd_mul [FPREGARGS]
+        EXPORT  _cxf_mul [FPREGARGS]
+        EXPORT  _cxd_div [FPREGARGS]
+        EXPORT  _cxf_div [FPREGARGS]
+        EXPORT  _cxd_rdv [FPREGARGS]
+        EXPORT  _cxf_rdv [FPREGARGS]
 
         EXPORT  __log_cabs
 
@@ -326,7 +326,7 @@ _cx_div
 ExtInf  DCD     &00007FFF, &00000000, &00000000
 
 
-_cxd_mul
+_cxd_mul ROUT
         SFMFD   f4,4,[sp]!
         MVFD    f4,f0
         MVFD    f5,f1
@@ -339,7 +339,7 @@ _cxd_mul
         LFMFD   f4,4,[sp]!
         MOV     pc,ip
 
-_cxf_mul
+_cxf_mul ROUT
         SFMFD   f4,4,[sp]!
         MVFS    f4,f0
         MVFS    f5,f1
@@ -352,7 +352,7 @@ _cxf_mul
         LFMFD   f4,4,[sp]!
         MOV     pc,ip
 
-_cxd_div
+_cxd_div ROUT
         SFMFD   f4,4,[sp]!
         MVFD    f4,f0
         MVFD    f5,f1
@@ -366,7 +366,7 @@ _cxd_div1
         LFMFD   f4,4,[sp]!
         MOV     pc,ip
 
-_cxd_rdv
+_cxd_rdv ROUT
         SFMFD   f4,4,[sp]!
         MVFD    f4,f2
         MVFD    f5,f3
@@ -374,7 +374,7 @@ _cxd_rdv
         MVFD    f7,f1
         B       _cxd_div1
 
-_cxf_div
+_cxf_div ROUT
         SFMFD   f4,4,[sp]!
         MVFS    f4,f0
         MVFS    f5,f1
@@ -388,7 +388,7 @@ _cxf_div1
         LFMFD   f4,4,[sp]!
         MOV     pc,ip
 
-_cxf_rdv
+_cxf_rdv ROUT
         SFMFD   f4,4,[sp]!
         MVFS    f4,f2
         MVFS    f5,f3
diff --git a/s/h_modmacro b/s/h_modmacro
index c71918915229b7519eae59d2473aa9638fe51240..cbd3a191adfff24e58ce5803c76509b259f05317 100644
--- a/s/h_modmacro
+++ b/s/h_modmacro
@@ -142,9 +142,10 @@ $Temps
         ; directlocal  if direct is <other>, and this is null, then <other>
         ;              is a local symbol, otherwise the value should be either
         ;              "EXPORT" or "IMPORT"
+        ; fpabi   floating point ABI qualifier(s) to add to IMPORT/EXPORT
 
         MACRO
-        Entry   $sym, $import, $sym2, $direct, $args, $directlocal
+        Entry   $sym, $import, $sym2, $direct, $args, $directlocal, $fpabi
         LCLS    Temps
    [ "$sym2" <> ""
 Temps   SETS    "$sym2"
@@ -153,7 +154,7 @@ Temps   SETS    "$sym"
    ]
 Temps   SETS    "$VBar":CC:Temps:CC:"$VBar"
    [ "$import"<>""
-        IMPORT  $Temps
+        IMPORT  $Temps $fpabi
    ]
         B       $Temps
         MEND
@@ -161,7 +162,7 @@ Temps   SETS    "$VBar":CC:Temps:CC:"$VBar"
 
 
         MACRO
-        Entry2   $sym, $import, $sym2, $direct, $args, $directlocal, $ignore
+        Entry2   $sym, $import, $sym2, $direct, $args, $directlocal, $ignore, $fpabi
         LCLS    Temps
    [ "$sym2" <> ""
 Temps   SETS    "$sym2"
@@ -170,7 +171,7 @@ Temps   SETS    "$sym"
    ]
 Temps   SETS    "$VBar":CC:Temps:CC:"$VBar"
    [ "$import"<>""
-        IMPORT  $Temps
+        IMPORT  $Temps $fpabi
    ]
         B       $Temps
         MEND
diff --git a/s/h_stubs b/s/h_stubs
index 2e264e1bdc59185eed14ded61bc5e3f316e82001..79b0282b24d35578678c57cb7ab03a4d9f6a6af2 100644
--- a/s/h_stubs
+++ b/s/h_stubs
@@ -27,21 +27,21 @@ fixedwssize     #       0
 VBar    SETS    "|"
 
         MACRO
-        Entry   $sym, $import, $sym2, $direct, $varargs, $directlocal
+        Entry   $sym, $import, $sym2, $direct, $varargs, $directlocal, $fpabi
         LCLS    temps
 temps   SETS    "$VBar":CC:"$sym":CC:"$VBar"
-        EXPORT  $temps
+        EXPORT  $temps $fpabi
 $temps  MOV     pc, #0
         MEND
 
         MACRO
-        Entry2  $sym, $import, $sym2, $direct, $varargs, $directlocal, $alias
+        Entry2  $sym, $import, $sym2, $direct, $varargs, $directlocal, $alias, $fpabi
         LCLS    temps
         LCLS    temps1
 temps   SETS    "$VBar":CC:"$sym":CC:"$VBar"
 temps1  SETS    "$VBar":CC:"$alias":CC:"$VBar"
-        EXPORT  $temps
-        EXPORT  $temps1
+        EXPORT  $temps $fpabi
+        EXPORT  $temps1 $fpabi
 $temps1
 $temps  MOV     pc, #0
         MEND
diff --git a/s/initmodule b/s/initmodule
index e16bdebef331c05f79e5132c5145309064730e89..97df8904fee055bb5f105d656642fb7052f08fa7 100644
--- a/s/initmodule
+++ b/s/initmodule
@@ -125,7 +125,7 @@ setresourcevar
 XMessageTrans_CloseFile EQU &61504 ; Put in hdr file someday
 
 |_Shared_Lib_Module_Die_Code|
-        STMDB   r13!, {lr}
+        STR     lr, [r13, #-4]!
 
         MOV     r0, #6
         MOV     r1, #0
@@ -144,7 +144,7 @@ XMessageTrans_CloseFile EQU &61504 ; Put in hdr file someday
         STR     r1, [r3]
 00
         CLRV
-        LDMIA   r13!, {pc}
+        LDR     pc, [r13], #4
 
 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ; This is the SWI Lib_Init code
@@ -270,7 +270,7 @@ ZeroInitClientStatics
         SUBS    r5, r5, r3
         BLE     DoneClientStatics
         MOV     r6, #0
-01      STMIA   r1!, {r6}
+01      STR     r6, [r1], #4
         SUBS    r5, r5, #4
         BGT     %B01
 
diff --git a/s/overmgr b/s/overmgr
index e23d9edd1673bd47df501d6722cd24393fcd17e2..fb566b8c032a6cc36406a7ae27efa8a270590652 100644
--- a/s/overmgr
+++ b/s/overmgr
@@ -320,7 +320,12 @@ Retry
  [ {CONFIG}=26
         LDMIA   IP, {R0-R8, LR, PC}^
  |
+      [ {FALSE} ; this instruction is now deprecated
         LDMIA   IP, {R0-R8, LR, PC}
+      |
+        LDMIA   IP, {R0-R8, LR}
+        LDR     PC, [IP, #10*4]
+      ]
  ]
 
 in_desktop
diff --git a/test/c/file b/test/c/file
new file mode 100644
index 0000000000000000000000000000000000000000..a788a3bdc220ba104c444d8797546f03f8b69375
--- /dev/null
+++ b/test/c/file
@@ -0,0 +1,170 @@
+/* Test harness for large file extensions
+ * Intended for use in debug builds where the file size check in fopen_common()
+ * has been disabled, and where OFF32_MAX has been reduced to 31
+ */
+
+#define _LARGEFILE_SOURCE
+#define _FILE_OFFSET_BITS 64
+
+#include <stdio.h>
+#include <errno.h>
+#include "swis.h"
+
+#define BUFSIZE 16
+
+int main(void)
+{
+  FILE *f;
+  char buffer[BUFSIZE];
+  int i;
+  char string[80];
+
+  /* Writing beyond file pointer limit */
+
+  errno = 0;
+  f = fopen("myfile", "w");
+  sprintf(string, "fopen errno = %d\n\r", errno);
+  _swix(OS_Write0, _IN(0), string);
+  if (f != NULL)
+  {
+    setvbuf(f, buffer, _IOFBF, BUFSIZE);
+
+    for (i = 0; i < 34; i++)
+    {
+      errno = 0;
+      int e = fputc(i, f);
+      sprintf(string, "fputc %d=%d errno = %d\n\r", i, e, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+
+    errno = 0;
+    fclose(f);
+    sprintf(string, "fclose errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+  }
+
+  /* Writing beyond file pointer limit, where the limit lies on a
+   * buffer boundary */
+
+  errno = 0;
+  f = fopen("myfile", "w");
+  sprintf(string, "fopen errno = %d\n\r", errno);
+  _swix(OS_Write0, _IN(0), string);
+  if (f != NULL)
+  {
+    setvbuf(f, buffer, _IOFBF, BUFSIZE);
+    errno = 0;
+    fseeko(f, 15, SEEK_SET);
+    sprintf(string, "fseeko errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+
+    for (i = 15; i < 34; i++)
+    {
+      errno = 0;
+      int e = fputc(i, f);
+      sprintf(string, "fputc %d=%d errno = %d\n\r", i, e, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+
+    errno = 0;
+    fclose(f);
+    sprintf(string, "fclose errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+  }
+
+  /* Reading beyond file pointer limit */
+
+  errno = 0;
+  f = fopen("myfile2", "r");
+  sprintf(string, "fopen errno = %d\n\r", errno);
+  _swix(OS_Write0, _IN(0), string);
+  if (f != NULL)
+  {
+    setvbuf(f, buffer, _IOFBF, BUFSIZE);
+
+    for (i = 0; i < 35; i++)
+    {
+      errno = 0;
+      int c = fgetc(f);
+      sprintf(string, "fgetc %d=%d errno = %d\n\r", i, c, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+
+    errno = 0;
+    fclose(f);
+    sprintf(string, "fclose errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+  }
+
+  /* Reading beyond file pointer limit, when data has been written
+   * up to a buffer boundary */
+
+  errno = 0;
+  f = fopen("myfile2", "r+");
+  sprintf(string, "fopen errno = %d\n\r", errno);
+  _swix(OS_Write0, _IN(0), string);
+  if (f != NULL)
+  {
+    setvbuf(f, buffer, _IOFBF, BUFSIZE);
+
+    for (i = 0; i < 16; i++)
+    {
+      errno = 0;
+      int e = fputc(i, f);
+      sprintf(string, "fputc %d=%d errno = %d\n\r", i, e, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+    errno = 0;
+    fseeko(f, 0, SEEK_CUR);
+    sprintf(string, "fseeko errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+    for (; i < 35; i++)
+    {
+      errno = 0;
+      int c = fgetc(f);
+      sprintf(string, "fgetc %d=%d errno = %d\n\r", i, c, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+
+    errno = 0;
+    fclose(f);
+    sprintf(string, "fclose errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+  }
+
+  /* Reading beyond file pointer limit, when data has been written
+   * up to NOT a buffer boundary */
+
+  errno = 0;
+  f = fopen("myfile2", "r+");
+  sprintf(string, "fopen errno = %d\n\r", errno);
+  _swix(OS_Write0, _IN(0), string);
+  if (f != NULL)
+  {
+    setvbuf(f, buffer, _IOFBF, BUFSIZE);
+
+    for (i = 0; i < /*13*/19; i++)
+    {
+      errno = 0;
+      int e = fputc(i, f);
+      sprintf(string, "fputc %d=%d errno = %d\n\r", i, e, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+    errno = 0;
+    fseeko(f, 0, SEEK_CUR);
+    sprintf(string, "fseeko errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+    for (; i < 35; i++)
+    {
+      errno = 0;
+      int c = fgetc(f);
+      sprintf(string, "fgetc %d=%d errno = %d\n\r", i, c, errno);
+      _swix(OS_Write0, _IN(0), string);
+    }
+
+    errno = 0;
+    fclose(f);
+    sprintf(string, "fclose errno = %d\n\r", errno);
+    _swix(OS_Write0, _IN(0), string);
+  }
+}