2009-11-22  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2009-10-24.

	* include/libsupp.h: Prototypes for towupper added.

	* src/c99/ctype/towupper.c: Implemented as wrapper to toupper.


2009-10-26  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* include/libsupp.h: GCC-4.4.X specific definitions for va_arg, etc. added.

	* src/include/libc/fsexthlp.h: Ditto.


2009-10-24  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/fcntl/open.c: Implementation of POSIX conforming handling
	of pathnames ending with a slash.  Will only be supported by libsupp
	and not by djgpp libc.a.

	* src/posix/fcntl/open-2.03.c: Ditto.

	* src/ansi/stdio/fopen.c: Implementation of POSIX conforming handling
	of pathnames ending with a slash.  Will only be supported by libsupp
	and not by djgpp libc.a.

	* src/ansi/stdio/fopen-2.03.c: Ditto.


2009-08-04  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2009-04-14.

	* src/posix/sys/stat/fstat-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.

	* include/libsupp.h: Prototypes for fstat_2_03 function added.


2009-08-03  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/unistd/dup-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.
	* src/posix/unistd/dup2-2.03.c: Ditto.
	* src/posix/unistd/read-2.03.c: Ditto.
	* src/posix/unistd/write-2.03.c: Ditto.

	* include/libsupp.h: Prototypes for dup_2_03, dup2_2_03, read_2_03 and
	write_2_03 functions added.


2009-08-02  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/fcntl/fcntl-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.
	* src/posix/stdio/fdopen-2.03.c: Ditto.

	* include/libsupp.h: Prototypes for fcntl_2_03 and fdopen_2_03
	functions added.


2009-08-01  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/compat/unistd/fsync-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.
	* src/compat/unistd/ftruncat-2.03.c: Ditto.
	* src/dos/io/_close-2.03.c: Ditto.
	* src/dos/io/_write-2.03.c: Ditto.

	* include/libsupp.h: Prototypes for select_2_03, fsync_2_03, ftruncat_2_03,
	_close_2_03 and _write_2_03 functions added.


2009-07-31  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/compat/time/select-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.

	* include/libsupp.h: Prototypes for select_2_03 function added.


2009-07-27  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/unistd/fflush-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.
	* src/ansi/stdio/flsbuf-2.03.c: Ditto.
	* src/ansi/stdio/freopen-2.03.c: Ditto.
	* src/ansi/stdio/fseek-2.03.c: Ditto.
	* src/ansi/stdio/ftell-2.03.c: Ditto.
	* src/ansi/stdio/rewind-2.03.c: Ditto.

	* src/include/libc/file-2.03.h: Added.

	* include/libsupp.h: Prototypes for fflush_2_03, flsbuf_2_03, freopen_2_03,
	fseek_2_03, ftell_2_03 and rewind_2_03 functions added.


2009-07-26  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/unistd/lseek-2.03.c: Added for a consistent use of the
	fd_properties struct with 2.03.
	* src/ansi/stdio/fclose-2.03.c: Ditto.

	* include/libsupp.h: Prototypes for lseek_2_03 and fclose_2_03 functions
	added.


2009-07-25  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/sys/stat/fchmod.c: Added for a consistent use of the fd_properties struct.
	* src/posix/sys/stat/fstat.c: Ditto.
	* src/posix/sys/stat/stat.c: Ditto.
	* src/posix/sys/statvfs/fstatvfs.c: Ditto.

	* include/libsupp.h: Prototypes for fchmod, fstat, stat and fstatvfs
	functions added.

	* src/compat/stdio/fseeko.c: Adjusted to use libsupp version of fseek.
	* src/compat/stdio/ftello.c: Adjusted to use libsupp version of ftell.

	* src/posix/unistd/close.c: Added for a consistent use of the fd_properties struct.


2009-07-24  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/compat/time/select.c: Added for a consistent use of the fd_properties struct.
	* src/compat/time/select.c: Ditto.
	* src/compat/unistd/fsync.c: Ditto.
	* src/compat/unistd/ftruncat.c: Ditto.
	* src/compat/unistd/llseek.c: Ditto.
	* src/dos/io/_close.c: Ditto.
	* src/dos/io/_write.c: Ditto.
	* src/posix/fcntl/fcntl.c: Ditto.
	* src/posix/stdio/fdopen.c: Ditto.
	* src/posix/unistd/dup.c: Ditto.
	* src/posix/unistd/dup2.c: Ditto.
	* src/posix/unistd/lseek.c: Ditto.
	* src/posix/unistd/pipe.c: Ditto.
	* src/posix/unistd/read.c: Ditto.
	* src/posix/unistd/write.c: Ditto.

	* include/libsupp.h: Prototypes for select, fsync, ftruncat, llseek,
	_close, _write, dup, dup2, lseek, pipe, read, and write functions added.


2009-07-23  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/ansi/stdio/fclose.c: Added for a consistent use of the fd_properties struct.
	* src/ansi/stdio/fflush.c: Ditto.
	* src/ansi/stdio/flsbuf.c: Ditto.
	* src/ansi/stdio/freopen.c: Ditto.
	* src/ansi/stdio/fseek.c: Ditto.
	* src/ansi/stdio/ftell.c: Ditto.
	* src/ansi/stdio/rewind.c: Ditto.

	* include/libsupp.h: Prototypes for fclose, fflush, flsbuf, freopen,
	fseek, ftell and rewind functions added.


2009-07-18  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* src/posix/fcntl/open.c: Implementation of POSIX conforming handling
	of pathnames ending with a slash.

	* src/posix/fcntl/open-2.03.c: Ditto.

	* src/posix/fcntl/fopen.c: Ditto.

	* src/posix/fcntl/fopen-2.03.c: Ditto.

	* include/libsupp.h: Prototypes for [f]open[-2.03].c added.

	* tests/test.c: Test for open added.


2009-06-20  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* include/libsupp.h: Macro _O_TEMPORARY as alias for O_TEMPORARY added
	for compatibility with other compilers.


2009-04-19  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2009-04-14

	* include/libsupp.h: Add SA_NOCLDSTOP, SA_RESTART, SA_NODEFER, SA_RESETHAND,
	SA_ONESHOT and SA_NOMASK and define them to zero if not defined.


2009-04-08  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* doc/supp.txi: Functions info added.
	* include/libsupp.h: Prototypes for atof and atold functions added.
	* src/ansi/stdlib/atof.c: Checked out from DJGPP's CVS tree.  Adjusted
	for the use with libsupp.
	* src/ansi/stdlib/atold.c: Ditto.


2009-04-04  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* tests/test.c: Check to testing %[aA] conversion specifiers of scanf added.
	* include/libsupp.h: Add SA_NOCLDSTOP and define it to zero.


2009-04-02  Juan Manuel Guerrero  <juan.guerrero@gmx.de>

	* include/libsupp.h: Prototypes for scanf family of functions added.
	* doc/supp.txi: Info for scanf family of functions added.


2009-02-02  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2009-02-01

	* src/libc/ansi/stdio/doscan.c: Checked out from DJGPP's CVS tree.  Adjusted
	for the use with libsupp.
	* src/ansi/stdio/fscanf.c: Ditto.
	* src/ansi/stdio/scanf.c: Ditto.
	* src/ansi/stdio/sscanf.c: Ditto.
	* src/libc/compat/stdio/vfscanf.S: Ditto.
	* src/libc/compat/stdio/vscanf.c: Ditto.
	* src/libc/compat/stdio/vsscanf.c: Ditto.


2009-01-03  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2008-12-31

	* include/libsupp.h: New macro USE_DJGPP_MBTOWC_FCTNS.  If defined multi byte functions
	from DJGPP's libc will be used.
	* src/libc/ansi/locale/libsupp_mblen.c: New implementation.
	* src/libc/ansi/locale/libsupp_mbrtowc.c: New implementation.  Wrapper to libsupp_mbtowc.
	* src/libc/ansi/locale/libsupp_mbtowc.c: New implementation.
	* src/libc/ansi/locale/libsupp_mbsinit.c: New implementation.


2008-12-20  Juan Manuel Guerrero  <juan.guerrero@gmx.de>
	Diffs against djgpp CVS head of 2008-12-20

	* include/libsupp.h: Added a linux and cygwin compatible mbstate_t struct.
	The library specific macro libsupp_mbstate_t is mapped to mbstate_t.
	* src/libc/ansi/stdlib/mbsinit.c: Reimplemented.

	* src/posix/dirent/readdir.c: Do not include dirent.h.  Include libsupp.h.
	Remove APPEND_STAR_DOT_STAR.
	* src/posix/dirent/opendir.c: Do not include dirent.h.  Include libsupp.h.
	Remove IS_ROOT_DIR, APPEND_STAR_DOT_STAR, __set_need_fake_dot_dotdot and
	_lfn_find_close.
	* src/posix/dirent/fake_dot.c: New file.  __set_need_fake_dot_dotdot now
	defined here.
	* src/posix/dirent/dirstruc.h: IS_ROOT_DIR and APPEND_STAR_DOT_STAR now
	defined here.


	* src/compat/string/cbf_strlcpy.c (libsupp_strlcpy): New function, deliberately
	designed to not require any assistance from the standard libraries.  Implemented
	and contributed by C.B. Falconer.
	(libsupp_strlcat): New function, deliberately designed to not require any assistance
	from the standard libraries.  Implemented and contributed by C.B. Falconer.
	* src/compat/string/memmem.c: New function.  Implementation of memmem
	* src/libc/ansi/locale/mbrtowc.c: New function.  Wrapper to mbtowc.
	* src/libc/ansi/stdlib/mbsinit.c: New function.


	* doc/libsupp.txi: libsupp documentation in texinfo format.
	* doc/supp.txi: libsupp documentation in texinfo format.
	* include/libsupp.h: Header of libsupp.a.
	* mklib.sh: Shell script to build and install the library.
	* src/ansi/stdio/doprnt.c: Checked out from DJGPP's CVS tree.  Adjusted
	for the use with libsupp.
	* src/ansi/stdio/fprintf.c: Ditto.
	* src/ansi/stdio/printf.c: Ditto.
	* src/ansi/stdio/snprintf.c: Ditto.
	* src/ansi/stdio/sprintf.c: Ditto.
	* src/ansi/stdio/vfprintf.c: Ditto.
	* src/ansi/stdio/vprintf.c: Ditto.
	* src/ansi/stdio/vsnprntf.c: Ditto.
	* src/ansi/stdio/vsprintf.c: Ditto.
	* src/ansi/stdlib/strtod.c: Ditto.
	* src/ansi/stdlib/strtold.c: Ditto.
	* src/ansi/time/strftime.c: Ditto.
	* src/c99/math/sgnbitd.c: Ditto.
	* src/c99/math/sgnbitf.c: Ditto.
	* src/c99/math/sgnbitld.c: Ditto.
	* src/c99/stdlib/strtof.c: Ditto.
	* src/compat/argz/add.c: New function.  Implementation of argz family
	of functions.
	* src/compat/argz/add_sep.c: Ditto.
	* src/compat/argz/append.c: Ditto.
	* src/compat/argz/count.c: Ditto.
	* src/compat/argz/create.c: Ditto.
	* src/compat/argz/creatsep.c: Ditto.
	* src/compat/argz/delete.c: Ditto.
	* src/compat/argz/extract.c: Ditto.
	* src/compat/argz/insert.c: Ditto.
	* src/compat/argz/next.c: Ditto.
	* src/compat/argz/replace.c: Ditto.
	* src/compat/argz/strngify.c: Ditto.
	* src/compat/stdio/asnprntf.c: Checked out from DJGPP's CVS tree.  Adjusted
	for the use with libsupp.
	* src/compat/stdio/asprintf.c: Ditto.
	* src/compat/stdio/cprintf.c: Ditto.
	* src/compat/stdio/fseeko.c: Ditto.
	* src/compat/stdio/ftello.c: Ditto.
	* src/compat/stdio/vasnprtf.c: Ditto.
	* src/compat/stdio/vasprntf.c: Ditto.




diff -aprNU5 libsupp-6.2.orig/doc/libsupp.txi libsupp-6.2/doc/libsupp.txi
--- libsupp-6.2.orig/doc/libsupp.txi	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/doc/libsupp.txi	2009-11-22 04:01:02 +0000
@@ -0,0 +1,70 @@
+\input texinfo   @c -*-texinfo-*-
+@c %**start of header
+@setfilename ./libsupp.info
+@settitle libsupp.a reference
+@c %**end of header
+
+@setchapternewpage odd
+@paragraphindent 0
+
+@ifinfo
+This is the reference manual for libsupp.a
+
+Copyright (c) 2008 DJ Delorie
+@end ifinfo
+
+@titlepage
+
+@sp 10
+@comment The title is printed in a large font.
+@center @titlefont{libsupp.a reference}
+
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 2008 DJ Delorie
+@end titlepage
+
+@node    Top,       Introduction,  (dir),    (dir)
+@comment node-name, next,          previous, up
+
+@top libsupp.a
+This is the reference manual for libsupp.a
+
+
+@menu
+* Introduction::
+
+* Functional Categories::  All public symbols listed by
+                           category
+
+* Alphabetical List::      All public symbols in alphabetical
+                           order
+
+@end menu
+
+@node    Introduction, Functional Categories, Top,      Top
+@comment node-name,    next,                  previous, up
+@chapter Introduction
+
+The supplementary library, @file{libsupp.a}, shall provide certain
+improved or missing functions from the standard C library, @file{libc.a},
+of DJGPP versions 2.04 beta and 2.03.  As with all libraries, this library
+must be linked before the standard C library, @file{libc.a}, is linked
+into your programs by the @file{gcc} control program.  This document
+gives the proper usage information about each of the functions and
+variables found in @file{libsupp.a}. 
+
+For each function or variable that the library provides, the definition
+of that symbol will include information on which header files to include
+in your source to obtain prototypes and type definitions relevant to the
+use of that symbol. 
+
+All provided functions are declared in the header in @file{libsupp.h}.
+
+@include supp.txi
+
+
+@contents
+@bye
+
diff -aprNU5 libsupp-6.2.orig/doc/supp.txi libsupp-6.2/doc/supp.txi
--- libsupp-6.2.orig/doc/supp.txi	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/doc/supp.txi	2009-11-22 04:01:02 +0000
@@ -0,0 +1,6679 @@
+@c -----------------------------------------------------------------------------
+@node Functional Categories, Alphabetical List, Introduction, Top
+@unnumbered Functional Categories
+
+@menu
+* argz functions::
+* file system functions::
+* io functions::
+* locale functions::
+* math functions::
+* memory functions::
+* stdio functions::
+* stdlib functions::
+* string functions::
+* time functions::
+* unix functions::
+@end menu
+@c -----------------------------------------------------------------------------
+@node argz functions, file system functions, , Functional Categories
+@unnumberedsec argz functions
+@menu
+* argz remarks::
+* argz_add::
+* argz_add_sep::
+* argz_count::
+* argz_create::
+* argz_create_sep::
+* argz_delete::
+* argz_extract::
+* argz_insert::
+* argz_next::
+* argz_replace::
+* argz_stringify::
+@end menu
+@c -----------------------------------------------------------------------------
+@node file system functions, io functions, argz functions, Functional Categories
+@unnumberedsec file system functions
+@menu
+* access::
+* chdir::
+* DTTOIF::
+* closedir::
+* fchdir::
+* fchmod::
+* fstatvfs::
+* opendir::
+* readdir::
+* realpath::
+* rewinddir::
+* _close::
+* _fixpath::
+* _write::
+@end menu
+@c -----------------------------------------------------------------------------
+@node io functions, locale functions, file system functions, Functional Categories
+@unnumberedsec io functions
+@menu
+* close::
+* dup::
+* dup2::
+* fcntl::
+* lfilelength::
+* llseek::
+* lseek::
+* lstat::
+* open::
+* read::
+* stat::
+* write::
+@end menu
+@c -----------------------------------------------------------------------------
+@node locale functions, math functions, io functions, Functional Categories
+@unnumberedsec locale functions
+@menu
+* mblen::
+* mbrtowc::
+* mbsinit::
+* mbtowc::
+@end menu
+@c -----------------------------------------------------------------------------
+@node math functions, memory functions, locale functions, Functional Categories
+@unnumberedsec math functions
+@menu
+* signbit::
+* __signbitd::
+* __signbitf::
+* __signbitld::
+@end menu
+@c -----------------------------------------------------------------------------
+@node memory functions, stdio functions, math functions, Functional Categories
+@unnumberedsec memory functions
+@menu
+* memmem::
+@end menu
+@c -----------------------------------------------------------------------------
+@node stdio functions, stdlib functions, memory functions, Functional Categories
+@unnumberedsec stdio functions
+@menu
+* asnprintf::
+* asprintf::
+* cprintf::
+* fclose::
+* fdopen::
+* fflush::
+* fprintf::
+* freopen::
+* fscanf::
+* fseek::
+* fseeko::
+* fstat::
+* fsync::
+* ftell::
+* ftello::
+* ftruncate::
+* printf::
+* rewind::
+* scanf::
+* snprintf::
+* sprintf::
+* sscanf::
+* vasnprintf::
+* vasprintf::
+* vfprintf::
+* vfscanf::
+* vprintf::
+* vscanf::
+* vsnprintf::
+* vsprintf::
+* vsscanf::
+* _doprnt::
+* _doscan::
+@end menu
+@c -----------------------------------------------------------------------------
+@node stdlib functions, string functions, stdio functions, Functional Categories
+@unnumberedsec stdlib functions
+@menu
+* atof::
+* _atold::
+@end menu
+@c -----------------------------------------------------------------------------
+@node string functions, time functions, stdlib functions, Functional Categories
+@unnumberedsec string functions
+@menu
+* strlcat::
+* strlcpy::
+* strndup::
+* strnicmp::
+* strnlen::
+* strtod::
+* strtof::
+* strtold::
+* _strtold::
+@end menu
+@c -----------------------------------------------------------------------------
+@node time functions, unix functions, string functions, Functional Categories
+@unnumberedsec time functions
+@menu
+* strftime::
+@end menu
+@c -----------------------------------------------------------------------------
+@node unix functions, , time functions, Functional Categories
+@unnumberedsec unix functions
+@menu
+* pipe::
+* select::
+@end menu
+@c -----------------------------------------------------------------------------
+@node Alphabetical List, , Functional Categories, Top
+@unnumbered Alphabetical List
+@menu
+* access::
+* argz remarks::
+* argz_add::
+* argz_add_sep::
+* argz_count::
+* argz_create::
+* argz_create_sep::
+* argz_delete::
+* argz_extract::
+* argz_insert::
+* argz_next::
+* argz_replace::
+* argz_stringify::
+* asnprintf::
+* asprintf::
+* atof::
+* chdir::
+* close::
+* closedir::
+* cprintf::
+* DTTOIF::
+* dup::
+* dup2::
+* fchdir::
+* fchmod::
+* fclose::
+* fdopen::
+* fcntl::
+* fflush::
+* fopen::
+* fprintf::
+* freopen::
+* fscanf::
+* fseek::
+* fseeko::
+* fstat::
+* fstatvfs::
+* fsync::
+* ftell::
+* ftello::
+* ftruncate::
+* lfilelength::
+* llseek::
+* lseek::
+* lstat::
+* mblen::
+* mbrtowc::
+* mbsinit::
+* mbtowc::
+* memmem::
+* open::
+* opendir::
+* pipe::
+* printf::
+* read::
+* readdir::
+* realpath::
+* rewind::
+* rewinddir::
+* scanf::
+* select::
+* signbit::
+* snprintf::
+* sprintf::
+* sscanf::
+* stat::
+* strftime::
+* strlcat::
+* strlcpy::
+* strndup::
+* strnicmp::
+* strnlen::
+* strtod::
+* strtof::
+* strtold::
+* vasnprintf::
+* vasprintf::
+* vfprintf::
+* vfscanf::
+* vprintf::
+* vscanf::
+* vsnprintf::
+* vsprintf::
+* vsscanf::
+* write::
+* _atold::
+* _close::
+* _doprnt::
+* _doscan::
+* _fixpath::
+* _strtold::
+* _write::
+* __signbitd::
+* __signbitf::
+* __signbitld::
+@end menu
+@c -----------------------------------------------------------------------------
+@node access, argz remarks, , Alphabetical List
+@unnumberedsec access
+@c From file ./posix/unistd/access.txh
+@findex access
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int access(const char *filename, int flags);
+@end example
+
+@subheading Description
+
+This function determines what kind of access modes a given file allows. 
+The parameter @var{flags} is the logical @code{or} of one or more of the
+following flags:
+
+@table @code
+
+@item R_OK
+
+Request if the file is readable.  Since all files are readable under
+MS-DOS, this access mode always exists. 
+
+@item W_OK
+
+Request if the file is writable.
+
+@item X_OK
+
+Request if the file is executable.
+
+@item F_OK
+
+Request if the file exists.
+
+@item D_OK
+
+Request if the file is really a directory.
+
+@end table
+
+@subheading Return Value
+
+Zero if the requested access mode is allowed, nonzero if not. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+if (access("file.ext", W_OK))
+  return ERROR_CANNOT_WRITE;
+open("file.ext", O_RDWR);
+@end example
+
+@c -----------------------------------------------------------------------------
+@node argz remarks, argz_add, access, Alphabetical List
+@unnumberedsec argz remarks
+@c From file ./compat/argz/argz.txh
+@cindex argz remarks
+
+
+These functions are glibc-specific and a GNU extension, so handle with care.
+
+An argz vector is a pointer to a character buffer together with a length.  The
+intended interpretation of the character buffer is array of strings, where the
+strings are separated by @code{NUL} bytes.  If the length is nonzero, the last
+byte of the buffer must be a @code{NUL} byte.  These functions are for handling
+argz vectors.  The pair (@code{NULL}, 0) is an argz  vector, and, conversely,
+argz vectors of length 0 must have @code{NULL} pointer.  Allocation of nonempty
+argz vectors is done using malloc, so that free can be used to dispose of them
+again.
+
+Argz vectors without final @code{NUL} may lead to Segmentation Faults.
+
+
+@subheading Return Value
+
+All argz functions that do memory allocation have a return type of @code{error_t},
+and return 0 for success, and ENOMEM if an allocation error occurs.
+
+@c -----------------------------------------------------------------------------
+@node argz_add, argz_add_sep, argz remarks, Alphabetical List
+@unnumberedsec argz_add
+@c From file ./compat/argz/add.txh
+@findex argz_add
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_add(char **argz, size_t *argz_len, const char *str)
+@end example
+
+@subheading Description
+
+Adds the string @var{str} to the end of the argz vector @var{argz} of length @var{argz_len}.
+If the string @var{str} was successfully added then the length @var{argz_len} will be increased
+accordingly.  Because the function modifies the argz vector, both its length @var{argz_len} and
+@var{argz} itself must be passed as pointers.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *str = "foobar";  /*  String to be added to argz.  */
+error_t error;
+
+error = argz_add(&argz, &argz_len, str);
+
+if (error)
+@{
+  printf("error: String %s could not be added to argz.\n", str);
+  exit(ENOMEM);
+@}
+else
+@{
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_add_sep, argz_count, argz_add, Alphabetical List
+@unnumberedsec argz_add_sep
+@c From file ./compat/argz/add_sep.txh
+@findex argz_add_sep
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_add_sep(char **argz, size_t *argz_len, const char *str,
+                     int sep)
+@end example
+
+@subheading Description
+
+Adds the string @var{str} to the end of the argz vector @var{argz} of length @var{argz_len}.
+For every occurence of the delimiter @var{sep} in @var{str}, the delimiter is replaced by
+the @code{NUL} byte as separating token.  If the string @var{str} was successfully added
+then the length @var{argz_len} will be increased accordingly.  Because the function modifies
+the argz vector, both its length @var{argz_len} and itself @var{argz} must be passed as pointers.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *str = "foo:bar:foo";  /*  String to be added to argz.  */
+int delimiter = ':';  /*  Separator token.  Every ':' in str  */
+                      /*  will be replaced with '\0'.  */
+error_t error;
+
+error = argz_add_sep(&argz, &argz_len, str, delimiter);
+
+if (error)
+@{
+  printf("error: String %s could not be added to argz.\n", str);
+  exit(ENOMEM);
+@}
+else
+@{
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_count, argz_create, argz_add_sep, Alphabetical List
+@unnumberedsec argz_count
+@c From file ./compat/argz/count.txh
+@findex argz_count
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+size_t argz_count(const char *argz, size_t argz_len)
+@end example
+
+@subheading Description
+
+Counts the number of strings contained in the argz vector @var{argz} of length @var{argz_len}.
+Every string must be terminated with a @code{NUL} byte to be counted.
+
+@subheading Return Value
+
+The number of strings.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+size_t entries;
+
+entries = argz_count(argz, argz_len);
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_create, argz_create_sep, argz_count, Alphabetical List
+@unnumberedsec argz_create
+@c From file ./compat/argz/create.txh
+@findex argz_create
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_create(char *const argv[], char **argz, size_t *argz_len)
+@end example
+
+@subheading Description
+
+Makes a @code{NUL} byte separated argz vector from a string array @var{argv},
+returning it via the pointer **@var{argz} and the total length via the pointer
+*@var{argz_len}.  The string array @var{argv} must be a Unix-style argument
+vector @code{argv} (a vector of pointers to normal C strings, terminated by @code{NULL}).
+Because the function modifies the argz vector, both its length @var{argz_len} and @var{argz}
+itself must be passed as pointers.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *const _argv[] = @{
+  "foo",
+  "bar",
+  NULL
+@};
+char *argz;  /*  Buffer will be allocated by argz_create.  */
+size_t argz_len;
+error_t error;
+
+
+error = argz_create(_argv, &argz, &argz_len);
+
+if (error)
+@{
+  printf("error: argz vector could not be created.\n");
+  exit(error);
+@}
+else
+@{
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_create_sep, argz_delete, argz_create, Alphabetical List
+@unnumberedsec argz_create_sep
+@c From file ./compat/argz/creatsep.txh
+@findex argz_create_sep
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_create_sep(const char *str, int sep, char **argz,
+                        size_t *argz_len)
+@end example
+
+@subheading Description
+
+Makes a @code{NUL} byte separated argz vector from a @var{sep} separated list in
+@var{str}, returning it via the pointer **@var{argz} and the total length via the pointer
+*@var{argz_len}.  Because the function modifies the argz vector, both its length @var{argz_len}
+and @var{argz} itself must be passed as pointers.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *path = "c:\\foo;c:\\bar;c:\\temp";
+int path_sep = ';';
+char *argz;  /*  Buffer will be allocated by argz_create_sep.  */
+size_t argz_len;
+error_t error;
+
+
+error = argz_create_sep(path, path_sep, &argz, &argz_len);
+
+if (error)
+@{
+  printf("error: argz vector could not be created.\n");
+  exit(error);
+@}
+else
+@{
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_delete, argz_extract, argz_create_sep, Alphabetical List
+@unnumberedsec argz_delete
+@c From file ./compat/argz/delete.txh
+@findex argz_delete
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+void argz_delete(char **argz, size_t *argz_len, char *entry)
+@end example
+
+@subheading Description
+
+Deletes the string @var{entry} from the argz vector in @var{argz} adjusting its
+length @var{argz_len} accordingly.  Because the function modifies the argz
+vector, both its length @var{argz_len} and @var{argz} itself must be passed as
+pointers.
+
+@subheading Return Value
+
+Nothing.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+argz_delete(&argz, &argz_len, "FOOBAR");
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_extract, argz_insert, argz_delete, Alphabetical List
+@unnumberedsec argz_extract
+@c From file ./compat/argz/extract.txh
+@findex argz_extract
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_extract(char *argz, size_t argz_len, char **argv)
+@end example
+
+@subheading Description
+Converts the @code{NUL} byte separated argz vector @var{argz} of length @var{argz_len}
+into a Unix-style argument vector @var{argv} (a vector of pointers to normal
+C strings, terminated by @code{NULL}) by storing the pointers to every string in
+@var{argz} in @var{argv}.  The user must supply a @var{argv} large enough to contain
+all pointers and the terminating @code{NULL} pointer.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char **_argv;  /*  Unix-style argument vector.  */
+size_t entries;
+error_t error;
+
+entries = argz_count(argz, argz_len);  /*  Get number of strings  */
+                                       /*  contained in argz.  */
+_argv = malloc((entries + 1) * sizeof(char *));  /* One entry more for */
+                                                 /* the terminating NULL. */
+error = argz_extract(argz, argz_len, _argv);
+
+if (error)
+@{
+  printf("error: Strings could not be extracted from argz.\n", str);
+  free(_argv);
+  exit(ENOMEM);
+@}
+else
+@{
+  size_t i;
+
+  for (i = 0; _argv[i]; i++)
+    printf("argv[%zi] = \"%s\"\n", i, _argv[i]);
+
+  free(_argv);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_insert, argz_next, argz_extract, Alphabetical List
+@unnumberedsec argz_insert
+@c From file ./compat/argz/insert.txh
+@findex argz_insert
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_insert(char **argz, size_t *argz_len, char *before,
+                    const char *entry)
+@end example
+
+@subheading Description
+
+Inserts the string @var{entry} into the argz vector @var{argz} of length @var{argz_len}
+before the string @var{before}, which should be an existing entry in @var{argz}; if @var{before}
+is @code{NULL}, @var{entry} is appended to the end.  Since @var{argz}'s first entry is the
+same as @var{argz}, @code{argz_insert(ARGZ, ARGZ_LEN, ARGZ, ENTRY)} will insert @var{entry}
+at the beginning of @var{argz}.  Because the function modifies the argz vector, both its
+length @var{argz_len} and @var{argz} itself must be passed as pointers.
+
+@subheading Return Value
+
+If @var{before} is not in @var{argz}, EINVAL is returned,
+else if memory can't be allocated for the new @var{argz},
+ENOMEM is returned, else 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *entry = "foobar";  /*  String to be inserted into argz.  */
+error_t error;
+
+error = argz_insert(&argz, &argz_len, before, entry);
+
+switch (error)
+@{
+case EINVAL:
+  printf("error: Entry \"%s\" is not in argz.\n", before);
+  exit(EINVAL);
+  break;
+case ENOMEM:
+  printf("error: Not enough memory to insert \"%s\" into argz.\n", entry);
+  exit(ENOMEM);
+  break;
+default:
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_next, argz_replace, argz_insert, Alphabetical List
+@unnumberedsec argz_next
+@c From file ./compat/argz/next.txh
+@findex argz_next
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+char *argz_next(const char *argz, size_t argz_len, const char *entry)
+@end example
+
+@subheading Description
+
+Returns the next entry in @var{argz} of length @var{argz_len} after the string @var{entry},
+or @code{NULL} if there are no more.  If entry is @code{NULL}, then the first entry is returned.
+
+@subheading Return Value
+
+A pointer to the entry or NULL.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *next_entry;
+
+next_entry = argz_next(argz, argz_len, entry);
+
+if (next_entry == NULL)
+@{
+  printf("error: No more entries in argz.\n");
+@}
+else
+@{
+  do_something_with(next_entry);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_replace, argz_stringify, argz_next, Alphabetical List
+@unnumberedsec argz_replace
+@c From file ./compat/argz/replace.txh
+@findex argz_replace
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+error_t argz_replace(char **argz, size_t *argz_len, const char *str, const char *with,
+                     unsigned *replace_count)
+@end example
+
+@subheading Description
+
+Replaces any occurrences of the string @var{str} in the argz vector @var{argz} with the string @var{with},
+reallocating @var{argz} as necessary.  If @var{replace_count} is non-zero, *@var{replace_count} will be
+incremented by the number of replacements performed.  Because the function modifies the argz vector,
+both its length @var{argz_len} and @var{argz} itself must be passed as pointers.
+
+@subheading Return Value
+
+If a memory allocation error occurs, ENOMEM is returned, otherwise 0.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *str = "foobar";  /*  String to be replaced in argz.  */
+char *with = "BARFOO"; /*  Replacement.  */
+error_t error;
+
+error = argz_replace(&argz, &argz_len, str, with, NULL);
+
+if (error)
+@{
+  printf("error: \"%s\" could not be replaced by \"%s\" in argz.\n", str, with);
+  exit(ENOMEM);
+@}
+else
+@{
+  do_something_with(argz, argz_len);
+  free(argz);  /*  Free the resources.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node argz_stringify, asnprintf, argz_replace, Alphabetical List
+@unnumberedsec argz_stringify
+@c From file ./compat/argz/strngify.txh
+@findex argz_stringify
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+void argz_stringify(char *argz, size_t argz_len, int sep)
+@end example
+
+@subheading Description
+
+Makes a @code{NUL} byte separated argz vector @var{argz} printable by converting
+all the @code{NUL}s except the last into the character @var{sep}.
+
+@subheading Return Value
+
+Nothing.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+
+argz_stringify(argz, argz_len, '/');
+
+@end example
+@c -----------------------------------------------------------------------------
+@node asnprintf, asprintf, argz_stringify, Alphabetical List
+@unnumberedsec asnprintf
+@c From file ./compat/stdio/asnprntf.txh
+@findex asnprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int asnprintf(char **bufferp, size_t n, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments (@dots{}) including
+the terminating null byte to the allocated buffer and returns
+a pointer to it via the first parameter *@var{bufferp}.  This
+memory must be returned to the heap with @code{free} (@pxref{free,,,libc.info}).
+This function will write @var{n} - 1 characters.  The @var{n}th character
+is used for the terminating nul.  If @var{n} is zero, @var{buffer} is not
+touched.  This function is analog of @code{snprintf()} (@pxref{snprintf}).
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding the trailing
+nul) is returned; otherwise EOF is returned to flag encoding or buffer space
+errors.
+
+The maximum accepted value of @var{n} is @code{INT_MAX}.  @code{INT_MAX} is
+defined in @code{<limits.h>}.  EOF is returned and @code{errno} is set to
+@code{EFBIG}, if @var{n} is greater than this limit.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No (see note 1)
+@item POSIX
+@tab No
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The buffer size limit is imposed by DJGPP.  Other systems may not have this limitation.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char *strbuf;  /*  Pointer to the buffer allocated by asnprintf.  */
+int strlng;
+long double pi = 3.1415926535897932384626433832795L;
+
+strlng = asnprintf(&strbuf, 100, "Pi = %.15Lf\n", pi);
+
+if (EOF == strlng)
+  printf("error: asnprintf failed.\n");
+else
+@{
+  /*
+   *  Your code using the buffer allocated by asnprintf.
+   */
+  do_something(strbuf, strlng);
+
+  free(strbuf);  /*  Release the memory allocated by asnprintf.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node asprintf, atof, asnprintf, Alphabetical List
+@unnumberedsec asprintf
+@c From file ./compat/stdio/asprintf.txh
+@findex asprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int asprintf(char **bufferp, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments (@dots{}) including
+the terminating null byte to the allocated buffer and returns
+a pointer to it via the first parameter *@var{bufferp}.  This
+memory must be returned to the heap with @code{free} (@pxref{free,,,libc.info}). 
+This function is analog of @code{sprintf()} (@pxref{sprintf}).
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding
+the terminating null byte) is returned; otherwise EOF is returned
+to flag encoding or buffer space errors and the pointer
+*@var{bufferp} is set to @code{NULL}.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *strbuf;  /*  Pointer to the buffer allocated by asprintf.  */
+int strlng;
+long double pi = 3.1415926535897932384626433832795L;
+
+strlng = asprintf(&strbuf, "Pi = %.15Lf\n", pi);
+
+if (EOF == strlng)
+  printf("error: asprintf failed.\n");
+else
+@{
+  /*
+   *  Your code using the buffer allocated by asprintf.
+   */
+  do_something(strbuf, strlng);
+
+  free(strbuf);  /*  Release the memory allocated by asprintf.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node atof, chdir, asprintf, Alphabetical List
+@unnumberedsec atof
+@c From file ./ansi/stdlib/atof.txh
+@findex atof
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+double atof(const char *string);
+@end example
+
+@subheading Description
+
+Convert as much of the string as possible to an equivalent double
+precision real number. 
+
+This function is almost like @code{strtod(string, NULL)} (@pxref{strtod}).
+
+@subheading Return Value
+
+The equivalent value, or zero if the string does not represent a number. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+main(int argc, char **argv)
+@{
+  double d = atof(argv[1]);
+  @dots{}
+@end example
+
+@c ----------------------------------------------------------------------
+@node chdir, close, atof, Alphabetical List
+@unnumberedsec chdir
+@c From file ./posix/unistd/chdir.txh
+@findex chdir
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int chdir(const char *new_directory);
+@end example
+
+@subheading Description
+
+This function changes the current directory to @var{new_directory}.
+If a drive letter is specified, the current directory for that drive
+is changed and the current disk is set to that drive, else the current
+directory for the current drive is changed.
+
+@subheading Return Value
+
+Zero if the new directory exists, else nonzero and @code{errno} set if error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+if (chdir("/tmp"))
+  perror("/tmp");
+@end example
+
+@c -----------------------------------------------------------------------------
+
+@node close, closedir, chdir, Alphabetical List
+@unnumberedsec close
+@c From file ./posix/unistd/close.txh
+@findex close
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int close(int fd);
+@end example
+
+@subheading Description
+
+The open file associated with @var{fd} is closed.
+
+@subheading Return Value
+
+Zero if the file was closed, nonzero if @var{fd} was invalid or already closed.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+int fd = open("data", O_RDONLY);
+close(fd);
+@end example
+@c -----------------------------------------------------------------------------
+@node closedir, cprintf, close, Alphabetical List
+@unnumberedsec closedir
+@c From file ./posix/dirent/closedir.txh
+@findex closedir
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int closedir(DIR *dir);
+@end example
+
+@subheading Description
+
+This function closes a directory opened by opendir (@pxref{opendir}).
+
+@subheading Return Value
+
+Zero on success, nonzero if @var{dir} is invalid.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node cprintf, DTTOIF, closedir, Alphabetical List
+@unnumberedsec cprintf
+@findex cprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int cprintf(const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Like @code{printf} (@pxref{printf}), but prints through the console,
+taking into consideration window borders and text attributes.  This
+implementation of cprintf allocates and releases the buffer at runtime
+so there is no more limit on the size of each individual cprintf call.
+
+@subheading Return Value
+
+The number of characters written.
+
+@subheading Portability
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+@subheading Implementation Note
+
+It's not safe to call this function inside static constructors, because
+conio needs to be initialized, and its initialization is done by a
+static constructor.  Since you don't have any control on the order in
+which static constructors are called (it's entirely up to the linker),
+you could have problems.
+
+If you can detect the situation when one of the conio functions is
+called for the very first time since program start, you could work
+around this problem by calling the @code{gppconio_init} function
+manually (this is the function called by a static constructor).
+@c -----------------------------------------------------------------------------
+@node DTTOIF, dup, cprintf, Alphabetical List
+@unnumberedsec DTTOIF
+@c From file ./posix/dirent/readdir.txh
+@findex DTTOIF
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+struct dirent *de;
+mode_t file_mode = DTTOIF(de->d_type)
+@end example
+
+@subheading Description
+
+This macro converts the @code{d_type} member of a @code{struct dirent}
+variable, as returned by @code{readdir} (@pxref{readdir}) to an
+equivalent value of the @code{st_mode} member of a @code{struct stat}
+variable (@pxref{stat,,,libc.info}).
+
+Note that the access rights are not set in the result returned by this
+macro.  Only the file-type information is copied.
+
+@subheading Return Value
+
+The file's mode bits are returned.  If the argument has the value
+@code{DT_UNKNOWN}, the result will be @code{S_IFREG}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+This macro is available on systems which support the @code{d_type} member in @code{struct dirent}.
+@end enumerate
+@c -----------------------------------------------------------------------------
+@node dup, dup2, DTTOIF, Alphabetical List
+@unnumberedsec dup
+@c From file ./posix/unistd/dup.txh
+@findex dup
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int dup(int old_handle);
+@end example
+
+@subheading Description
+
+This function duplicates the given file handle.  Both handles refer to
+the same file and file pointer. 
+
+@subheading Return Value
+
+The new file handle, or -1 if error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+do_file(dup(fileno(stdin)));
+@end example
+@c -----------------------------------------------------------------------------
+@node dup2, fchdir, dup, Alphabetical List
+@unnumberedsec dup2
+@c From file ./posix/unistd/dup2.txh
+@findex dup2
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int dup2(int existing_handle, int new_handle);
+@end example
+
+@subheading Description
+
+This call causes @var{new_handle} to refer to the same file and file
+pointer as @var{existing_handle}.  If @var{new_handle} is an open file,
+it is closed. 
+
+@subheading Return Value
+
+The new handle, or -1 on error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+/* copy new file to stdin stream */
+close(0);
+dup2(new_stdin, 0);
+close(new_stdin);
+@end example
+@c -----------------------------------------------------------------------------
+@node fchdir, fchmod, dup2, Alphabetical List
+@unnumberedsec fchdir
+@c From file ./posix/unistd/fchdir.txh
+@findex fchdir
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fchdir(int fd);
+@end example
+
+@subheading Description
+
+This function changes the current directory to the directory
+described by the file descriptor @var{fd}.
+
+@subheading Return Value
+
+Zero on success, else nonzero and @var{errno} set if error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+int fd;
+
+fd = open("dir", O_RDONLY);
+fchdir(fd);
+@end example
+@c -----------------------------------------------------------------------------
+@node fchmod, fclose, fchdir, Alphabetical List
+@unnumberedsec fchmod
+@c From file ./posix/sys/stat/fchmod.txh
+@findex fchmod
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fchmod(int fd, mode_t mode);
+@end example
+
+@subheading Description
+
+This function changes the mode (writable or write-only) of the file
+opened under the file descriptor @var{fd}.  The value of @var{mode}
+can be a combination of one or more of the @code{S_I*} constants
+described in the description of the @code{chmod} function (@pxref{chmod,,,libc.info}).
+
+Some @code{S_I*} constants are ignored for regular files:
+
+@itemize @bullet
+@item
+@code{S_I*GRP} and @code{S_I*OTH} are ignored, because DOS/Windows
+has no concept of ownership, so all files are considered to belong
+to the user;
+
+@item
+@code{S_IR*} are ignored, because files are always readable on DOS/Windows.
+@end itemize
+
+@code{fchmod} will always succeed for character devices, but the mode
+will be ignored.
+
+@code{fchmod} may not be able to change the mode of files that have been
+opened using low-level methods.  High-level methods for opening files
+include the @code{fopen} (@pxref{fopen}) and @code{open} (@pxref{open})
+functions.  Low-level methods include the @code{_open} (@pxref{F_open,,,libc.info})
+and @code{_dos_open} (@pxref{F_dos_open,,,libc.info}) functions.  In particular,
+redirected handles cannot have their mode changed with @code{fchmod}.
+
+@code{fchmod} may also not work as expected under DOS.  For instance,
+if a file is opened as read-write, then changed to read-only
+with @code{fchmod}, but then written to, then the mode will not
+be changed.
+
+This function can be hooked by File System Extensions
+(@pxref{File System Extensions,,,libc.info}).
+
+@subheading Return Value
+
+Zero if the file exists and the mode was changed, else -1.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+int fd;
+
+fd = open("/tmp/dj.dat", O_RDWR);
+fchmod(fd, S_IWUSR|S_IRUSR);
+@end example
+@c -----------------------------------------------------------------------------
+@node fclose, fdopen, fchmod, Alphabetical List
+@unnumberedsec fclose
+@c From file ./ansi/stdio/fclose.txh
+@findex fclose
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fclose(FILE *file);
+@end example
+
+@subheading Description
+
+This function closes the given @var{file}.
+
+@subheading Return Value
+
+Zero on success, else @code{EOF}. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+FILE *f = fopen("data", "r");
+fprintf(f, "Hello\n");
+fclose(f);
+@end example
+@c -----------------------------------------------------------------------------
+@node fdopen, fcntl, fclose, Alphabetical List
+@unnumberedsec fdopen
+@c From file ./posix/stdio/fdopen.txh
+@findex fdopen
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+FILE *fdopen(int fd, const char *mode);
+@end example
+
+@subheading Description
+
+This function opens a stream-type file that uses the given @var{fd}
+file, which must already be open.  The file is opened with the modes
+specified by @var{mode}, which is the same as for @code{fopen}. 
+@xref{fopen}.
+
+@subheading Return Value
+
+The newly created @code{FILE *}, or @code{NULL} on error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+FILE *stdprn = fdopen(4, "w");
+@end example
+@c -----------------------------------------------------------------------------
+@node fcntl, fflush, fdopen, Alphabetical List
+@unnumberedsec fcntl
+@c From file ./posix/fcntl/fcntl.txh
+@findex fcntl
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fcntl (int fd, int cmd, ...);
+@end example
+
+@subheading Description
+
+This function performs the operation specified by @var{cmd} on
+the file open on handle @var{fd}.  The following operations are defined
+by the header @code{fcntl.h}:
+
+@table @code
+@item F_DUPFD
+Returns a file handle that duplicates @var{fd} like @code{dup} does
+(@pxref{dup}), except that @code{fcntl} also makes sure the returned
+handle is the lowest available handle greater than or equal to the
+integer value of the third argument.
+
+@item F_GETFD
+Get the @code{FD_CLOEXEC} close-on-exec (a.k.a.@: no-inherit) status of
+@var{fd}.  If the returned value has its least-significant bit set, the
+file will not be inherited by programs invoked by this process;
+otherwise, the file will remain open in the child processes.
+
+Note that only the first 20 handles can be passed to child processes by
+DOS/Windows; handles beyond that cannot be inherited.  In addition, the
+stub loader of the child DJGPP program will forcibly close handles 19
+and 18 (since otherwise it will be unable to read the COFF executable
+information and enter protected mode).  Therefore, the current
+implementation always returns @code{FD_CLOEXEC} for handles 18 and
+above.
+
+For handles less than 18, the call will try to determine the status of
+the @code{O_NOINHERIT} flag for that file and will return either
+@code{FD_CLOEXEC} if the flag is set, or 0 if the flag is not set.  If
+the status of the @code{O_NOINHERIT} flag cannot be determined, the call
+will return -1, setting @code{errno} to @code{ENOSYS}.
+
+The no-inherit bit can be set when the file is opened by using the
+@code{O_NOINHERIT} in the open flags; see @ref{open}.
+
+@item F_SETFD
+Set or unset the close-on-exec flag for the handle @var{fd} using the
+LSB of the integer value supplied as the third argument.  Since only the
+first 20 handles are passed to child programs, and since the stub loader
+of the child DJGPP program will forcibly close handles 19 and 18 (since
+otherwise it will be unable to read the COFF executable information and
+enter protected mode), the flag can only be set or unset on the first 18
+handles.  Attempts to set the flag for handles 18 or above will always
+return 0, and attempts to unset the flag for handles 18 or above will
+always return -1, setting @code{errno} to @code{ENOSYS}.
+
+For handles less than 18, the call will try to set or unset the
+@code{O_NOINHERIT} flag for that file and will return 0 if the flag is
+changed.  If the @code{O_NOINHERIT} flag cannot be changed, the call
+will return -1, setting @code{errno} to @code{ENOSYS}.
+  
+@item F_GETFL
+Get the open mode and status flags associated with the handle @var{fd}.
+The flags are those supported by @code{open} and @code{creat} functions,
+like @code{O_RDONLY}, @code{O_APPEND}, etc.
+
+On Windows NT this cannot report the open mode correctly ---
+@code{O_RDONLY} is always returned.
+
+@item F_SETFL
+Set the open mode and status flags associated with the handle @var{fd}.
+This fails in all but one case, and sets @code{errno} to @code{ENOSYS},
+since DOS and Windows don't allow changing the descriptor flags after
+the file is open.
+
+The one allowed case is for @code{O_NONBLOCK}, since DJGPP doesn't
+support it anyway.  That is, calls using @code{F_SETFL} will fail for
+all flag values @strong{except} @code{O_NONBLOCK}.
+
+@example
+#include <fcntl.h>
+
+ret = fcntl(fd, F_SETFL, O_BINARY); /* This will fail, returning -1  */
+                                    /* and setting errno to ENOSYS.  */
+
+ret = fcntl(fd, F_SETFL, O_NONBLOCK); /* This will succeed          */
+                                      /* returning 0.               */
+@end example
+
+@item F_GETLK
+Return the lock structure that prevents obtaining the lock pointed to by
+the third argument, or set the @code{l_type} field of the lock structure
+to @code{F_UNLCK} if there is no obstruction.  Currently, only the
+setting of the @code{l_type} field is provided.  This call will not
+return values in the @code{struct flock} parameter identifying what lock
+parameters prevent getting the requested lock, since there is no way to
+obtain this information from DOS/Windows.  If the lock cannot be
+obtained, -1 is returned and @code{errno} is set to the reason (which
+will be one of @code{EINVAL}, @code{EBADF}, @code{EACCES} or
+@code{ENOLCK}).
+
+Locking of directories is not supported.
+
+@item F_SETLK
+Set or clear a file segment lock according to the structure pointed to
+by the third argument.  The lock is set when @code{l_type} is
+@code{F_RDLCK} (shared lock request) or @code{F_WRLCK} (exclusive lock
+request), and the lock is cleared when @code{l_type} is @code{F_UNLCK}.
+If the lock is already held, then this call returns -1 and sets
+@code{errno} to @code{EACCES}.
+
+The @code{F_RDLCK} value for requesting a read lock is always treated as
+if it were @code{F_WRLCK} for a write lock.
+
+This is because DOS/Win9x only supports one kind of lock, and it is the
+exclusive kind.
+
+Locking of directories is not supported.
+
+@item F_SETLKW
+Same as @code{F_SETLK}, but if the lock is blocked, the call will wait
+(using @code{__dpmi_yield}, see (@pxref{__dpmi_yield,,,libc.info}) until it is
+unblocked and the lock can be applied.  This call will @strong{never
+exit} if the program making the call is the program which already owns
+the lock.
+
+Locking of directories is not supported.
+
+@item F_GETLK64
+@item F_SETLK64
+@item F_SETLKW64
+Each of these does exactly the same function as the non-"64" version,
+but the third argument must be of type @code{struct flock64}, which
+allows the @var{l_start} and @var{l_len} members to be @code{long long
+int} values.  The current code will only use these @code{long long int}
+values modulo @math{2^32}, which allows file locking positions up to 4
+gigabytes minus 1.  True 64-bit file locking is @strong{not} supported.
+
+The @code{struct flock64} members @var{l_start} and @var{l_len} are
+declared to be of type @code{offset_t}, which is in turn typedef'ed to
+be a @code{long long}.
+
+Locking of directories is not supported.
+@end table
+
+This function can be hooked by the @dfn{Filesystem extensions}, see
+(@pxref{File System Extensions,,,libc.info}).  If you don't want this,
+and you are calling @code{fcntl} with the @code{F_DUPFD} command, you
+should use @code{dup2} instead, see @ref{dup2}.
+
+@subheading Return Value
+
+If an invalid or unsupported value is passed in @var{cmd}, or @var{fd}
+is an invalid file handle, the function returns -1 and sets @code{errno}
+to the appropriate value.  Unsupported values of @var{cmd} cause
+@code{ENOSYS} to be stored in @code{errno}.  If @var{cmd} is
+@code{F_DUPFD}, the function returns the new descriptor or -1 in case of
+a failure.
+
+Lock requests which specify the open file's current @code{EOF} position
+as the value of @var{l_start} and zero as the @var{l_len} value will
+fail, returning -1 with @code{errno} set to @code{EACCES}.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001; (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+Contrary to Posix requirement, the handle returned by @code{F_DUPFD} shares the @code{FD_CLOEXEC} flag with @var{fd} (unless they are on different sides of the 20-handle mark), since DOS/Windows only maintain a single set of bits for all the handles associated with the same call to @code{open}.
+@end enumerate
+
+
+@subheading Example
+
+@example
+ /* Save the handle in a way that it won't be passed
+    to child processes.  */
+  int saved_fd = fcntl(fd, F_DUPFD, 20);
+
+ /* Set an advisory lock for the whole file.  */
+  struct flock flock;
+  int retval, fd;
+
+  flock.l_type = F_RDLCK;
+  flock.l_whence = SEEK_SET;
+  flock.l_start = flock.l_len = 0;
+  errno = 0;
+  retval = fcntl(fd, F_SETLK, &flock);
+
+ /* Get the status of the lock we just obtained
+    (should return -1 with errno == EACCES).  */
+  errno = 0;
+  retval = fcntl(fd, F_GETLK, &flock);
+
+ /* Release the lock.  */
+  errno = 0;
+  flock.l_type = F_UNLCK;
+  retval = fcntl(fd, F_SETLK, &flock);
+
+ /* Get the status of the lock we just released
+    (should return 0).  */
+  errno = 0;
+  flock.l_type = F_RDLCK;
+  retval = fcntl(fd, F_GETLK, &flock);
+
+ /* Try to set the O_BINARY flag on the open file
+    (should return -1 with errno == ENOSYS).  */
+  errno = 0;
+  retval = fcntl(fd, F_SETFL, O_BINARY);
+
+ /* Set the O_NONBLOCK flag on the open file
+    (should return 0).  */
+  errno = 0;
+  retval = fcntl(fd, F_SETFL, O_NONBLOCK);
+
+ /* Get the flags on the open file
+    (always returns 0).  */
+  errno = 0;
+  retval = fcntl(fd, F_GETFL);
+
+@end example
+@c -----------------------------------------------------------------------------
+@node fflush, fopen, fcntl, Alphabetical List
+@unnumberedsec fflush
+@c From file ./ansi/stdio/fflush.txh
+@findex fflush
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fflush(FILE *file);
+@end example
+
+@subheading Description
+
+If @var{file} is not a @code{NULL} pointer, this function causes any
+unwritten buffered data to be written out to the given @var{file}.  This
+is useful in cases where the output is line buffered and you want to
+write a partial line.
+
+If @var{file} is a @code{NULL} pointer, @code{fflush} writes any
+buffered output to all files opened for output.
+
+Note that @code{fflush} has no effect for streams opened for reading
+only.  Also note that the operating system can further buffer/cache
+writes to disk files; a call to @code{fsync} (@pxref{fsync}) or
+@code{sync} (@pxref{sync,,,libc.info}) is typically required to
+actually deliver data to the file(s).
+
+@subheading Return Value
+
+Zero on success, -1 on error.  When called with a @code{NULL} pointer,
+-1 will be returned if an error happened while flushing some of the
+streams (but @code{fflush} will still try to flush all the rest before
+it returns).
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+printf("Enter value : ");
+fflush(stdout);
+scanf(result);
+@end example
+@c -----------------------------------------------------------------------------
+@node fopen, fprintf, fflush, Alphabetical List
+@unnumberedsec fopen
+@c From file ./ansi/stdio/fopen.txh
+@findex fopen
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+FILE *fopen(const char *filename, const char *mode);
+@end example
+
+@subheading Description
+
+This function opens a stream corresponding to the named @var{filename}
+with the given @var{mode}.  The mode can be one of the following:
+
+@table @code
+
+@item r
+
+Open an existing file for reading.
+
+@item w
+
+Create a new file (or truncate an existing file) and open it for
+writing. 
+
+@item a
+
+Open an existing file (or create a new one) for writing.  The file
+pointer is positioned to the end of the file before every write. 
+
+@end table
+
+Followed by any of these characters:
+
+@table @code
+
+@item b
+
+Force the file to be open in binary mode instead of the default mode.
+
+When called to open the console in binary mode, @code{fopen} will
+disable the generation of @code{SIGINT} when you press @kbd{Ctrl-C}
+(@kbd{Ctrl-Break} will still cause @code{SIGINT}), because many programs
+that use binary reads from the console will also want to get the
+@samp{^C} characters.  You can use the @code{__djgpp_set_ctrl_c} library
+function (@pxref{__djgpp_set_ctrl_c,,,libc.info}) if you want @kbd{Ctrl-C} to
+generate interrupts while console is read in binary mode.
+
+@item t
+
+Force the file to be open in text mode instead of the default mode.
+
+@item +
+
+Open the file as with @code{O_RDWR} so that both reads and writes
+can be done to the same file.
+
+@end table
+
+If the file is open for both reading and writing, you must call
+@code{fflush}, @code{fseek}, or @code{rewind} before switching from read
+to write or from write to read. 
+
+The open file is set to line buffered if the underlying object is a
+device (stdin, stdout, etc), or is fully buffered if the underlying
+object is a disk file (data.c, etc).
+
+If @code{b} or @code{t} is not specified in @var{mode}, the file type is
+chosen by the value of @code{fmode} (@pxref{_fmode,,,libc.info}). 
+
+You can open directories using @code{fopen}, but there is limited
+support for stream file operations on directories.  In particular,
+they cannot be read from or written to.
+
+If you need to specify the DOS share flags use the @code{__djgpp_share_flags}.
+@xref{__djgpp_share_flags,,,libc.info}.
+
+@subheading Return Value
+
+A pointer to the @code{FILE} object, or @code{NULL} if there was an
+error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+FILE *f = fopen("foo", "rb+"); /* open existing file for read/write,
+                                * binary mode */
+@end example
+@c -----------------------------------------------------------------------------
+@node fprintf, freopen, fopen, Alphabetical List
+@unnumberedsec fprintf
+@c From file ./ansi/stdio/fprintf.txh
+@findex fprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fprintf(FILE *file, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Prints formatted output to the named file.  @xref{printf}.
+
+@subheading Return Value
+
+The number of characters written.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node freopen, fscanf, fprintf, Alphabetical List
+@unnumberedsec freopen
+@c From file ./ansi/stdio/freopen.txh
+@findex freopen
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+FILE *freopen(const char *filename, const char *mode, FILE *file);
+@end example
+
+@subheading Description
+
+This function closes @var{file} if it was open, then opens a new
+file like @code{fopen(filename, mode)} (@pxref{fopen})
+but it reuses @var{file}.
+
+This is useful to, for example, associate @code{stdout} with a new file. 
+
+@subheading Return Value
+
+The new file, or @code{NULL} on error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+freopen("/tmp/stdout.dat", "wb", stdout);
+@end example
+@c -----------------------------------------------------------------------------
+@node fscanf, fseek, freopen, Alphabetical List
+@unnumberedsec fscanf
+@c From file ./ansi/stdio/fscanf.txh
+@findex fscanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fscanf(FILE *file, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+This function scans formatted text from @var{file} and stores it in the
+variables pointed to by the arguments.  @xref{scanf}.
+
+@subheading Return Value
+
+The number of items successfully scanned.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node fseek, fseeko, fscanf, Alphabetical List
+@unnumberedsec fseek
+@c From file ./ansi/stdio/fseek.txh
+@findex fseek
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fseek(FILE *file, long offset, int mode);
+@end example
+
+@subheading Description
+
+This function moves the file pointer for @var{file} according to
+@var{mode}:
+
+@table @code
+
+@item SEEK_SET
+
+The file pointer is moved to the offset specified.
+
+@item SEEK_CUR
+
+The file pointer is moved relative to its current position.
+
+@item SEEK_END
+
+The file pointer is moved to a position @var{offset} bytes from the end
+of the file.  The offset is usually nonpositive in this case. 
+
+@end table
+
+@emph{Warning!} The ANSI standard only allows values of zero for
+@var{offset} when @var{mode} is not @code{SEEK_SET} and the file has
+been opened as a text file.  Although this restriction is not enforced,
+beware that there is not a one-to-one correspondence between file
+characters and text characters under MS-DOS, so some @code{fseek}
+operations may not do exactly what you expect.
+
+Also, since @code{lseek} under DOS does not return an error indication
+when you try to move the file pointer before the beginning of the file,
+neither will @code{fseek}.  Portable programs should call @code{ftell}
+after @code{fseek} to get the actual position of the file pointer.
+
+Note that DOS does not mind if you seek before the beginning of the
+file, like seeking from the end of the file by more than the file's
+size.  Therefore, @code{lseek} will not return with an error in such
+cases either.
+
+@subheading Return Value
+
+Zero if successful, nonzero if not. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+fseek(stdin, 12, SEEK_CUR); /* skip 12 bytes */
+@end example
+@c -----------------------------------------------------------------------------
+@node fseeko, fstat, fseek, Alphabetical List
+@unnumberedsec fseeko
+@c From file ./ansi/stdio/fseeko.txh
+@findex fseeko
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fseeko(FILE *file, off_t offset, int mode);
+@end example
+
+@subheading Description
+
+The @code{fseeko} function is equivalent to the @code{fseek}
+function except that the @var{offset} argument is of type off_t.
+This function moves the file pointer for @var{file} according to
+@var{mode}:
+
+@table @code
+
+@item SEEK_SET
+
+The file pointer is moved to the offset specified.
+
+@item SEEK_CUR
+
+The file pointer is moved relative to its current position.
+
+@item SEEK_END
+
+The file pointer is moved to a position @var{offset} bytes from the end
+of the file.  The offset is usually nonpositive in this case. 
+
+@end table
+
+For further information see the documentation for the @code{fseek} function
+(@pxref{fseek}).
+
+@subheading Return Value
+
+Zero if successful, nonzero if not. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+fseeko(stdin, 12, SEEK_CUR); /* skip 12 bytes */
+@end example
+@c -----------------------------------------------------------------------------
+@node fstat, fstatvfs, fseeko, Alphabetical List
+@unnumberedsec fstat
+@c From file ./posix/sys/stat/fstat.txh
+@findex fstat
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fstat(int file, struct stat *sbuf);
+@end example
+
+@subheading Description
+
+This function obtains the status of the open file @var{file} and stores
+it in @var{sbuf}.  @xref{stat}, for the description of members of
+@code{struct stat}.
+
+The @code{st_size} member is an signed 32-bit integer type, so it will
+overflow on FAT32 volumes for files that are larger than 2GB.
+Therefore, if your program needs to support large files, you should
+treat the value of @code{st_size} as an unsigned value.
+
+For some drives @code{st_blksize} has a default value, to improve
+performance.  The floppy drives A: and B: default to a block size
+of 512 bytes.  Network drives default to a block size of 4096 bytes.
+
+Some members of @code{struct stat} are very expensive to compute.  If
+your application is a heavy user of @code{fstat} and is too slow, you
+can disable computation of the members your application doesn't need, as
+described in (@pxref{_djstat_flags,,,libc.info}).
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @code{errno} set). 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+struct stat s;
+fstat(fileno(stdin), &s);
+if (S_ISREG(s.st_mode))
+  puts("STDIN is a redirected disk file");
+else if (S_ISCHR(s.st_mode))
+  puts("STDIN is a character device");
+@end example
+
+@subheading Bugs
+
+If a file was open in write-only mode, its execute and symlink mode 
+bits might be incorrectly reported as if the file were non-executable
+or non-symlink.  This is because executables and symlinks are only 
+recognized by reading their first few bytes, which cannot be done for 
+files open in write-only mode.
+
+For @code{fstat} to return correct info, you should make sure that all
+the data written to the file has been delivered to the operating system,
+e.g. by calling both @code{fflush} and @code{fsync}.  Otherwise, the
+buffering of the library I/O functions and the OS might cause stale info
+to be returned.
+
+@subheading Implementation Notes
+
+Supplying a 100% Unix-compatible @code{fstat} function under DOS is an
+implementation nightmare.  The following notes describe some of the
+obscure points specific to @code{fstat}s behavior in DJGPP.
+
+1. The @samp{drive} for character devices (like @code{con}, @code{/dev/null}
+and others is returned as -1.  For drives networked by Novell Netware, it
+is returned as -2.
+
+2. The starting cluster number of a file serves as its inode number.
+For files whose starting cluster number is inaccessible (empty files,
+all files on Windows, files on networked drives, etc.) the
+@code{st_inode} field will be @cite{invented} in a way which guarantees
+that no two different files will get the same inode number (thus it is
+unique).  This invented inode will also be different from any real
+cluster number of any local file.  However, only for local, non-empty
+files/directories the inode is guaranteed to be consistent between
+@code{stat} and @code{fstat} function calls.  (Note that files on
+different drives can have identical inode numbers, and thus comparing
+files for identity should include comparison of the @code{st_dev}
+member.)
+
+3. On all versions of Windows except Windows 3.X, the inode number is
+invented using the file name.  @code{fstat} can probably use the file name
+that was used to open the file, when generating the inode.  This is done
+such that the same inode will be generated irrespective of the actual path
+used to open the file (e.g.: @file{foo.txt}, @file{./foo.txt},
+@file{../somedir/foo.txt}).  If file names cannot be used, @code{fstat}
+always returns different inode numbers for any two files open
+on different handles, even if the same file is open twice
+on two different handles.
+
+4. The WRITE access mode bit is set only for the user (unless the file is
+read-only, hidden or system).  EXECUTE bit is set for directories,  files
+which can be executed from the DOS prompt (batch files, .com, .dll and .exe
+executables) or run by @code{go32-v2.exe}.  For files which reside on
+networked drives under Novell Netware, this can sometimes fail, in which
+case only the read access bit is set.
+
+5. The variable @code{_djstat_flags} (@pxref{_djstat_flags,,,libc.info}) controls
+what hard-to-get fields of @code{struct stat} are needed by the
+application.
+@c -----------------------------------------------------------------------------
+@node fstatvfs, fsync, fstat, Alphabetical List
+@unnumberedsec fstatvfs
+@c From file ./posix/sys/statvfs/fstatvfs.txh
+@findex fstatvfs
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fstatvfs (int fd, struct statvfs *sbuf);
+@end example
+
+@subheading Description
+
+This function returns information about the ``filesystem'' (FS)
+containing the file referred to by the file descriptor @var{fd}
+and stores it in @var{sbuf}, which has the structure below:
+
+@example
+struct statvfs @{
+  unsigned long f_bsize;   /* FS block size */
+  unsigned long f_frsize;  /* fundamental block size */
+  fsblkcnt_t    f_blocks;  /* # of blocks on filesystem */
+  fsblkcnt_t    f_bfree;   /* # of free blocks on FS */
+  fsblkcnt_t    f_bavail;  /* # of free blocks on FS for
+                            * unprivileged users */
+  fsfilcnt_t    f_files;   /* # of file serial numbers */
+  fsfilcnt_t    f_ffree;   /* # of free file serial numbers */
+  fsfilcnt_t    f_favail;  /* # of free file serial numbers
+                            * for unprivileged users */
+  unsigned long f_fsid;    /* FS identifier */
+  unsigned long f_flag;    /* FS flags: bitwise OR of ST_NOSUID,
+                            * ST_RDONLY */
+  unsigned long f_namemax; /* Maximum file name length on FS */
+@};
+@end example
+
+Note that if INT 21h is hooked by a TSR, the total size is limited
+to approximately 2GB (@pxref{statvfs,,,libc.info}).
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @code{errno} set).
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node fsync, ftell, fstatvfs, Alphabetical List
+@unnumberedsec fsync
+@c From file ./compat/unistd/fsync.txh
+@findex fsync
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int fsync(int file);
+@end example
+
+@subheading Description
+
+Forces all information about the file with the given descriptor to be
+synchronized with the disk image.  Works by calling DOS function 0x68.
+@emph{Warning}: External disk caches are not flushed by this function.
+
+@code{fsync} does not support directories.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+fsync(fileno(stdout));
+@end example
+@c -----------------------------------------------------------------------------
+@node ftell, ftello, fsync, Alphabetical List
+@unnumberedsec ftell
+@c From file ./ansi/stdio/ftell.txh
+@findex ftell
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+long ftell(FILE *file);
+@end example
+
+@subheading Description
+
+Returns the current file position for @code{file}.  This is suitable for
+a future call to @code{fseek}. 
+
+@subheading Return Value
+
+The file position, or -1 on error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+long p = ftell(stdout);
+@end example
+@c -----------------------------------------------------------------------------
+@node ftello, ftruncate, ftell, Alphabetical List
+@unnumberedsec ftello
+@c From file ./ansi/stdio/ftello.txh
+@findex ftello
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+off_t ftello(FILE *file);
+@end example
+
+@subheading Description
+The @code{ftello} function is equivalent to the @code{ftell}
+function except that the return value is of type off_t.
+Returns the current file position for @code{file}.  This is suitable for
+a future call to @code{fseeko}.
+
+For further information see the documentation for the @code{ftell} function
+(@pxref{ftell}).
+
+@subheading Return Value
+
+The file position, or -1 on error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+off_t p = ftello(stdout);
+@end example
+@c -----------------------------------------------------------------------------
+@node ftruncate, lfilelength, ftello, Alphabetical List
+@unnumberedsec ftruncate
+@c From file ./compat/unistd/ftruncat.txh
+@findex ftruncate
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int ftruncate(int handle, off_t where);
+@end example
+
+@subheading Description
+
+This function truncates the file open on @var{handle} at byte position
+@var{where}.  The file pointer associated with @var{handle} is not
+changed.
+
+Note that this function knows nothing about buffering by stdio functions
+like @code{fwrite} and @code{fprintf}, so if @var{handle} comes from a
+@code{FILE} object, you need to call @code{fflush} before calling this
+function.
+
+@code{ftruncate} does not support directories.
+
+@subheading Return Value
+
+Zero for success, nonzero for failure.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+int x = open("data", O_WRONLY);
+ftruncate(x, 1000);
+close(x);
+@end example
+@c -----------------------------------------------------------------------------
+@node lfilelength, llseek, ftruncate, Alphabetical List
+@unnumberedsec lfilelength
+@c From file ./posix/sys/stat/lfilelen.txh
+@findex lfilelength
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+long long lfilelength(int fhandle);
+@end example
+
+@subheading Description
+
+This function returns the size, in bytes, of a file whose handle is
+specified in the argument @var{fhandle}.  To get the handle of a file
+opened by @code{fopen} (@pxref{fopen}) or @code{freopen} (@pxref{freopen}),
+you can use @code{fileno} macro (@pxref{fileno,,,libc.info}).
+
+@subheading Return Value
+
+The size of the file in bytes, or (if any error occured) -1LL and
+@code{errno} set to a value describing the cause of the failure.
+
+The return value is of type @code{long long} which allows file sizes of
+@math{2^63-1} bytes to be returned.  Note that FAT16 limits files to near
+@math{2^31} bytes and FAT32 limits files to @math{2^32-2} bytes.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+  printf("Size of file to which STDIN is redirected is %ld\n", 
+          lfilelength(0));
+@end example
+@c -----------------------------------------------------------------------------
+@node llseek, lseek, lfilelength, Alphabetical List
+@unnumberedsec llseek
+@c From file ./compat/unistd/llseek.txh
+@findex llseek
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+offset_t llseek(int fd, offset_t offset, int whence);
+@end example
+
+@subheading Description
+
+This function moves the file pointer for @var{fd} according to
+@var{whence}:
+
+@table @code
+
+@item SEEK_SET
+
+The file pointer is moved to the offset specified.
+
+@item SEEK_CUR
+
+The file pointer is moved relative to its current position.
+
+@item SEEK_END
+
+The file pointer is moved to a position @var{offset} bytes from the end
+of the file.  The offset is usually nonpositive in this case. 
+
+@end table
+
+@var{offset} is of type long long, thus enabling you to seek with
+offsets as large as ~2^63 (FAT16 limits this to ~2^31; FAT32 limits
+this to 2^32-2).
+
+@subheading Return Value
+
+The new offset is returned. Note that due to limitations in the
+underlying DOS implementation the offset wraps around to 0 at offset
+2^32. -1 means the call failed.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+long long ret;
+
+ret = llseek(fd, (1<<32), SEEK_SET); /* Now ret equals 0
+                                      * (unfortunately). */
+ret = llseek(fd, -1, SEEK_CUR); /* Now ret equals 2^32-1 (good!). */
+ret = llseek(fd, 0, SEEK_SET); /* Now ret equals 0 (good!). */
+ret = llseek(fd, -1, SEEK_CUR); /* Now ret equals 2^32-1 (bad). */
+@end example
+@c -----------------------------------------------------------------------------
+@node lseek, lstat, llseek, Alphabetical List
+@unnumberedsec lseek
+@c From file ./posix/unistd/lseek.txh
+@findex lseek
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+off_t lseek(int fd, off_t offset, int whence);
+@end example
+
+@subheading Description
+
+This function moves the file pointer for handle @var{fd} according to
+@var{whence}:
+
+@table @code
+
+@item SEEK_SET
+
+The file pointer is moved to the @var{offset} specified.
+
+@item SEEK_CUR
+
+The file pointer is moved @var{offset} bytes relative to its current
+position.
+
+@item SEEK_END
+
+The file pointer is moved to a position @var{offset} bytes from the end
+of the file.  The value of @var{offset} is usually nonpositive in this
+case. 
+
+@end table
+
+@subheading Return Value
+
+The new offset is returned, or -1 and @code{errno} set on failure.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+lseek(fd, 12, SEEK_CUR); /* skip 12 bytes */
+@end example
+@c -----------------------------------------------------------------------------
+@node lstat, mblen, lseek, Alphabetical List
+@unnumberedsec lstat
+@c From file ./posix/sys/stat/lstat.txh
+@findex lstat
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int lstat(const char *file, struct stat *sbuf);
+@end example
+
+@subheading Description
+
+This function obtains the status of the file @var{file} and stores
+it in @var{sbuf}.  If @var{file} is a symbolic link, then @code{lstat}
+returns information about the symbolic link.  To get information about
+the target of a symbolic link, use @code{stat} (@pxref{stat}) instead.
+
+@var{sbuf} has this structure:
+
+@smallexample
+struct  stat @{
+        time_t    st_atime;     /* time of last access       */
+        time_t    st_ctime;     /* time of file's creation   */
+        dev_t     st_dev;       /* The drive number (0 = a:) */
+        gid_t     st_gid;       /* what getgid() returns */
+        ino_t     st_ino;       /* starting cluster or unique identifier */
+        mode_t    st_mode;      /* file mode - S_IF* and S_IRUSR/S_IWUSR */
+        time_t    st_mtime;     /* time that the file was last written */
+        nlink_t   st_nlink;     /* 2 + number of subdirs, or 1 for files */
+        off_t     st_size;      /* size of file in bytes */
+	blksize_t st_blksize;   /* block size in bytes*/
+        uid_t     st_uid;       /* what getuid() returns */
+	dev_t     st_rdev;      /* The drive number (0 = a:) */
+@};
+@end smallexample
+
+The @code{st_atime}, @code{st_ctime} and @code{st_mtime} have different
+values only when long file names are supported (e.g. on Windows 9X);
+otherwise, they all have the same value: the time that the file was last
+written@footnote{
+Even when long file names @emph{are} supported, the three time values
+returned by @code{lstat} might be identical if the file was last written
+by a program which used legacy DOS functions that don't know about long
+file names.}.  Most Windows 9X VFAT filesystems only support the date of
+the file's last access (the time is set to zero); therefore, the DJGPP
+implementation of @code{lstat} sets the @code{st_atime} member to the
+same value as @code{st_mtime} if the time part of @code{st_atime}
+returned by the filesystem is zero (to prevent the situation where the
+file appears to have been created @emph{after} it was last accessed,
+which doesn't look good).
+
+The @code{st_size} member is an signed 32-bit integer type, so it will
+overflow on FAT32 volumes for files that are larger than 2GB.
+Therefore, if your program needs to support large files, you should
+treat the value of @code{st_size} as an unsigned value.
+
+For some drives @code{st_blksize} has a default value, to improve
+performance.  The floppy drives A: and B: default to a block size
+of 512 bytes.  Network drives default to a block size of 4096 bytes.
+
+Some members of @code{struct stat} are very expensive to compute.  If
+your application is a heavy user of @code{lstat} and is too slow, you can
+disable computation of the members your application doesn't need, as
+described in @pxref{_djstat_flags,,,libc.info}.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @code{errno} set).
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+struct stat s;
+lstat("data.txt", &s);
+if (S_ISDIR(s.st_mode))
+  printf("is directory\n");
+@end example
+
+@subheading Implementation Notes
+
+Supplying a 100% Unix-compatible @code{lstat} function under DOS is an
+implementation nightmare.  The following notes describe some of the
+obscure points specific to @code{lstat}s behavior in DJGPP.
+
+1. The @samp{drive} for character devices (like @code{con}, @code{/dev/null}
+and others is returned as -1.  For drives networked by Novell Netware, it
+is returned as -2.
+
+2. The starting cluster number of a file serves as its inode number.  For
+files whose starting cluster number is inaccessible (empty files, files on
+Windows 9X, on networked drives, etc.) the @code{st_inode} field will be
+@emph{invented}
+in a way which guarantees that no two different files will get the same
+inode number (thus it is unique).  This invented inode will also be
+different from any real cluster number of any local file.  However, only
+on plain DOS, and only for local, non-empty files/directories the inode
+is guaranteed to be consistent between @code{stat}, @code{fstat} and 
+@code{lstat} function calls.  (Note that two files whose names are
+identical but for the drive letter, will get the same invented inode,
+since each filesystem has its own independent inode numbering, and
+comparing files for identity should include the value of @code{st_dev}.)
+
+3. The WRITE access mode bit is set only for the user (unless the file is
+read-only, hidden or system).  EXECUTE bit is set for directories,  files
+which can be executed from the DOS prompt (batch files, .com, .dll and .exe
+executables) or run by @code{go32-v2}.
+
+4. Size of directories is reported as the number of its files (sans `.' and
+`..' entries) multiplied by 32 bytes (the size of directory entry).  On FAT
+filesystems that support the LFN API (such as Windows 9X), the reported
+size of the directory accounts for additional space used to store the long
+file names.
+
+5. Time stamp for root directories is taken from the volume label entry,
+if that's available; otherwise, it is reported as 1-Jan-1980.
+
+6. The variable @code{_djstat_flags} (@pxref{__djstat_flags,,,libc.info}) controls
+what hard-to-get fields of @code{struct stat} are needed by the
+application.
+
+7. @code{lstat} should not be used to get an up-to-date info about a file
+which is open and has been written to, because @code{lstat} will only
+return correct data after the file is closed.  Use @code{fstat}
+(@pxref{fstat,,,libc.info}) while the file is open.  Alternatively, you can call
+@code{fflush} and @code{fsync} to make the OS flush all the file's data
+to the disk, before calling @code{lstat}.
+
+8. The number of links @code{st_nlink} is always 1 for files other than
+directories.  For directories, it is the number of subdirectories plus
+2.  This is so that programs written for Unix that depend on this to
+optimize recursive traversal of the directory tree, will still work.
+@c -----------------------------------------------------------------------------
+@node mblen, mbrtowc, lstat, Alphabetical List
+@unnumberedsec mblen
+@c From file ./ansi/locale/mblen.txh
+@findex mblen
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int mblen(const char *s, size_t n);
+@end example
+
+@subheading Description
+
+This is a minimal ANSI-conforming implementation of @code{mblen}.  In this
+implementation, the only multi-byte character sequences recognized are single
+bytes, and thus 1 is returned unless @var{s} is the @code{NULL} pointer or has
+a length of 0 or is the empty string.
+
+@subheading Return Value
+
+0 if @var{s} is @code{NULL} or an empty string; 1 if the character is a single
+byte character; -1 if the multi-byte character is invalid (@var{n} greater than 1);
+otherwise the number of bytes in the multibyte character is returned (always 1).
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+length += mblen(string, 1);
+@end example
+@c -----------------------------------------------------------------------------
+@node mbrtowc, mbsinit, mblen, Alphabetical List
+@unnumberedsec mbrtowc
+@c From file ./ansi/locale/mbrtowc.txh
+@findex mbrtowc
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+@end example
+
+@subheading Description
+
+This is a minimal ANSI-conforming implementation of @code{mbrtowc}.  In this
+implementation, the only multi-byte character sequences recognized are single
+bytes, and they are converted to themselves.  Because DJGPP/DOS does not offer reentrancy support
+this function calls @code{mbtowc} to do the job (@pxref{mbtowc}).
+
+The variable @var{*ps} that stores the conversion state information has this structure:
+
+@smallexample
+typedef struct
+@{
+  int __count;
+  union
+  @{
+    wint_t __wch;
+    unsigned char __wchb[4];
+  @} __value;  /*  Value so far.  */
+@} libsupp_mbstate_t;
+@end smallexample
+
+@subheading Return Value
+
+if @code{mbtowc} fails, then -1 (casted to size_t) is returned and @var{ps->__count} is set to 0;
+else the value returned by @code{mbtowc} is returned after be casted to size_t.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+mbstate_t mbs;
+wchar_t wc;
+conv_status = mbrtowc(&wc, string, 1, &mbs);
+@end example
+@c -----------------------------------------------------------------------------
+@node mbsinit, mbtowc, mbrtowc, Alphabetical List
+@unnumberedsec mbtowc
+@c From file ./ansi/locale/mbtowc.txh
+@findex mbtowc
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int mbsinit(const mbstate_t *ps);
+@end example
+
+@subheading Description
+
+Test for initial shift state.  The initial state is the state at the beginning
+of conversion of a string.  There are two kinds of state: The one used by multi
+byte to wide character conversion functions and the one used by wide character
+to multibyte conversion functions, but they both fit in a mbstate_t, and they
+both have the same representation for an initial state.
+For 8-bit encodings, all states are equivalent to the initial state.
+
+The variable @var{*ps} storinng the conversion state information has this structure:
+
+@smallexample
+typedef struct
+@{
+  int __count;
+  union
+  @{
+    wint_t __wch;
+    unsigned char __wchb[4];
+  @} __value;  /*  Value so far.  */
+@} libsupp_mbstate_t;
+@end smallexample
+
+@subheading Return Value
+
+Non-zero if @var{ps} is a @code{NULL} pointer or if @var{*ps} is in initial state;
+else zero.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+mbstate_t conv_state;
+memset(&conv_state, 0, sizeof(mbstate_t));  /*  Setting to zero is equal to the initial state.  */
+if (mbsinit(&conv_state))
+@{
+  /*  In initial state.  */
+@}
+else
+@{
+  /*  Not in initial state.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node mbtowc, memmem, mbsinit, Alphabetical List
+@unnumberedsec mbtowc
+@c From file ./ansi/locale/mbtowc.txh
+@findex mbtowc
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int mbtowc(wchar_t *pwc, const char *s, size_t n);
+@end example
+
+@subheading Description
+
+This is a minimal ANSI-conforming implementation of @code{mbtowc}.  In this
+implementation, the only multi-byte character sequences recognized are single
+bytes, and they are converted to themselves.  Each call to @code{mbtowc} copies one
+single character from @var{*s} to @var{*pwc}, unless @var{s} is a @code{NULL} pointer.
+The argument @var{n} is ignored if it greater than 1.  If the input string @var{s} is
+the empty string, a @code{wchar_t} nul is placed in the output string @code{pwc} and
+0 is returned.  If the input has a length of 0, no changes are made to the @code{pwc}
+output string.
+
+@subheading Return Value
+
+0 if @var{s} is @code{NULL} or is the empty string; 1 if the character is a
+single-byte character; -1 if @var{n} is less than one.  If the return value
+is -1, no changes are made to the @var{pwc} output string.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+wchar_t wc;
+conv_status = mbtowc(&wc, string, 1);
+@end example
+@c -----------------------------------------------------------------------------
+@node memmem, open, mbtowc, Alphabetical List
+@unnumberedsec memmem
+@c From file ./compat/string/memmem.txh
+@findex memmem
+@subheading Syntax
+
+@example
+#include <string.h>
+
+char *memmem(const void *haystack, size_t haystack_len,
+             const void *needle, size_t needle_len);
+@end example
+
+@subheading Description
+
+This function finds the start of the first occurrence of the substring @var{needle} of
+length @var{needle_len} in the memory area @var{haystack} of length @var{haystack_len}.
+
+@subheading Return Value
+
+A pointer to the beginning of the substring @var{needle}, or @code{NULL} if @var{needle} wasn't found.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No (see note 1)
+@item POSIX
+@tab No
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+This function is a GNU extension.
+
+@end enumerate
+@c -----------------------------------------------------------------------------
+@node open, opendir, memmem, Alphabetical List
+@unnumberedsec open
+@c From file ./posix/fcntl/open.txh
+@findex open
+@subheading Syntax
+
+@example
+#include <fcntl.h>
+#include <sys/stat.h> /* for mode definitions */
+
+int open(const char *file, int mode /*, int permissions */);
+@end example
+
+@subheading Description
+
+This function opens the named @var{file} in the given @var{mode}, which
+is any combination of the following bits:
+
+@table @code
+
+@item O_RDONLY
+
+The file is opened for reading.
+
+@item O_WRONLY
+
+The file is opened for writing.
+
+@item O_RDWR
+
+The file is opened for both reading and writing.
+
+@item O_CREAT
+
+If the file does not exist, it is created. @xref{creat,,,libc.info}.
+
+@item O_TRUNC
+
+If the file does exist, it is truncated to zero bytes.
+
+@item O_EXCL
+
+If the file exists, and @code{O_CREAT} is also specified, the
+@code{open} call will fail.  If the file is a symlink and @code{O_CREAT}
+is also specified, then the contents of the symlink are ignored -
+the @code{open} call will fail.
+
+@item O_APPEND
+
+The file pointer is positioned at the end of the file before each write. 
+
+@item O_TEXT
+
+The file is opened in text mode, meaning that Ctrl-M characters are
+stripped on reading and added on writing as needed.  The default mode is
+specified by the @code{_fmode} variable @ref{_fmode,,,libc.info}. 
+
+@item O_BINARY
+
+The file is opened in binary mode.
+
+When called to open the console in binary mode, @code{open} will disable
+the generation of @code{SIGINT} when you press @kbd{Ctrl-C}
+(@kbd{Ctrl-Break} will still cause @code{SIGINT}), because many programs
+that use binary reads from the console will also want to get the
+@samp{^C} characters.  You can use the @code{__djgpp_set_ctrl_c} library
+function (@pxref{__djgpp_set_ctrl_c,,,libc.info}) if you want @kbd{Ctrl-C} to
+generate interrupts while console is read in binary mode.
+
+@item O_NOINHERIT
+
+Child processes will not inherit this file handle.  This is also known
+as @dfn{close-on-exec}--see @ref{fcntl,,,libc.info}.  This bit is DOS- and
+Windows-specific; portable programs should use @code{fcntl} instead.
+
+@item O_TEMPORARY
+
+Delete @var{file} when all file descriptors that refer to it are closed.
+
+Note that @var{file} should not also be opened with the low-level functions
+@code{_creat}, @code{_creatnew}, @code{_dos_creat}, @code{_dos_creatnew},
+and @code{_dos_open}.  Otherwise @var{file} may not be deleted as expected.
+
+@end table
+
+If the file is created by this call, it will be given the read/write
+permissions specified by @var{permissions}, which may be any combination
+of these values:
+
+@table @code
+
+@item S_IRUSR
+
+The file is readable.  This is always true for MS-DOS.
+
+@item S_IWUSR
+
+The file is writable.
+
+@end table
+
+Other @code{S_I*} values may be included, but they will be ignored.
+
+You can specify the share flags (a DOS specific feature) in @var{mode}.
+And you can indicate default values for the share flags in
+@code{__djgpp_share_flags}. @xref{__djgpp_share_flags,,,libc.info}.
+
+You can open directories using @code{open}, but there is limited
+support for POSIX file operations on directories.  In particular,
+directories cannot be read using @code{read} (@pxref{read,,,libc.info})
+or written using @code{write} (@pxref{write,,,libc.info}).  The principal reason
+for allowing @code{open} to open directories is to support changing
+directories using @code{fchdir} (@pxref{fchdir}).  If you wish to read
+the contents of a directory, use the @code{opendir} (@pxref{opendir})
+and @code{readdir} (@pxref{readdir}) functions instead.  File descriptors
+for directories are not inherited by child programs.
+
+@subheading Return Value
+
+If successful, the file descriptor is returned.  On error, a negative
+number is returned and @code{errno} is set to indicate the error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+int q = open("/tmp/foo.dat", O_RDONLY|O_BINARY);
+@end example
+@c -----------------------------------------------------------------------------
+@node opendir, pipe, open, Alphabetical List
+@unnumberedsec opendir
+@c From file ./posix/dirent/opendir.txh
+@findex opendir
+@subheading Syntax
+
+@example
+#include <dirent.h>
+
+extern int __opendir_flags;
+
+DIR *opendir(char @var{*name});
+@end example
+
+@subheading Description
+
+This function "opens" a directory so that you can read the list of file
+names in it.  The pointer returned must be passed to @code{closedir}
+when you are done with it.  @xref{readdir}.
+
+The global variable @code{__opendir_flags} can be set to include the
+following values to control the operation of @code{opendir}:
+
+@table @code
+
+@item __OPENDIR_PRESERVE_CASE
+Do not change the case of files to lower case.  Just in case Micros*ft
+decides to support case-sensitive file systems some day.
+
+You can also use this flag if you want the names of files like
+@file{README} and @file{FAQ} from Unix distributions to be returned in
+upper-case on Windows 9X filesystems.  @pxref{_preserve_fncase,,,libc.info},
+for other ways of achieving this and for more detailed description of the
+automatic letter-case conversion by DJGPP library functions.
+
+@item __OPENDIR_NO_HIDDEN
+Do not include hidden files and directories in the search.  By default,
+all files and directories are included.
+
+@item __OPENDIR_FIND_HIDDEN
+Provided for back-compatibility with previous DJGPP versions, where
+hidden files and directories were by default skipped.  In versions 2.02
+and later, this flag has no effect.
+
+@item __OPENDIR_FIND_LABEL
+Include volume labels in the search.  By default, these are skipped.
+
+@item __OPENDIR_NO_D_TYPE
+Do not compute the @code{d_type} member of @code{struct dirent}.  If
+this flag is set, all files will get @code{DT_UNKNOWN} in the
+@code{d_type} member.  By default, this flag is reset.  @xref{readdir}.
+@end table
+
+You can simply put @samp{int __opendir_flags = ...;} in your code.  The
+default is to let it get set to zero as an uninitialized variable.
+
+@subheading Return Value
+
+The open directory structure, or @code{NULL} on error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001 (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The @code{__opendir_flags} variable is DJGPP-specific.
+@end enumerate
+
+@subheading Example
+
+@example
+DIR *d = opendir(".");
+closedir(d);
+@end example
+@c -----------------------------------------------------------------------------
+@node pipe, printf, opendir, Alphabetical List
+@unnumberedsec pipe
+@c From file ./posix/unistd/pipe.txh
+@findex pipe
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int pipe(int fildes[2]);
+@end example
+
+@subheading Description
+
+This function creates a pipe and places a file descriptor for the read end
+of the pipe in @code{@var{fildes}[0]}, and another for the write end in
+@code{@var{fildes}[1]}.  Data written to @code{@var{fildes}[1]} will be read
+from @code{@var{fildes}[0]} on a first-in first-out (FIFO) basis.
+
+Note this pipe implementation won't help port instances of
+@code{fork}/@code{exec} or any other methods that require support for
+multitasking.
+
+@subheading Return Value
+
+Zero for success, otherwise -1 is returned and @code{errno} is set to indicate
+the error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+
+#include <unistd.h>
+#include <process.h>
+
+/* Pipe the output of program to the input of another. */
+
+int main()
+@{
+  int pipe_fds[2];
+  int stdin_save, stdout_save;
+  
+  if (pipe(pipe_fds) < 0)
+    return -1;
+
+  /* Duplicate stdin and stdout so we can restore them later. */
+  stdin_save = dup(STDIN_FILENO);
+  stdout_save = dup(STDOUT_FILENO);
+
+  /* Make the write end of the pipe stdout. */
+  dup2(pipe_fds[1], STDOUT_FILENO);
+
+  /* Run the program. Its output will be written to the pipe. */
+  spawnl(P_WAIT, "/dev/env/DJDIR/bin/ls.exe", "ls.exe", NULL);
+
+  /* Close the write end of the pipe. */
+  close(pipe_fds[1]);
+
+  /* Restore stdout. */
+  dup2(stdout_save, STDOUT_FILENO);
+
+  /* Make the read end of the pipe stdin. */
+  dup2(pipe_fds[0], STDIN_FILENO);
+
+  /* Run another program. Its input will come from the output of the
+     first program. */
+  spawnl(P_WAIT, "/dev/env/DJDIR/bin/less.exe", "less.exe", "-E", NULL);
+
+  /* Close the read end of the pipe. */
+  close(pipe_fds[0]);
+
+  /* Restore stdin. */
+  dup2(stdin_save, STDIN_FILENO);
+  
+  return 0;
+@}
+
+@end example
+@c -----------------------------------------------------------------------------
+@node printf, read, pipe, Alphabetical List
+@unnumberedsec printf
+@c From file ./ansi/stdio/printf.txh
+@findex printf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int printf(const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments (@dots{}) to @code{stdout}.
+
+The format string contains regular characters to print, as well as
+conversion specifiers, which begin with a percent symbol.  Conversions
+can be applied to the nth argument after the format string in the argument
+list, rather than to the next unused argument.  In this case, the conversion
+specifier character @code{%} is replaced by the sequence @code{"%n$"}, where
+@code{n} is a decimal integer in the range [@code{1}, @code{number of the last argument}],
+giving the position of the argument in the argument list.  The format string
+can contain either numbered argument conversion specifiers (that is,
+@code{"%n$"} and @code{"*m$"}), or unnumbered argument conversion specifiers
+(that is @code{%} and @code{*}), but not both.  The only exception to this
+is that @code{%%} can be mixed with @code{"%n$"} form.  When numbered argument
+specifications are used, specifying the Nth argument requires that all the
+leading arguments, from the first to the (N-1)th, are specified in the format
+string.  In format strings containing the @code{"%n$"} form of conversion
+specification, numbered arguments in the argument list can be referenced
+from the format string as many times as required.
+
+Each conversion specifier contains the following fields:
+
+@itemize @bullet
+
+@item
+
+an optional flag, which may alter the conversion:
+
+@table @code
+
+@item '
+
+The integer part of the result of a decimal conversion (@code{%i},
+@code{%d}, @code{%u}, @code{%f}, @code{%F}, @code{%g} or @code{%G})
+will be formatted with thousands' grouping characters.
+The non-monetary grouping character is used.
+
+@item -
+
+left-justify the field.
+
+@item +
+
+Force a @code{+} sign on positive numbers.
+
+@item space
+
+To leave a blank space where a plus or minus sign would have been. 
+
+@item #
+
+Alternate conversion - prefix octal numbers with @code{0}, hexadecimal
+numbers with @code{0x} or @code{0X}, or force a trailing decimal point
+if a floating point conversion would have omitted it. 
+
+@item 0
+
+To pad numbers with leading zeros.
+
+@end table
+
+@item
+
+A field width specifier, which specifies the minimum width of the field. 
+This may also be an asterisk (@code{*}), which means that the actual
+width will be obtained from the next argument.  If the argument is
+negative, it supplies a @code{-} flag and a positive width. 
+In format strings containing the @code{"%n$"} form of a conversion
+specification, a field width can be indicated by the sequence @code{"*m$"},
+where m is a decimal integer in the range [@code{1}, @code{number of the last argument}],
+giving the position in the argument list (after the format argument) of
+an integer argument containing the field width.
+
+@item
+
+An optional decimal point and a precision.  This may also be an
+asterisk, but a negative argument for it indicates a precision of zero. 
+The precision specifies the minimum number of digits to print for an
+integer, the number of fraction digits for a floating point number (max
+for @code{g} or @code{G}, actual for others), or the maximum number of
+characters for a string. 
+In format strings containing the @code{"%n$"} form of a conversion
+specification, a precision can be indicated by the sequence @code{"*m$"},
+where m is a decimal integer in the range [@code{1}, @code{number of the last argument}],
+giving the position in the argument list (after the format argument) of
+an integer argument containing the precision.
+
+@item
+
+An optional conversion qualifier, which may be:
+
+@table @code
+@item hh
+to specify @code{char};
+
+@item h
+to specify @code{short} integers;
+
+@item j
+to specify @code{intmax_t} or @code{uintmax_t} integers;
+
+@item l
+to specify doubles or @code{long} integers;
+
+@item ll
+(two lower-case ell letters) to specify @code{long long} integers;
+to specify @code{long} doubles, although this is non-standard;
+
+@item L
+to specify @code{long} doubles;
+
+@item t
+to specify @code{ptrdiff_t};
+
+@item z
+to specify @code{size_t}.
+@end table
+
+@item
+
+The conversion type specifier:
+
+@table @code
+
+@item a
+@itemx A
+
+A floating point number (float or double) printed in the style
+@code{"[-]0xh.hhhhp[+|-]d"}, where @code{h} represents a hexadecimal
+digit, @code{d} represents a decimal digit and @code{p} stands for the
+base 2.  For long double, use @code{"La"} or @code{"LA"}.  The case of
+the exponent, the case of the letters @code{"abcdef"} and the case of
+@code{"x"} matches the specifier case.  The representation always has
+an exponent.
+
+@item c
+
+A single character.
+
+@item d
+
+A signed integer.
+
+@item D
+
+A signed long integer.  This is non-standard and obsolete.
+Please use @code{ld} instead.
+
+@item e
+@itemx E
+
+A floating point number (float or double).  For long double, use
+@code{"Le"} or @code{"LE"}.  The exponent case matches the specifier
+case.  The representation always has an exponent.
+
+@item f
+@item F
+
+A floating point number (float or double).  For long double, use
+@code{"Lf"}.  The representation never has an exponent.
+
+@item g
+@itemx G
+
+A floating point number (float or double).  For long double, use
+@code{"Lg"} or @code{"LG"}.  The exponent case matches the specifier
+case.  The representation has an exponent if it needs one.
+
+@item i
+
+A signed integer.
+
+@item n
+
+The next argument is a pointer to an integer, and the number of
+characters generated so far is stored in that integer. 
+
+@item o
+
+A unsigned integer, printed in base 8 instead of base 10.
+
+@item O
+
+A unsigned long integer, printed in base 8 instead of base 10.
+This is non-standard and obsolete.  Please use @code{lo} instead.
+
+@item p
+
+A pointer.  This is printed with an @code{x} specifier.
+
+@item s
+
+A @code{NULL}-terminated string.
+
+@item u
+
+An unsigned integer.
+
+@item U
+
+An unsigned long integer.  This is non-standard and obsolete.
+Please use @code{lu} instead.
+
+@item x
+@itemx X
+
+An unsigned integer, printed in base 16 instead of base 10.  The case of
+the letters used matches the specifier case. 
+
+@item %
+
+A single percent symbol is printed.
+
+@end table
+
+@end itemize
+
+@subheading Return Value
+
+The number of characters written.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99 (see note 1) (see note 2)
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The @code{hh}, @code{j}, @code{t}
+and @code{z} conversion specifiers first appeared
+in the ANSI C99 standard.
+
+@item
+The @code{D}, @code{O} and @code{U} conversion types
+are non-standard.  gcc may generate warnings, if you use them.
+
+@end enumerate
+
+@subheading Example
+
+@example
+printf("%-3d %10.2f%% Percent of %s\n", index, per[index], name[index]);
+@end example
+
+The following statement can be used to print date and time
+using language-independent format:
+
+@example
+printf(format, weekday, month, day, hour, precision, min);
+@end example
+
+
+For American usage, the format string could look like:
+
+@example
+"%s, %s %d, %d:%.*d\n"
+@end example
+
+The integer precision has the value 2.
+The above example will produce the following message:
+
+@example
+Sunday, October 27, 9:09
+@end example
+
+
+For German usage, the format string could look like:
+
+@example
+"%1$s, %3$d. %2$s, %4$d:%6$.*5$d\n"
+@end example
+
+The above example will produce the following message:
+
+@example
+Sonntag, 27. Oktober, 9:09
+@end example
+@c -----------------------------------------------------------------------------
+@node read, readdir, printf, Alphabetical List
+@unnumberedsec read
+@c From file ./posix/unistd/read.txh
+@findex read
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+ssize_t read(int fd, void *buffer, size_t length);
+@end example
+
+@subheading Description
+
+This function reads at most @var{length} bytes from file @var{fd} into
+@var{buffer}.  Note that in some cases, such as end-of-file conditions
+and text files, it may read less than the requested number of bytes. 
+At end-of-file, @code{read} will read exactly zero bytes.
+
+Directories cannot be read using @code{read} --- use @code{readdir}
+instead.
+
+@subheading Return Value
+
+The number of bytes read, zero meaning end-of-file, or -1 for an error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+char buf[10];
+int r = read(0, buf, 10);
+@end example
+@c -----------------------------------------------------------------------------
+@node readdir, realpath, read, Alphabetical List
+@unnumberedsec readdir
+@c From file ./posix/dirent/readdir.txh
+@findex readdir
+@tindex dirent@r{ structure}
+@subheading Syntax
+
+@example
+#include <dirent.h>
+
+struct dirent *readdir(DIR *dir);
+@end example
+
+@subheading Description
+
+This function reads entries from a directory opened by @code{opendir}
+(@pxref{opendir}).  It returns the information in a static buffer with
+this format:
+
+@example
+struct dirent @{
+  unsigned short d_namlen;  /* The length of the name (like strlen) */
+  char d_name[MAXNAMLEN+1]; /* The name */
+  mode_t d_type;            /* The file's type */
+@};
+@end example
+
+Note that some directory entries might be skipped by @code{readdir},
+depending on the bits set in the global variable
+@code{__opendir_flags}.  @xref{opendir, __opendir_flags, opendir}.
+
+The possible values of the @code{d_type} member are:
+
+@table @code
+@item DT_REG
+This is a regular file.
+@item DT_BLK
+The file is a block device.
+@item DT_CHR
+The file is a character device.
+@item DT_DIR
+The file is a directory.
+@item DT_FIFO
+This is a pipe (never happens in DJGPP).
+@item DT_LABEL
+The file is a volume label.
+@item DT_LNK
+The file is a symlink.
+@item DT_SOCK
+The file is a socket.
+@item DT_UNKNOWN
+The file's type is unknown.  This value is put into the @code{d_type}
+member if the exact file's type is too expensive to compute.  If the
+@code{__OPENDIR_NO_D_TYPE} flag is set in the global variable
+@code{__opendir_flags}, @emph{all} files get marked with
+@code{DT_UNKNOWN}.
+@end table
+
+The macro @code{DTTOIF} (@pxref{DTTOIF,,,libc.info}) can be used to convert the
+@code{d_type} member to the equivalent value of the @code{st_mode}
+member of @code{struct stat}, see @pxref{stat,,,libc.info}.
+
+@subheading Return Value
+
+A pointer to a static buffer that is overwritten with each call.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001 (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The @code{__opendir_flags} variable is DJGPP-specific.  The @code{d_type} member is an extension available on some systems such as GNU/Linux.
+@end enumerate
+
+@subheading Example
+
+@example
+DIR *d = opendir(".");
+struct dirent *de;
+while (de = readdir(d))
+  puts(de->d_name);
+closedir(d);
+@end example
+@c -----------------------------------------------------------------------------
+@node realpath, rewind, readdir, Alphabetical List
+@unnumberedsec realpath
+@c From file ./posix/stdlib/realpath.txh
+@findex realpath
+@subheading Syntax
+
+@example
+#include <libsup.h>
+
+char *realpath(const char *in_path, char *out_path);
+@end example
+
+@subheading Description
+
+This function canonicalizes the input path @var{in_path} and stores the
+result in the buffer pointed to by @var{out_path}.
+
+The path is canonicialized by removing consecutive and trailing slashes,
+making the path absolute if it's relative by prepending the current drive
+letter and working directory, removing "." components, collapsing
+".." components, adding a drive specifier if needed, and converting all
+slashes to '/'.  DOS-style 8+3 names of directories which are part of
+the pathname, as well as its final filename part, are returned
+lower-cased in @var{out_path}, but long filenames are left intact.
+@pxref{_preserve_fncase,,,libc.info}, for more details on letter-case conversions in
+filenames.
+
+Since the returned path name can be longer than the original one, the
+caller should ensure there is enough space in the buffer pointed to by
+@var{out_path}.  Use of ANSI-standard constant @code{FILENAME_MAX}
+(defined on @file{stdio.h}) or Posix-standard constant @code{PATH_MAX}
+(defined on @file{limits.h}) is recommended.
+
+@subheading Return Value
+
+If successful, a pointer to the result buffer is returned. Otherwise,
+@code{NULL} is returned and @code{errno} is set to indicate which error
+was detected.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+char oldpath[100], newpath[PATH_MAX];
+scanf("%s", oldpath);
+realpath(oldpath, newpath);
+printf("that really is %s\n", newpath);
+@end example
+@c -----------------------------------------------------------------------------
+@node rewind, rewinddir, realpath, Alphabetical List
+@unnumberedsec rewind
+@c From file ./ansi/stdio/rewind.txh
+@findex rewind
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+void rewind(FILE *file);
+@end example
+
+@subheading Description
+
+This function repositions the file pointer to the beginning of the file
+and clears the error indicator. 
+
+@subheading Return Value
+
+None.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+rewind(stdin);
+@end example
+@c -----------------------------------------------------------------------------
+@node rewinddir, scanf, rewind, Alphabetical List
+@unnumberedsec rewinddir
+@c From file ./posix/dirent/rewinddi.txh
+@findex rewinddir
+@subheading Syntax
+
+@example
+#include <dirent.h>
+
+void rewinddir(DIR *dir);
+@end example
+
+@subheading Description
+
+This function resets the position of the @var{dir} so that the next call
+to @code{readdir} (@pxref{readdir}) starts at the beginning again. 
+
+@subheading Return Value
+
+None.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+DIR *d = opendir(".");
+rewinddir(d);
+@end example
+@c -----------------------------------------------------------------------------
+@node scanf, select, rewinddir, Alphabetical List
+@unnumberedsec scanf
+@c From file ./ansi/stdio/scanf.txh
+@findex scanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int scanf(const char *format, @dots{});
+@end example
+
+@subheading Description
+
+This function scans formatted text from @code{stdin} and stores it in
+the variables pointed to by the arguments.  @xref{scanf}.
+
+The format string contains regular characters which much match the input
+exactly as well as a conversion specifiers, which begin with a percent
+symbol.  Any whitespace in the format string matches zero or more of any
+whitespace characters in the input.  Thus, a single space may match a
+newline and two tabs in the input.  All conversions except @samp{c} and
+@samp{[} also skip leading whitespace automatically.  Each conversion
+specifier contains the following fields:
+
+@itemize @bullet
+
+@item An asterisk (@samp{*}) which indicates that the input should be
+converted according to the conversion spec, but not stored anywhere. 
+This allows to describe an input field that is to be skipped.
+
+@item A width specifier, which specifies the maximum number of input
+characters to use in the conversion. 
+
+@item An optional conversion qualifier, which may be:
+
+@table @code
+@item hh
+to specify @code{char};
+
+@item h
+to specify @code{short} integers;
+
+@item j
+to specify @code{intmax_t} or @code{uintmax_t} integers;
+
+@item l
+to specify doubles or @code{long} integers;
+
+@itemx ll
+(two lower-case ell letters) to specify @code{long long} integers;
+to specify @code{long} doubles, although this is non-standard;
+
+@item L
+to specify @code{long} doubles;
+
+@item t
+to specify @code{ptrdiff_t};
+
+@item z
+to specify @code{size_t}.
+@end table
+
+If the @samp{h} qualifier appears before a specifier
+that implies conversion to a @code{long} or @code{float} or
+@code{double}, like in @samp{%hD} or @samp{%hf}, it is generally
+ignored.
+
+@item The conversion type specifier@footnote{Some of the combinations
+listed below are non-standard.  If you use the non-standard specifiers,
+a compiler could complain.}:
+
+@table @code
+
+@item c
+
+Copy the next character (or @var{width} characters) to the given buffer.
+This conversion suppresses skipping of the leading whitespace; use
+@samp{%1s} to read the next non-whitespace character.  Unlike with
+@samp{%s}, the copied characters are @strong{not} terminated with a null
+character.  If the @var{width} parameter is not specified, a @var{width}
+of one is implied.
+
+@item d
+
+Convert the input to a signed @code{int} using 10 as the base of the
+number representation.
+
+@item hhd
+
+Convert the input to a signed @code{char} using 10 as the base.
+
+@item hd
+
+Convert the input to a signed @code{short} using 10 as the base.
+
+@item jd
+
+Convert the input to an @code{intmax_t} using 10 as the base.
+
+@item ld
+@itemx D
+
+Convert the input to a signed @code{long} using 10 as the base.
+
+@item Ld
+@itemx lld
+@itemx lD
+
+Convert the input to a signed @code{long long} using 10 as the base.
+
+@item td
+
+Convert the input to a @code{ptrdiff_t} using 10 as the base.
+
+@item zd
+
+Convert the input to a @code{size_t} using 10 as the base.
+
+
+@item a
+@itemx A
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{float}).
+
+@item e
+@itemx E
+@itemx f
+@itemx F
+@itemx g
+@itemx G
+
+Convert the input to a floating point number (a @code{float}).
+
+@item la
+@itemx lA
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{double}).
+
+@item le
+@itemx lE
+@itemx lf
+@itemx lF
+@itemx lg
+@itemx lG
+
+Convert the input to a floating point number (a @code{double}).
+
+@item La
+@itemx LA
+@item lla
+@itemx llA
+
+Convert the input of the form [+|-]0xH.HHHHp|P[+|-]DDD to a floating point number (a @code{double}).
+
+@item Le
+@itemx LE
+@itemx lle
+@itemx llE
+@itemx Lf
+@itemx LF
+@itemx llf
+@itemx llF
+@itemx Lg
+@itemx LG
+@itemx llg
+@itemx llG
+
+Convert the input to a floating point number (a @code{long double}.
+
+@item i
+
+Convert the input, determining base automatically by the presence of
+@code{0x} or @code{0} prefixes, and store in a signed @code{int}.
+@xref{strtol,,,libc.info}.
+
+@item hhi
+
+Like @samp{i}, but stores the result in a signed @code{char}.
+
+@item hi
+
+Like @samp{i}, but stores the result in a signed @code{short}.
+
+@item ji
+
+Like @samp{i}, but stores the result in an @code{intmax_t}.
+
+@item li
+@itemx I
+
+Like @samp{i}, but stores the result in a signed @code{long}.
+
+@item Li
+@itemx lli
+@itemx lI
+
+Like @samp{i}, but stores the result in a signed @code{long long}.
+
+@item ti
+
+Like @samp{i}, but stores the result in a @code{ptrdiff_t}.
+
+@item zi
+
+Like @samp{i}, but stores the result in a @code{size_t}.
+
+@item n
+
+Store the number of characters scanned so far into the @code{int}
+pointed to by the argument.
+
+@item hhn
+
+Like @samp{n}, but the argument should point to a signed @code{char}.
+
+@item hn
+
+Like @samp{n}, but the argument should point to a signed @code{short}.
+
+@item jn
+
+Like @samp{n}, but the argument should point to an @code{intmax_t}.
+
+@item ln
+
+Like @samp{n}, but the argument should point to a signed @code{long}.
+
+@item Ln
+@itemx lln
+
+Like @samp{n}, but the argument should point to a signed @code{long long}.
+
+@item tn
+
+Like @samp{n}, but the argument should point to a @code{ptrdiff_t}.
+
+@item zn
+
+Like @samp{n}, but the argument should point to a @code{size_t}.
+
+@item o
+
+Convert the input to an unsigned @code{int}, using base 8.
+
+@item hho
+
+Convert the input to an unsigned @code{char}, using base 8.
+
+@item ho
+
+Convert the input to an unsigned @code{short}, using base 8.
+
+@item jo
+
+Convert the input to an @code{uintmax_t}, using base 8.
+
+@item lo
+@itemx O
+
+Convert the input to an unsigned @code{long}, using base 8.
+
+@item Lo
+@itemx llo
+@itemx lO
+
+Convert the input to an unsigned @code{long long}, using base 8.
+
+@item to
+
+Convert the input to a @code{ptrdiff_t}, using base 8.
+
+@item zo
+
+Convert the input to a @code{size_t}, using base 8.
+
+@item p
+
+Convert the input to a pointer.  This is like using the @code{x} format. 
+
+@item s
+
+Copy the input to the given string, skipping leading whitespace and
+copying non-whitespace characters up to the next whitespace.  The string
+stored is then terminated with a null character. 
+
+@item u
+
+Convert the input to an unsigned @code{int} using 10 as the base.
+
+@item hhu
+
+Convert the input to an unsigned @code{char} using 10 as the base.
+
+@item hu
+
+Convert the input to an unsigned @code{short} using 10 as the base.
+
+@item ju
+
+Convert the input to an @code{uintmax_t} using 10 as the base.
+
+@item lu
+@itemx U
+
+Convert the input to an unsigned @code{long} using 10 as the base.
+
+@item Lu
+@itemx llu
+@itemx lU
+
+Convert the input to an unsigned @code{long long} using 10 as the base.
+
+@item tu
+
+Convert the input to a @code{ptrdiff_t} using 10 as the base.
+
+@item zu
+
+Convert the input to a @code{size_t} using 10 as the base.
+
+@item x
+@itemx X
+
+Convert the input to an unsigned @code{int}, using base 16.
+
+@item hhx
+@itemx hhX
+
+Convert the input to an unsigned @code{char}, using base 16.
+
+@item hx
+@itemx hX
+
+Convert the input to an unsigned @code{short}, using base 16.
+
+@item jx
+@itemx jX
+
+Convert the input to an @code{uintmax_t}, using base 16.
+
+@item lx
+@itemx lX
+
+Convert the input to an unsigned @code{long}, using base 16.
+
+@item Lx
+@itemx LX
+@itemx llx
+@itemx llX
+
+Convert the input to an unsigned @code{long long}, using base 16.
+
+@item tx
+@itemx tX
+
+Convert the input to a @code{ptrdiff_t}, using base 16.
+
+@item zx
+@itemx zX
+
+Convert the input to a @code{size_t}, using base 16.
+
+@item [@dots{}]
+
+Stores the matched characters in a @code{char} array, followed by a
+terminating null character.  If you do not specify the @var{width}
+parameter, @code{scanf} behaves as if @var{width} had a very large
+value.  Up to @var{width} characters are consumed and assigned, provided
+that they match the specification inside the brackets.  The characters
+between the brackets determine which characters are allowed, and thus
+when the copying stops.  These characters may be regular characters
+(example: @samp{[abcd]}) or a range of characters (example:
+@samp{[a-d]}).  If the first character is a caret (@samp{^}), then the
+set specifies the set of characters that do not get copied (i.e.  the
+set is negated).  To specify that the set contains a close-bracket
+(@samp{]}), put it immediately after @samp{[} or @samp{[^}.  To specify
+a literal dash (@samp{-}), write it either immediately after @samp{[} or
+@samp{[^}, or immediately before the closing @samp{]}.
+
+@item %
+
+This must match a percent character in the input. 
+
+@end table
+
+@end itemize
+
+Integer formats make use of @code{strtol} or @code{strtoul} to perform
+the actual conversions.  Floating-point conversions use @code{strtod}
+and @code{_strtold}.
+
+@subheading Return Value
+
+The number of items successfully matched and assigned.  If input ends,
+or if there is any input failure before the first item is converted and
+assigned, @code{EOF} is returned.  Note that literal characters
+(including whitespace) in the format string which matched input
+characters count as ``converted items'', so input failure @emph{after}
+such characters were read and matched will @strong{not} cause @code{EOF}
+to be returned.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99 (see note 1); (see note 2)
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The @code{hh}, @code{j}, @code{t}
+and @code{z} conversion specifiers first appeared
+in the ANSI C99 standard.
+
+@item
+The conversion specifiers @samp{F}, @samp{D}, @samp{I},
+@samp{O}, and @code{U} are DJGPP extensions; they are provided
+for compatibility with Borland C and other compilers.
+The conversion specifiers for the @code{long long} data type are
+GCC extensions.  The meaning of @samp{[a-c]} as a range of characters
+is a very popular extension to ANSI (which merely says a dash
+``may have a special meaning'' in that context).
+
+@end enumerate
+
+@subheading Example
+
+@example
+int x, y;
+char buf[100];
+scanf("%d %d %s", &x, &y, buf);
+
+/* read to end-of-line */
+scanf("%d %[^\n]\n", &x, buf);
+/* read letters only */
+scanf("%[a-zA-Z]", buf);
+@end example
+@c -----------------------------------------------------------------------------
+@node select, signbit, scanf, Alphabetical List
+@unnumberedsec select
+@c From file ./compat/time/select.txh
+@findex select
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int
+select(int nfds,
+	fd_set *readfds,
+	fd_set *writefds,
+	fd_set *exceptfds,
+	struct timeval *timeout)
+@end example
+
+@subheading Description
+
+This function waits for files to be ready for input or output, or to
+have exceptional condition pending, or for a timeout.
+
+Each @code{fd_set} variable is a bitmap representation of a set of file
+descriptors, one bit for every descriptor.  The following macros shall
+be used to deal with these sets (in the table below, @var{p} is a
+pointer to an @code{fd_set} object and @var{n} is a file descriptor):
+
+@table @code
+
+@item FD_ZERO(p)
+
+Initialize the set @var{p} to all zeros.
+
+@item FD_SET(n, p)
+
+Set member @var{n} in set @var{p}.
+
+@item FD_CLR(n, p)
+
+Clear member @var{n} in set @var{p}.
+
+@item FD_ISSET(n, p)
+
+Return the value of member @var{n} in set @var{p}.
+
+@item FD_SETSIZE
+
+The maximum number of descriptors supported by the system.
+
+@end table
+
+The @var{nfds} parameter is the number of bits to be examined in each of
+the @code{fd_set} sets: the function will only check file descriptors
+@code{0} through @code{@var{nfds} - 1}, even if some bits are set for
+descriptors beyond that.
+
+On input, some of the bits of each one of the @code{fd_set} sets for
+which the function should wait, should be set using the @code{FD_SET}
+macro.  @code{select} examines only those descriptors whose bits are
+set.
+
+Any of @code{readfds}, @code{writefds}, and @code{exceptfds} can be a
+@code{NULL} pointer, if the caller is not interested in testing the
+corresponding conditions.
+
+On output, if @code{select} returns a non-negative value, each
+non-@code{NULL} argument of the three sets will be replaced with a
+subset in which a bit is set for every descriptor that was found to be,
+respectively, ready for input, ready for output, and pending an
+exceptional condition.  Note that if @code{select} returns -1, meaning a
+failure, the descriptor sets are @emph{unchanged}, so you should always
+test the return value before looking at the bits in the returned sets.
+
+The @var{timeout} value may be a NULL pointer (no timeout, i.e., wait
+forever), a pointer to a zero-value structure (poll mode, i.e., test
+once and exit immediately), or a pointer to a @code{struct timeval}
+variable (timeout: @code{select} will repeatedly test all the
+descriptors until some of them become ready, or the timeout expires).
+
+@code{struct timeval} is defined as follows:
+
+@example
+struct timeval @{
+  time_t tv_sec;
+  long tv_usec;
+@};
+@end example
+
+
+@subheading Return Value
+
+On successfull return, @code{select} returns the number of files ready,
+or 0, if the timeout expired.  The input sets are replaced with subsets
+that describe which files are ready for which operations.  If
+@code{select} returns 0 (i.e., the timeout has expired), all the
+non-@code{NULL} sets have all their bits reset to zero.
+
+On failure, @code{select} returns -1, sets @code{errno} to a suitable
+value, and leaves the descriptor sets unchanged.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+  struct timeval timeout;
+  fd_set read_fds, write_fds;
+  int i, select_result;
+
+  timeout.tv_sec = 5;  /* 5-second timeout */
+  timeout.tv_usec = 0;
+
+  /* Display status of the 5 files open by default.  */
+  for (i = 0; i < 5; i++)
+    @{
+
+      FD_ZERO (&read_fds);
+      FD_SET (i, &read_fds);
+      select_result = select (i + 1, &read_fds, 0, 0, &timeout);
+      if (select_result == -1)
+        @{
+          fprintf(stderr, "%d: Failure for input", i);
+          perror("");
+        @}
+      else
+        fprintf(stderr,
+                "%d: %s ready for input\n", i,
+                select_result ? "" : "NOT");
+      FD_ZERO (&write_fds);
+      FD_SET (i, &write_fds);
+      select_result = select (i + 1, 0, &write_fds, 0, &timeout);
+      if (select_result == -1)
+        @{
+          fprintf(stderr, "%d: Failure for output", i);
+          perror("");
+        @}
+      else
+        fprintf(stderr,
+                "%d: %s ready for output\n", i,
+                select_result ? "" : "NOT");
+    @}
+@end example
+
+@subheading Implementation Notes
+
+The following notes describe some details pertinent to the DJGPP
+implementation of @code{select}:
+
+@itemize @bullet{}
+@item
+While @code{select} waits for the timeout to expire, it repeatedly calls
+the @code{__dpmi_yield} function (@pxref{__dpmi_yield,,,libc.info}), so that any
+other programs that run at the same time (e.g., on Windows) get more CPU
+time.
+
+@item
+A file handle that belongs to a @code{FILE} object created by
+@code{fopen} or @code{fdopen} (@pxref{fopen}) for which @code{feof} or
+@code{ferror} return non-zero, will be reported in the @code{exceptfds}
+set; also, such a handle will be reported not input-ready if there are
+no pending buffered characters in the @code{FILE} object.  This might be
+a feature or a bug, depending on your point of view; in particular, Unix
+implementations usually don't check buffered input.  Portable programs
+should refrain from mixing @code{select} with buffered I/O.
+
+@item
+DOS doesn't support exceptional conditions, so file handles used for
+unbuffered I/O will @emph{never} be marked in @code{exceptfds}.
+
+@item
+DOS always returns an output-ready indication for a file descriptor
+connected to a disk file.  So use of @code{writefds} is only meaningful
+for character devices.
+
+@item
+The usual text-mode input from the keyboard and other character devices
+is line-buffered by DOS.  This means that if you type one character,
+@code{select} will indicate that file handle 0 is ready for input, but a
+call to @code{getc} will still block until the @key{Enter} key is
+pressed.  If you need to make sure that reading a single character won't
+block, you should read either with BIOS functions such as @code{getkey}
+(@pxref{getkey,,,libc.info}) or with raw input DOS functions such as @code{getch}
+(@pxref{getch,,,libc.info}), or switch the handle to binary mode with a call to
+@code{setmode} (@pxref{setmode,,,libc.info}).
+@end itemize
+@c -----------------------------------------------------------------------------
+@node signbit, snprintf, select, Alphabetical List
+@unnumberedsec signbit
+@c From file ./c99/math/signbit.txh
+@findex signbit
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int signbit(x);
+@end example
+
+@subheading Description
+
+The macro @code{signbit} returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99; not C89
+@end multitable
+
+
+@subheading Example
+
+@example
+float f = 1;
+double d = INFINITY;
+long double ld = NAN;
+
+printf("value is %s.\n", (signbit(f)) ? "negative" : "positive");
+printf("value is %s.\n", (signbit(d)) ? "negative" : "positive");
+printf("value is %s.\n", (signbit(ld)) ? "negative" : "positive");
+
+@end example
+
+@c -----------------------------------------------------------------------------
+@node snprintf, sprintf, signbit, Alphabetical List
+@unnumberedsec snprintf
+@c From file ./ansi/stdio/snprintf.txh
+@findex snprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int snprintf(char *buffer, size_t n, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+This function works similarly to @code{sprintf()} (@pxref{sprintf}), but
+the size @var{n} of the @var{buffer} is also taken into account.  This
+function will write @var{n} - 1 characters.  The @var{n}th character is used
+for the terminating nul.  If @var{n} is zero, @var{buffer} is not touched.
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding the trailing
+nul) is returned; otherwise -1 is returned to flag encoding or buffer space
+errors.
+
+The maximum accepted value of @var{n} is @code{INT_MAX}.  @code{INT_MAX} is
+defined in @code{<limits.h>}.  -1 is returned and @code{errno} is set to
+@code{EFBIG}, if @var{n} is greater than this limit.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99 (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The buffer size limit is imposed by DJGPP.  Other systems may not have this limitation.
+
+@end enumerate
+@c -----------------------------------------------------------------------------
+@node sprintf, sscanf, snprintf, Alphabetical List
+@unnumberedsec sprintf
+@c From file ./ansi/stdio/sprintf.txh
+@findex sprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int sprintf(char *buffer, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments (@dots{}) to the @var{buffer}.
+@xref{printf}.
+
+To avoid buffer overruns, it is safer to use @code{snprintf()}
+(@pxref{snprintf}).
+
+@subheading Return Value
+
+The number of characters written.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node sscanf, stat, sprintf, Alphabetical List
+@unnumberedsec sscanf
+@c From file ./ansi/stdio/sscanf.txh
+@findex sscanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int sscanf(const char *string, const char *format, @dots{});
+@end example
+
+@subheading Description
+
+This function scans formatted text from the @var{string} and stores it
+in the variables pointed to by the arguments.  @xref{scanf}.
+
+@subheading Return Value
+
+The number of items successfully scanned.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node stat, strftime, sscanf, Alphabetical List
+@unnumberedsec stat
+@c From file ./posix/sys/stat/stat.txh
+@findex stat
+@tindex stat@r{ structure}
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int stat(const char *file, struct stat *sbuf);
+@end example
+
+@subheading Description
+
+This function obtains the status of the file @var{file} and stores
+it in @var{sbuf}.  @code{stat} follows symbolic links.  To get
+information about a symbolic link, use @code{lstat} (@pxref{lstat})
+instead.
+
+@var{sbuf} has this structure:
+
+@smallexample
+struct  stat @{
+        time_t    st_atime;     /* time of last access       */
+        time_t    st_ctime;     /* time of file's creation   */
+        dev_t     st_dev;       /* The drive number (0 = a:) */
+        gid_t     st_gid;       /* what getgid() returns */
+        ino_t     st_ino;       /* starting cluster or unique identifier */
+        mode_t    st_mode;      /* file mode - S_IF* and S_IRUSR/S_IWUSR */
+        time_t    st_mtime;     /* time that the file was last written */
+        nlink_t   st_nlink;     /* 2 + number of subdirs, or 1 for files */
+        off_t     st_size;      /* size of file in bytes */
+        blksize_t st_blksize;   /* block size in bytes*/
+        uid_t     st_uid;       /* what getuid() returns */
+	dev_t     st_rdev;      /* The drive number (0 = a:) */
+@};
+@end smallexample
+
+The @code{st_atime}, @code{st_ctime} and @code{st_mtime} have different
+values only when long file names are supported (e.g. on Windows 9X);
+otherwise, they all have the same value: the time that the file was last
+written@footnote{
+Even when long file names @emph{are} supported, the three time values
+returned by @code{stat} might be identical if the file was last written
+by a program which used legacy DOS functions that don't know about long
+file names.}.  Most Windows 9X VFAT filesystems only support the date of
+the file's last access (the time is set to zero); therefore, the DJGPP
+implementation of @code{stat} sets the @code{st_atime} member to the
+same value as @code{st_mtime} if the time part of @code{st_atime}
+returned by the filesystem is zero (to prevent the situation where the
+file appears to have been created @emph{after} it was last accessed,
+which doesn't look good).
+
+The @code{st_size} member is an signed 32-bit integer type, so it will
+overflow on FAT32 volumes for files that are larger than 2GB.
+Therefore, if your program needs to support large files, you should
+treat the value of @code{st_size} as an unsigned value.
+
+For some drives @code{st_blksize} has a default value, to improve
+performance.  The floppy drives A: and B: default to a block size
+of 512 bytes.  Network drives default to a block size of 4096 bytes.
+
+Some members of @code{struct stat} are very expensive to compute.  If
+your application is a heavy user of @code{stat} and is too slow, you can
+disable computation of the members your application doesn't need, as
+described in @pxref{_djstat_flags,,,libc.info}.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @code{errno} set).
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+struct stat s;
+stat("data.txt", &s);
+if (S_ISDIR(s.st_mode))
+  printf("is directory\n");
+@end example
+
+@subheading Implementation Notes
+
+Supplying a 100% Unix-compatible @code{stat} function under DOS is an
+implementation nightmare.  The following notes describe some of the
+obscure points specific to @code{stat}s behavior in DJGPP.
+
+1. The @samp{drive} for character devices (like @code{con}, @code{/dev/null}
+and others is returned as -1.  For drives networked by Novell Netware, it
+is returned as -2.
+
+2. The starting cluster number of a file serves as its inode number.  For
+files whose starting cluster number is inaccessible (empty files, files on
+Windows 9X, on networked drives, etc.) the @code{st_inode} field will be
+@emph{invented}
+in a way which guarantees that no two different files will get the same
+inode number (thus it is unique).  This invented inode will also be
+different from any real cluster number of any local file.  However, only
+on plain DOS, and only for local, non-empty files/directories the inode
+is guaranteed to be consistent between @code{stat}, @code{fstat} and
+@code{lstat} function calls.  (Note that two files whose names are
+identical but for the drive letter, will get the same invented inode,
+since each filesystem has its own independent inode numbering, and
+comparing files for identity should include the value of @code{st_dev}.)
+
+3. The WRITE access mode bit is set only for the user (unless the file is
+read-only, hidden or system).  EXECUTE bit is set for directories,  files
+which can be executed from the DOS prompt (batch files, .com, .dll and .exe
+executables) or run by @code{go32-v2}.
+
+4. Size of directories is reported as the number of its files (sans `.' and
+`..' entries) multiplied by 32 bytes (the size of directory entry).  On FAT
+filesystems that support the LFN API (such as Windows 9X), the reported
+size of the directory accounts for additional space used to store the long
+file names.
+
+5. Time stamp for root directories is taken from the volume label entry,
+if that's available; otherwise, it is reported as 1-Jan-1980.
+
+6. The variable @code{_djstat_flags} (@pxref{_djstat_flags,,,libc.info}) controls
+what hard-to-get fields of @code{struct stat} are needed by the
+application.
+
+7. @code{stat} should not be used to get an up-to-date info about a file
+which is open and has been written to, because @code{stat} will only
+return correct data after the file is closed.  Use @code{fstat}
+(@pxref{fstat,,,libc.info}) while the file is open.  Alternatively, you can call
+@code{fflush} and @code{fsync} to make the OS flush all the file's data
+to the disk, before calling @code{stat}.
+
+8. The number of links @code{st_nlink} is always 1 for files other than
+directories.  For directories, it is the number of subdirectories plus
+2.  This is so that programs written for Unix that depend on this to
+optimize recursive traversal of the directory tree, will still work.
+@c -----------------------------------------------------------------------------
+@node strftime, strlcat, stat, Alphabetical List
+@unnumberedsec strftime
+@c From file ./ansi/time/strftime.txh
+@findex strftime
+@subheading Syntax
+
+@example
+#include <time.h>
+
+size_t strftime(char *buf, size_t n, const char *format,
+                const struct tm *time_info);
+@end example
+
+@subheading Description
+
+This function formats the time data in @var{time_info} according to the
+given @var{format} and stores it in @var{buf}, not exceeding @var{n}
+bytes.
+
+The format string is like @code{printf} in that any character other than
+@code{%} is added to the output string, and for each character following
+a @code{%} a pattern is added to the string as follows, with the
+examples as if the time was Friday, October 1, 1993, at 03:30:34 PM EDT:
+
+@table @code
+
+@item %A
+
+The full weekday name (@code{Friday})
+
+@item %a
+
+The abbreviated weekday name (@code{Fri})
+
+@item %B
+
+The full month name (@code{October})
+
+@item %b
+@itemx %h
+
+The abbreviated month name (@code{Oct})
+
+@item %C
+
+The century number (year/100) as a 2-digit integer (@code{19})
+
+@item %c
+
+Short for @code{%m/%d/%y %H:%M:%S} (@code{10/01/93 15:30:34})
+
+@item %D
+
+Short for @code{%m/%d/%y} (@code{10/01/93})
+
+@item %d
+
+The day of the month (1-31), zero padded to two characters (@code{02})
+
+@item %Ex
+In some locales, the @code{E} modifier selects alternative representations
+of certain conversion specifiers @code{x}.  But in the "C" locale supported
+by djgpp, it is ignored, and treated as @code{%x}.  E.G.: @code{%EC} will be
+mapped to @code{%C}.
+
+@item %e
+
+The day of the month (1-31), blank padded to two characters (@code{ 2})
+
+@item %F
+
+The ISO 8601:2000 date format, in the form @code{%Y-%m-%d} (@code{1993-10-01})
+
+@item %G
+
+The ISO 8601:2000 standard week-based year with century as a decimal number.
+The 4-digit year corresponding to the ISO week number (see @code{%V}).  This has the
+same format and value as @code{%Y}, except that if the ISO week number belongs to the
+previous or next year, that year is used instead (@code{1993})
+
+@item %g
+
+Like @code{%G}, but without century, i.e., with a 2-digit year (@code{93})
+
+@item %H
+
+The hour (0-24), zero padded to two characters (@code{15})
+
+@item %I
+
+The hour (1-12), zero padded to two characters (@code{03})
+
+@item %j
+
+The Julian day (1-366), zero padded to three characters (@code{275})
+
+@item %k
+
+The hour (0-24), space padded to two characters (@code{15})
+
+@item %l
+
+The hour (1-12), space padded to two characters(@code{ 3})
+
+@item %M
+
+The minutes (0-59), zero padded to two characters (@code{30})
+
+@item %m
+
+The month (1-12), zero padded to two characters (@code{10})
+
+@item %n
+
+A newline (@code{\n})
+
+@item %Ox
+In some locales, the @code{O} modifier selects alternative digit characters
+for certain conversion specifiers @code{x}.  But in the "C" locale supported
+by djgpp, it is ignored, and treated as @code{%x}.  E.G.: @code{%OH} will be
+mapped to @code{%H}.
+
+@item %p
+
+AM or PM (@code{PM})
+
+@item %P
+
+Like @code{%p} but in lowercase: am or pm (@code{pm})
+
+@item %R
+
+Short for @code{%H:%M} (@code{15:30})
+
+@item %r
+
+Short for @code{%I:%M:%S %p} (@code{03:30:35 PM})
+
+@item %S
+
+The seconds (0-60), zero padded to two characters (@code{35})
+
+@item %s
+
+The seconds since the Epoch, i.e., since 1970-01-01 00:00:00 UTC (@code{749489433})
+
+@item %T
+
+Short for @code{%H:%M:%S} (@code{15:30:35})
+
+@item %t
+
+A tab (@code{\t})
+
+@item %U
+
+The week of the year (0-53), with the first week defined by the first Sunday of
+the year, and earlier days are in week 0, zero padded to two characters (@code{39})
+
+@item %u
+
+The day of the week (1-7), Monday being 1 (@code{6})
+
+@item %V
+
+The ISO week of the year (01-53), where weeks start on Monday, with the first
+week defined by the first Thursday of the year, zero padded to two characters (@code{39})
+
+@item %W
+
+The week of the year (0-53), with the first week defined by the first Monday of
+the year, and earlier days are in week 0, zero padded to two characters (@code{39})
+
+@item %w
+
+The day of the week (0-6), Sunday being 0 (@code{5})
+
+@item %x
+
+Date represented according to the current locale.
+
+@item %X
+
+Time represented according to the current locale.
+
+@item %y
+
+The year (00-99) of the century (@code{93})
+
+@item %Y
+
+The year, zero padded to four digits (@code{1993})
+
+@item %Z
+
+The timezone abbreviation (@code{EDT})
+
+@item %z
+
+The time-zone as hour offset from GMT in the ISO 8601:2000 standard format (@code{+hhmm} or @code{-hhmm}),
+or by no characters if no timezone is determinable.  Required to emit RFC 822-conformant
+dates using @code{%a, %d %b %Y  %H:%M:%S  %z} (@code{Fri, 01 Oct 1993  03:30:34  -0500})
+
+@item %+
+
+The date and time in date(1) format.  Not supported in djgpp
+
+@item %%
+
+A percent symbol (@code{%})
+
+@end table
+
+
+The following flag characters, preceding the conversion specifier characters described
+above, are permitted:
+
+@table @code
+
+@item _
+
+(underscore) Pad a numeric result string with spaces
+
+
+@item -
+
+(dash) Do not pad a numeric result string
+
+@item 0
+
+Pad a numeric result string with zeros even if the conversion specifier character
+uses space-padding by default
+
+@item ^
+
+Convert alphabetic characters in result string to upper case
+
+@item #
+
+Swap the case of the result string.  (This flag only works with certain conversion specifier characters,
+and of these, it is only really useful with %Z).
+
+@end table
+
+@subheading Return Value
+
+The number of characters stored.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+time_t now = time (NULL);
+struct tm *t = localtime (&now);
+char buf[100];
+/* Print today's date e.g. "January 31, 2001".  */
+strftime (buf, 100, "%B %d, %Y", t);
+@end example
+@c -----------------------------------------------------------------------------
+@node strlcat, strlcpy, strftime, Alphabetical List
+@unnumberedsec strlcat
+@c From file ./compat/string/strlcat.txh
+@findex strlcat
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+size_t strlcat (char *dest, const char *src, size_t size);
+@end example
+
+@subheading Description
+
+Concatenate characters from @var{src} to @var{dest} and nul-terminate
+the resulting string.  As much of @var{src} is copied into @var{dest}
+as there is space for.
+
+@var{size} should be the size of the destination string buffer @var{dest}
+plus the space for the nul-terminator.  @var{size} may be computed
+in many cases using the @code{sizeof} operator.
+
+@code{strlcat} may be used as a less ambiguous alternative
+to @code{strncat} (@pxref{strncat,,,libc.info}).  @code{strlcat} returns
+the length of the concatenated string whether or not it was possible
+to copy it all --- this makes it easier to calculate
+the required buffer size.
+
+If @var{dest} is not nul-terminated, then @var{dest} is not modified.
+
+@code{strlcat} will not examine more than @var{size} characters
+of @var{dest}.  This is to avoid overrunning the buffer @var{dest}.
+
+If @var{dest} and @var{src} are overlapping buffers, the behavior
+is undefined.  One possible result is a buffer overrun - accessing
+out-of-bounds memory.
+
+The original OpenBSD paper describing @code{strlcat}
+and @code{strlcpy} (@pxref{strlcpy}) is available on the web:
+@uref{http://www.openbsd.org/papers/strlcpy-paper.ps}.
+
+@subheading Return Value
+
+The length of the string that @code{strlcat} tried to create is returned,
+whether or not @code{strlcat} could store it in @var{dest}.  If all
+of @var{src} was concatenated to @var{dst}, the return value will be less
+than @var{size}.
+
+If @var{dest} is not nul-terminated, then @code{strlcat} will consider
+@var{dest} to be @var{size} in length and return @var{size} plus
+the length of @var{src}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+The following example shows how you can check that
+the destination string buffer was large enough to store
+the source string concatenated to the destination string.
+In this case @code{somestring} is truncated, when it is concatenated
+to @code{buf}.
+
+@example
+const char somestring[] = "bar";
+char buf[5] = "foo";
+
+if (strlcat(buf, somestring, sizeof(buf)) >= sizeof(buf))
+  puts("somestring was truncated, when concatenating to buf.");
+@end example
+@c -----------------------------------------------------------------------------
+@node strlcpy, strndup, strlcat, Alphabetical List
+@unnumberedsec strlcpy
+@c From file ./compat/string/strlcpy.txh
+@findex strlcpy
+@subheading Syntax
+
+@example
+#include <string.h>
+
+size_t strlcpy (char *dest, const char *src, size_t size);
+@end example
+
+@subheading Description
+
+Copy characters from @var{src} to @var{dest} and nul-terminate
+the resulting string.  Up to @code{@var{size} - 1} characters are
+copied to @var{dest}.
+
+@var{size} should be the size of the destination string buffer @var{dest}
+plus the space for the nul-terminator.  @var{size} may be computed
+in many cases using the @code{sizeof} operator.
+
+@code{strlcpy} is a less ambiguous version of @code{strncpy}
+(@pxref{strncpy,,,libc.info}).  Unlike @code{strncpy}, @code{strlcpy} @emph{always}
+nul-terminates the destination @var{dest} for non-zero sizes @var{size}.
+@code{strlcpy} returns the length of the string whether or not
+it was possible to copy it all --- this makes it easier to calculate
+the required buffer size.
+
+If @var{dest} and @var{src} are overlapping buffers, the behavior
+is undefined.  One possible result is a buffer overrun - accessing
+out-of-bounds memory.
+
+The original OpenBSD paper describing @code{strlcpy}
+and @code{strlcat} (@pxref{strlcat}) is available on the web:
+@uref{http://www.openbsd.org/papers/strlcpy-paper.ps}.
+
+@subheading Return Value
+
+The length of the string that @code{strlcpy} tried to create is returned,
+whether or not @code{strlcpy} could store it in @var{dest}.  If all
+of @var{src} was copied, the return value will be less than @var{size}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+The following example shows how you can check that
+the destination string buffer was large enough to store the source string.
+In this case @code{somestring} is truncated to fit into @code{buf}.
+
+@example
+const char somestring[] = "foo";
+char buf[3];
+
+if (strlcpy(buf, somestring, sizeof(buf)) >= sizeof(buf))
+  puts("somestring was truncated, when copying to buf.");
+@end example
+@c -----------------------------------------------------------------------------
+@node strndup, strnicmp, strlcpy, Alphabetical List
+@unnumberedsec strndup
+@c From file ./compat/string/strndup.txh
+@findex strndup
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+char *strndup(const char *source, size_t n);
+@end example
+
+@subheading Description
+
+Returns a newly allocated area of memory that contains a duplicate with at most
+@var{n} characters of the string pointed to by @var{source}.  The result is
+always NUL terminated.  The memory returned by this call must be freed by the
+caller.
+
+@subheading Return Value
+
+Returns the newly allocated string, or @code{NULL} if there
+is no more memory.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No (see note 1)
+@item POSIX
+@tab No
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+This function is a GNU extension.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char *foo()
+@{
+  return strndup("hello world", 5);
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node strnicmp, strnlen, strndup, Alphabetical List
+@unnumberedsec strnicmp
+@c From file ./compat/string/strnicmp.txh
+@findex strnicmp
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int strnicmp(const char *s1, const char *s2, size_t max);
+@end example
+
+@subheading Description
+
+This function compares @var{s1} and @var{s2}, ignoring case, up to a
+maximum of @var{max} characters. 
+
+@subheading Return Value
+
+Zero if the strings are equal, a positive number if @var{s1} comes after
+@var{s2} in the ASCII collating sequense, else a negative number. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+if (strnicmp(foo, "-i", 2) == 0)
+  do_include();
+@end example
+@c -----------------------------------------------------------------------------
+@node strnlen, strtod, strnicmp, Alphabetical List
+@unnumberedsec strnlen
+@c From file ./compat/string/strnlen.txh
+@findex strnlen
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+char *strnlen(const char *string, size_t n);
+@end example
+
+@subheading Description
+
+This function returns the number of characters in @var{string} until it
+reaches a @code{NUL} character or the maximum: @var{n} number of characters
+have been inspected.
+
+@subheading Return Value
+
+The length of the string or @var{n}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No (see note 1)
+@item POSIX
+@tab No
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+This function is a GNU extension.
+
+@end enumerate
+
+@subheading Example
+
+@example
+size_t foo()
+@{
+  return strnlen("hello world", 5);
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node strtod, strtof, strnlen, Alphabetical List
+@unnumberedsec strtod
+@c From file ./ansi/stdlib/strtod.txh
+@findex strtod
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+double strtod(const char *s, char **endp);
+@end example
+
+@subheading Description
+
+This function converts as many characters of @var{s} that look like a
+floating point number into that number.  The floating point number may
+also take the form of a hex floating point number (case-insensitively)
+like this [+|-]0xH.HHHp[+|-]DDD.  It also recognises (case-insensitively)
+``Inf'', ``Infinity'', ``NaN'', ``NaN(@var{optional decimal-number})'',
+``NaN(@var{optional octal-number})'' and ``NaN(@var{optional hex-number})''.
+If @var{endp} is not a null pointer, a pointer to the first unconverted
+character will be stored in the location pointed to by @var{endp}.  
+
+@subheading Return Value
+
+The value represented by @var{s}.
+
+If @var{s} is ``Inf'' or ``Infinity'', with any variations of
+case and optionally prefixed with ``+'' or ``-'', the return value is
+@code{INFINITY} (if no prefix or a ``+'' prefix) or @code{-INFINITY}
+(if the prefix is ``-'').
+
+If @var{s} is ``NaN'' or ``NaN()'', with any variations of case
+and optionally prefixed with ``+'' or ``-'', the return value is
+@code{(double)NAN}.  If the prefix is ``-'' the sign bit in the NaN
+will be set to 1.
+
+If @var{s} is ``NaN(@var{decimal-number})'', ``NaN(@var{octal-number})''
+or ``NaN(@var{hex-number})'', with any variations of
+case and optionally prefixed with ``+'' or ``-'', the return value is
+a NaN with the mantissa bits set to the lower 52 bits
+of @var{decimal-number}, @var{octal-number} or @var{hex-number}
+(the mantissa for doubles consists of 52 bits).  Use
+at most 16 hexadecimal digits in @var{hex-number} or the internal
+conversion will overflow, which results in a mantissa with all bits
+set.  If the bit pattern given is 0 (which won't work as a
+representation of a NaN) @code{(double)NAN} will be returned.  If the
+prefix is ``-'' the sign bit in the NaN will be set to 1.  Testing
+shows that SNaNs might be converted into QNaNs (most significant bit
+will be set in the mantissa).  
+
+If a number represented by @var{s} doesn't fit into the range of values
+representable by the type @code{double}, the function returns either
+@code{-HUGE_VAL} (if @var{s} begins with the character @code{-}) or
+@code{+HUGE_VAL}, and sets @code{errno} to @code{ERANGE}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99 (see note 1)
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+Support for ``Inf'', ``Infinity'', ``NaN'' and
+``NaN(@dots{})'' was standardised in ANSI C99.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char buf[] = "123ret";
+char buf2[] = "0x123ret";
+char buf3[] = "NAN(123)";
+char buf4[] = "NAN(0x123)";
+char buf5[] = "0x1234567.89ABCDefP+123";
+char *bp;
+double x, x2, x3, x4;
+
+x = strtod(buf, &bp);
+x2 = strtod(buf2, &bp);
+x3 = strtod(buf3, &bp);
+x4 = strtod(buf4, &bp);
+x5 = strtod(buf5, &bp);
+@end example
+
+@c -----------------------------------------------------------------------------
+@node strtof, strtold, strtod, Alphabetical List
+@unnumberedsec strtof
+@c From file ./c99/stdlib/strtof.txh
+@findex strtof
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+float strtof(const char *s, char **endp);
+@end example
+
+@subheading Description
+
+This function converts as many characters of @var{s} that look like a
+floating point number into that number.  The floating point number may
+also take the form of a hex floating point number (case-insensitively)
+like this [+|-]0xH.HHHp[+|-]DDD.  It also recognises (case-insensitively)
+``Inf'', ``Infinity'', ``NaN'', ``NaN(@var{optional decimal-number})'',
+``NaN(@var{optional octal-number})'' and ``NaN(@var{optional hex-number})''.
+If @var{endp} is not a null pointer, a pointer to the first unconverted
+character will be stored in the location pointed to by @var{endp}.  
+
+@subheading Return Value
+
+The value represented by @var{s}.
+
+If @var{s} is ``Inf'' or ``Infinity'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{INFINITY} (if no prefix or a ``+'' prefix) or @code{-INFINITY}
+(if the prefix is ``-'').
+
+If @var{s} is ``NaN'' or ``NaN()'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{NAN}.  If the prefix is ``-'' the sign bit in the NaN will be
+set to 1.
+
+If @var{s} is ``NaN(@var{decimal-number})'', ``NaN(@var{octal-number})''
+or ``NaN(@var{hex-number})'', with any variations of case
+and optionally prefixed with ``+'' or ``-'', the return value is a NaN
+with the mantissa bits set to the lower 23 bits
+of @var{decimal-number}, @var{octal-number} or @var{hex-number}
+(the mantissa for floats consists of 23 bits).  Use at most 8
+hexadecimal digits in @var{hex-number} or the internal conversion will
+overflow, which results in a mantissa with all bits set.  If the bit
+pattern given is 0 (which won't work as a representation of a NaN)
+@code{NAN} will be returned.  If the prefix is ``-'' the sign bit in
+the NaN will be set to 1.  Testing shows that SNaNs might be converted
+into QNaNs (most significant bit will be set in the mantissa).
+
+If a number represented by @var{s} doesn't fit into the range of values
+representable by the type @code{float}, the function returns either
+@code{-HUGE_VALF} (if @var{s} begins with the character @code{-}) or
+@code{+HUGE_VALF}, and sets @code{errno} to @code{ERANGE}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99 (see note 1); not C89
+@item POSIX
+@tab 1003.1-2001; not 1003.2-1992
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+Support for ``Inf'', ``Infinity'', ``NaN'' and
+``NaN(@dots{})'' was standardised in ANSI C99.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char buf[] = "123ret";
+char buf2[] = "0x123ret";
+char buf3[] = "NAN(123)";
+char buf4[] = "NAN(0x123)";
+char buf5[] = "0x1234567.89ABCDefP+12";
+char *bp;
+float x, x2, x3, x4;
+
+x = strtof(buf, &bp);
+x2 = strtof(buf2, &bp);
+x3 = strtof(buf3, &bp);
+x4 = strtof(buf4, &bp);
+x5 = strtod(buf5, &bp);
+@end example
+@c -----------------------------------------------------------------------------
+@node strtold, vasnprintf, strtof, Alphabetical List
+@unnumberedsec strtold
+@c From file ./ansi/stdlib/strtold.txh
+@findex strtold
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+long double strtold(const char *s, char **endp);
+@end example
+
+@subheading Description
+
+This function converts as many characters of @var{s} that look like a
+floating point number into that number.  The floating point number may
+also take the form of a hex floating point number (case-insensitively)
+like this [+|-]0xH.HHHp[+|-]DDD.  It also recognises (case-insensitively)
+``Inf'', ``Infinity'', ``NaN'', ``NaN(@var{optional decimal-number})'',
+``NaN(@var{optional octal-number})'' and ``NaN(@var{optional hex-number})''.
+If @var{endp} is not a null pointer, a pointer to the first unconverted
+character will be stored in the location pointed to by @var{endp}.  
+
+@subheading Return Value
+
+The value represented by @var{s}. 
+
+If @var{s} is ``Inf'' or ``Infinity'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{INFINITY} (if no prefix or a ``+'' prefix) or @code{-INFINITY}
+(if the prefix is ``-'').  
+
+If @var{s} is ``NaN'' or ``NaN()'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{(long double)NAN}.  If the prefix is ``-'' the sign bit in the
+NaN will be set to 1.  
+
+If @var{s} is ``NaN(@var{decimal-number})'', ``NaN(@var{octal-number})''
+or ``NaN(@var{hex-number})'', with any variations of case
+and optionally prefixed with ``+'' or ``-'', the return value is a NaN
+with the mantissa bits set to the lower 63 bits
+of @var{decimal-number}, @var{octal-number} or @var{hex-number}
+and the most significant bit to 1 (the mantissa for long 
+doubles consists of 64 bits where the most significant bit is the
+integer bit which must be set for NaNs).  Use at most 16 hexadecimal
+digits in @var{hex-number} or the internal conversion will overflow,
+which results in a mantissa with all bits set.  If the bit pattern
+given is 0 (which won't work as a representation of a NaN) @code{(long
+double)NAN} will be returned.  If the prefix is ``-'' the sign bit in
+the NaN will be set to 1.  Testing shows that SNaNs might be converted
+into QNaNs (the second most significant bit will be set in the
+mantissa).  
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99 (see note 1); not C89
+@item POSIX
+@tab 1003.1-2001; not 1003.2-1992
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+Support for ``Inf'', ``Infinity'', ``NaN'' and
+``NaN(@dots{})'' was standardised in ANSI C99.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char buf[] = "123ret";
+char buf2[] = "0x123ret";
+char buf3[] = "NAN(123)";
+char buf4[] = "NAN(0x123)";
+char buf5[] = "0x1234567.89abcdefP+1234";
+char *bp;
+long double x, x2, x3, x4;
+
+x = strtold(buf, &bp);
+x2 = strtold(buf2, &bp);
+x3 = strtold(buf3, &bp);
+x4 = strtold(buf4, &bp);
+x5 = strtold(buf5, &bp);
+@end example
+@c -----------------------------------------------------------------------------
+@node vasnprintf, vasprintf, strtold, Alphabetical List
+@unnumberedsec vasnprintf
+@c From file ./compat/stdio/vasnprtf.txh
+@findex vasnprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vasnprintf(char **buffer, size_t n, const char *format,
+               va_list ap);
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments in (@var{ap}) including
+the terminating null byte to the allocated buffer and returns
+a pointer to it via the first parameter *@var{bufferp}.  This
+memory must be returned to the heap with @code{free} (@pxref{free,,,libc.info}). 
+This function will write @var{n} - 1 characters.  The @var{n}th character
+is used for the terminating nul.  If @var{n} is zero, @var{buffer} is not
+touched.  This function is analog of @code{vsnprintf()} (@pxref{vsnprintf}).
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding the trailing
+nul) is returned; otherwise EOF is returned to flag encoding or buffer space
+errors.
+
+The maximum accepted value of @var{n} is @code{INT_MAX}.  @code{INT_MAX} is
+defined in @code{<limits.h>}.  EOF is returned and @code{errno} is set to
+@code{EFBIG}, if @var{n} is greater than this limit.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No (see note 1)
+@item POSIX
+@tab No
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The buffer size limit is imposed by DJGPP.  Other systems may not have this limitation.
+
+@end enumerate
+
+@subheading Example
+
+@example
+char *strbuf;  /*  Pointer to the buffer allocated by vasnprintf.  */
+int strlng;
+
+strlng = vasnprintf(&strbuf, 1000, "arg[0] = %s\n"
+                                   "arg[1] = %s\n"
+                                   "arg[2] = %s\n", arg_list);
+
+if (EOF == strlng)
+  printf("error: vasnprintf failed.\n");
+else
+@{
+  /*
+   *  Your code using the buffer allocated by vasnprintf.
+   */
+  do_something(strbuf, strlng);
+
+  free(strbuf);  /*  Release the memory allocated by vasnprintf.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node vasprintf, vfprintf, vasnprintf, Alphabetical List
+@unnumberedsec vasprintf
+@c From file ./compat/stdio/vasprintf.txh
+@findex vasprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vasprintf(char **bufferp, const char *format, va_list ap);
+@end example
+
+@subheading Description
+
+Sends formatted output from the arguments in (@var{ap}) including
+the terminating null byte to the allocated buffer and returns
+a pointer to it via the first parameter *@var{bufferp}.  This
+memory must be returned to the heap with @code{free} (@pxref{free,,,libc.info}). 
+This function is analog of @code{vsprintf()} (@pxref{vsprintf}).
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding
+the terminating null byte) is returned; otherwise EOF is returned
+to flag encoding or buffer space errors and the pointer
+*@var{bufferp} is set to @code{NULL}.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char *strbuf;  /*  Pointer to the buffer allocated by vasprintf.  */
+int strlng;
+
+strlng = vasprintf(&strbuf, "arg[0] = %s\n"
+                            "arg[1] = %s\n"
+                            "arg[2] = %s\n", arg_list);
+
+if (EOF == strlng)
+  printf("error: vasprintf failed.\n");
+else
+@{
+  /*
+   *  Your code using the buffer allocated by vasprintf.
+   */
+  do_something(strbuf, strlng);
+
+  free(strbuf);  /*  You must release the memory allocated by vasprintf.  */
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node vfprintf, vfscanf, vasprintf, Alphabetical List
+@unnumberedsec vfprintf
+@c From file ./ansi/stdio/vfprintf.txh
+@findex vfprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vfprintf(FILE *file, const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+Sends formatted output from the @var{arguments} to the @var{file}. 
+@xref{printf}.
+
+@subheading Return Value
+
+The number of characters written.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+@example
+void my_errmsg(char *format, ...)
+@{
+  va_list arg;
+
+  va_start(arg, format);
+  fprintf(stderr, "my_errmsg: ");
+  vfprintf(stderr, format, arg);
+  va_end(arg);
+@}
+@end example
+@c -----------------------------------------------------------------------------
+@node vfscanf, vprintf, vfprintf, Alphabetical List
+@unnumberedsec vfscanf
+@c From file ./compat/stdio/vfscanf.txh
+@findex vfscanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vfscanf(FILE *file, const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+This function scans formatted text from @var{file} and stores it in the
+variables pointed to by the @var{arguments}.  @xref{scanf}.
+
+@subheading Return Value
+
+The number of items successfully scanned.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+@c -----------------------------------------------------------------------------
+@node vprintf, vscanf, vfscanf, Alphabetical List
+@unnumberedsec vprintf
+@c From file ./ansi/stdio/vprintf.txh
+@findex vprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vprintf(const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+Sends formatted output from the @var{arguments} to @code{stdout}. 
+@xref{printf}. @xref{vfprintf}.
+
+@subheading Return Value
+
+The number of characters written.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node vscanf, vsnprintf, vprintf, Alphabetical List
+@unnumberedsec vscanf
+@c From file ./compat/stdio/vscanf.txh
+@findex vscanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vscanf(const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+This function scans formatted text from @code{stdin} and stores it in the
+variables pointed to by the @var{arguments}. @xref{scanf}.
+@xref{vfscanf}.
+
+@subheading Return Value
+
+The number of items successfully scanned.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+@c -----------------------------------------------------------------------------
+@node vsnprintf, vsprintf, vscanf, Alphabetical List
+@unnumberedsec vsnprintf
+@c From file ./ansi/stdio/vsnprntf.txh
+@findex vsnprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vsnprintf(char *buffer, size_t n, const char *format, va_list ap);
+@end example
+
+@subheading Description
+
+This function works similarly to @code{vsprintf()} (@pxref{vsprintf}), but
+the size @var{n} of the @var{buffer} is also taken into account.  This
+function will write @var{n} - 1 characters.  The @var{n}th character is used
+for the terminating nul.  If @var{n} is zero, @var{buffer} is not touched.
+
+@subheading Return Value
+
+The number of characters that would have been written (excluding the trailing
+nul) is returned; otherwise -1 is returned to flag encoding or buffer space
+errors.
+
+The maximum accepted value of @var{n} is @code{INT_MAX}.  @code{INT_MAX} is
+defined in @code{<limits.h>}.  -1 is returned and @code{errno} is set to
+@code{EFBIG}, if @var{n} is greater than this limit.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99 (see note 1)
+@end multitable
+
+@noindent
+Notes:
+
+@enumerate
+@item
+The buffer size limit is imposed by DJGPP.  Other systems may not have this limitation.
+
+@end enumerate
+@c -----------------------------------------------------------------------------
+@node vsprintf, vsscanf, vsnprintf, Alphabetical List
+@unnumberedsec vsprintf
+@c From file ./ansi/stdio/vsprintf.txh
+@findex vsprintf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vsprintf(char *buffer, const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+Sends formatted output from the @var{arguments} to the @var{buffer}.
+@xref{printf}. @xref{vfprintf}.
+
+To avoid buffer overruns, it is safer to use @code{vsnprintf()}
+(@pxref{vsnprintf}).
+
+@subheading Return Value
+
+The number of characters written.
+
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C89; C99
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+@c -----------------------------------------------------------------------------
+@node vsscanf, write, vsprintf, Alphabetical List
+@unnumberedsec vsscanf
+@c From file ./compat/stdio/vsscanf.txh
+@findex vsscanf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int vsscanf(const char *string, const char *format, va_list arguments);
+@end example
+
+@subheading Description
+
+This function scans formatted text from the @var{string} and stores it
+in the variables pointed to by the @var{arguments}. @xref{scanf}.
+@xref{vfscanf}.
+
+@subheading Return Value
+
+The number of items successfully scanned.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+@c -----------------------------------------------------------------------------
+@node write,  _atold, vsscanf, Alphabetical List
+@unnumberedsec write
+@c From file ./posix/unistd/write.txh
+@findex write
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int write(int file, const void *buffer, size_t count);
+@end example
+
+@subheading Description
+
+This function writes @var{count} bytes from @var{buffer} to
+@var{file}.  It returns the number of bytes actually written.  It will
+return zero or a number less than @var{count} if the disk is full, and
+may return less than @var{count} even under valid conditions.
+
+Note that if @var{file} is a text file, @code{write} may write more
+bytes than it reports. 
+
+If @var{count} is zero, the function does nothing and returns zero.
+Use @code{_write} if you want to actually ask DOS to write zero bytes.
+
+The precise behavior of @code{write} when the target filesystem is full
+is somewhat troublesome, because DOS doesn't fail the underlying system
+call.  If your application needs to rely on @code{errno} being set to
+@code{ENOSPC} in such cases, you need to invoke @code{write} as shown in
+the example below.  In a nutshell, the trick is to call @code{write} one
+more time after it returns a value smaller than the @var{count}
+parameter; then it will @emph{always} set @code{errno} if the disk is
+full.
+
+@subheading Return Value
+
+The number of bytes written, zero at EOF, or -1 on error.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab 1003.2-1992; 1003.1-2001
+@end multitable
+
+
+@subheading Example
+
+This example shows how to call @code{write} in a way which ensures that
+@code{errno} will be set to @code{ENOSPC} if the target filesystem is or
+becomes full:
+
+@example
+  char *buf_ptr;    /* the buffer to write */
+  size_t buf_len;   /* the number of bytes to write */
+  int desc;         /* the file descriptor to write to */
+
+  while (buf_len > 0)
+  @{
+    int written = write (desc, buf_ptr, buf_len);
+    if (written <= 0)
+      break;
+
+    buf_ptr += written;
+    buf_len -= written;
+  @}
+@end example
+@c -----------------------------------------------------------------------------
+@node _atold, _close, write, Alphabetical List
+@unnumberedsec _atold
+@c From file ./ansi/stdlib/atold.txh
+@findex _atold
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+long double _atold(const char *string);
+@end example
+
+@subheading Description
+
+Convert as much of the string as possible to an equivalent long double
+precision real number.
+
+This function is almost like @code{_strtold(string, NULL)} (@pxref{_strtold}).
+
+@subheading Return Value
+
+The equivalent value, or zero if the string does not represent a number. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+main(int argc, char **argv)
+@{
+  long double d = _atold(argv[1]);
+  @dots{}
+@end example
+@c -----------------------------------------------------------------------------
+@node _close, _doprnt, _atold, Alphabetical List
+@unnumberedsec _close
+@c From file ./dos/io/_close.txh
+@findex _close
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int _close(int fd);
+@end example
+
+@subheading Description
+
+This is a direct connection to the MS-DOS close function call, int
+0x21, %ah = 0x3e. This function can be hooked by the
+(@pxref{File System Extensions,,,libc.info}). If you don't want this,
+you should use (@pxref{_dos_close,,,libc.info}).
+
+@subheading Return Value
+
+Zero if the file was closed, else nonzero. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+@c -----------------------------------------------------------------------------
+@node _doprnt, _doscan, _close, Alphabetical List
+@unnumberedsec _doprnt
+@c From file ./ansi/stdio/doprnt.txh
+@findex _doprnt
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int _doprnt(const char *format, void *params, FILE *file);
+@end example
+
+@subheading Description
+
+This is an internal function that is used by all the @code{printf} style
+functions, which simply pass their format, arguments, and stream to this
+function. 
+
+@xref{printf}, for a discussion of the allowed formats and arguments. 
+
+@subheading Return Value
+
+The number of characters generated is returned.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+int args[] = @{ 1, 2, 3, 66 @};
+_doprnt("%d %d %d %c\n", args, stdout);
+@end example
+@c -----------------------------------------------------------------------------
+@node _doscan, _fixpath, _doprnt, Alphabetical List
+@unnumberedsec _doscan
+@c From file ./ansi/stdio/doscan.txh
+@findex _doscan
+@subheading Syntax
+
+@example
+#include <stdarg.h>
+#include <libsupp.h>
+
+int _doscan(FILE *file, const char *format, va_list argp);
+@end example
+
+@subheading Description
+
+This is an internal function that is used by all the @code{scanf} style
+functions, which simply pass their format, arguments, and stream to this
+function. 
+
+@xref{scanf}, for a discussion of the allowed formats and arguments. 
+
+@subheading Return Value
+
+The number of characters successfully scanned is returned, or -1 on
+error. 
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+TODO: This example is bogus now!
+TODO: Rewrite this example!
+
+int x, y;
+int *args[2];
+args[0] = &x;
+args[1] = &y;
+_doscan(stdin, "%d %d", args);
+@end example
+@c -----------------------------------------------------------------------------
+@node _fixpath, _strtold, _doscan, Alphabetical List
+@unnumberedsec _fixpath
+@c From file ./posix/sys/stat/fixpath.txh
+@findex _fixpath
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+void _fixpath(const char *in_path, char *out_path);
+@end example
+
+@subheading Description
+
+This function canonicalizes the input path @var{in_path} and stores the
+result in the buffer pointed to by @var{out_path}.
+
+The path is fixed by removing consecutive and trailing slashes, making
+the path absolute if it's relative by prepending the current drive
+letter and working directory, removing "." components, collapsing
+".." components, adding a drive specifier if needed, and converting all
+slashes to '/'.  DOS-style 8+3 names of directories which are part of
+the pathname, as well as its final filename part, are returned
+lower-cased in @var{out_path}, but long filenames are left intact.
+@pxref{_preserve_fncase,,,libc.info}, for more details on letter-case conversions
+in filenames.
+
+Since the returned path name can be longer than the original one, the
+caller should ensure there is enough space in the buffer pointed to by
+@var{out_path}.  Using ANSI-standard constant @code{FILENAME_MAX}
+(defined on @file{stdio.h}) or Posix-standard constant @code{PATH_MAX}
+(defined on @file{limits.h}) is recommended.
+
+@subheading Return Value
+
+None.  If the length of the returned path name exceeds @code{FILENAME_MAX},
+@code{errno} is set to @code{ENAMETOOLONG}.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char oldpath[100], newpath[FILENAME_MAX];
+scanf("%s", oldpath);
+_fixpath(oldpath, newpath);
+printf("that really is %s\n", newpath);
+@end example
+@c -----------------------------------------------------------------------------
+@node _strtold, _write, _fixpath, Alphabetical List
+@unnumberedsec _strtold
+@c From file ./ansi/stdlib/strtold.txh
+@findex _strtold
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+long double _strtold(const char *s, char **endp);
+@end example
+
+@subheading Description
+
+This function converts as many characters of @var{s} that look like a
+floating point number into that number.  The floating point number may
+also take the form of a hex floating point number (case-insensitively)
+like this [+|-]0xH.HHHp[+|-]DDD.  It also recognises (case-insensitively)
+``Inf'', ``Infinity'', ``NaN'', ``NaN(@var{optional decimal-number})'',
+``NaN(@var{optional octal-number})'' and ``NaN(@var{optional hex-number})''.
+If @var{endp} is not a null pointer, a pointer to the first unconverted
+character will be stored in the location pointed to by @var{endp}.  
+
+There is also a standardised version of this function:
+@code{strtold} (@pxref{strtold}).
+
+@subheading Return Value
+
+The value represented by @var{s}. 
+
+If @var{s} is ``Inf'' or ``Infinity'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{INFINITY} (if no prefix or a ``+'' prefix) or @code{-INFINITY}
+(if the prefix is ``-'').  
+
+If @var{s} is ``NaN'' or ``NaN()'', with any variations of case and
+optionally prefixed with ``+'' or ``-'', the return value is
+@code{(long double)NAN}.  If the prefix is ``-'' the sign bit in the
+NaN will be set to 1.  
+
+If @var{s} is ``NaN(@var{decimal-number})'', ``NaN(@var{octal-number})''
+or ``NaN(@var{hex-number})'', with any variations of case
+and optionally prefixed with ``+'' or ``-'', the return value is a NaN
+with the mantissa bits set to the lower 63 bits
+of @var{decimal-number}, @var{octal-number} or @var{hex-number}
+and the most significant bit to 1 (the mantissa for long 
+doubles consists of 64 bits where the most significant bit is the
+integer bit which must be set for NaNs).  Use at most 16 hexadecimal
+digits in @var{hex-number} or the internal conversion will overflow,
+which results in a mantissa with all bits set.  If the bit pattern
+given is 0 (which won't work as a representation of a NaN) @code{(long
+double)NAN} will be returned.  If the prefix is ``-'' the sign bit in
+the NaN will be set to 1.  Testing shows that SNaNs might be converted
+into QNaNs (the second most significant bit will be set in the
+mantissa).  
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+@example
+char buf[] = "123ret";
+char buf2[] = "0x123ret";
+char buf3[] = "NAN(123)";
+char buf4[] = "NAN(0x123)";
+char buf5[] = "0x1234567.89ABCDefP+1234";
+char *bp;
+long double x, x2, x3, x4;
+
+x = _strtold(buf, &bp);
+x2 = _strtold(buf2, &bp);
+x3 = _strtold(buf3, &bp);
+x4 = _strtold(buf4, &bp);
+x5 = _strtold(buf5, &bp);
+@end example
+@c -----------------------------------------------------------------------------
+@node _write, __signbitd, _strtold, Alphabetical List
+@unnumberedsec _write
+@c From file ./dos/io/_write.txh
+@findex _write
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+ssize_t _write(int fildes, const void *buf, size_t nbyte);
+@end example
+
+@subheading Description
+
+This is a direct connection to the MS-DOS write function call, int
+0x21, %ah = 0x40.  No conversion is done on the data; it is written as
+raw binary data.  This function can be hooked by the File-system
+extensions, see (@pxref{File System Extensions,,,libc.info}).  If you don't want this,
+you should use @code{_dos_write} instead, see (@pxref{_dos_write,,,libc.info}).
+
+@subheading Return Value
+
+The number of bytes written, or -1 (and @code{errno} set) in case of
+failure.
+
+Note that DOS doesn't return an error indication when the target disk is
+full; therefore if the disk fills up while the data is written,
+@code{_write} does @strong{not} return -1, it returns the number of
+bytes it succeeded to write.  If you need to detect the disk full
+condition reliably, call @code{_write} again to try to write the rest of
+the data.  This will cause DOS to return zero as the number of written
+bytes, and @emph{then} @code{_write} will return -1 and set @code{errno}
+to @code{ENOSPC}.  The example below shows one way of doing this.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab No
+@item POSIX
+@tab No
+@end multitable
+
+
+@subheading Example
+
+This example shows how to call @code{_write} in a way which ensures that
+@code{errno} will be set to @code{ENOSPC} if the target filesystem is or
+becomes full:
+
+@example
+  char *buf_ptr;    /* the buffer to write */
+  size_t buf_len;   /* the number of bytes to write */
+  int desc;         /* the file descriptor to write to */
+
+  while (buf_len > 0)
+  @{
+    int written = _write (desc, buf_ptr, buf_len);
+    if (written <= 0)
+      break;
+
+    buf_ptr += written;
+    buf_len -= written;
+  @}
+@end example
+@c -----------------------------------------------------------------------------
+@node __signbitd, __signbitf, _write, Alphabetical List
+@unnumberedsec __signbitd
+@c From file ./c99/math/sgnbitd.txh
+@findex __signbitd
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int __signbitd(double x);
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99; not C89
+@end multitable
+
+
+@subheading Example
+
+@example
+
+printf("double value is %s.\n", (__signbitd(0.0)) ? "negative" : "positive");
+
+@end example
+@c -----------------------------------------------------------------------------
+@node __signbitf, __signbitld, __signbitd, Alphabetical List
+@unnumberedsec __signbitf
+@c From file ./c99/math/sgnbitf.txh
+@findex __signbitf
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int __signbitf(float x);
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99; not C89
+@end multitable
+
+
+@subheading Example
+
+@example
+
+printf("float value is %s.\n", (__signbitf(0.0F)) ? "negative" : "positive");
+
+@end example
+@c -----------------------------------------------------------------------------
+@node __signbitld, , __signbitf, Alphabetical List
+@unnumberedsec __signbitld
+@c From file ./c99/math/sgnbitld.txh
+@findex __signbitld
+@subheading Syntax
+
+@example
+#include <libsupp.h>
+
+int __signbitld(long double x);
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@multitable {ANSI/ISO C} {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
+@item ANSI/ISO C
+@tab C99; not C89
+@end multitable
+
+
+@subheading Example
+
+@example
+
+printf("long double value is %s.\n", (__signbitld(0.0L)) ? "negative" : "positive");
+
+@end example
+@c -----------------------------------------------------------------------------
+
diff -aprNU5 libsupp-6.2.orig/include/libsupp.h libsupp-6.2/include/libsupp.h
--- libsupp-6.2.orig/include/libsupp.h	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/include/libsupp.h	2009-11-22 04:03:54 +0000
@@ -0,0 +1,691 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+
+#ifndef __libsupp_h_
+#define __libsupp_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/version.h>  /*  gcc 4.3.0 no longer includes this by default.  */
+#include <stdarg.h>
+
+/* For GCC-4.4.X the definitions have chenged again ...                    */
+/* This is however not surprising as we are messing here with internal     */
+/* stuff of GCC.                                                           */
+#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)
+# undef va_start
+# undef va_end
+# undef va_arg
+# define va_start(ap, last_arg)   __builtin_va_start(ap, last_arg)
+# define va_end(ap)               __builtin_va_end(ap)
+# define va_arg(v, l)             __builtin_va_arg(v, l)
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/*
+ *  Functions implemented in libsupp 1.0.
+ */
+
+#if __DJGPP_MINOR__ < 4
+__extension__ typedef signed long long intmax_t;
+__extension__ typedef unsigned long long uintmax_t;
+__DJ_off_t
+# undef  __DJ_off_t
+# define __DJ_off_t
+#else
+# ifndef _OFF_T
+__DJ_off_t
+#  define _OFF_T
+# endif
+#endif
+
+
+int            libsupp__doprnt(const char *_fmt, va_list _ap, FILE *_f);
+int            libsupp_asnprintf(char **_sp, size_t _n, const char *_fmt, ...) __attribute__((format (__printf__, 3, 4)));
+int            libsupp_asprintf(char **_sp, const char *_fmt, ...) __attribute__((format (__printf__, 2, 3)));
+int            libsupp_cprintf(const char *_fmt, ...) __attribute__((format (__printf__, 1, 2)));
+int            libsupp_fprintf(FILE *_f, const char *_fmt, ...) __attribute__((format (__printf__, 2, 3)));
+int            libsupp_printf(const char *_fmt, ...) __attribute__((format (__printf__, 1, 2)));
+int            libsupp_snprintf(char *_s, size_t _n, const char *_fmt, ...) __attribute__((format (__printf__, 3, 4)));
+int            libsupp_sprintf(char *_s, const char *_fmt, ...) __attribute__((format (__printf__, 2, 3)));
+int            libsupp_vasnprintf(char **_sp, size_t _n, const char *_fmt, va_list _ap) __attribute__((format (__printf__, 3, 0)));
+int            libsupp_vasprintf(char **_sp, const char *_fmt, va_list _ap) __attribute__((format (__printf__, 2, 0)));
+int            libsupp_vfprintf(FILE *_s, const char *_fmt, va_list _ap) __attribute__((format (__printf__, 2, 0)));
+int            libsupp_vprintf(const char *_fmt, va_list _ap) __attribute__((format (__printf__, 1, 0)));
+int            libsupp_vsnprintf(char *_s, size_t n, const char *_fmt, va_list _ap) __attribute__((format (__printf__, 3, 0)));
+int            libsupp_vsprintf(char *_s, const char *_fmt, va_list _ap) __attribute__((format (__printf__, 2, 0)));
+
+
+/*
+ *  Functions implemented in libsupp 2.0.
+ */
+
+int            libsupp_fseeko(FILE *_stream, off_t _offset, int _mode);
+off_t          libsupp_ftello(FILE *_stream);
+
+int            libsupp___signbitf(float x) __attribute__((const));
+int            libsupp___signbitd(double x) __attribute__((const));
+int            libsupp___signbitld(long double x) __attribute__((const));
+
+
+/*
+ *  Functions implemented in libsupp 3.0.
+ */
+
+double         libsupp_strtod(const char *_s, char **_sret);
+float          libsupp_strtof(const char *_s, char **_sret);
+long double    libsupp_strtold(const char *_s, char **_sret);
+
+
+#include <errno.h>
+
+#ifndef _ERROR_T
+typedef int error_t;
+# define _ERROR_T
+#endif
+
+error_t        libsupp_argz_add(char **_argz, size_t *_argz_len, const char *_str);
+error_t        libsupp_argz_add_sep(char **_argz, size_t *_argz_len, const char *_str, int _sep);
+error_t        libsupp_argz_append(char **_argz, size_t *_argz_len, const char *_buf, size_t _buf_len);
+size_t         libsupp_argz_count(const char *_argz, size_t _argz_len);
+error_t        libsupp_argz_create(char *const _argv[], char **_argz, size_t *_argz_len);
+error_t        libsupp_argz_create_sep(const char *_str, int _sep, char **_argz, size_t *_argz_len);
+void           libsupp_argz_delete(char **_argz, size_t *_argz_len, char *_entry);
+void           libsupp_argz_extract(const char *_argz, size_t _argz_len, char **_argv);
+error_t        libsupp_argz_insert(char **_argz, size_t *_argz_len, char *_before, const char *_entry);
+char          *libsupp_argz_next(const char *_argz, size_t _argz_len, const char *_entry);
+error_t        libsupp_argz_replace(char **_argz, size_t *_argz_len, const char *_str, const char *_with, unsigned *_replace_count);
+void           libsupp_argz_stringify(char *_argz, size_t _argz_len, int _sep);
+
+
+/*
+ *  Functions implemented in libsupp 4.0.
+ */
+
+char          *libsupp_strndup(const char *_str, size_t _n);
+size_t         libsupp_strnlen(const char *_str, size_t _n);
+
+
+/*
+ *  Functions implemented in libsupp 5.0.
+ */
+
+#include <dirent.h>
+
+#if __DJGPP_MINOR__ < 4
+
+#define DT_REG      0x1
+#define DT_BLK      0x2
+#define DT_CHR      0x3
+#define DT_DIR      0x4
+#define DT_FIFO     0x5
+#define DT_LABEL    0x6
+#define DT_LNK      0x7
+#define DT_UNKNOWN  0xf
+
+#define DTTOIF(dt)  (((dt) == DT_UNKNOWN ? 0 : (dt) - 1) << 12)
+
+
+# include <sys/types.h>
+
+# undef  dirent
+# define dirent     libsupp_dirent
+struct dirent {
+  char d_namlen;
+  char d_name[256];
+  mode_t d_type;
+};
+
+DIR           *libsupp_opendir_2_03(const char *_dir_name);
+struct dirent *libsupp_readdir_2_03(DIR *_dirp);
+
+int            libsupp_open_2_03(const char* _filename, int _oflag, ...);
+int            libsupp_close_2_03(int _handle);
+int            libsupp_fchdir_2_03(int _fd);
+#else
+DIR           *libsupp_opendir(const char *_dir_name);
+struct dirent *libsupp_readdir(DIR *_dirp);
+#endif
+void           libsupp_rewinddir(DIR *_dirp);
+
+
+/*
+ *  Functions implemented in libsupp 5.1.
+ */
+
+int            libsupp_closedir(DIR *_dirp);
+
+
+/*
+ *  Functions implemented in libsupp 5.2.
+ */
+
+#include <sys/stat.h>
+
+#if __DJGPP_MINOR__ < 4
+int            libsupp_access_2_03(const char *_fn, int _flags);
+int            libsupp___chdir_2_03(const char *_mydirname);
+void           libsupp__fixpath_2_03(const char *_in, char *_out);
+int            libsupp_stat_2_03(const char *_path, struct stat *_statbuf);
+int            libsupp_symlink_2_03(const char *_source, const char *_dest);
+#else
+int            libsupp_access(const char *_fn, int _flags);
+int            libsupp___chdir(const char *_mydirname);
+void           libsupp__fixpath(const char *_in, char *_out);
+char          *libsupp___canonicalize_path(const char *_in, char *_out, size_t _path_max);
+int            libsupp_lstat(const char *_path, struct stat *_statbuf);
+char          *libsupp_realpath(const char *_in, char *_out);
+#endif
+
+
+/*
+ *  Functions implemented in libsupp 6.0.
+ */
+
+#include <time.h>
+
+size_t         libsupp_strftime(char *_s, size_t _maxsize, const char *_format, const struct tm *_t);
+void          *libsupp_memmem(const void *_haystack, size_t _haystack_len, const void *_needle, size_t _needle_len);
+
+#include <wctype.h>
+
+wint_t         libsupp_towlower(wint_t _c);
+
+#ifndef USE_DJGPP_STRL_FCTNS
+# include <stddef.h>
+
+size_t         libsupp_strlcpy(char *_dst, const char *_src, size_t _sz);
+size_t         libsupp_strlcat(char *_dst, const char *_src, size_t _sz);
+#endif
+
+
+/*
+ *  Functions implemented in libsupp 6.1.
+ */
+
+#ifndef USE_DJGPP_MBTOWC_FCTNS
+# include <wchar.h>
+
+/*  Conversion state information.  */
+typedef struct
+{
+  int __count;
+  union
+  {
+    wint_t __wch;
+    unsigned char __wchb[4];
+  } __value;  /*  Value so far.  */
+} libsupp_mbstate_t;
+
+# undef  mbstate_t
+# define mbstate_t  libsupp_mbstate_t
+
+int            libsupp_mblen(const char *_s, size_t _n);
+int            libsupp_mbsinit(const libsupp_mbstate_t *_ps);
+size_t         libsupp_mbrtowc(wchar_t *_pwc, const char *_s, size_t _n, libsupp_mbstate_t *_ps);
+int            libsupp_mbtowc(wchar_t *_pwc, const char *_s, size_t _n);
+#endif
+
+
+/*
+ *  Functions implemented in libsupp 6.2.
+ */
+#if 0
+/*
+ *  None of them are supported by DJGPP...
+ */
+#ifndef SA_NOCLDSTOP
+# define SA_NOCLDSTOP  1                /* Do not generate SIGCHLD when children stop */
+#endif
+#ifndef SA_RESTART
+# define SA_RESTART    0x10000000       /* Restart syscall on signal return */
+#endif
+#ifndef SA_NODEFER
+# define SA_NODEFER    0x40000000       /* Don't automatically block the signal when its handler is being executed  */
+#endif
+#ifndef SA_ONESHOT
+# define SA_ONESHOT    SA_RESETHAND     /* Historical linux name */
+#endif
+#ifndef SA_NOMASK
+# define SA_NOMASK     SA_NODEFER       /* Historical linux name */
+#endif
+#else
+/*
+ *  .. so define them to some sane default.
+ */
+#ifndef SA_NOCLDSTOP
+# define SA_NOCLDSTOP  0  /* Do not generate SIGCHLD when children stop */
+#endif
+#ifndef SA_RESTART
+# define SA_RESTART    0  /* Restart syscall on signal return */
+#endif
+#ifndef SA_NODEFER
+# define SA_NODEFER    0  /* Don't automatically block the signal when its handler is being executed  */
+#endif
+#ifndef SA_RESETHAND
+# define SA_RESETHAND  0
+#endif
+#ifndef SA_ONESHOT
+# define SA_ONESHOT    SA_RESETHAND     /* Historical linux name */
+#endif
+#ifndef SA_NOMASK
+# define SA_NOMASK     SA_NODEFER       /* Historical linux name */
+#endif
+#endif
+
+#ifndef _O_TEMPORARY
+# define _O_TEMPORARY  O_TEMPORARY
+#endif
+
+
+int            libsupp__doscan(FILE *_iop, const char *_fmt, va_list _argp);
+int            libsupp_fscanf(FILE *_f, const char *_fmt, ...);
+int            libsupp_scanf(const char *_fmt, ...);
+int            libsupp_sscanf(const char *_str, const char *_fmt, ...);
+int            libsupp_vfscanf(FILE *_iop, const char *_fmt, va_list _argp);
+int            libsupp_vscanf(const char *_fmt, va_list _ap);
+int            libsupp_vsscanf(const char *_str, const char *_fmt, va_list _ap);
+
+double         libsupp_atof(const char *_ascii);
+long double    libsupp__atold(const char *_ascii);
+
+int            libsupp_strnicmp(const char *_s1, const char *_s2, size_t _n);
+
+wint_t         libsupp_towupper(wint_t _c);
+
+
+#include <fcntl.h>           /*  For the modes.  */
+#if __DJGPP_MINOR__ >= 4
+# include <sys/statvfs.h>    /*  For struct statvfs.  */
+#endif
+
+#if __DJGPP_MINOR__ < 4
+int            libsupp_fclose_2_03(FILE *_f);
+int            libsupp_fflush_2_03(FILE *_f);
+int            libsupp__flsbuf_2_03(int _c, FILE *_f);
+FILE          *libsupp_fopen_2_03(const char *_file, const char *_mode);
+FILE          *libsupp_freopen_2_03(const char *_file, const char *_mode, FILE *_f);
+int            libsupp_fseek_2_03(FILE *_f, long _offset, int _ptrname);
+long           libsupp_ftell_2_03(FILE *_f);
+void           libsupp_rewind_2_03(FILE *_f);
+int            libsupp_select_2_03(int _nfds, fd_set *_readfds, fd_set *_writefds, fd_set *_exceptfds, struct timeval *_timeout);
+int            libsupp_fsync_2_03(int _fd);
+int            libsupp_ftruncate_2_03(int _fd, off_t _where);
+int            libsupp__close_2_03(int _handle);
+int            libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+int            libsupp_fcntl_2_03(int _fd, int _cmd, ...);
+FILE          *libsupp_fdopen_2_03(int _fildes, const char *_mode);
+int            libsupp_dup2_2_03(int _fd, int _newfd);
+int            libsupp_dup_2_03(int _fd);
+off_t          libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+ssize_t        libsupp_read_2_03(int _handle, void* _buffer, size_t _count);
+ssize_t        libsupp_write_2_03(int _handle, const void* _buffer, size_t _count);
+int            libsupp_fstat_2_03(int _handle, struct stat *_statbuf);
+#else
+int            libsupp_fclose(FILE *_f);
+int            libsupp_fflush(FILE *_f);
+int            libsupp__flsbuf(int _c, FILE *_f);
+FILE          *libsupp_fopen(const char *_file, const char *_mode);
+FILE          *libsupp_freopen(const char *_file, const char *_mode, FILE *_f);
+int            libsupp_fseek(FILE *_f, long _offset, int _ptrname);
+long           libsupp_ftell(FILE *_f);
+void           libsupp_rewind(FILE *_f);
+int            libsupp_select(int _nfds, fd_set *_readfds, fd_set *_writefds, fd_set *_exceptfds, struct timeval *_timeout);
+int            libsupp_fsync(int _fd);
+int            libsupp_ftruncate(int _fd, off_t _where);
+offset_t       libsupp_llseek(int _handle, offset_t _offset, int _whence);
+int            libsupp__close(int _handle);
+ssize_t        libsupp__write(int _handle, const void* _buffer, size_t _count);
+int            libsupp__write_fill_seek_gap(int _fd);
+int            libsupp__write_int(int _fd, const char *_buffer, unsigned long long _write_count);
+int            libsupp_fcntl(int _fd, int _cmd, ...);
+int            libsupp_open(const char* _filename, int _oflag, ...);
+FILE          *libsupp_fdopen(int _fildes, const char *_mode);
+int            libsupp_fchmod(int _fd, mode_t _mode);
+int            libsupp_fstat(int _handle, struct stat *_statbuf);
+int            libsupp_stat(const char *_path, struct stat *_statbuf);
+int            libsupp_fstatvfs(int _fd, struct statvfs *_outbuf);
+int            libsupp_close(int _handle);
+int            libsupp_dup2(int _fd, int _newfd);
+int            libsupp_dup(int _fd);
+off_t          libsupp_lseek(int _handle, off_t _offset, int _whence);
+int            libsupp_pipe(int _fildes[2]);
+ssize_t        libsupp_read(int _handle, void* _buffer, size_t _count);
+ssize_t        libsupp_write(int _handle, const void* _buffer, size_t _count);
+long long      libsupp_lfilelength(int _fhandle);
+#endif
+
+#ifdef HUGE_VALF
+# undef  HUGE_VALF
+# define HUGE_VALF libsupp___dj_huge_valf
+extern float       libsupp___dj_huge_valf;
+#endif
+
+#ifdef HUGE_VALL
+# undef  HUGE_VALL
+# define HUGE_VALL libsupp___dj_huge_vall
+extern long double libsupp___dj_huge_vall;
+#endif
+
+#ifdef NAN
+# undef  NAN
+# define NAN libsupp___dj_nan
+extern float libsupp___dj_nan;
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+
+/*
+ *  Make them visible.
+ */
+
+#undef  _doprnt
+#define _doprnt                     libsupp__doprnt
+#undef  asnprintf
+#define asnprintf                   libsupp_asnprintf
+#undef  asprintf
+#define asprintf                    libsupp_asprintf
+#undef  cprintf
+#define cprintf                     libsupp_cprintf
+#undef  fprintf
+#define fprintf                     libsupp_fprintf
+#undef  printf
+#define printf                      libsupp_printf
+#undef  snprintf
+#define snprintf                    libsupp_snprintf
+#undef  sprintf
+#define sprintf                     libsupp_sprintf
+#undef  vasnprintf
+#define vasnprintf                  libsupp_vasnprintf
+#undef  vasprintf
+#define vasprintf                   libsupp_vasprintf
+#undef  vfprintf
+#define vfprintf                    libsupp_vfprintf
+#undef  vprintf
+#define vprintf                     libsupp_vprintf
+#undef  vsnprintf
+#define vsnprintf                   libsupp_vsnprintf
+#undef  vsprintf
+#define vsprintf                    libsupp_vsprintf
+
+#undef  fseeko
+#define fseeko                      libsupp_fseeko
+#undef  ftello
+#define ftello                      libsupp_ftello
+
+#undef  __signbitd
+#define __signbitd                  libsupp___signbitd
+#undef  __signbitf
+#define __signbitf                  libsupp___signbitf
+#undef  __signbitld
+#define __signbitld                 libsupp___signbitld
+
+#ifndef signbit
+#define signbit(x)   (__extension__ ({__typeof__(x) __x = (x); \
+                                      (sizeof(__x) == sizeof(float)) ? __signbitf(__x) :  \
+                                      (sizeof(__x) == sizeof(double)) ? __signbitd(__x) : \
+                                      __signbitld(__x); \
+                                     }))
+#endif /* !signbit */
+
+#undef  strtod
+#define strtod                      libsupp_strtod
+#undef  strtof
+#define strtof                      libsupp_strtof
+#undef  strtold
+#define strtold                     libsupp_strtold
+#undef  _strtold
+#define _strtold                    libsupp_strtold
+
+#undef  argz_add
+#define argz_add                    libsupp_argz_add
+#undef  argz_add_sep
+#define argz_add_sep                libsupp_argz_add_sep
+#undef  argz_append
+#define argz_append                 libsupp_argz_append
+#undef  argz_count
+#define argz_count                  libsupp_argz_count
+#undef  argz_create
+#define argz_create                 libsupp_argz_create
+#undef  argz_create_sep
+#define argz_create_sep             libsupp_argz_create_sep
+#undef  argz_delete
+#define argz_delete                 libsupp_argz_delete
+#undef  argz_extract
+#define argz_extract                libsupp_argz_extract
+#undef  argz_insert
+#define argz_insert                 libsupp_argz_insert
+#undef  argz_next
+#define argz_next                   libsupp_argz_next
+#undef  argz_replace
+#define argz_replace                libsupp_argz_replace
+#undef  argz_stringify
+#define argz_stringify              libsupp_argz_stringify
+
+#undef  strndup
+#define strndup                     libsupp_strndup
+#undef  strnlen
+#define strnlen                     libsupp_strnlen
+
+#if __DJGPP_MINOR__ < 4
+# undef  opendir
+# define opendir                    libsupp_opendir_2_03
+# undef  readdir
+# define readdir                    libsupp_readdir_2_03
+# undef  open
+# define open                       libsupp_open_2_03
+# undef  close
+# define close                      libsupp_close_2_03
+# undef  fchdir
+# define fchdir                     libsupp_fchdir_2_03
+#else
+# undef  opendir
+# define opendir                    libsupp_opendir
+# undef  readdir
+# define readdir                    libsupp_readdir
+# undef  close
+# define close                      libsupp_close
+#endif
+#undef  rewinddir
+#define rewinddir                   libsupp_rewinddir
+
+#undef  closedir
+#define closedir                    libsupp_closedir
+
+#if __DJGPP_MINOR__ < 4
+# undef  access
+# define access                     libsupp_access_2_03
+# undef  chdir
+# define chdir                      libsupp___chdir_2_03
+# undef  __chdir
+# define __chdir                    libsupp___chdir_2_03
+# undef  _fixpath
+# define _fixpath                   libsupp__fixpath_2_03
+# undef  stat
+# define stat(file, statbuf)        libsupp_stat_2_03((file), (statbuf))  /*  Replace the function name and not the struct name.  */
+# undef  symlink
+# define symlink                    libsupp_symlink_2_03
+# undef  access
+# define access                     libsupp_access_2_03
+#else
+# undef  access
+# define access                     libsupp_access
+# undef  chdir
+# define chdir                      libsupp___chdir
+# undef  __chdir
+# define __chdir                    libsupp___chdir
+# undef  _fixpath
+# define _fixpath                   libsupp__fixpath
+# undef  __canonicalize_path
+# define __canonicalize_path        libsupp___canonicalize_path
+# undef  lstat
+# define lstat                      libsupp_lstat
+# undef  realpath
+# define realpath                   libsupp_realpath
+#endif
+
+#ifndef USE_DJGPP_STRLCPY
+# undef  strlcpy
+# define strlcpy                    libsupp_strlcpy
+# undef  strlcat
+# define strlcat                    libsupp_strlcat
+#endif
+#undef  memmem
+#define memmem                      libsupp_memmem
+#undef  strftime
+#define strftime                    libsupp_strftime
+#undef  towlower
+#define towlower                    libsupp_towlower
+
+#ifndef USE_DJGPP_MBTOWC_FCTNS
+# undef  mblen
+# define mblen                      libsupp_mblen
+# undef  mbrtowc
+# define mbrtowc                    libsupp_mbrtowc
+# undef  mbtowc
+# define mbtowc                     libsupp_mbtowc
+# undef  mbsinit
+# define mbsinit                    libsupp_mbsinit
+#endif
+
+#undef  _doscan
+#define _doscan                     libsupp__doscan
+#undef  fscanf
+#define fscanf                      libsupp_fscanf
+#undef  scanf
+#define scanf                       libsupp_scanf
+#undef  sscanf
+#define sscanf                      libsupp_sscanf
+#undef  vfscanf
+#define vfscanf                     libsupp_vfscanf
+#undef  vscanf
+#define vscanf                      libsupp_vscanf
+#undef  vsscanf
+#define vsscanf                     libsupp_vsscanf
+#undef  atof
+#define atof                        libsupp_atof
+#undef  _atold
+#define _atold                      libsupp__atold
+#undef  strnicmp
+#define strnicmp                    libsupp_strnicmp
+
+#if __DJGPP_MINOR__ < 4
+# undef  fclose
+# define fclose                     libsupp_fclose_2_03
+# undef  fflush
+# define fflush                     libsupp_fflush_2_03
+# undef  _flsbuf
+# define _flsbuf                    libsupp__flsbuf_2_03
+# undef  fopen
+# define fopen                      libsupp_fopen_2_03
+# undef  freopen
+# define freopen                    libsupp_freopen_2_03
+# undef  rewind
+# define rewind                     libsupp_rewind_2_03
+# undef  ftell
+# define ftell                      libsupp_ftell_2_03
+# undef  select
+# define select                     libsupp_select_2_03
+# undef  fsync
+# define fsync                      libsupp_fsync_2_03
+# undef  ftruncate
+# define ftruncate                  libsupp_ftruncate_2_03
+# undef  _close
+# define _close                     libsupp__close_2_03
+# undef  _write
+# define _write                     libsupp__write_2_03
+# undef  fcntl
+# define fcntl                      libsupp_fcntl_2_03
+# undef  fdopen
+# define fdopen                     libsupp_fdopen_2_03
+# undef  dup2
+# define dup2                       libsupp_dup2_2_03
+# undef  dup
+# define dup                        libsupp_dup_2_03
+# undef  lseek
+# define lseek                      libsupp_lseek_2_03
+# undef  read
+# define read                       libsupp_read_2_03
+# undef  write
+# define write                      libsupp_write_2_03
+# undef  fstat
+# define fstat                      libsupp_fstat_2_03
+#else
+# undef  fclose
+# define fclose                     libsupp_fclose
+# undef  fflush
+# define fflush                     libsupp_fflush
+# undef  _flsbuf
+# define _flsbuf                    libsupp__flsbuf
+# undef  fopen
+# define fopen                      libsupp_fopen
+# undef  freopen
+# define freopen                    libsupp_freopen
+# undef  fseek
+# define fseek                      libsupp_fseek
+# undef  ftell
+# define ftell                      libsupp_ftell
+# undef  rewind
+# define rewind                     libsupp_rewind
+# undef  select
+# define select                     libsupp_select
+# undef  fsync
+# define fsync                      libsupp_fsync
+# undef  ftruncate
+# define ftruncate                  libsupp_ftruncate
+# undef  llseek
+# define llseek                     libsupp_llseek
+# undef  _close
+# define _close                     libsupp__close
+# undef  _write
+# define _write                     libsupp__write
+# undef  _write_fill_seek_gap
+# define _write_fill_seek_gap       libsupp__write_fill_seek_gap
+# undef  _write_int
+# define _write_int                 libsupp__write_int
+# undef  fcntl
+# define fcntl                      libsupp_fcntl
+# undef  open
+# define open                       libsupp_open
+# undef  fdopen
+# define fdopen                     libsupp_fdopen
+# undef  fchmod
+# define fchmod                     libsupp_fchmod
+# undef  fstat
+# define fstat                      libsupp_fstat
+# undef  stat
+# define stat(path, statbuf)        libsupp_stat((path), (statbuf))  /*  Replace the function name and not the struct name.  */
+# undef  fstatvfs
+# define fstatvfs                   libsupp_fstatvfs
+# undef  close
+# define close                      libsupp_close
+# undef  dup2
+# define dup2                       libsupp_dup2
+# undef  dup
+# define dup                        libsupp_dup
+# undef  lseek
+# define lseek                      libsupp_lseek
+# undef  pipe
+# define pipe                       libsupp_pipe
+# undef  read
+# define read                       libsupp_read
+# undef  write
+# define write                      libsupp_write
+# undef  lfilelength
+# define lfilelength                libsupp_lfilelength
+#endif
+
+#undef  towupper
+#define towupper                    libsupp_towupper
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__libsupp_h_ */
diff -aprNU5 libsupp-6.2.orig/mklib.sh libsupp-6.2/mklib.sh
--- libsupp-6.2.orig/mklib.sh	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/mklib.sh	2009-11-22 04:01:02 +0000
@@ -0,0 +1,117 @@
+#! /bin/sh
+
+echo "Output is in log.txt..."
+
+{
+#
+#  Build library.
+#
+
+echo "Making the library..."
+cd src
+start_dir=$PWD
+rm -f ./libsupp.a
+
+cat > gcc.opt << _EOF
+-MD
+-O2
+-mtune=i586
+-march=i386
+-Werror
+-Wall
+-Wbad-function-cast
+-Wcast-qual
+-Wmissing-declarations
+-Wmissing-prototypes
+-Wpointer-arith
+-Wshadow
+-Wstrict-prototypes
+-Wwrite-strings
+-Wundef
+-Wcast-align
+-Wsign-compare
+-nostdinc
+-iquote .
+-iquote ../../include
+-iquote ../../../include
+-iquote ../../../../include
+-isystem /dev/env/DJDIR/include
+_EOF
+
+gcc_opt="$start_dir/gcc.opt"
+src_dirs=
+for src_dir in $(find . -maxdepth 1 -mindepth 1 -type d -and -not -name 'include'); do
+  cd $src_dir
+  for src_dir in $(find . -type d); do
+    if [ -n "$(find $src_dir -maxdepth 1 -mindepth 1 -type f -and -name '*.c')" ]; then
+      src_dirs="$src_dirs $PWD${src_dir/.\///}"
+    fi
+  done
+  cd ..
+done
+for src_dir in $src_dirs; do
+  cd $src_dir
+  c_files=$(echo ./*.c)
+  for file in $c_files; do
+    echo "compiling $file..."
+    gcc @$gcc_opt -c $file || exit 1
+  done
+done
+cd $start_dir
+echo
+obj_files=$(find . -type f -and -name '*.o')
+ar vsq ./libsupp.a $obj_files || exit 1
+rm -f $(find . -type f -and -name '*.d') $obj_files ./gcc.opt
+cd ..
+
+
+#
+#  Build info docs.
+#
+
+echo
+echo
+echo "Making the info docs..."
+cd doc
+rm -f ./libsupp.info
+makeinfo --no-split ./libsupp.txi
+cd ..
+
+
+#
+#  Run the testsuite.
+#
+
+echo
+echo
+echo "Running the test..."
+cd tests
+gcc -Wall -g -O0 test.c -o test.exe ./../src/libsupp.a
+
+if [ -f ./test.exe ] && [ -x ./test.exe ]; then
+  ./test.exe
+else
+  echo "Test failed..."
+  exit 1;
+fi
+cd ..
+
+
+#
+#  Install library, header and info docs.
+#
+echo
+echo
+if [ $# -gt 0 ]; then
+  prefix=$(echo "${start_dir}" | sed "s|srcs/contrib/libsupp-[0-9.]*/src|libs|")
+else
+  prefix="./_build_"
+fi
+echo "Installing the products in" $prefix
+mkdir -p ${prefix}/info
+mv -f ./doc/libsupp.info ${prefix}/info/libsupp.info
+mkdir -p ${prefix}/include
+cp -f ./include/libsupp.h ${prefix}/include/libsupp.h
+mkdir -p ${prefix}/lib
+mv -f ./src/libsupp.a ${prefix}/lib/libsupp.a
+} &> log.txt
diff -aprNU5 libsupp-6.2.orig/src/ansi/locale/libsupp_mblen.c libsupp-6.2/src/ansi/locale/libsupp_mblen.c
--- libsupp-6.2.orig/src/ansi/locale/libsupp_mblen.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/locale/libsupp_mblen.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include "libsupp.h"
+
+int
+libsupp_mblen(const char *s, size_t n)
+{
+  return (s == NULL || *s == '\0') ? 0 : (n < 1) ? -1 : 1;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/locale/libsupp_mbrtowc.c libsupp-6.2/src/ansi/locale/libsupp_mbrtowc.c
--- libsupp-6.2.orig/src/ansi/locale/libsupp_mbrtowc.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/locale/libsupp_mbrtowc.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,18 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include "libsupp.h"
+
+size_t
+libsupp_mbrtowc(wchar_t *pwc, const char *s, size_t n, libsupp_mbstate_t *ps)
+{
+  int ret_val = (s == NULL) ? libsupp_mbtowc(NULL, "", 1) : libsupp_mbtowc(pwc, s, n);
+
+
+  if (ret_val == -1)
+  {
+    ps->__count = 0;
+    return (size_t)(-1);
+  }
+  else
+    return (size_t)ret_val;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/locale/libsupp_mbsinit.c libsupp-6.2/src/ansi/locale/libsupp_mbsinit.c
--- libsupp-6.2.orig/src/ansi/locale/libsupp_mbsinit.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/locale/libsupp_mbsinit.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include "libsupp.h"
+
+int
+libsupp_mbsinit(const libsupp_mbstate_t *ps)
+{
+  return (ps == NULL || ps->__count == 0) ? 1 : 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/locale/libsupp_mbtowc.c libsupp-6.2/src/ansi/locale/libsupp_mbtowc.c
--- libsupp-6.2.orig/src/ansi/locale/libsupp_mbtowc.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/locale/libsupp_mbtowc.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include "libsupp.h"
+
+int
+libsupp_mbtowc(wchar_t *pwc, const char *s, size_t n)
+{
+  return (s == NULL) ? 0 : (n < 1) ? -1 : (pwc) ? (*pwc = (wchar_t)*s), (*s != '\0') : 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/doprnt.c libsupp-6.2/src/ansi/stdio/doprnt.c
--- libsupp-6.2.orig/src/ansi/stdio/doprnt.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/doprnt.c	2009-11-22 04:01:02 +0000
@@ -15,14 +15,17 @@
 #include <locale.h>
 #include <stddef.h>
 #include <string.h>
 #include <math.h>
 #include <limits.h>
-#include <stdbool.h>
-#include <libc/file.h>
 #include <libc/local.h>
-#include <libc/ieee.h>
+
+#include "../include/stdbool.h"
+#include "../include/libc/file.h"
+#include "../include/libc/ieee.h"
+#include "libsupp.h"
+
 
 static char decimal_point;
 static char thousands_sep;
 static char *grouping;
 
@@ -106,11 +109,11 @@ static char NULL_REP[] = "(null)";
 static const char LOWER_DIGITS[] = "0123456789abcdef";
 static const char UPPER_DIGITS[] = "0123456789ABCDEF";
 
 
 int
-_doprnt(const char *fmt0, va_list argp, FILE *fp)
+libsupp__doprnt(const char *fmt0, va_list argp, FILE *fp)
 {
   const char *fmt;		/* format string */
   int ch;			/* character from fmt */
   int cnt;			/* return value accumulator */
   int n;			/* random handy integer */
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/doscan.c libsupp-6.2/src/ansi/stdio/doscan.c
--- libsupp-6.2.orig/src/ansi/stdio/doscan.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/doscan.c	2009-11-22 04:01:02 +0000
@@ -8,13 +8,16 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <locale.h>
-#include <libc/file.h>
 #include <libc/local.h>
 
+#include "../include/libc/file.h"
+#include "libsupp.h"
+
+
 #define	SPC	01
 #define	STP	02
 
 #define CHAR	0
 #define	SHORT	1
@@ -45,22 +48,22 @@ static char _sctab[256] = {
 };
 
 static int nchars = 0;
 static char decimal_point = '.';
 
-int _doscan_low(FILE *_iop, int (*_scan_getc)(FILE *), int (*_scan_ungetc)(int, FILE *), const char *_fmt, va_list _argp);
+int libsupp__doscan_low(FILE *_iop, int (*_scan_getc)(FILE *), int (*_scan_ungetc)(int, FILE *), const char *_fmt, va_list _argp);
 
 
 int 
-_doscan(FILE *iop, const char *fmt, va_list argp)
+libsupp__doscan(FILE *iop, const char *fmt, va_list argp)
 {
-  return(_doscan_low(iop, fgetc, ungetc, fmt, argp));
+  return(libsupp__doscan_low(iop, fgetc, ungetc, fmt, argp));
 }
 
 int
-_doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
-            const char *fmt, va_list argp)
+libsupp__doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
+                    const char *fmt, va_list argp)
 {
   register int ch;
   int nmatch, len, ch1;
   int *ptr, fileended, size;
   int suppressed;
@@ -319,19 +322,19 @@ _innum(int *ptr, int type, int len, int 
   *np++ = 0;
   switch((scale<<4) | size) {
 
   case (FLOAT<<4) | SHORT:
   case (FLOAT<<4) | REGULAR:
-    *(float *)ptr = atof(numbuf);
+    *(float *)ptr = libsupp_atof(numbuf);
     break;
 
   case (FLOAT<<4) | LONG:
-    *(double *)ptr = atof(numbuf);
+    *(double *)ptr = libsupp_atof(numbuf);
     break;
 
   case (FLOAT<<4) | LONGDOUBLE:
-    *(long double *)ptr = _atold(numbuf);
+    *(long double *)ptr = libsupp__atold(numbuf);
     break;
 
   case (INT<<4) | CHAR:
     *(char *)ptr = (char)lcval;
     break;
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fclose-2.03.c libsupp-6.2/src/ansi/stdio/fclose-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/fclose-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fclose-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,52 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_fclose_2_03(FILE *_f);
+int libsupp_fflush_2_03(FILE *_f);
+int libsupp_close_2_03(int _handle);
+
+
+int
+libsupp_fclose_2_03(FILE *f)
+{
+  const int fd = fileno(f);
+  int r = EOF;
+
+  if (!f)
+    return r;
+
+  /* A FILE for a directory won't have any of the read or write flags
+   * set. But we still want to tidy it up. */
+  if (   (f->_flag & (_IOREAD|_IOWRT|_IORW) && !(f->_flag&_IOSTRG))
+      || (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY))
+  {
+    r = libsupp_fflush_2_03(f);
+    if (libsupp_close_2_03(fileno(f)) < 0)
+      r = EOF;
+    if (f->_flag&_IOMYBUF)
+      free(f->_base);
+  }
+  if (f->_flag & _IORMONCL && f->_name_to_remove)
+  {
+    remove(f->_name_to_remove);
+    free(f->_name_to_remove);
+    f->_name_to_remove = 0;
+  }
+  f->_cnt = 0;
+  f->_base = 0;
+  f->_ptr = 0;
+  f->_bufsiz = 0;
+  f->_flag = 0;
+  f->_file = -1;
+  return r;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fclose.c libsupp-6.2/src/ansi/stdio/fclose.c
--- libsupp-6.2.orig/src/ansi/stdio/fclose.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fclose.c	2009-11-22 04:01:02 +0000
@@ -1,32 +1,36 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <libc/file.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-fclose(FILE *f)
+libsupp_fclose(FILE *f)
 {
   const int fd = fileno(f);
   int r = EOF;
 
   if (!f)
     return r;
 
   /* A FILE for a directory won't have any of the read or write flags
    * set. But we still want to tidy it up. */
   if (   (f->_flag & (_IOREAD|_IOWRT|_IORW) && !(f->_flag&_IOSTRG))
-      || (__get_fd_flags(fd) & FILE_DESC_DIRECTORY))
+      || (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY))
   {
-    r = fflush(f);
-    if (close(fd) < 0)
+    r = libsupp_fflush(f);
+    if (libsupp_close(fd) < 0)
       r = EOF;
     if (f->_flag&_IOMYBUF)
       free(f->_base);
   }
 
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fflush-2.03.c libsupp-6.2/src/ansi/stdio/fflush-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/fflush-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fflush-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,86 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <io.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int   libsupp_fflush_2_03(FILE *_f);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+int   libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+
+
+int
+libsupp_fflush_2_03(FILE *f)
+{
+  char *base;
+  int rn;
+  ssize_t n;
+
+  if (f == NULL)
+  {
+    int e = errno;
+
+    errno = 0;
+    _fwalk((void (*)(FILE *))fflush);
+    if (errno)
+      return EOF;
+    errno = e;
+    return 0;
+  }
+
+  if (libsupp___get_fd_flags(fileno(f)) & FILE_DESC_APPEND)
+  {
+    int save_errno = errno; /* We don't want llseek()'s setting 
+			       errno to remain. */
+    if (libsupp_lseek_2_03(fileno(f), 0L, SEEK_END) == -1)
+    {
+      errno = save_errno;
+      return -1;
+    }
+  }
+
+  f->_flag &= ~_IOUNGETC;
+  if ((f->_flag&(_IONBF|_IOWRT))==_IOWRT
+      && (base = f->_base) != NULL
+      && (rn = n = f->_ptr - base) > 0)
+  {
+    f->_ptr = base;
+    f->_cnt = (f->_flag&(_IOLBF|_IONBF)) ? 0 : f->_bufsiz;
+    do {
+      /* If termios hooked this handle, call the termios hook.
+	 We only do this with handles marked by putc and fwrite,
+	 to prevent double conversion of NL to CR-LF and avoid
+	 messing up the special termios conversions the user
+	 might have requested for CR and NL.  */
+      if ((f->_flag & _IOTERM) == 0
+	  || __libc_write_termios_hook == NULL
+	  || __libc_write_termios_hook(fileno(f), base, rn, &n) == 0)
+	n = libsupp__write_2_03(fileno(f), base, rn);
+      if (n <= 0) {
+	f->_flag |= _IOERR;
+	return EOF;
+      }
+      rn -= n;
+      base += n;
+    } while (rn > 0);
+  }
+  if (f->_flag & _IORW)
+  {
+    f->_cnt = 0;
+    f->_flag &= ~(_IOWRT|_IOREAD);
+    f->_ptr = f->_base;
+  }
+  return 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fflush.c libsupp-6.2/src/ansi/stdio/fflush.c
--- libsupp-6.2.orig/src/ansi/stdio/fflush.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fflush.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -9,16 +10,19 @@
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <io.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-fflush(FILE *f)
+libsupp_fflush(FILE *f)
 {
   char *base;
   ssize_t n;
   size_t rn;
 
@@ -32,15 +36,15 @@ fflush(FILE *f)
       return EOF;
     errno = e;
     return 0;
   }
 
-  if (__get_fd_flags(fileno(f)) & FILE_DESC_APPEND)
+  if (libsupp___get_fd_flags(fileno(f)) & FILE_DESC_APPEND)
   {
     int save_errno = errno; /* We don't want llseek()'s setting 
 			       errno to remain. */
-    if( llseek(fileno(f), 0LL, SEEK_END) == -1 )
+    if (libsupp_llseek(fileno(f), 0LL, SEEK_END) == -1)
     {
       errno = save_errno;
       return -1;
     }
   }
@@ -60,11 +64,11 @@ fflush(FILE *f)
 	 messing up the special termios conversions the user
 	 might have requested for CR and NL.  */
       if ((f->_flag & _IOTERM) == 0
 	  || __libc_write_termios_hook == NULL
 	  || __libc_write_termios_hook(fileno(f), base, rn, &n) == 0)
-	n = _write(fileno(f), base, rn);
+	n = libsupp__write(fileno(f), base, rn);
       if (n <= 0) {
 	f->_flag |= _IOERR;
 	return EOF;
       }
       rn -= n;
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/flsbuf-2.03.c libsupp-6.2/src/ansi/stdio/flsbuf-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/flsbuf-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/flsbuf-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,131 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <go32.h>
+#include <io.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int   libsupp__flsbuf_2_03(int _c, FILE *_f);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+int   libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+
+
+int
+libsupp__flsbuf_2_03(int c, FILE *f)
+{
+  char *base;
+  size_t rn;
+  ssize_t n;
+  char c1;
+  int size;
+
+  if (f->_flag & _IORW)
+  {
+    f->_flag |= _IOWRT;
+    f->_flag &= ~(_IOEOF|_IOREAD);
+  }
+
+  if ((f->_flag&_IOWRT)==0)
+    return EOF;
+
+  /* if the buffer is not yet allocated, allocate it */
+  if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0)
+  {
+    size = _go32_info_block.size_of_transfer_buffer;
+    if ((f->_base = base = malloc (size)) == NULL)
+    {
+      f->_flag |= _IONBF;
+      f->_flag &= ~(_IOFBF|_IOLBF);
+    }
+    else
+    {
+      f->_flag |= _IOMYBUF;
+      f->_cnt = f->_bufsiz = size;
+      f->_ptr = base;
+      rn = 0;
+      if (f == stdout && isatty (fileno (stdout)))
+	f->_flag |= _IOLBF;
+    }
+  }
+
+  if (f->_flag & _IOLBF)
+  {
+    /* in line-buffering mode we get here on each character */
+    *f->_ptr++ = c;
+    rn = f->_ptr - base;
+    if (c == '\n' || rn >= f->_bufsiz)
+    {
+      /* time for real flush */
+      f->_ptr = base;
+      f->_cnt = 0;
+    }
+    else
+    {
+      /* we got here because _cnt is wrong, so fix it */
+      /* Negative _cnt causes all output functions
+	to call _flsbuf for each character, thus realizing line-buffering */
+      f->_cnt = -rn;
+      return c;
+    }
+  }
+  else if (f->_flag & _IONBF)
+  {                   
+    c1 = c;           
+    rn = 1;           
+    base = &c1;       
+    f->_cnt = 0;      
+  }                   
+  else /* _IOFBF */
+  {
+    rn = f->_ptr - base;
+    f->_ptr = base;
+    f->_cnt = f->_bufsiz;
+  }
+  while (rn > 0)
+  {
+    /* If termios hooked this handle, call the termios hook.
+       We only do this with handles marked by putc and fwrite,
+       to prevent double conversion of NL to CR-LF and avoid
+       messing up the special termios conversions the user
+       might have requested for CR and NL.  */
+    if ((f->_flag & _IOTERM) == 0
+	|| __libc_write_termios_hook == NULL
+	|| __libc_write_termios_hook(fileno(f), base, rn, &n) == 0)
+    {
+      int fd = fileno(f);
+      if (libsupp___get_fd_flags(fd) & FILE_DESC_APPEND)
+      {
+	int save_errno = errno; /* We don't want llseek()'s setting 
+				   errno to remain. */
+	if (libsupp_lseek_2_03(fd, 0L, SEEK_END) == -1)
+	{
+	  errno = save_errno;
+	  return EOF;
+	}
+      }
+      n = libsupp__write_2_03(fileno(f), base, rn);
+    }
+    if (n <= 0)
+    {
+      f->_flag |= _IOERR;
+      return EOF;
+    }
+    rn -= n;
+    base += n;
+  }
+  if ((f->_flag&(_IOLBF|_IONBF)) == 0)
+  {
+    f->_cnt--;
+    *f->_ptr++ = c;
+  }
+  return c;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/flsbuf.c libsupp-6.2/src/ansi/stdio/flsbuf.c
--- libsupp-6.2.orig/src/ansi/stdio/flsbuf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/flsbuf.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -8,16 +9,19 @@
 #include <sys/types.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <go32.h>
-#include <libc/file.h>
 #include <io.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-_flsbuf(int c, FILE *f)
+libsupp__flsbuf(int c, FILE *f)
 {
   char *base;
   ssize_t n;
   size_t rn;
   char c1;
@@ -99,21 +103,21 @@ _flsbuf(int c, FILE *f)
     if ((f->_flag & _IOTERM) == 0
 	|| __libc_write_termios_hook == NULL
 	|| __libc_write_termios_hook(fileno(f), base, rn, &n) == 0)
     {
       int fd = fileno(f);
-      if (__get_fd_flags(fd) & FILE_DESC_APPEND)
+      if (libsupp___get_fd_flags(fd) & FILE_DESC_APPEND)
       {
 	int save_errno = errno; /* We don't want llseek()'s setting 
 				   errno to remain. */
-	if( llseek(fd, 0, SEEK_END) == -1 )
+	if (libsupp_llseek(fd, 0, SEEK_END) == -1)
 	{
 	  errno = save_errno;
 	  return EOF;
 	}
       }
-      n = _write(fd, base, rn);
+      n = libsupp__write(fd, base, rn);
     }
     if (n <= 0)
     {
       f->_flag |= _IOERR;
       return EOF;
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fopen-2.03.c libsupp-6.2/src/ansi/stdio/fopen-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/fopen-2.03.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fopen-2.03.c	2009-11-22 04:01:02 +0000
@@ -1,20 +1,28 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <libc/local.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+
+FILE *libsupp_fopen_2_03(const char *_file, const char *_mode);
+int libsupp_open_2_03(const char* _filename, int _oflag, ...);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
 
 FILE *
-fopen(const char *file, const char *mode)
+libsupp_fopen_2_03(const char *file, const char *mode)
 {
   FILE *f;
   int fd, rw, oflags = 0;
   char tbchar;
 
@@ -52,11 +60,11 @@ fopen(const char *file, const char *mode
   else if (tbchar == 'b')
     oflags |= O_BINARY;
   else
     oflags |= (_fmode & (O_TEXT|O_BINARY));
 
-  fd = open(file, oflags, 0666);
+  fd = libsupp_open_2_03(file, oflags, 0666);
   if (fd < 0)
     return NULL;
 
   f->_cnt = 0;
   f->_file = fd;
@@ -68,11 +76,11 @@ fopen(const char *file, const char *mode
   else
     f->_flag = _IOWRT;
 
   if (*mode == 'a')
   {
-    llseek(fd, 0LL, SEEK_END);
+    libsupp_lseek_2_03(fd, 0L, SEEK_END);
   }
 
   f->_base = f->_ptr = NULL;
 
   /* If this is a FILE for a directory, we need to make sure certain
@@ -82,11 +90,11 @@ fopen(const char *file, const char *mode
    * - The write flag should be clear, since writes aren't allowed.
    * - The read-write flag should be clear, because of the above.
    * - The EOF flag should be set, so that certain functions
    *   fail reads and writes. (Easier than modifying the functions).
    */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
   {
     f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
     f->_flag |= _IOEOF;
   }
 
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fopen.c libsupp-6.2/src/ansi/stdio/fopen.c
--- libsupp-6.2.orig/src/ansi/stdio/fopen.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fopen.c	2009-11-22 04:01:02 +0000
@@ -1,20 +1,24 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <libc/local.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 FILE *
-fopen(const char *file, const char *mode)
+libsupp_fopen(const char *file, const char *mode)
 {
   FILE *f;
   int fd, rw, oflags = 0;
   char tbchar;
 
@@ -52,11 +56,11 @@ fopen(const char *file, const char *mode
   else if (tbchar == 'b')
     oflags |= O_BINARY;
   else
     oflags |= (_fmode & (O_TEXT|O_BINARY));
 
-  fd = open(file, oflags, 0666);
+  fd = libsupp_open(file, oflags, 0666);
   if (fd < 0)
     return NULL;
 
   f->_cnt = 0;
   f->_file = fd;
@@ -68,11 +72,11 @@ fopen(const char *file, const char *mode
   else
     f->_flag = _IOWRT;
 
   if (*mode == 'a')
   {
-    llseek(fd, 0LL, SEEK_END);
+    libsupp_llseek(fd, 0LL, SEEK_END);
   }
 
   f->_base = f->_ptr = NULL;
 
   /* If this is a FILE for a directory, we need to make sure certain
@@ -82,11 +86,11 @@ fopen(const char *file, const char *mode
    * - The write flag should be clear, since writes aren't allowed.
    * - The read-write flag should be clear, because of the above.
    * - The EOF flag should be set, so that certain functions
    *   fail reads and writes. (Easier than modifying the functions).
    */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
   {
     f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
     f->_flag |= _IOEOF;
   }
 
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fprintf.c libsupp-6.2/src/ansi/stdio/fprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/fprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fprintf.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-fprintf(register FILE *iop, const char *fmt, ...)
+libsupp_fprintf(register FILE *iop, const char *fmt, ...)
 {
   va_list args;
   int len;
   char localbuf[BUFSIZ];
 
@@ -16,19 +17,19 @@ fprintf(register FILE *iop, const char *
   if (iop->_flag & _IONBF)
   {
     iop->_flag &= ~_IONBF;
     iop->_ptr = iop->_base = localbuf;
     iop->_bufsiz = BUFSIZ;
-    len = _doprnt(fmt, args, iop);
+    len = libsupp__doprnt(fmt, args, iop);
     fflush(iop);
     iop->_flag |= _IONBF;
     iop->_base = NULL;
     iop->_bufsiz = 0;
     iop->_cnt = 0;
   }
   else
-    len = _doprnt(fmt, args, iop);
+    len = libsupp__doprnt(fmt, args, iop);
 
   va_end(args);
 
   return ferror(iop) ? EOF : len;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/freopen-2.03.c libsupp-6.2/src/ansi/stdio/freopen-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/freopen-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/freopen-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,103 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libc/dosio.h>
+#include <io.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+FILE *libsupp_freopen_2_03(const char *_file, const char *_mode, FILE *_f);
+int   libsupp_fclose_2_03(FILE *_f);
+int   libsupp__close_2_03(int _handle);
+int   libsupp_dup2_2_03(int _fd, int _newfd);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+int   libsupp_open_2_03(const char* _filename, int _oflag, ...);
+
+FILE *
+libsupp_freopen_2_03(const char *file, const char *mode, FILE *f)
+{
+  int fd, fdo, rw, oflags=0;
+  char tbchar;
+
+  if (file == 0 || mode == 0 || f == 0)
+    return 0;
+
+  rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
+
+  fdo = fileno(f);
+  libsupp_fclose_2_03(f);
+
+  switch (*mode) {
+  case 'a':
+    oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
+    break;
+  case 'r':
+    oflags = rw ? O_RDWR : O_RDONLY;
+    break;
+  case 'w':
+    oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
+    break;
+  default:
+    return NULL;
+  }
+  if (mode[1] == '+')
+    tbchar = mode[2];
+  else
+    tbchar = mode[1];
+  if (tbchar == 't')
+    oflags |= O_TEXT;
+  else if (tbchar == 'b')
+    oflags |= O_BINARY;
+  else
+    oflags |= (_fmode & (O_TEXT|O_BINARY));
+
+  fd = libsupp_open_2_03(file, oflags, 0666);
+  if (fd < 0)
+    return NULL;
+
+  if(fd != fdo) {			/* This should rarely happen, but if it does for */
+    libsupp_dup2_2_03(fd, fdo);		/* stdin/stdout/stderr handles, we must fix it or */
+    libsupp__close_2_03(fd);		/* child processes won't popen properly. */
+    fd = fdo;
+  }
+
+  if (*mode == 'a')
+    libsupp_lseek_2_03(fd, 0L, SEEK_END);
+
+  f->_cnt = 0;
+  f->_file = fd;
+  f->_bufsiz = 0;
+  if (rw)
+    f->_flag = _IORW;
+  else if (*mode == 'r')
+    f->_flag = _IOREAD;
+  else
+    f->_flag = _IOWRT;
+
+  f->_base = f->_ptr = NULL;
+
+  /* If this is a FILE for a directory, we need to make sure certain
+   * flags are clear and certain flags are set. Namely:
+   *
+   * - The read flag should be clear, since reads aren't allowed.
+   * - The write flag should be clear, since writes aren't allowed.
+   * - The read-write flag should be clear, because of the above.
+   * - The EOF flag should be set, so that certain functions
+   *   fail reads and writes. (Easier than modifying the functions).
+   */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  {
+    f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
+    f->_flag |= _IOEOF;
+  }
+
+  return f;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/freopen.c libsupp-6.2/src/ansi/stdio/freopen.c
--- libsupp-6.2.orig/src/ansi/stdio/freopen.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/freopen.c	2009-11-22 04:01:02 +0000
@@ -1,33 +1,37 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <libc/dosio.h>
 #include <io.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 FILE *
-freopen(const char *file, const char *mode, FILE *f)
+libsupp_freopen(const char *file, const char *mode, FILE *f)
 {
   int fd, fdo, rw, oflags=0;
   char tbchar;
 
   if (file == 0 || mode == 0 || f == 0)
     return 0;
 
   rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
 
   fdo = fileno(f);
-  fclose(f);
+  libsupp_fclose(f);
 
   switch (*mode) {
   case 'a':
     oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY) | O_APPEND;
     break;
@@ -49,17 +53,17 @@ freopen(const char *file, const char *mo
   else if (tbchar == 'b')
     oflags |= O_BINARY;
   else
     oflags |= (_fmode & (O_TEXT|O_BINARY));
 
-  fd = open(file, oflags, 0666);
+  fd = libsupp_open(file, oflags, 0666);
   if (fd < 0)
     return NULL;
 
   if(fd != fdo && fdo >= 0) {   /* Might rarely happen, but if it does for */
-    dup2(fd, fdo);	/* stdin/stdout/stderr handles, we must fix it or */
-    _close(fd);		/* child processes won't popen properly. */
+    libsupp_dup2(fd, fdo);	/* stdin/stdout/stderr handles, we must fix it or */
+    libsupp__close(fd);		/* child processes won't popen properly. */
     fd = fdo;
   }
 
   f->_cnt = 0;
   f->_file = fd;
@@ -71,11 +75,11 @@ freopen(const char *file, const char *mo
   else
     f->_flag = _IOWRT;
 
   if (*mode == 'a')
   {
-    llseek(fd, 0LL, SEEK_END);
+    libsupp_llseek(fd, 0LL, SEEK_END);
   }
 
   f->_base = f->_ptr = NULL;
 
   /* If this is a FILE for a directory, we need to make sure certain
@@ -85,11 +89,11 @@ freopen(const char *file, const char *mo
    * - The write flag should be clear, since writes aren't allowed.
    * - The read-write flag should be clear, because of the above.
    * - The EOF flag should be set, so that certain functions
    *   fail reads and writes. (Easier than modifying the functions).
    */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
   {
     f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
     f->_flag |= _IOEOF;
   }
 
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fscanf.c libsupp-6.2/src/ansi/stdio/fscanf.c
--- libsupp-6.2.orig/src/ansi/stdio/fscanf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fscanf.c	2009-11-22 04:01:02 +0000
@@ -1,12 +1,13 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-fscanf(FILE *f, const char *fmt, ...)
+libsupp_fscanf(FILE *f, const char *fmt, ...)
 {
   int r;
   va_list a=0;
   va_start(a, fmt);
   r = _doscan(f, fmt, a);
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fseek-2.03.c libsupp-6.2/src/ansi/stdio/fseek-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/fseek-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fseek-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,73 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int   libsupp_fseek_2_03(FILE *_f, long _offset, int _ptrname);
+int   libsupp_fflush_2_03(FILE *_f);
+long  libsupp_ftell_2_03(FILE *_f);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
+int
+libsupp_fseek_2_03(FILE *f, long offset, int ptrname)
+{
+  const int fd = fileno(f);
+  long p = -1;			/* can't happen? */
+
+  /* If this is a FILE for a directory, we have no concept of position.
+   * The stream I/O functions cannot be used to read/write a FILE
+   * for directories. So, just return position 0. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+    return 0;
+
+  /* See comment in filbuf.c */
+  f->_fillsize = 512;
+
+  f->_flag &= ~_IOEOF;
+  if (f->_flag & _IOREAD)
+  {
+    if (f->_base && !(f->_flag & _IONBF))
+    {
+      p = libsupp_ftell_2_03(f);
+      if (ptrname == SEEK_CUR)
+      {
+	offset += p;
+	ptrname = SEEK_SET;
+      }
+      /* check if the target position is in the buffer and
+        optimize seek by moving inside the buffer */
+      if (ptrname == SEEK_SET && (f->_flag & (_IOUNGETC|_IORW)) == 0
+      && p-offset <= f->_ptr-f->_base && offset-p <= f->_cnt)
+      {
+        f->_ptr+=offset-p;
+        f->_cnt+=p-offset;
+        return 0;
+      }
+    }
+
+    if (f->_flag & _IORW)
+      f->_flag &= ~_IOREAD;
+
+    p = libsupp_lseek_2_03(fileno(f), offset, ptrname);
+    f->_cnt = 0;
+    f->_ptr = f->_base;
+    f->_flag &= ~_IOUNGETC;
+  }
+  else if (f->_flag & (_IOWRT|_IORW))
+  {
+    p = libsupp_fflush_2_03(f);
+    return libsupp_lseek_2_03(fileno(f), offset, ptrname) == -1 || p == EOF ?
+      -1 : 0;
+  }
+  return p==-1 ? -1 : 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/fseek.c libsupp-6.2/src/ansi/stdio/fseek.c
--- libsupp-6.2.orig/src/ansi/stdio/fseek.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/fseek.c	2009-11-22 04:01:02 +0000
@@ -1,38 +1,42 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <fcntl.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-fseek(FILE *f, long offset, int ptrname)
+libsupp_fseek(FILE *f, long offset, int ptrname)
 {
   const int fd = fileno(f);
   long p = -1;			/* can't happen? */
 
   /* If this is a FILE for a directory, we have no concept of position.
    * The stream I/O functions cannot be used to read/write a FILE
    * for directories. So, just return position 0. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
     return 0;
 
   /* See comment in filbuf.c */
   f->_fillsize = 512;
 
   f->_flag &= ~_IOEOF;
   if (f->_flag & _IOREAD)
   {
     if (f->_base && !(f->_flag & _IONBF))
     {
-      p = ftell(f);
+      p = libsupp_ftell(f);
       if (ptrname == SEEK_CUR)
       {
 	offset += p;
 	ptrname = SEEK_SET;
       }
@@ -48,18 +52,18 @@ fseek(FILE *f, long offset, int ptrname)
     }
 
     if (f->_flag & _IORW)
       f->_flag &= ~_IOREAD;
 
-    p = lseek(fd, offset, ptrname);
+    p = libsupp_lseek(fd, offset, ptrname);
     f->_cnt = 0;
     f->_ptr = f->_base;
     f->_flag &= ~_IOUNGETC;
   }
   else if (f->_flag & (_IOWRT|_IORW))
   {
-    p = fflush(f);
-    return lseek(fd, offset, ptrname) == -1 || p == EOF ?
+    p = libsupp_fflush(f);
+    return libsupp_lseek(fd, offset, ptrname) == -1 || p == EOF ?
       -1 : 0;
   }
   return p==-1 ? -1 : 0;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/ftell-2.03.c libsupp-6.2/src/ansi/stdio/ftell-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/ftell-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/ftell-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,49 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+long  libsupp_ftell_2_03(FILE *_f);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
+long
+libsupp_ftell_2_03(FILE *f)
+{
+  const int fd = fileno(f);
+  long tres;
+  int adjust=0;
+
+  /* If this is a FILE for a directory, we have no concept of position.
+   * The stream I/O functions cannot be used to read/write a FILE
+   * for directories. So, just return position 0. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+    return 0;
+
+  if (f->_cnt < 0)
+    f->_cnt = 0;
+  if (f->_flag&_IOREAD)
+  {
+    adjust = - f->_cnt;
+  }
+  else if (f->_flag&(_IOWRT|_IORW))
+  {
+    if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
+      adjust = f->_ptr - f->_base;
+  }
+  else
+    return -1;
+  tres = libsupp_lseek_2_03(fileno(f), 0L, 1);
+  if (tres<0)
+    return tres;
+  tres += adjust;
+  return tres;
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/ftell.c libsupp-6.2/src/ansi/stdio/ftell.c
--- libsupp-6.2.orig/src/ansi/stdio/ftell.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/ftell.c	2009-11-22 04:01:02 +0000
@@ -1,27 +1,31 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <libc/file.h>
 #include <fcntl.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 long
-ftell(FILE *f)
+libsupp_ftell(FILE *f)
 {
   const int fd = fileno(f);
   long tres;
   int adjust = 0;
 
   /* If this is a FILE for a directory, we have no concept of position.
    * The stream I/O functions cannot be used to read/write a FILE
    * for directories. So, just return position 0. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
     return 0;
 
   if (f->_cnt < 0)
     f->_cnt = 0;
   if (f->_flag&_IOREAD)
@@ -33,11 +37,11 @@ ftell(FILE *f)
     if (f->_flag&_IOWRT && f->_base && (f->_flag&_IONBF)==0)
       adjust = f->_ptr - f->_base;
   }
   else
     return -1;
-  tres = lseek(fd, 0L, 1);
+  tres = libsupp_lseek(fd, 0L, 1);
   if (tres<0)
     return tres;
   tres += adjust;
   return tres;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/printf.c libsupp-6.2/src/ansi/stdio/printf.c
--- libsupp-6.2.orig/src/ansi/stdio/printf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/printf.c	2009-11-22 04:01:02 +0000
@@ -1,20 +1,21 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-printf(const char *fmt, ...)
+libsupp_printf(const char *fmt, ...)
 {
   va_list args;
   int len;
 
   va_start(args, fmt);
-  len = _doprnt(fmt, args, stdout);
+  len = libsupp__doprnt(fmt, args, stdout);
   va_end(args);
 
   /* People were confused when printf() didn't flush stdout,
      so we'll do it to reduce confusion */
   if (stdout->_flag & _IOLBF)
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/rewind-2.03.c libsupp-6.2/src/ansi/stdio/rewind-2.03.c
--- libsupp-6.2.orig/src/ansi/stdio/rewind-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/ansi/stdio/rewind-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,34 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+void  libsupp_rewind_2_03(FILE *_f);
+int   libsupp_fflush_2_03(FILE *_f);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
+void libsupp_rewind_2_03(FILE *f)
+{
+  const int fd = fileno(f);
+
+  /* If this is a FILE for a directory, we must maintain its EOF flag.
+   * Just return. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+    return;
+
+  libsupp_fflush_2_03(f);
+  libsupp_lseek_2_03(fileno(f), 0L, SEEK_SET);
+  f->_fillsize = 512;	/* See comment in filbuf.c */
+  f->_cnt = 0;
+  f->_ptr = f->_base;
+  f->_flag &= ~(_IOERR|_IOEOF);
+  if (f->_flag & _IORW)
+    f->_flag &= ~(_IOREAD|_IOWRT);
+}
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/rewind.c libsupp-6.2/src/ansi/stdio/rewind.c
--- libsupp-6.2.orig/src/ansi/stdio/rewind.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/rewind.c	2009-11-22 04:01:02 +0000
@@ -1,25 +1,29 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <libc/file.h>
-#include <libc/fd_props.h>
 
-void rewind(FILE *f)
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+
+void libsupp_rewind(FILE *f)
 {
   const int fd = fileno(f);
 
   /* If this is a FILE for a directory, we must maintain its EOF flag.
    * Just return. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
     return;
 
-  fflush(f);
-  lseek(fd, 0L, SEEK_SET);
+  libsupp_fflush(f);
+  libsupp_lseek(fd, 0L, SEEK_SET);
   f->_fillsize = 512;	/* See comment in filbuf.c */
   f->_cnt = 0;
   f->_ptr = f->_base;
   f->_flag &= ~(_IOERR|_IOEOF);
   if (f->_flag & _IORW)
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/scanf.c libsupp-6.2/src/ansi/stdio/scanf.c
--- libsupp-6.2.orig/src/ansi/stdio/scanf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/scanf.c	2009-11-22 04:01:02 +0000
@@ -1,15 +1,16 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-scanf(const char *fmt, ...)
+libsupp_scanf(const char *fmt, ...)
 {
   int r;
   va_list a=0;
   va_start(a, fmt);
-  r = _doscan(stdin, fmt, a);
+  r = libsupp__doscan(stdin, fmt, a);
   va_end(a);
   return r;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/snprintf.c libsupp-6.2/src/ansi/stdio/snprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/snprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/snprintf.c	2009-11-22 04:01:02 +0000
@@ -1,16 +1,16 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
+#include "libsupp.h"
 
 int
-snprintf(char *str, size_t n, const char *fmt, ...)
+libsupp_snprintf(char *str, size_t n, const char *fmt, ...)
 {
   va_list ap;
   int len;
 
   va_start(ap, fmt);
-  len = vsnprintf(str, n, fmt, ap);
+  len = libsupp_vsnprintf(str, n, fmt, ap);
   va_end(ap);
 
   return len;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/sprintf.c libsupp-6.2/src/ansi/stdio/sprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/sprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/sprintf.c	2009-11-22 04:01:02 +0000
@@ -1,22 +1,24 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
 #include <limits.h>
-#include <libc/file.h>
+
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-sprintf(char *str, const char *fmt, ...)
+libsupp_sprintf(char *str, const char *fmt, ...)
 {
   va_list args;
   FILE _strbuf;
   int len;
 
   __stropenw(&_strbuf, str, INT_MAX);
   va_start(args, fmt);
-  len = _doprnt(fmt, args, &_strbuf);
+  len = libsupp__doprnt(fmt, args, &_strbuf);
   va_end(args);
   __strclosew(&_strbuf);
   return len;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/sscanf.c libsupp-6.2/src/ansi/stdio/sscanf.c
--- libsupp-6.2.orig/src/ansi/stdio/sscanf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/sscanf.c	2009-11-22 04:01:02 +0000
@@ -1,19 +1,20 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-sscanf(const char *str, const char *fmt, ...)
+libsupp_sscanf(const char *str, const char *fmt, ...)
 {
   int r;
   va_list a=0;
   FILE _strbuf;
 
   va_start(a, fmt);
   __stropenr(&_strbuf, str);
-  r = _doscan(&_strbuf, fmt, a);
+  r = libsupp__doscan(&_strbuf, fmt, a);
   va_end(a);
   return r;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/vfprintf.c libsupp-6.2/src/ansi/stdio/vfprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/vfprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/vfprintf.c	2009-11-22 04:01:02 +0000
@@ -1,27 +1,28 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vfprintf(FILE *f, const char *fmt, va_list ap)
+libsupp_vfprintf(FILE *f, const char *fmt, va_list ap)
 {
   int len;
   char localbuf[BUFSIZ];
 
   if (f->_flag & _IONBF)
   {
     f->_flag &= ~_IONBF;
     f->_ptr = f->_base = localbuf;
     f->_bufsiz = BUFSIZ;
-    len = _doprnt(fmt, ap, f);
+    len = libsupp__doprnt(fmt, ap, f);
     (void)fflush(f);
     f->_flag |= _IONBF;
     f->_base = NULL;
     f->_bufsiz = 0;
     f->_cnt = 0;
   }
   else
-    len = _doprnt(fmt, ap, f);
+    len = libsupp__doprnt(fmt, ap, f);
   return (ferror(f) ? EOF : len);
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/vprintf.c libsupp-6.2/src/ansi/stdio/vprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/vprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/vprintf.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vprintf(const char *fmt, va_list ap)
+libsupp_vprintf(const char *fmt, va_list ap)
 {
   int len;
 
-  len = _doprnt(fmt, ap, stdout);
+  len = libsupp__doprnt(fmt, ap, stdout);
   return (ferror(stdout) ? EOF : len);
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/vsnprntf.c libsupp-6.2/src/ansi/stdio/vsnprntf.c
--- libsupp-6.2.orig/src/ansi/stdio/vsnprntf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/vsnprntf.c	2009-11-22 04:01:02 +0000
@@ -1,15 +1,17 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
 #include <string.h>
-#include <stdarg.h>
 #include <limits.h>
 #include <errno.h>
-#include <libc/file.h>
+
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
+libsupp_vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
 {
   FILE _strbuf;
   int len;
 
   /* _cnt is an int in the FILE structure. To prevent wrap-around, we limit
@@ -26,11 +28,11 @@ vsnprintf(char *str, size_t n, const cha
   if (n > 0)
     __stropenw(&_strbuf, str, n - 1);
   else
     __stropenw(&_strbuf, NULL, 0);
 
-  len = _doprnt(fmt, ap, &_strbuf);
+  len = libsupp__doprnt(fmt, ap, &_strbuf);
 
   /* Ensure nul termination */
   if (n > 0)
     __strclosew(&_strbuf);
 
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdio/vsprintf.c libsupp-6.2/src/ansi/stdio/vsprintf.c
--- libsupp-6.2.orig/src/ansi/stdio/vsprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdio/vsprintf.c	2009-11-22 04:01:02 +0000
@@ -1,18 +1,20 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
 #include <limits.h>
-#include <libc/file.h>
+
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vsprintf(char *str, const char *fmt, va_list ap)
+libsupp_vsprintf(char *str, const char *fmt, va_list ap)
 {
   FILE f;
   int len;
 
   __stropenw(&f, str, INT_MAX);
-  len = _doprnt(fmt, ap, &f);
+  len = libsupp__doprnt(fmt, ap, &f);
   __strclosew(&f);
   return len;
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdlib/atof.c libsupp-6.2/src/ansi/stdlib/atof.c
--- libsupp-6.2.orig/src/ansi/stdlib/atof.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdlib/atof.c	2009-11-22 04:01:02 +0000
@@ -1,8 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdlib.h>
+#include "libsupp.h"
 
 double
-atof(const char *ascii)
+libsupp_atof(const char *ascii)
 {
-  return strtod(ascii, 0);
+  return libsupp_strtod(ascii, 0);
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdlib/atold.c libsupp-6.2/src/ansi/stdlib/atold.c
--- libsupp-6.2.orig/src/ansi/stdlib/atold.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdlib/atold.c	2009-11-22 04:01:02 +0000
@@ -1,8 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <stdlib.h>
+#include "libsupp.h"
 
 long double
-_atold(const char *ascii)
+libsupp__atold(const char *ascii)
 {
-  return _strtold(ascii, 0);
+  return libsupp_strtold(ascii, 0);
 }
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdlib/strtod.c libsupp-6.2/src/ansi/stdlib/strtod.c
--- libsupp-6.2.orig/src/ansi/stdlib/strtod.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdlib/strtod.c	2009-11-22 04:01:02 +0000
@@ -10,12 +10,14 @@
 #include <stdlib.h>
 #include <float.h>
 #include <errno.h>
 #include <ctype.h>
 #include <string.h>
-#include <libc/unconst.h>
-#include <libc/ieee.h>
+
+#include "../include/libc/unconst.h"
+#include "../include/libc/ieee.h"
+#include "libsupp.h"
 
 #define HEX_DIGIT_SIZE    (4)
 #define DOUBLE_BIAS       (0x3FFU)
 #define MAX_BIN_EXPONENT  (1023)   /*  Max. and min. binary exponent (inclusive) as  */
 #define MIN_BIN_EXPONENT  (-1022)  /*  defined in Intel manual (253665.pdf, Table 4.2).  */
@@ -26,11 +28,11 @@
 #define IS_EXPONENT(x)    (((x[0]) == 'P' || (x[0]) == 'p') && \
                            (x[1] == '+' || x[1] == '-' || IS_DEC_DIGIT(x[1])))
 
 
 double
-strtod(const char *s, char **sret)
+libsupp_strtod(const char *s, char **sret)
 {
   long double r;		/* result */
   int e;			/* exponent */
   long double d;		/* scale */
   int sign;			/* +- 1.0 */
diff -aprNU5 libsupp-6.2.orig/src/ansi/stdlib/strtold.c libsupp-6.2/src/ansi/stdlib/strtold.c
--- libsupp-6.2.orig/src/ansi/stdlib/strtold.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/stdlib/strtold.c	2009-11-22 04:01:02 +0000
@@ -8,12 +8,14 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <errno.h>
 #include <math.h>
 #include <string.h>
-#include <libc/unconst.h>
-#include <libc/ieee.h>
+
+#include "../include/libc/unconst.h"
+#include "../include/libc/ieee.h"
+#include "libsupp.h"
 
 #define HEX_DIGIT_SIZE    (4)
 #define LONG_DOUBLE_BIAS  (0x3FFFU)
 #define MAX_BIN_EXPONENT  (16383)   /*  Max. and min. binary exponent (inclusive) as  */
 #define MIN_BIN_EXPONENT  (-16382)  /*  defined in Intel manual (253665.pdf, Table 4.2).  */
@@ -29,11 +31,11 @@ static long double powten[] =
   1e1L, 1e2L, 1e4L, 1e8L, 1e16L, 1e32L, 1e64L, 1e128L, 1e256L,
   1e512L, 1e1024L, 1e2048L, 1e4096L
 };
 
 long double
-strtold(const char *s, char **sret)
+libsupp_strtold(const char *s, char **sret)
 {
   long double r;		/* result */
   int e, ne;			/* exponent */
   int sign;			/* +- 1.0 */
   int esign;
diff -aprNU5 libsupp-6.2.orig/src/ansi/time/strftime.c libsupp-6.2/src/ansi/time/strftime.c
--- libsupp-6.2.orig/src/ansi/time/strftime.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/ansi/time/strftime.c	2009-11-22 04:01:02 +0000
@@ -5,11 +5,12 @@
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
 #include <string.h>
 #include <time.h>
 #include <ctype.h>
-#include <stdbool.h>
+#include "../include/stdbool.h"
+#include "libsupp.h"
 
 
 #define THURSDAY       4
 #define SATURDAY       6
 #define SUNDAY         7
@@ -409,11 +410,11 @@ _fmt(const char *format, const struct tm
   }
   return gsize;
 }
 
 size_t
-strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
+libsupp_strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
 {
   pt = s;
   if ((gsize = maxsize) < 1)
     return 0;
   if (_fmt(format, t, false))
diff -aprNU5 libsupp-6.2.orig/src/c99/ctype/towlower.c libsupp-6.2/src/c99/ctype/towlower.c
--- libsupp-6.2.orig/src/c99/ctype/towlower.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/c99/ctype/towlower.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,9 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#include "libsupp.h"
+
+wint_t
+libsupp_towlower(wint_t c)
+{
+  return (c < 0x00ff) ? (wint_t)tolower((int)c) : c;
+}
diff -aprNU5 libsupp-6.2.orig/src/c99/ctype/towupper.c libsupp-6.2/src/c99/ctype/towupper.c
--- libsupp-6.2.orig/src/c99/ctype/towupper.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/c99/ctype/towupper.c	2009-11-22 04:05:04 +0000
@@ -0,0 +1,9 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+#include <ctype.h>
+#include "libsupp.h"
+
+wint_t
+libsupp_towupper(wint_t c)
+{
+  return (c < 0x00ff) ? (wint_t)toupper((int)c) : c;
+}
diff -aprNU5 libsupp-6.2.orig/src/c99/math/hugevalf.c libsupp-6.2/src/c99/math/hugevalf.c
--- libsupp-6.2.orig/src/c99/math/hugevalf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/hugevalf.c	2009-11-22 04:01:02 +0000
@@ -1,4 +1,7 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
 
-float_t __dj_huge_valf = { 0x00000, 0xff, 0x0 };
+
+float_t libsupp___dj_huge_valf = { 0x00000, 0xff, 0x0 };
diff -aprNU5 libsupp-6.2.orig/src/c99/math/hugevall.c libsupp-6.2/src/c99/math/hugevall.c
--- libsupp-6.2.orig/src/c99/math/hugevall.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/hugevall.c	2009-11-22 04:01:02 +0000
@@ -1,4 +1,7 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
 
-long_double_t __dj_huge_vall = { 0x00000000, 0x80000000, 0x7fff, 0x0 };
+
+long_double_t libsupp___dj_huge_vall = { 0x00000000, 0x80000000, 0x7fff, 0x0 };
diff -aprNU5 libsupp-6.2.orig/src/c99/math/nan_def.c libsupp-6.2/src/c99/math/nan_def.c
--- libsupp-6.2.orig/src/c99/math/nan_def.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/nan_def.c	2009-11-22 04:01:02 +0000
@@ -1,4 +1,7 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
 
-float_t __dj_nan = { 0x7fffff, 0xff, 0x0 };
+
+float_t libsupp___dj_nan = { 0x7fffff, 0xff, 0x0 };
diff -aprNU5 libsupp-6.2.orig/src/c99/math/sgnbitd.c libsupp-6.2/src/c99/math/sgnbitd.c
--- libsupp-6.2.orig/src/c99/math/sgnbitd.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/sgnbitd.c	2009-11-22 04:01:02 +0000
@@ -1,11 +1,13 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <math.h>
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
+
 
 int
-__signbitd(double x)
+libsupp___signbitd(double x)
 {
   _double_union_t fp_value;
 
   fp_value.d = x;
   return (int)fp_value.dt.sign;
diff -aprNU5 libsupp-6.2.orig/src/c99/math/sgnbitf.c libsupp-6.2/src/c99/math/sgnbitf.c
--- libsupp-6.2.orig/src/c99/math/sgnbitf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/sgnbitf.c	2009-11-22 04:01:02 +0000
@@ -1,11 +1,13 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <math.h>
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
+
 
 int
-__signbitf(float x)
+libsupp___signbitf(float x)
 {
   _float_union_t fp_value;
 
   fp_value.f = x;
   return (int)fp_value.ft.sign;
diff -aprNU5 libsupp-6.2.orig/src/c99/math/sgnbitld.c libsupp-6.2/src/c99/math/sgnbitld.c
--- libsupp-6.2.orig/src/c99/math/sgnbitld.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/math/sgnbitld.c	2009-11-22 04:01:02 +0000
@@ -1,11 +1,13 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <math.h>
-#include <libc/ieee.h>
+#include "libsupp.h"
+#include "../include/libc/ieee.h"
+
 
 int
-__signbitld(long double x)
+libsupp___signbitld(long double x)
 {
   _longdouble_union_t fp_value;
 
   fp_value.ld = x;
   return (int)fp_value.ldt.sign;
diff -aprNU5 libsupp-6.2.orig/src/c99/stdlib/strtof.c libsupp-6.2/src/c99/stdlib/strtof.c
--- libsupp-6.2.orig/src/c99/stdlib/strtof.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/c99/stdlib/strtof.c	2009-11-22 04:01:02 +0000
@@ -12,12 +12,14 @@
 #include <stdlib.h>
 #include <float.h>
 #include <errno.h>
 #include <ctype.h>
 #include <string.h>
-#include <libc/unconst.h>
-#include <libc/ieee.h>
+
+#include "../include/libc/unconst.h"
+#include "../include/libc/ieee.h"
+#include "libsupp.h"
 
 #define HEX_DIGIT_SIZE    (4)
 #define FLOAT_BIAS        (0x7FU)
 #define MAX_BIN_EXPONENT  (127)   /*  Max. and min. binary exponent (inclusive) as  */
 #define MIN_BIN_EXPONENT  (-126)  /*  defined in Intel manual (253665.pdf, Table 4.2).  */
@@ -28,11 +30,11 @@
 #define IS_EXPONENT(x)    (((x[0]) == 'P' || (x[0]) == 'p') && \
                            (x[1] == '+' || x[1] == '-' || IS_DEC_DIGIT(x[1])))
 
 
 float
-strtof(const char *s, char **sret)
+libsupp_strtof(const char *s, char **sret)
 {
   long double r;		/* result */
   int e;			/* exponent */
   long double d;		/* scale */
   int sign;			/* +- 1.0 */
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/add.c libsupp-6.2/src/compat/argz/add.c
--- libsupp-6.2.orig/src/compat/argz/add.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/add.c	2009-11-22 04:01:02 +0000
@@ -1,16 +1,17 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_add(char **argz, size_t *argz_len, const char *str)
+libsupp_argz_add(char **argz, size_t *argz_len, const char *str)
 {
   /*
    *  Add STR to the end of the argz vector in ARGZ of length ARGZ_LEN.
    *  If a memory allocation error occurs, ENOMEM is returned,
    *  otherwise 0.
    */
 
-  return argz_append(argz, argz_len, str, strlen(str) + 1);
+  return libsupp_argz_append(argz, argz_len, str, strlen(str) + 1);
 }
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/add_sep.c libsupp-6.2/src/compat/argz/add_sep.c
--- libsupp-6.2.orig/src/compat/argz/add_sep.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/add_sep.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_add_sep(char **argz, size_t *argz_len, const char *str, int sep)
+libsupp_argz_add_sep(char **argz, size_t *argz_len, const char *str, int sep)
 {
   /*
    *  Add SEP separated list in STR to the end of the argz vector
    *  in ARGZ with length ARGZ_LEN adjusted accordingly.
    *  If a memory allocation error occurs, ENOMEM is returned,
@@ -16,11 +17,11 @@ argz_add_sep(char **argz, size_t *argz_l
 
   char *str_argz = NULL;
   size_t str_argz_len = 0;
 
 
-  argz_create_sep(str, sep, &str_argz, &str_argz_len);
+  libsupp_argz_create_sep(str, sep, &str_argz, &str_argz_len);
 
   if (str_argz_len)
   {
     size_t new_argz_len = *argz_len + str_argz_len;
 
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/append.c libsupp-6.2/src/compat/argz/append.c
--- libsupp-6.2.orig/src/compat/argz/append.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/append.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_append(char **argz, size_t *argz_len, const char *buf, size_t buf_len)
+libsupp_argz_append(char **argz, size_t *argz_len, const char *buf, size_t buf_len)
 {
   /*
    *  Append BUF, of length BUF_LEN to the argz vector in ARGZ
    *  of length ARGZ_LEN.
    *  If a memory allocation error occurs, ENOMEM is returned,
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/count.c libsupp-6.2/src/compat/argz/count.c
--- libsupp-6.2.orig/src/compat/argz/count.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/count.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,13 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
+#include "libsupp.h"
 
 #define EOS  '\0'
 
 
 size_t
-argz_count(const char *argz, size_t argz_len)
+libsupp_argz_count(const char *argz, size_t argz_len)
 {
   /*
    *  Return the number of strings in ARGZ.
    */
 
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/create.c libsupp-6.2/src/compat/argz/create.c
--- libsupp-6.2.orig/src/compat/argz/create.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/create.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_create(char *const argv[], char **argz, size_t *argz_len)
+libsupp_argz_create(char *const argv[], char **argz, size_t *argz_len)
 {
   /*
    *  Make a '\0' separated argz vector from a ARGV vector,
    *  returning it via ARGZ, and the total length in ARGZ_LEN.
    *  If a memory allocation error occurs, ENOMEM is returned,
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/creatsep.c libsupp-6.2/src/compat/argz/creatsep.c
--- libsupp-6.2.orig/src/compat/argz/creatsep.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/creatsep.c	2009-11-22 04:01:02 +0000
@@ -1,15 +1,16 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 #define EOS '\0'
 
 
 error_t
-argz_create_sep(const char *str, int sep, char **argz, size_t *argz_len)
+libsupp_argz_create_sep(const char *str, int sep, char **argz, size_t *argz_len)
 {
   /*
    *  Make a '\0' separated argz vector from a SEP separated list in
    *  STR, returning it via ARGZ, and the total length in ARGZ_LEN.
    *  If a memory allocation error occurs, ENOMEM is returned,
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/delete.c libsupp-6.2/src/compat/argz/delete.c
--- libsupp-6.2.orig/src/compat/argz/delete.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/delete.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libsupp.h"
+
 
 void
-argz_delete(char **argz, size_t *argz_len, char *entry)
+libsupp_argz_delete(char **argz, size_t *argz_len, char *entry)
 {
   /*
    *  Delete ENTRY from the argz vector in ARGZ
    *  adjusting its length ARGZ_LEN accordingly.
    */
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/extract.c libsupp-6.2/src/compat/argz/extract.c
--- libsupp-6.2.orig/src/compat/argz/extract.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/extract.c	2009-11-22 04:01:02 +0000
@@ -1,22 +1,23 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
-#include <libc/unconst.h>
+
+#include "../include/libc/unconst.h"
+#include "libsupp.h"
 
 #define EOS  '\0'
 
 
 void
-argz_extract(const char *argz, size_t argz_len, char **argv)
+libsupp_argz_extract(const char *argz, size_t argz_len, char **argv)
 {
   /*
    *  Store pointers to each string in ARGZ, plus a terminating 0 element,
    *  into the argv array ARGV, which must be large enough to hold them all.
    */
 
-  const size_t counts = argz_count(argz, argz_len);
+  const size_t counts = libsupp_argz_count(argz, argz_len);
   size_t i;
 
 
 
   if (counts == argz_len)
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/insert.c libsupp-6.2/src/compat/argz/insert.c
--- libsupp-6.2.orig/src/compat/argz/insert.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/insert.c	2009-11-22 04:01:02 +0000
@@ -1,14 +1,15 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stddef.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_insert(char **argz, size_t *argz_len, char *before, const char *entry)
+libsupp_argz_insert(char **argz, size_t *argz_len, char *before, const char *entry)
 {
   /*
    *  Insert ENTRY into ARGZ of length ARGZ_LEN before BEFORE, which should be an
    *  existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
    *  Since ARGZ's first entry is the same as ARGZ, argz_insert(ARGZ, ARGZ_LEN,
@@ -20,11 +21,11 @@ argz_insert(char **argz, size_t *argz_le
   ptrdiff_t first_part_len;
   size_t entry_len;
 
 
   if (before == NULL)
-    return argz_add(argz, argz_len, entry);
+    return libsupp_argz_add(argz, argz_len, entry);
 
   if (before < *argz || before >= *argz + *argz_len)
     return EINVAL;
 
   for (; before != *argz && before[-1]; before--)
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/next.c libsupp-6.2/src/compat/argz/next.c
--- libsupp-6.2.orig/src/compat/argz/next.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/next.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <string.h>
-#include <libc/unconst.h>
+
+#include "../include/libc/unconst.h"
+#include "libsupp.h"
 
 
 char *
-argz_next(const char *argz, size_t argz_len, const char *entry)
+libsupp_argz_next(const char *argz, size_t argz_len, const char *entry)
 {
   /*
    *  Return the next entry in ARGZ of length ARGZ_LEN after ENTRY,
    *  or NULL if there are no more.  If entry is NULL, then the first
    *  entry is returned.
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/replace.c libsupp-6.2/src/compat/argz/replace.c
--- libsupp-6.2.orig/src/compat/argz/replace.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/replace.c	2009-11-22 04:01:02 +0000
@@ -1,14 +1,15 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stddef.h>
 
+#include "libsupp.h"
+
 
 error_t
-argz_replace(char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count)
+libsupp_argz_replace(char **argz, size_t *argz_len, const char *str, const char *with, unsigned *replace_count)
 {
   /*
    *  Replace any occurrences of the string STR in the argz vector ARGZ with string WITH,
    *  reallocating ARGZ as necessary.  If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be
    *  incremented by number of replacements performed.
@@ -30,11 +31,11 @@ argz_replace(char **argz, size_t *argz_l
     dst_len = 0;
     src = *argz;
     src_len = *argz_len;
     str_len = strlen(str);
     with_len = strlen(with);
-    while (!error && (entry = argz_next(src, src_len, entry)))
+    while (!error && (entry = libsupp_argz_next(src, src_len, entry)))
       if (strstr(entry, str))
       {
         dst_len = src_len + with_len - str_len;
         dst =  malloc(dst_len);
         if (dst == NULL)
diff -aprNU5 libsupp-6.2.orig/src/compat/argz/strngify.c libsupp-6.2/src/compat/argz/strngify.c
--- libsupp-6.2.orig/src/compat/argz/strngify.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/argz/strngify.c	2009-11-22 04:01:02 +0000
@@ -1,13 +1,13 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <argz.h>
+#include "libsupp.h"
 
 #define EOS  '\0'
 
 
 void
-argz_stringify(char *argz, size_t argz_len, int sep)
+libsupp_argz_stringify(char *argz, size_t argz_len, int sep)
 {
   /*
    *  Make '\0' separated argz vector ARGZ printable by converting
    *  all the '\0's except the last into the character SEP.
    */
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/asnprntf.c libsupp-6.2/src/compat/stdio/asnprntf.c
--- libsupp-6.2.orig/src/compat/stdio/asnprntf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/asnprntf.c	2009-11-22 04:01:02 +0000
@@ -1,11 +1,10 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
+#include "libsupp.h"
 
 int
-asnprintf(char **strp, size_t n, const char *fmt, ...)
+libsupp_asnprintf(char **strp, size_t n, const char *fmt, ...)
 {
   va_list args;
   int len;
 
   va_start(args, fmt);
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/asprintf.c libsupp-6.2/src/compat/stdio/asprintf.c
--- libsupp-6.2.orig/src/compat/stdio/asprintf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/asprintf.c	2009-11-22 04:01:02 +0000
@@ -1,16 +1,15 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <stdarg.h>
-#include <stdio.h>
+#include "libsupp.h"
 
 int
-asprintf(char **strp, const char *fmt, ...)
+libsupp_asprintf(char **strp, const char *fmt, ...)
 {
   va_list args;
   int len;
 
   va_start(args, fmt);
-  len = vasprintf(strp, fmt, args);
+  len = libsupp_vasprintf(strp, fmt, args);
   va_end(args);
 
   return len;
 }
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/cprintf.c libsupp-6.2/src/compat/stdio/cprintf.c
--- libsupp-6.2.orig/src/compat/stdio/cprintf.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/stdio/cprintf.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,25 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <stdlib.h>
+#include <conio.h>
+
+#include "libsupp.h"
+
+int
+libsupp_cprintf(const char *fmt, ...)
+{
+  int      cnt;
+  char    *buf;
+  va_list  ap;
+  
+  va_start(ap, fmt);
+  cnt = libsupp_vasprintf(&buf, fmt, ap);
+  va_end(ap);
+  
+  if (cnt != EOF)
+  {
+    cputs(buf);
+    free(buf);
+  }
+
+  return cnt;
+}
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/fseeko.c libsupp-6.2/src/compat/stdio/fseeko.c
--- libsupp-6.2.orig/src/compat/stdio/fseeko.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/stdio/fseeko.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,11 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2007 DJ Delorie, see COPYING.DJ for details */
+#include "libsupp.h"
+
+int
+libsupp_fseeko(FILE *f, off_t offset, int ptrname)
+{
+  /*  As long as off_t is equal long, a cast should be enough.  */
+
+  return libsupp_fseek(f, (long)offset, ptrname);
+}
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/ftello.c libsupp-6.2/src/compat/stdio/ftello.c
--- libsupp-6.2.orig/src/compat/stdio/ftello.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/stdio/ftello.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,11 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2007 DJ Delorie, see COPYING.DJ for details */
+#include "libsupp.h"
+
+off_t
+libsupp_ftello(FILE *f)
+{
+  /*  As long as off_t is equal long, a cast should be enough.  */
+
+  return (off_t)libsupp_ftell(f);
+}
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/vasnprtf.c libsupp-6.2/src/compat/stdio/vasnprtf.c
--- libsupp-6.2.orig/src/compat/stdio/vasnprtf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/vasnprtf.c	2009-11-22 04:01:02 +0000
@@ -1,16 +1,17 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdarg.h>
 #include <limits.h>
 #include <errno.h>
-#include <libc/file.h>
+
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vasnprintf(char **strp, size_t n, const char *fmt, va_list argsp)
+libsupp_vasnprintf(char **strp, size_t n, const char *fmt, va_list argsp)
 {
   FILE _strbuf;
   int len;
 
 
@@ -23,11 +24,11 @@ vasnprintf(char **strp, size_t n, const 
   }
 
   /*  Just query how much space is needed.  */
   memset(&_strbuf, 0, sizeof(_strbuf));
   __stropenw(&_strbuf, NULL, 0);
-  len = _doprnt(fmt, argsp, &_strbuf);
+  len = libsupp__doprnt(fmt, argsp, &_strbuf);
 
   *strp = NULL;
   if (n > 0)
   {
     if (len != EOF)
@@ -37,11 +38,11 @@ vasnprintf(char **strp, size_t n, const 
         len = n;
       *strp = malloc(len);
       if (*strp)
       {
         __stropenw(&_strbuf, *strp, len - 1);
-        len = _doprnt(fmt, argsp, &_strbuf);
+        len = libsupp__doprnt(fmt, argsp, &_strbuf);
         __strclosew(&_strbuf);
         if (len == EOF)
         {
           free(*strp);
           *strp = NULL;
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/vasprntf.c libsupp-6.2/src/compat/stdio/vasprntf.c
--- libsupp-6.2.orig/src/compat/stdio/vasprntf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/vasprntf.c	2009-11-22 04:01:02 +0000
@@ -1,31 +1,34 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <libc/file.h>
+
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vasprintf(char **strp, const char *fmt, va_list argsp)
+libsupp_vasprintf(char **strp, const char *fmt, va_list argsp)
 {
   FILE _strbuf;
   int len;
 
 
   /*  Just query how much space is needed.  */
   memset(&_strbuf, 0, sizeof(_strbuf));
   __stropenw(&_strbuf, NULL, 0);
-  len = _doprnt(fmt, argsp, &_strbuf);
+  len = libsupp__doprnt(fmt, argsp, &_strbuf);
 
   *strp = NULL;
   if (len != EOF)
   {
     *strp = malloc(len + 1);
     if (*strp)
     {
       __stropenw(&_strbuf, *strp, len);
-      len = _doprnt(fmt, argsp, &_strbuf);
+      len = libsupp__doprnt(fmt, argsp, &_strbuf);
       __strclosew(&_strbuf);
       if (len == EOF)
       {
         free(*strp);
         *strp = NULL;
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/vfscanf.S libsupp-6.2/src/compat/stdio/vfscanf.S
--- libsupp-6.2.orig/src/compat/stdio/vfscanf.S	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/vfscanf.S	2009-11-22 04:01:02 +0000
@@ -1,4 +1,5 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
-	.global _vfscanf
-_vfscanf:
-	jmp __doscan
+	.global _libsupp_vfscanf
+_libsupp_vfscanf:
+	jmp _libsupp__doscan
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/vscanf.c libsupp-6.2/src/compat/stdio/vscanf.c
--- libsupp-6.2.orig/src/compat/stdio/vscanf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/vscanf.c	2009-11-22 04:01:02 +0000
@@ -1,9 +1,11 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vscanf(const char *fmt, va_list ap)
+libsupp_vscanf(const char *fmt, va_list ap)
 {
-  return _doscan(stdin, fmt, ap);
+  return libsupp__doscan(stdin, fmt, ap);
 }
diff -aprNU5 libsupp-6.2.orig/src/compat/stdio/vsscanf.c libsupp-6.2/src/compat/stdio/vsscanf.c
--- libsupp-6.2.orig/src/compat/stdio/vsscanf.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/stdio/vsscanf.c	2009-11-22 04:01:02 +0000
@@ -1,14 +1,15 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
-#include <stdio.h>
-#include <stdarg.h>
-#include <libc/file.h>
+#include "libsupp.h"
+#include "../include/libc/file.h"
+
 
 int
-vsscanf(const char *str, const char *fmt, va_list ap)
+libsupp_vsscanf(const char *str, const char *fmt, va_list ap)
 {
   FILE _strbuf;
 
   __stropenr(&_strbuf, str);
-  return _doscan(&_strbuf, fmt, ap);
+  return libsupp__doscan(&_strbuf, fmt, ap);
 }
diff -aprNU5 libsupp-6.2.orig/src/compat/string/cbf_strlcpy.c libsupp-6.2/src/compat/string/cbf_strlcpy.c
--- libsupp-6.2.orig/src/compat/string/cbf_strlcpy.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/string/cbf_strlcpy.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,135 @@
+/* ------- file strlcpy.c ------- */
+/* Implementation of strlcpy and strlcat
+   See http://www.courtesan.com/todd/papers/strlcpy.html
+
+   These routines are explicitly designed to move no
+   data and simply return the projected size of the
+   final strings when called with sz == 0.
+
+   In addition they treat src == NULL as an empty string
+
+   strlcat expects that the sz parameter is greater than
+   the size of the dst string.  If not, the treatment is
+   exactly the same as if a sz value of 0 was used.
+*/
+
+#include "libsupp.h"
+
+/* NOTE: these routines are deliberately designed to
+   not require any assistance from the standard
+   libraries.  This makes them more useful in any
+   embedded systems that must minimize the load size.
+
+   Public domain, by C.B. Falconer
+   bug reports to mailto:cbfalconer@worldnet.att.net
+*/
+
+/* NOTE: Modified to fit libsupp requirements by Juan M. Guerrero,  2008-09-17.
+   <juan.guerrero@gmx.de>
+*/
+
+
+/* ---------------------- */
+
+size_t libsupp_strlcpy(char *dst, const char *src, size_t sz)
+{
+   const char *start = src;
+
+   if (src && sz--) {
+      while ((*dst++ = *src))
+         if (sz--) src++;
+         else {
+            *(--dst) = '\0';
+            break;
+         }
+   }
+   if (src) {
+      while (*src++) continue;
+      return src - start - 1;
+   }
+   else if (sz) *dst = '\0';
+   return 0;
+} /* strlcpy */
+
+/* ---------------------- */
+
+size_t libsupp_strlcat(char *dst, const char *src, size_t sz)
+{
+   char  *start = dst;
+
+   while (*dst++)    /* assumes sz >= strlen(dst) */
+      if (sz) sz--;    /* i.e. well formed string */
+   dst--;
+   return dst - start + libsupp_strlcpy(dst, src, sz);
+} /* strlcat */
+
+/* ---------------------- */
+
+#ifdef TESTING
+#include <stdio.h>
+
+typedef size_t (*op)(char *, const char *, size_t);
+#define FLD 16
+
+/* ---------------------- */
+
+static void putleftinfld(const char *str, int field, int quote)
+{
+   int                used;
+   static const char *nullstr = "(NULL)";
+
+   if (!str) str = nullstr;
+   if (quote) used = printf("\"%s\"", str);
+   else       used = printf("%s", str);
+   while (used++ < field) putchar(' ');
+} /* putleftinfld */
+
+/* ---------------------- */
+
+static void dotest(op fn, char *s1, char *s2, size_t sz)
+{
+   unsigned long lgh;
+
+   putleftinfld(s1, FLD, 1); putleftinfld(s2, FLD, 1);
+   if      (fn == libsupp_strlcat) printf(" cat ");
+   else if (fn == libsupp_strlcpy) printf(" cpy ");
+   else                        printf(" ??? ");
+   lgh = fn(s1, s2, sz);
+   printf("%3lu %3lu \"%s\"\n", (unsigned long)sz, lgh, s1);
+} /* dotest */
+
+/* ---------------------- */
+
+int main(void)
+{
+   char         *str1     = "string1";
+   char          str2[10] = "";
+   char          str3[5]  = "";
+   char          str4[]   = "";
+
+   puts("Testing lgh = stringop(dest, source, sz)\n");
+   putleftinfld(" dest", FLD, 0);
+   putleftinfld(" source", FLD, 0);
+   puts(" opn  sz lgh  result");
+   putleftinfld(" ====", FLD, 0);
+   putleftinfld(" ======", FLD, 0);
+   puts(" ===  == ===  ======");
+
+   dotest(libsupp_strlcpy, str2, str1, sizeof str2);
+   dotest(libsupp_strlcpy, str3, str1, sizeof str3);
+   dotest(libsupp_strlcpy, str4, str1, sizeof str4);
+   dotest(libsupp_strlcat, str2, str1, sizeof str2);
+   dotest(libsupp_strlcpy, str2, "x ", sizeof str2);
+   dotest(libsupp_strlcat, str2, str1, sizeof str2);
+   dotest(libsupp_strlcpy, str2, "x ", sizeof str2);
+   dotest(libsupp_strlcat, str2, str1, 0);
+   dotest(libsupp_strlcpy, str2, str1, 0);
+   dotest(libsupp_strlcat, str2, "longer string", 0);
+   dotest(libsupp_strlcpy, str2, NULL, sizeof str2);
+   dotest(libsupp_strlcpy, str2, "x ", sizeof str2);
+   dotest(libsupp_strlcat, str2, NULL, sizeof str2);
+
+   return 0;
+} /* main */
+#endif
+/* ------- End file cbf_strlcpy.c ------- */
diff -aprNU5 libsupp-6.2.orig/src/compat/string/memmem.c libsupp-6.2/src/compat/string/memmem.c
--- libsupp-6.2.orig/src/compat/string/memmem.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/string/memmem.c	2009-11-22 04:01:02 +0000
@@ -1,12 +1,14 @@
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 #include <string.h>
-#include <libc/unconst.h>
+
+#include "../include/libc/unconst.h"
+#include "libsupp.h"
 
 
 void *
-memmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
+libsupp_memmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len)
 {
   if (haystack == NULL || needle == NULL)
     return NULL;
   else if (needle_len == 0)
     /*  The first occurrence of the empty string is deemed to occur at the beginning of the string.  */
diff -aprNU5 libsupp-6.2.orig/src/compat/string/strndup.c libsupp-6.2/src/compat/string/strndup.c
--- libsupp-6.2.orig/src/compat/string/strndup.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/string/strndup.c	2009-11-22 04:01:02 +0000
@@ -1,11 +1,15 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 #include <string.h>
 #include <stdlib.h>
 
+#include "libsupp.h"
+
+
 char *
-strndup(const char *str, size_t n)
+libsupp_strndup(const char *str, size_t n)
 {
   char *copy;
   size_t str_len;
 
 
diff -aprNU5 libsupp-6.2.orig/src/compat/string/strnicmp.c libsupp-6.2/src/compat/string/strnicmp.c
--- libsupp-6.2.orig/src/compat/string/strnicmp.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/string/strnicmp.c	2009-11-22 04:01:02 +0000
@@ -1,14 +1,18 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <string.h>
 #include <ctype.h>
 
+#include "libsupp.h"
+
+
 int
-strnicmp(const char *s1, const char *s2, size_t n)
+libsupp_strnicmp(const char *s1, const char *s2, size_t n)
 {
 
   if (n == 0)
     return 0;
   do {
diff -aprNU5 libsupp-6.2.orig/src/compat/string/strnlen.c libsupp-6.2/src/compat/string/strnlen.c
--- libsupp-6.2.orig/src/compat/string/strnlen.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/string/strnlen.c	2009-11-22 04:01:02 +0000
@@ -1,10 +1,14 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 #include <string.h>
 
+#include "libsupp.h"
+
+
 size_t
-strnlen(const char *str, size_t n)
+libsupp_strnlen(const char *str, size_t n)
 {
   const char *start;
 
 
   for (start = str; n && *str; n--, str++)
diff -aprNU5 libsupp-6.2.orig/src/compat/time/select-2.03.c libsupp-6.2/src/compat/time/select-2.03.c
--- libsupp-6.2.orig/src/compat/time/select-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/time/select-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,336 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* An implementation of select()
+
+   Copyright 1995 by Morten Welinder
+   This file maybe freely distributed and modified as long as the
+   copyright notice remains.
+
+   Notes: In a single process system as Dos this really boils down to
+   something that can check whether a character from standard input
+   is ready.  However, the code is organised in a way to make it easy
+   to extend to multi process systems like WinNT and OS/2.  */
+
+#include <libc/stubs.h>
+#include <sys/types.h>
+#include <time.h>
+#include <dpmi.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <libc/file.h>
+#include <libc/local.h>
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+#include <sys/fsext.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_select_2_03(int _nfds, fd_set *_readfds, fd_set *_writefds, fd_set *_exceptfds, struct timeval *_timeout);
+
+
+inline static int
+fp_output_ready(FILE *fp)
+{
+  return !ferror(fp);
+}
+
+/* This is as close as we get, I think.  For a file connected to a printer
+   we could of course go ask the BIOS, but this should be enough.  */
+
+inline static int
+fp_except_ready(FILE *fp)
+{
+  return ferror (fp);
+}
+
+inline static int
+fp_input_ready (FILE *fp)
+{
+  /* I think if there is something in the buffer, we should return
+     ``ready'', even if some error was encountered.  Let him consume
+     the buffered characters, *then* return ``not ready''.  */
+  if (fp->_cnt)
+    return 1;
+
+  if (ferror (fp))
+    return 0;
+
+  /* There is nothing in the buffer (perhaps because we read unbuffered).
+     We don't know if we are ready.  Return ``ready'' anyway and let
+     read() or write() tell the truth.  */
+  return 1;
+}
+
+/* The Dos call 4407 always returns TRUE for disk files.  So the
+   following really is meaningful for character devices only...  */
+
+inline static int
+fd_output_ready(int fd)
+{
+
+  __dpmi_regs regs;
+
+  /* If it's a directory, always return 0. We can't write to directories. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+    return 0;
+
+  regs.x.ax = 0x4407;
+  regs.x.bx = fd;
+  __dpmi_int (0x21, &regs);
+  if (regs.x.flags & 1)
+  {
+    errno = __doserr_to_errno (regs.x.ax);
+    return -1;
+  }
+  else
+    return regs.h.al == 0xff;
+}
+
+inline static int
+fd_input_ready(int fd)
+{
+
+  __dpmi_regs regs;
+
+  /* If it's a directory, always return 1. That way the caller
+     will hit the EISDIR error as quickly as possible. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+    return 1;
+
+  /* If it's a disk file, always return 1, since DOS returns ``not ready''
+     for files at EOF, but we won't block in that case.  */
+  regs.x.ax = 0x4400;
+  regs.x.bx = fd;
+  __dpmi_int (0x21, &regs);
+  if (regs.x.flags & 1)
+  {
+    errno = __doserr_to_errno (regs.x.ax);
+    return -1;
+  }
+  if ((regs.x.dx & 0x80) == 0)	/* if not a character device */
+    return 1;
+  else if ((regs.x.dx & 1) == 1 /* if a STDIN device and termios buffers */
+	   && __libc_read_termios_hook && __libc_tty_p->t_count )
+    return 1;
+
+  regs.x.ax = 0x4406;
+  regs.x.bx = fd;
+  __dpmi_int (0x21, &regs);
+  if (regs.x.flags & 1)
+  {
+    errno = __doserr_to_errno (regs.x.ax);
+    return -1;
+  }
+  else
+    return regs.h.al == 0xff;
+}
+
+int
+libsupp_select_2_03(int nfds,
+	fd_set *readfds,
+	fd_set *writefds,
+	fd_set *exceptfds,
+	struct timeval *timeout)
+{
+  int ready;
+  fd_set oread, owrite, oexcept;
+  struct timeval now, then;
+
+  if (nfds > FD_SETSIZE)
+  {
+    errno = EINVAL;
+    return -1;
+  }
+
+  FD_ZERO (&oread);
+  FD_ZERO (&owrite);
+  FD_ZERO (&oexcept);
+  ready = 0;
+
+  then.tv_sec = 0;
+  then.tv_usec = 0;
+  if (timeout)
+  {
+    if (timeout->tv_usec < 0)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+    gettimeofday (&now, 0);
+    then.tv_usec = timeout->tv_usec + now.tv_usec;
+    then.tv_sec = timeout->tv_sec + now.tv_sec + then.tv_usec / 1000000;
+    then.tv_usec %= 1000000;
+  }
+
+  do {
+    int i;
+    int fd0 = 0;
+    __file_rec *fr = __file_rec_list;
+    FILE *fp;
+
+    /* First, check the file handles with low-level DOS calls.  */
+    for (i = 0; i < nfds; i++)
+    {
+      register int ioctl_result;
+      __FSEXT_Function *func = __FSEXT_get_function(i);
+      int fsext_ready = -1;
+
+      if (func)
+	__FSEXT_func_wrapper(func, __FSEXT_ready, &fsext_ready, i);
+
+      if (readfds && FD_ISSET (i, readfds))
+      {
+	if (fsext_ready != -1)
+	{
+	  if (fsext_ready & __FSEXT_ready_read)
+	    ready++, FD_SET(i, &oread);
+	}
+        else if ((ioctl_result = fd_input_ready (i)) == -1)
+          return -1;
+        else if (ioctl_result)
+          ready++, FD_SET (i, &oread);
+      }
+      if (writefds && FD_ISSET (i, writefds))
+      {
+        if (fsext_ready != -1)
+	{
+	  if (fsext_ready & __FSEXT_ready_write)
+	    ready++, FD_SET(i, &owrite);
+	}
+        else if ((ioctl_result = fd_output_ready (i)) == -1)
+          return -1;
+        else if (ioctl_result)
+          ready++, FD_SET (i, &owrite);
+      }
+      if (exceptfds && FD_ISSET (i, exceptfds))
+      {
+        if (fsext_ready != -1)
+	{
+	  if (fsext_ready & __FSEXT_ready_error)
+	    ready++, FD_SET(i, &oexcept);
+	}
+      }
+    }
+
+    /* Now look at the table of FILE ptrs and reset the bits for file
+       descriptors which we *thought* are ready, but for which the flags
+       say they're NOT ready.  */
+    for (i = 0; fr; i++)
+    {
+      if (i >= fd0 + fr->count) /* done with this subtable, go to next */
+      {
+	fd0 += fr->count;
+	fr = fr->next;
+      }
+      if (fr)
+      {
+        fp = fr->files[i - fd0];
+        if (fp->_flag)
+        {
+          int this_fd = fileno(fp);
+
+          if (this_fd < nfds)
+          {
+            if (readfds && FD_ISSET (this_fd, readfds) &&
+                FD_ISSET (this_fd, &oread) && !fp_input_ready (fp))
+              ready--, FD_CLR (this_fd, &oread);
+            if (writefds && FD_ISSET (this_fd, writefds) &&
+                FD_ISSET (this_fd, &owrite) && !fp_output_ready (fp))
+              ready--, FD_CLR (this_fd, &owrite);
+
+            /* For exceptional conditions, ferror() is the only one
+               which can tell us an exception is pending.  */
+            if (exceptfds && FD_ISSET (this_fd, exceptfds) &&
+                fp_except_ready (fp))
+              ready++, FD_SET (this_fd, &oexcept);
+          }
+        }
+      }
+    }
+
+    /* Exit if we found what we were waiting for.  */
+    if (ready > 0)
+    {
+      if (readfds)
+	*readfds = oread;
+      if (writefds)
+	*writefds = owrite;
+      if (exceptfds)
+	*exceptfds = oexcept;
+      return ready;
+    }
+
+    /* Exit if we hit the time limit.  */
+    if (timeout)
+    {
+      gettimeofday (&now, 0);
+      if (now.tv_sec > then.tv_sec
+	  || (now.tv_sec == then.tv_sec && now.tv_usec >= then.tv_usec))
+      {
+	if (readfds)
+	  FD_ZERO (readfds);
+	if (writefds)
+	  FD_ZERO (writefds);
+	if (exceptfds)
+	  FD_ZERO (exceptfds);
+	return 0;
+      }
+    }
+
+    /* We are busy-waiting, so give other processes a chance to run.  */
+    __dpmi_yield ();
+  } while (1);
+}
+
+#ifdef  TEST
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+  struct timeval timeout;
+  fd_set read_fds, write_fds;
+  int i, select_result;
+
+  timeout.tv_sec = 15;
+  timeout.tv_usec = 0;
+
+  /* Display status of the 5 files open by default.  */
+  for (i = 0; i < 5; i++)
+    {
+
+      FD_ZERO (&read_fds);
+      FD_SET (i, &read_fds);
+      select_result = select (i + 1, &read_fds, 0, 0, &timeout);
+      if (select_result == -1)
+        {
+          fprintf(stderr, "%d: Failure for input", i);
+          perror("");
+        }
+      else
+        fprintf(stderr,
+                "%d: %s ready for input\n", i, select_result ? "" : "NOT");
+      FD_ZERO (&write_fds);
+      FD_SET (i, &write_fds);
+      select_result = select (i + 1, 0, &write_fds, 0, &timeout);
+      if (select_result == -1)
+        {
+          fprintf(stderr, "%d: Failure for output", i);
+          perror("");
+        }
+      else
+        fprintf(stderr,
+                "%d: %s ready for output\n", i, select_result ? "" : "NOT");
+    }
+  return 0;
+}
+
+#endif
diff -aprNU5 libsupp-6.2.orig/src/compat/time/select.c libsupp-6.2/src/compat/time/select.c
--- libsupp-6.2.orig/src/compat/time/select.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/time/select.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -19,19 +20,22 @@
 #include <time.h>
 #include <dpmi.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <libc/file.h>
 #include <libc/local.h>
 #include <libc/dosio.h>
 #include <libc/getdinfo.h>
 #include <libc/ttyprvt.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <io.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 inline static int
 fp_output_ready(FILE *fp)
 {
   return !ferror(fp);
@@ -71,11 +75,11 @@ inline static int
 fd_output_ready(int fd)
 {
   __dpmi_regs regs;
 
   /* If it's a directory, always return 0. We can't write to directories. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
     return 0;
 
   regs.x.ax = 0x4407;
   regs.x.bx = fd;
   __dpmi_int (0x21, &regs);
@@ -94,11 +98,11 @@ fd_input_ready(int fd)
   __dpmi_regs regs;
   short dev_info;
 
   /* If it's a directory, always return 1. That way the caller
      will hit the EISDIR error as quickly as possible. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
     return 1;
 
   /* If it's a disk file, always return 1, since DOS returns ``not ready''
      for files at EOF, but we won't block in that case.  */
   dev_info = _get_dev_info(fd);
@@ -125,11 +129,11 @@ fd_input_ready(int fd)
   else
     return regs.h.al == 0xff;
 }
 
 int
-select(int nfds,
+libsupp_select(int nfds,
 	fd_set *readfds,
 	fd_set *writefds,
 	fd_set *exceptfds,
 	struct timeval *timeout)
 {
@@ -302,11 +306,11 @@ main(void)
   for (i = 0; i < 5; i++)
     {
 
       FD_ZERO (&read_fds);
       FD_SET (i, &read_fds);
-      select_result = select (i + 1, &read_fds, 0, 0, &timeout);
+      select_result = libsupp_select (i + 1, &read_fds, 0, 0, &timeout);
       if (select_result == -1)
         {
           fprintf(stderr, "%d: Failure for input", i);
           perror("");
         }
diff -aprNU5 libsupp-6.2.orig/src/compat/unistd/fsync-2.03.c libsupp-6.2/src/compat/unistd/fsync-2.03.c
--- libsupp-6.2.orig/src/compat/unistd/fsync-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/unistd/fsync-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,38 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <dpmi.h>
+#include <errno.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_fsync_2_03(int _fd);
+
+
+int
+libsupp_fsync_2_03(int _fd)
+{
+  int oerrno = errno;
+  __dpmi_regs r;
+
+  /* Directory? If so, fail. */
+  if (libsupp___get_fd_flags(_fd) & FILE_DESC_DIRECTORY)
+  {
+    errno = EINVAL;
+    return -1;
+  }
+
+  r.h.ah = 0x68;
+  r.x.bx = _fd;
+  __dpmi_int(0x21, &r);
+  if ((r.x.flags & 1) && (r.x.ax != 1) && (r.x.ax != 6))
+  {
+    errno = __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+  errno = oerrno;
+  return 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/compat/unistd/fsync.c libsupp-6.2/src/compat/unistd/fsync.c
--- libsupp-6.2.orig/src/compat/unistd/fsync.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/unistd/fsync.c	2009-11-22 04:01:02 +0000
@@ -1,22 +1,25 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
 #include <dpmi.h>
 #include <errno.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
 
 int
-fsync(int _fd)
+libsupp_fsync(int _fd)
 {
   __dpmi_regs r;
   int oerrno = errno;
 
   /* Directory? If so, fail. */
-  if (__get_fd_flags(_fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(_fd) & FILE_DESC_DIRECTORY)
   {
     errno = EINVAL;
     return -1;
   }
 
diff -aprNU5 libsupp-6.2.orig/src/compat/unistd/ftruncat-2.03.c libsupp-6.2/src/compat/unistd/ftruncat-2.03.c
--- libsupp-6.2.orig/src/compat/unistd/ftruncat-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/compat/unistd/ftruncat-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,38 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <io.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int   libsupp_ftruncate_2_03(int _fd, off_t _where);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+int   libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+
+
+int
+libsupp_ftruncate_2_03(int fd, off_t where)
+{
+  off_t here;
+  int retval = 0;
+
+  /* Directory? If so, fail. */
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  {
+    errno = EINVAL;
+    return -1;
+  }
+
+  here = libsupp_lseek_2_03(fd, 0, SEEK_CUR);
+  if (here == -1)
+    return -1;
+  if (libsupp_lseek_2_03(fd, where, SEEK_SET) == -1)
+    return -1;
+  if (libsupp__write_2_03(fd, 0, 0) < 0)
+    retval = -1;
+  libsupp_lseek_2_03(fd, here, SEEK_SET);
+  return retval;
+}
diff -aprNU5 libsupp-6.2.orig/src/compat/unistd/ftruncat.c libsupp-6.2/src/compat/unistd/ftruncat.c
--- libsupp-6.2.orig/src/compat/unistd/ftruncat.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/unistd/ftruncat.c	2009-11-22 04:01:02 +0000
@@ -1,32 +1,35 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
 #include <io.h>
 #include <errno.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
 
 int
-ftruncate(int fd, off_t where)
+libsupp_ftruncate(int fd, off_t where)
 {
   off_t here;
   int retval = 0;
 
   /* Directory? If so, fail. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
   {
     errno = EINVAL;
     return -1;
   }
 
-  here = lseek(fd, 0, SEEK_CUR);
+  here = libsupp_lseek(fd, 0, SEEK_CUR);
   if (here == -1)
     return -1;
-  if (lseek(fd, where, SEEK_SET) == -1)
+  if (libsupp_lseek(fd, where, SEEK_SET) == -1)
     return -1;
-  if (_write(fd, 0, 0) < 0)
+  if (libsupp__write(fd, 0, 0) < 0)
     retval = -1;
-  lseek(fd, here, SEEK_SET);
+  libsupp_lseek(fd, here, SEEK_SET);
   return retval;
 }
diff -aprNU5 libsupp-6.2.orig/src/compat/unistd/llseek.c libsupp-6.2/src/compat/unistd/llseek.c
--- libsupp-6.2.orig/src/compat/unistd/llseek.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/compat/unistd/llseek.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /*
  * File llseek.c.
@@ -16,38 +17,40 @@
 #include <unistd.h>
 #include <dpmi.h>
 #include <errno.h>
 #include <libc/dosio.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
 
 offset_t
-llseek( int handle, offset_t offset, int whence )
+libsupp_llseek(int handle, offset_t offset, int whence)
 {
   __dpmi_regs r;
   int has_props;
 
   __FSEXT_Function *func = __FSEXT_get_function(handle);
   if( func )
   {
     int rv;
-    if( __FSEXT_func_wrapper(func, __FSEXT_llseek, &rv,
-			     handle, offset, whence) )
+    if ( __FSEXT_func_wrapper(func, __FSEXT_llseek, &rv,
+			      handle, offset, whence))
     {
       return rv;
     }
   }
 
-  has_props = __has_fd_properties(handle);
+  has_props = libsupp___has_fd_properties(handle);
 
   /* Directory? If so, we're done. */
-  if (has_props && (__fd_properties[handle]->flags & FILE_DESC_DIRECTORY))
+  if (has_props && (__libsupp_fd_properties[handle]->flags & FILE_DESC_DIRECTORY))
     return 0;
 
   /* POSIX doesn't allow seek on a pipe.  */
-  if (has_props && (__fd_properties[handle]->flags & FILE_DESC_PIPE))
+  if (has_props && (__libsupp_fd_properties[handle]->flags & FILE_DESC_PIPE))
   {
     errno = ESPIPE;
     return -1;
   }
 
@@ -62,20 +65,20 @@ llseek( int handle, offset_t offset, int
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
 
   if (!has_props ||
-      (__fd_properties[handle]->flags & FILE_DESC_DONT_FILL_EOF_GAP) == 0)
+      (__libsupp_fd_properties[handle]->flags & FILE_DESC_DONT_FILL_EOF_GAP) == 0)
   {
     if (offset > 0)
     {
       if (!has_props)
-        has_props = (__set_fd_properties(handle, NULL, 0) == 0);
+        has_props = (libsupp___set_fd_properties(handle, NULL, 0) == 0);
       if (has_props)
-        __set_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP);
+        libsupp___set_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP);
     }
     else if (has_props && (whence == SEEK_SET || whence == SEEK_END))
-      __clear_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP);
+      libsupp___clear_fd_flags(handle, FILE_DESC_ZERO_FILL_EOF_GAP);
   }
   return( ( ( (unsigned)r.x.dx ) << 16) + r.x.ax );
 }
 
diff -aprNU5 libsupp-6.2.orig/src/dos/io/_close-2.03.c libsupp-6.2/src/dos/io/_close-2.03.c
--- libsupp-6.2.orig/src/dos/io/_close-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/dos/io/_close-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,51 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <unistd.h>
+#include <errno.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <io.h>
+#include <sys/fsext.h>
+
+#include <libc/dosio.h>
+
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+int libsupp__close_2_03(int _handle);
+
+
+int
+libsupp__close_2_03(int handle)
+{
+  __dpmi_regs r;
+
+  __FSEXT_Function *func = __FSEXT_get_function(handle);
+  if (func)
+  {
+    int rv;
+    if (__FSEXT_func_wrapper(func, __FSEXT_close, &rv, handle))
+    {
+      /* So that we don't try to use it later!
+	 The extension *should* do this itself! */
+      __FSEXT_set_function(handle, 0);
+      return rv;
+    }
+    /* same here */
+    __FSEXT_set_function(handle, 0);
+  }
+
+  r.h.ah = 0x3e;
+  r.x.bx = handle;
+  __dpmi_int(0x21, &r);
+  if (r.x.flags & 1)
+  {
+    errno = EBADF;
+    return -1;
+  }
+  if (libsupp___has_fd_properties(handle))
+    libsupp___clear_fd_properties(handle);
+  return 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/dos/io/_close.c libsupp-6.2/src/dos/io/_close.c
--- libsupp-6.2.orig/src/dos/io/_close.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/dos/io/_close.c	2009-11-22 04:01:02 +0000
@@ -1,21 +1,24 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <stdarg.h>
 #include <unistd.h>
 #include <errno.h>
 #include <go32.h>
 #include <dpmi.h>
 #include <io.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
 
 int
-_close(int handle)
+libsupp__close(int handle)
 {
   __dpmi_regs r;
 
   __FSEXT_Function *func = __FSEXT_get_function(handle);
   if (func)
@@ -38,9 +41,9 @@ _close(int handle)
   if (r.x.flags & 1)
   {
     errno = EBADF;
     return -1;
   }
-  if (__has_fd_properties(handle))
-    __clear_fd_properties(handle);
+  if (libsupp___has_fd_properties(handle))
+    libsupp___clear_fd_properties(handle);
   return 0;
 }
diff -aprNU5 libsupp-6.2.orig/src/dos/io/_write-2.03.c libsupp-6.2/src/dos/io/_write-2.03.c
--- libsupp-6.2.orig/src/dos/io/_write-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/dos/io/_write-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,68 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <io.h>
+#include <sys/fsext.h>
+
+#include <libc/dosio.h>
+
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+int libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+
+
+int
+libsupp__write_2_03(int handle, const void* buffer, size_t count)
+{
+  size_t j, i;
+  int nput;
+  unsigned long tbsize;
+  __dpmi_regs r;
+
+  __FSEXT_Function *func = __FSEXT_get_function(handle);
+  if (func)
+  {
+    int rv;
+    if (__FSEXT_func_wrapper(func, __FSEXT_write, &rv, handle))
+      return rv;
+  }
+
+  tbsize = _go32_info_block.size_of_transfer_buffer;
+  nput = 0;
+  do {
+    j = (count <= tbsize) ? count : tbsize;
+    if (j)
+      dosmemput(buffer, j, __tb);
+    r.x.ax = 0x4000;
+    r.x.bx = handle;
+    r.x.cx = j;
+    r.x.dx = __tb & 15;
+    r.x.ds = __tb / 16;
+    __dpmi_int(0x21, &r);
+    if (r.x.flags & 1)
+    {
+      errno = __doserr_to_errno(r.x.ax);
+      return -1;
+    }
+    i = r.x.ax;
+    count -= i;
+    buffer = (void *)((int)buffer + i);
+    nput += i;
+  } while(count && (i == j));
+
+  if (count && nput == 0)
+  {
+    errno = ENOSPC;
+    return -1;
+  }
+
+  return nput;
+}
diff -aprNU5 libsupp-6.2.orig/src/dos/io/_write.c libsupp-6.2/src/dos/io/_write.c
--- libsupp-6.2.orig/src/dos/io/_write.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/dos/io/_write.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -9,84 +10,86 @@
 #include <errno.h>
 #include <go32.h>
 #include <dpmi.h>
 #include <io.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
 #include <libc/farptrgs.h>
 #include <libc/getdinfo.h>
 
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 ssize_t
-_write(int handle, const void* buffer, size_t count)
+libsupp__write(int handle, const void* buffer, size_t count)
 {
   __FSEXT_Function *func = __FSEXT_get_function(handle);
   if (func)
   {
     int rv;
     if (__FSEXT_func_wrapper(func, __FSEXT_write, &rv, handle, buffer, count))
       return rv;
   }
 
-  if (__has_fd_properties(handle)
-      && (__fd_properties[handle]->flags & FILE_DESC_ZERO_FILL_EOF_GAP))
+  if (libsupp___has_fd_properties(handle)
+      && (__libsupp_fd_properties[handle]->flags & FILE_DESC_ZERO_FILL_EOF_GAP))
   {
-    if (_write_fill_seek_gap(handle) < 0)
+    if (libsupp__write_fill_seek_gap(handle) < 0)
       return -1;
   }
 
-  return _write_int(handle, buffer, count);
+  return libsupp__write_int(handle, buffer, count);
 }
 
 /* If the file pointer offset is beyond EOF, fill the gap between EOF and
    the file pointer offset with zeroes.  This emulates the behavior described
    in the POSIX documentation for lseek.  */
 int
-_write_fill_seek_gap(int fd)
+libsupp__write_fill_seek_gap(int fd)
 {
   offset_t eof_off, cur_off, fill_count;
   unsigned long buf_size;
   unsigned long i;
   short fd_info;
   
-  __clear_fd_flags(fd, FILE_DESC_ZERO_FILL_EOF_GAP);
+  libsupp___clear_fd_flags(fd, FILE_DESC_ZERO_FILL_EOF_GAP);
 
   /* Quit when there can't be an EOF gap or its existance doesn't matter.  */
-  if (__fd_properties[fd]->flags & FILE_DESC_DONT_FILL_EOF_GAP)
+  if (__libsupp_fd_properties[fd]->flags & FILE_DESC_DONT_FILL_EOF_GAP)
     return 0;
     
   /* Quit when not working with a file.  */
   fd_info = _get_dev_info(fd);
   if (fd_info & _DEV_CDEV)
   {
     /* Don't bother with handles that don't need the fix.  */
-    __set_fd_flags(fd, FILE_DESC_DONT_FILL_EOF_GAP);
+    libsupp___set_fd_flags(fd, FILE_DESC_DONT_FILL_EOF_GAP);
     return 0;
   }
   
   /* Quit when unable to get the file length.  */    
-  eof_off = lfilelength (fd);
+  eof_off = libsupp_lfilelength (fd);
   if (eof_off < 0)
     return 0;
   
   /* Quit when unable to get the current file offset.  */
-  cur_off = llseek (fd, 0, SEEK_CUR);
+  cur_off = libsupp_llseek (fd, 0, SEEK_CUR);
   if (cur_off < 0)
     return 0;
 
   /* Quit if the current offset is not past EOF.  */
   if (cur_off <= eof_off)
     return 0;
     
   /* Quit when unable to seek to EOF.  */
-  if (llseek (fd, eof_off, SEEK_SET) == -1)
+  if (libsupp_llseek (fd, eof_off, SEEK_SET) == -1)
     return 0;
 
   /* Clear once again because the llseek call above will
      set the fill test flag.  */
-  __clear_fd_flags(fd, FILE_DESC_ZERO_FILL_EOF_GAP);
+  libsupp___clear_fd_flags(fd, FILE_DESC_ZERO_FILL_EOF_GAP);
   
   /* Fill the transfer buffer with zeros.  */
   fill_count = cur_off - eof_off;
 
   buf_size = (fill_count > __tb_size) ? __tb_size : fill_count;
@@ -102,19 +105,19 @@ _write_fill_seek_gap(int fd)
   /* Write out 'fill_count' number of zeros.  */
   /* Warning! If fill_count > ULONG_MAX, this call won't work.
      But changing _write_int's last argument to 'unsigned long long'
      won't work either because gcc generates bad code for long longs
      passed via the stack.  */
-  return _write_int(fd, NULL, fill_count);
+  return libsupp__write_int(fd, NULL, fill_count);
 }
 
 /* Write WRITE_COUNT bytes of data to the file associated with FD.
    If BUFFER is not NULL, the data pointed to by BUFFER is put into the
    transfer buffer and written out. Otherwise, the data already in the
    transfer buffer is written out. */
 int
-_write_int(int fd, const char *buffer, unsigned long long write_count)
+libsupp__write_int(int fd, const char *buffer, unsigned long long write_count)
 {
   unsigned long buf_size;
   unsigned long chunk_count;
   int total_written;
   unsigned short bytes_written;
diff -aprNU5 libsupp-6.2.orig/src/dos/io/fd_props.c libsupp-6.2/src/dos/io/fd_props.c
--- libsupp-6.2.orig/src/dos/io/fd_props.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/dos/io/fd_props.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <strings.h>
@@ -8,143 +9,144 @@
 #include <sys/stat.h>
 #include <libc/bss.h>
 #include <fcntl.h>
 #include <io.h>
 #include <unistd.h>
-#include <libc/fd_props.h>
 
-extern void (*__fd_properties_cleanup_hook);
+#include "../include/libc/fd_props.h"
 
-static void open_fd(fd_properties *fd, int open_flags);
-static void close_fd(fd_properties *fd);
-static fd_properties * find_eq_filename(const fd_properties *fd);
-static fd_properties * alloc_fd_properties(void);
-static void free_fd_properties(fd_properties *);
-static void insert_list(fd_properties **, fd_properties *);
-static void remove_list(fd_properties **, fd_properties *);
+void (*__libsupp_fd_properties_cleanup_hook);
+
+static void open_fd(libsupp_fd_properties *fd, int open_flags);
+static void close_fd(libsupp_fd_properties *fd);
+static libsupp_fd_properties * find_eq_filename(const libsupp_fd_properties *fd);
+static libsupp_fd_properties * alloc_fd_properties(void);
+static void free_fd_properties(libsupp_fd_properties *);
+static void insert_list(libsupp_fd_properties **, libsupp_fd_properties *);
+static void remove_list(libsupp_fd_properties **, libsupp_fd_properties *);
 static void exit_cleanup(void);
 
 /* Array of pointers to fd_properties objects associated
    with a file descriptor.  */
-fd_properties **__fd_properties = NULL;
+libsupp_fd_properties **__libsupp_fd_properties = NULL;
 
 /* List of fd_properties objects associated with at least
    one file descriptor.  */
-static fd_properties *active_fds;
+static libsupp_fd_properties *active_fds;
 
 /* List of fd_properties objects not currently in use.  */
-static fd_properties *cached_fds;
+static libsupp_fd_properties *cached_fds;
 
 static int old_bss_count;
 
 /* Perform file descriptor specific initialization.  */
 static inline void
-open_fd(fd_properties *cur_fd, int open_flags)
+open_fd(libsupp_fd_properties *cur_fd, int open_flags)
 {
   cur_fd->flags = 0;
   if (cur_fd->filename && (open_flags & O_TEMPORARY))
     cur_fd->flags |= FILE_DESC_TEMPORARY;
   if (open_flags & O_APPEND)
     cur_fd->flags |= FILE_DESC_APPEND;
 }
 
 /* Perform file descriptor specific finalization.  */
 static inline void
-close_fd(fd_properties *cur_fd)
+close_fd(libsupp_fd_properties *cur_fd)
 {
   /* Delete the file if no other descriptors use the file.  Otherwise,
      mark the other descriptor with the temporary flag.  */
   if (cur_fd->flags & FILE_DESC_TEMPORARY)
   {
-    fd_properties *ptr = find_eq_filename(cur_fd);
+    libsupp_fd_properties *ptr = find_eq_filename(cur_fd);
     if (ptr)
       ptr->flags |= FILE_DESC_TEMPORARY;
     else
       remove(cur_fd->filename);
   }
 }
 
 /* Set properties associated with a file descriptor.  */
 int
-__set_fd_properties(int fd, const char *file, int open_flags)
+libsupp___set_fd_properties(int fd, const char *file, int open_flags)
 {
   char *result;
 
   if (old_bss_count != __bss_count)
   {
-    size_t size = 255 * sizeof(fd_properties *);
+    size_t size = 255 * sizeof(libsupp_fd_properties *);
     old_bss_count = __bss_count;
-    __fd_properties = malloc(size);
+    __libsupp_fd_properties = malloc(size);
     active_fds = NULL;
     cached_fds = NULL;
-    if (__fd_properties == NULL)
+    if (__libsupp_fd_properties == NULL)
       return -1;
-    memset(__fd_properties, 0, size);
-    __fd_properties_cleanup_hook = exit_cleanup;
+    memset(__libsupp_fd_properties, 0, size);
+    __libsupp_fd_properties_cleanup_hook = exit_cleanup;
   }
 
   /* This function may be called twice for the same fd,
      so allocate and initialize when not already done.*/
-  if (__fd_properties[fd] == NULL)
+  if (__libsupp_fd_properties[fd] == NULL)
   {
-    __fd_properties[fd] = alloc_fd_properties();
-    if (__fd_properties[fd] == NULL)
+    __libsupp_fd_properties[fd] = alloc_fd_properties();
+    if (__libsupp_fd_properties[fd] == NULL)
       return -1;
 
     /* Initialize the object and insert it into list.  */
-    __fd_properties[fd]->ref_count = 1;
+    __libsupp_fd_properties[fd]->ref_count = 1;
     result = _truename(file, NULL);
-    __fd_properties[fd]->filename = result;
+    __libsupp_fd_properties[fd]->filename = result;
 
-    insert_list(&active_fds, __fd_properties[fd]);
+    insert_list(&active_fds, __libsupp_fd_properties[fd]);
   }
 
-  open_fd(__fd_properties[fd], open_flags);
+  open_fd(__libsupp_fd_properties[fd], open_flags);
 
   return 0;
 }
 
 /* Set properties of a file descriptor returned by dup or dup2.  */
 void
-__dup_fd_properties(int from, int to)
+libsupp___dup_fd_properties(int from, int to)
 {
-  if (__fd_properties[from])
+  if (__libsupp_fd_properties[from])
   {
-    __fd_properties[to] = __fd_properties[from];
-    ++(__fd_properties[to]->ref_count);
+    __libsupp_fd_properties[to] = __libsupp_fd_properties[from];
+    ++(__libsupp_fd_properties[to]->ref_count);
   }
 }
 
 /* Clear properties associated with a file descriptor.  */
 int
-__clear_fd_properties(int fd)
+libsupp___clear_fd_properties(int fd)
 {
   /* If there are no properties with this descriptor then punt.  */
-  if (__fd_properties[fd] == NULL)
+  if (__libsupp_fd_properties[fd] == NULL)
     return -1;
 
-  if (--(__fd_properties[fd]->ref_count) == 0)
+  if (--(__libsupp_fd_properties[fd]->ref_count) == 0)
   {
     /* The last file descriptor using this object has closed.  Perform
        any final actions before the object is put into the cache.  */
-    close_fd(__fd_properties[fd]);
+    close_fd(__libsupp_fd_properties[fd]);
 
-    free(__fd_properties[fd]->filename);
-    __fd_properties[fd]->filename = NULL;
-    free_fd_properties(__fd_properties[fd]);
+    free(__libsupp_fd_properties[fd]->filename);
+    __libsupp_fd_properties[fd]->filename = NULL;
+    free_fd_properties(__libsupp_fd_properties[fd]);
   }
-  __fd_properties[fd] = NULL;
+  __libsupp_fd_properties[fd] = NULL;
 
   return 0;
 }
 
 /* Find another properties object using the same filename.  */
 static
-fd_properties *
-find_eq_filename(const fd_properties *fd)
+libsupp_fd_properties *
+find_eq_filename(const libsupp_fd_properties *fd)
 {
-  fd_properties *ptr = active_fds;
+  libsupp_fd_properties *ptr = active_fds;
   
   while (ptr)
   {
     if ((ptr != fd) && (stricmp(fd->filename, ptr->filename) == 0))
       return ptr;
@@ -152,18 +154,18 @@ find_eq_filename(const fd_properties *fd
   }
   return NULL;
 }
 
 /* Return a properties object for use with one or more file descriptors.  */
-static fd_properties *
+static libsupp_fd_properties *
 alloc_fd_properties(void)
 {
-  fd_properties *ptr;
+  libsupp_fd_properties *ptr;
   
   if (cached_fds == NULL)
   {
-    ptr = malloc(sizeof(fd_properties));
+    ptr = malloc(sizeof(libsupp_fd_properties));
     if (ptr == NULL)
       return ptr;
   }
   else
   {
@@ -177,33 +179,33 @@ alloc_fd_properties(void)
   return ptr;   
 }
 
 /* Remove the object from the active list, and insert it into the cache.  */
 static void
-free_fd_properties(fd_properties *fd)
+free_fd_properties(libsupp_fd_properties *fd)
 {
   remove_list(&active_fds, fd);
   insert_list(&cached_fds, fd);
 }
 
 /* Insert a properties object into a list.  */
 static void
-insert_list(fd_properties **head_ptr, fd_properties *item)
+insert_list(libsupp_fd_properties **head_ptr, libsupp_fd_properties *item)
 {
-  fd_properties *head = *head_ptr;
+  libsupp_fd_properties *head = *head_ptr;
   item->next = head;
   item->prev = NULL;
   if (head)
     head->prev = item;
   *head_ptr = item;
 }
 
 /* Remove a properties object from a list.  */
 static void
-remove_list(fd_properties **head_ptr, fd_properties *item)
+remove_list(libsupp_fd_properties **head_ptr, libsupp_fd_properties *item)
 {
-  fd_properties *head = *head_ptr;
+  libsupp_fd_properties *head = *head_ptr;
   
   if (item->prev)
   {
     (item->prev)->next = item->next;
     item->prev = NULL;
@@ -224,17 +226,17 @@ remove_list(fd_properties **head_ptr, fd
 static void
 exit_cleanup(void)
 {
   int fd;
 
-  if (__fd_properties == NULL || active_fds == NULL)
+  if (__libsupp_fd_properties == NULL || active_fds == NULL)
     return;
 
   fd = 0;
   while (fd < 255)
   {
-    if (__fd_properties[fd])
+    if (__libsupp_fd_properties[fd])
       _close(fd);
     ++fd;
   }
 }
 
diff -aprNU5 libsupp-6.2.orig/src/include/libc/fd_props.h libsupp-6.2/src/include/libc/fd_props.h
--- libsupp-6.2.orig/src/include/libc/fd_props.h	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/include/libc/fd_props.h	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 #ifndef __dj_include_libc_fdprops_h__
 #define __dj_include_libc_fdprops_h__
 
@@ -37,50 +38,50 @@ extern "C" {
 #define FILE_DESC_APPEND            0x10
 
 /* Set when the descriptor is used for directory emulation. */
 #define FILE_DESC_DIRECTORY         0x20
 
-typedef struct fd_properties fd_properties;
+typedef struct libsupp_fd_properties libsupp_fd_properties;
 
-struct fd_properties
+struct libsupp_fd_properties
 {
   unsigned char ref_count;
   char *filename;
   unsigned long flags;
-  fd_properties *prev;
-  fd_properties *next;
+  libsupp_fd_properties *prev;
+  libsupp_fd_properties *next;
 };
 
-extern fd_properties ** __fd_properties;
+extern libsupp_fd_properties ** __libsupp_fd_properties;
 
-int __set_fd_properties(int _fd, const char * _file, int _oflags);
-void __dup_fd_properties(int _from, int _to);
-int __clear_fd_properties(int _fd);
+int  libsupp___set_fd_properties(int _fd, const char * _file, int _oflags);
+void libsupp___dup_fd_properties(int _from, int _to);
+int  libsupp___clear_fd_properties(int _fd);
 
-static __inline__ int __has_fd_properties(int _fd)
+static __inline__ int libsupp___has_fd_properties(int _fd)
 {
-  return _fd >= 0 && __fd_properties && __fd_properties[_fd];
+  return _fd >= 0 && __libsupp_fd_properties && __libsupp_fd_properties[_fd];
 }
 
-static __inline__ void __set_fd_flags(int _fd, unsigned long _flags)
+static __inline__ void libsupp___set_fd_flags(int _fd, unsigned long _flags)
 {
-  __fd_properties[_fd]->flags |= _flags;  
+  __libsupp_fd_properties[_fd]->flags |= _flags;  
 }
 
-static __inline__ void __clear_fd_flags(int _fd, unsigned long _flags)
+static __inline__ void libsupp___clear_fd_flags(int _fd, unsigned long _flags)
 {
-  __fd_properties[_fd]->flags &= ~_flags;
+  __libsupp_fd_properties[_fd]->flags &= ~_flags;
 }
 
-static __inline__ unsigned long __get_fd_flags(int _fd)
+static __inline__ unsigned long libsupp___get_fd_flags(int _fd)
 {
-  return __has_fd_properties(_fd) ? __fd_properties[_fd]->flags : 0;
+  return libsupp___has_fd_properties(_fd) ? __libsupp_fd_properties[_fd]->flags : 0;
 }
 
-static __inline__ const char * __get_fd_name(int _fd)
+static __inline__ const char * libsupp___get_fd_name(int _fd)
 {
-  return __has_fd_properties(_fd) ? __fd_properties[_fd]->filename : NULL;
+  return libsupp___has_fd_properties(_fd) ? __libsupp_fd_properties[_fd]->filename : NULL;
 }
 
 #endif /* !_POSIX_SOURCE */
 #endif /* !__STRICT_ANSI__ */
 #endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
diff -aprNU5 libsupp-6.2.orig/src/include/libc/file-2.03.h libsupp-6.2/src/include/libc/file-2.03.h
--- libsupp-6.2.orig/src/include/libc/file-2.03.h	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/include/libc/file-2.03.h	2009-11-22 04:01:02 +0000
@@ -0,0 +1,119 @@
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_libc_file_h__
+#define __dj_include_libc_file_h__
+
+#include <fcntl.h>
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _POSIX_SOURCE
+
+#define _IOREAD   000010
+#define _IOWRT    000020
+#define _IOMYBUF  000040
+#define _IOEOF    000100
+#define _IOERR    000200
+#define _IOSTRG   000400
+#define _IORW     001000
+#define _IOAPPEND 002000
+#define _IORMONCL 004000  /* remove on close, for temp files */
+/* if _flag & _IORMONCL, ._name_to_remove needs freeing */
+#define _IOUNGETC 010000  /* there is an ungetc'ed character in the buffer */
+#define _IOTERM   020000  /* file's handle hooked by termios */
+#define _IONTERM  040000  /* file's handle not hooked by termios */
+
+int	_flsbuf(int, FILE*);
+int	_filbuf(FILE *);
+void	_fwalk(void (*)(FILE *));
+
+static __inline__ int __getc_raw(FILE *const p)
+{
+   if(p->_cnt>0)
+   {
+      p->_cnt--;
+      return((unsigned char)*(p->_ptr++));
+   }
+   return(_filbuf(p));
+}
+
+static __inline__ int __putc_raw(int const x,FILE *const p)
+{
+   if(p->_cnt>0)
+   {
+      p->_cnt--;
+      return((unsigned char)(*(p->_ptr++)=(unsigned char)x));
+   }
+   return(_flsbuf((unsigned char)x,p));
+}
+
+static __inline__ int __is_text_file(FILE *const p)
+{
+   return(!((p)->_flag & (_IOSTRG | _IOTERM))
+	  && (__file_handle_modes[(p)->_file]&O_TEXT));
+}
+
+static __inline__ int __getc(FILE *const p)
+{
+  int __c;
+  if (__libc_read_termios_hook
+      && ((p)->_flag & (_IOTERM | _IONTERM)) == 0)
+  {
+    extern int __isatty(int);
+    /* first time we see this handle--see if termios hooked it */
+    if (!((p)->_flag & _IOSTRG) && __isatty((p)->_file))
+      (p)->_flag |= _IOTERM;
+    else
+      (p)->_flag |= _IONTERM;
+  }
+  __c = __getc_raw(p);
+  if (__c=='\r' && __is_text_file(p))
+    return __getc_raw(p);
+  return __c;
+}
+
+static __inline__ int __putc(const int x,FILE *const p)
+{
+  if (__libc_write_termios_hook
+      && ((p)->_flag & (_IOTERM | _IONTERM)) == 0)
+  {
+    extern int __isatty(int);
+    /* first time we see this handle--see if termios hooked it */
+    if (!((p)->_flag & _IOSTRG) && __isatty((p)->_file))
+      (p)->_flag |= _IOTERM;
+    else
+      (p)->_flag |= _IONTERM;
+  }
+  if(x=='\n' && __is_text_file(p))
+    __putc_raw('\r',p);
+  return __putc_raw(x,p);
+}
+
+#undef  fileno
+#define fileno(f)	(f->_file)
+#undef  feof
+#define feof(f)		(((f)->_flag&_IOEOF)!=0)
+#undef  ferror
+#define ferror(f)	(((f)->_flag&_IOERR)!=0)
+
+#endif /* !_POSIX_SOURCE */
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifndef __dj_ENFORCE_FUNCTION_CALLS
+#endif /* !__dj_ENFORCE_FUNCTION_CALLS */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dj_include_libc_file_h__ */
diff -aprNU5 libsupp-6.2.orig/src/include/libc/fsexthlp.h libsupp-6.2/src/include/libc/fsexthlp.h
--- libsupp-6.2.orig/src/include/libc/fsexthlp.h	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/include/libc/fsexthlp.h	2009-11-22 04:01:02 +0000
@@ -1,11 +1,25 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 #ifndef __dj_include_libc_fsexthlp_h__
 #define __dj_include_libc_fsexthlp_h__
 
 #include <stdarg.h>
+
+/* For GCC-4.4.X the definitions have chenged again ...                    */
+/* This is however not surprising as we are messing here with internal     */
+/* stuff of GCC.                                                           */
+#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)
+# undef va_start
+# undef va_end
+# undef va_arg
+# define va_start(ap, last_arg)   __builtin_va_start(ap, last_arg)
+# define va_end(ap)               __builtin_va_end(ap)
+# define va_arg(v, l)             __builtin_va_arg(v, l)
+#endif
+
 #include <sys/fsext.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/closedir.c libsupp-6.2/src/posix/dirent/closedir.c
--- libsupp-6.2.orig/src/posix/dirent/closedir.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/dirent/closedir.c	2009-11-22 04:01:02 +0000
@@ -1,20 +1,22 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
 #include <stdlib.h>
 #include <errno.h>
-#include <dirent.h>
+
+#include "libsupp.h"
 #include "dirstruc.h"
 
 int
-closedir(DIR *dir)
+libsupp_closedir(DIR *dir)
 {
   int retval = 0;
   int e = errno;
 
   errno = 0;
-  rewinddir(dir);	/* under LFN this closes the search handle */
+  libsupp_rewinddir(dir);	/* under LFN this closes the search handle */
   if (errno == 0)
     errno = e;
   else
     retval = -1;
   free(dir->name);
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/dirstruc.h libsupp-6.2/src/posix/dirent/dirstruc.h
--- libsupp-6.2.orig/src/posix/dirent/dirstruc.h	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/dirent/dirstruc.h	2009-11-22 04:01:02 +0000
@@ -1,12 +1,30 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
 #include <dir.h>
 
+#define IS_ROOT_DIR(path)  (((path)[1] == ':') && ((path)[2] == '/') && ((path)[3] == '\0'))
+
+#define APPEND_STAR_DOT_STAR(dst, src)  \
+  do {                                  \
+    int _i;                             \
+                                        \
+    for (_i = 0; (src)[_i]; _i++)       \
+      (dst)[_i] = (src)[_i];            \
+    (dst)[_i++] = '/';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '.';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '\0';                 \
+  } while(0)
+
 struct __dj_DIR {
   int num_read;
   char *name;
   int flags;
   struct ffblk ff;
   struct dirent de;
   int need_fake_dot_dotdot; /* 0=no, 1=.., 2=. */
 };
+
+void libsupp___set_need_fake_dot_dotdot(DIR *_dirp);
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/fake_dot.c libsupp-6.2/src/posix/dirent/fake_dot.c
--- libsupp-6.2.orig/src/posix/dirent/fake_dot.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/dirent/fake_dot.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,40 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "libsupp.h"
+#include "dirstruc.h"
+
+void
+libsupp___set_need_fake_dot_dotdot(DIR *dir)
+{
+  int oerrno = errno;
+
+  dir->need_fake_dot_dotdot = 0;
+  if (IS_ROOT_DIR(dir->name))
+  {    
+    /* see if findfirst finds "." anyway */
+    char dir_name[FILENAME_MAX + 1];
+
+    APPEND_STAR_DOT_STAR(dir_name, dir->name);
+    if (findfirst(dir_name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC)
+	|| strcmp(dir->ff.ff_name, "."))
+    {
+      dir->need_fake_dot_dotdot = 2;
+
+      /* Restore errno in certain cases. findfirst() will fail for empty
+	 root directories on drives, but this should not be considered
+	 an error. */
+      if ((errno == ENOENT) || (errno == ENMFILE))
+	errno = oerrno;
+    }
+
+    if (_USE_LFN && dir->ff.lfn_handle)
+    {
+      _lfn_find_close(dir->ff.lfn_handle);
+      dir->ff.lfn_handle = 0;
+    }
+  }
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/opendir-2.03.c libsupp-6.2/src/posix/dirent/opendir-2.03.c
--- libsupp-6.2.orig/src/posix/dirent/opendir-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/dirent/opendir-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,85 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libc/dosio.h>
+#include <dpmi.h>
+
+#include "libsupp.h"
+#include "dirstruc.h"
+
+int   libsupp_access_2_03(const char *_fn, int _flags);
+void  libsupp__fixpath_2_03(const char *_in, char *_out);
+DIR  *libsupp_opendir_2_03(const char *_dir_name);
+
+DIR *
+libsupp_opendir_2_03(const char *name)
+{
+  int length;
+  DIR *dir;
+
+  dir = (DIR *)malloc(sizeof(DIR));
+  if (dir == 0)
+    return 0;
+  dir->num_read = 0;
+  dir->name = (char *)malloc(PATH_MAX);
+  if (dir->name == 0)
+  {
+    free(dir);
+    return 0;
+  }
+
+  dir->flags = __opendir_flags;
+  if (!(__opendir_flags & __OPENDIR_PRESERVE_CASE) && _preserve_fncase())
+    dir->flags |= __OPENDIR_PRESERVE_CASE;
+
+  /* Make absolute path */
+  libsupp__fixpath_2_03(name, dir->name);
+
+  /* Ensure that directory to be accessed exists */
+  if (libsupp_access_2_03(dir->name, D_OK))
+  {
+    free(dir->name);
+    free(dir);
+    return 0;
+  }
+
+  /* Strip trailing slashes.
+     The "/ *.*" is no longer part of the directory
+     name but is appended in every libc function
+     that requires it.  */
+  length = strlen(dir->name);
+  while (1)
+  {
+    if (length == 0) break;
+    length--;
+    if (dir->name[length] == '/' ||
+	dir->name[length] == '\\')
+      dir->name[length] = '\0';
+    else
+    {
+      length++;
+      break;
+    }
+  }
+  dir->name[length++] = 0;
+
+  /* If we're doing opendir of the root directory, we need to
+     fake out the . and .. entries, as some unix programs (like
+     mkisofs) expect them and fail if they don't exist */
+  libsupp___set_need_fake_dot_dotdot(dir);
+
+  return dir;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/opendir.c libsupp-6.2/src/posix/dirent/opendir.c
--- libsupp-6.2.orig/src/posix/dirent/opendir.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/dirent/opendir.c	2009-11-22 04:01:02 +0000
@@ -9,84 +9,23 @@
 #include <libc/symlink.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <dirent.h>
 #include <errno.h>
 #include <limits.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <libc/dosio.h>
 #include <dpmi.h>
-#include "dirstruc.h"
-
-#define IS_ROOT_DIR(path)  (((path)[1] == ':') && ((path)[2] == '/') && ((path)[3] == '\0'))
-
-#define APPEND_STAR_DOT_STAR(dst, src)  \
-  do {                                  \
-    int _i;                             \
-                                        \
-    for (_i = 0; (src)[_i]; _i++)       \
-      (dst)[_i] = (src)[_i];            \
-    (dst)[_i++] = '/';                  \
-    (dst)[_i++] = '*';                  \
-    (dst)[_i++] = '.';                  \
-    (dst)[_i++] = '*';                  \
-    (dst)[_i++] = '\0';                 \
-  } while(0)
-
-
-void
-_lfn_find_close(int handle)
-{
-  __dpmi_regs r;
 
-  r.x.bx = handle;
-  r.x.ax = 0x71a1;
-  __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
-  {
-    errno = __doserr_to_errno(r.x.ax);
-  }
-}
-
-void
-__set_need_fake_dot_dotdot(DIR *dir)
-{
-  int oerrno = errno;
-
-  dir->need_fake_dot_dotdot = 0;
-  if (IS_ROOT_DIR(dir->name))
-  {    
-    /* see if findfirst finds "." anyway */
-    char dir_name[FILENAME_MAX + 1];
-
-    APPEND_STAR_DOT_STAR(dir_name, dir->name);
-    if (findfirst(dir_name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC)
-	|| strcmp(dir->ff.ff_name, "."))
-    {
-      dir->need_fake_dot_dotdot = 2;
-
-      /* Restore errno in certain cases. findfirst() will fail for empty
-	 root directories on drives, but this should not be considered
-	 an error. */
-      if ((errno == ENOENT) || (errno == ENMFILE))
-	errno = oerrno;
-    }
-
-    if (_USE_LFN && dir->ff.lfn_handle)
-    {
-      _lfn_find_close(dir->ff.lfn_handle);
-      dir->ff.lfn_handle = 0;
-    }
-  }
-}
+#include "libsupp.h"
+#include "dirstruc.h"
 
 DIR *
-opendir(const char *name)
+libsupp_opendir(const char *name)
 {
   int length;
   DIR *dir;
   char name_copy[FILENAME_MAX + 1];
 
@@ -107,14 +46,14 @@ opendir(const char *name)
   dir->flags = __opendir_flags;
   if (!(__opendir_flags & __OPENDIR_PRESERVE_CASE) && _preserve_fncase())
     dir->flags |= __OPENDIR_PRESERVE_CASE;
 
   /* Make absolute path */
-  _fixpath(name_copy, dir->name);
+  libsupp__fixpath(name_copy, dir->name);
 
   /* Ensure that directory to be accessed exists */
-  if (access(dir->name, D_OK))
+  if (libsupp_access(dir->name, D_OK))
   {
     free(dir->name);
     free(dir);
     return 0;
   }
@@ -140,9 +79,9 @@ opendir(const char *name)
   dir->name[length++] = 0;
 
   /* If we're doing opendir of the root directory, we need to
      fake out the . and .. entries, as some unix programs (like
      mkisofs) expect them and fail if they don't exist */
-  __set_need_fake_dot_dotdot(dir);
+  libsupp___set_need_fake_dot_dotdot(dir);
 
   return dir;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/readdir-2.03.c libsupp-6.2/src/posix/dirent/readdir-2.03.c
--- libsupp-6.2.orig/src/posix/dirent/readdir-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/dirent/readdir-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,103 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "libsupp.h"
+#include "dirstruc.h"
+
+struct dirent *libsupp_readdir_2_03(DIR *_dirp);
+
+struct dirent *
+libsupp_readdir_2_03(DIR *dir)
+{
+  int done;
+  int oerrno = errno;
+  int mbsize;
+
+  if (dir->need_fake_dot_dotdot)
+  {
+    /* Fake out . and .. on /; see opendir for comments */
+    dir->need_fake_dot_dotdot --;
+    if (dir->need_fake_dot_dotdot)
+      strcpy(dir->de.d_name, ".");
+    else
+      strcpy(dir->de.d_name, "..");
+    dir->de.d_namlen = strlen(dir->de.d_name);
+    if ((__opendir_flags & __OPENDIR_NO_D_TYPE) == 0)
+      dir->de.d_type = DT_DIR;
+    else
+      dir->de.d_type = DT_UNKNOWN;
+    return &(dir->de);
+  }
+
+  if (dir->num_read)
+    done = findnext(&dir->ff);
+  else
+  {
+    char dir_name[FILENAME_MAX + 1];
+    int ff_flags = FA_ARCH|FA_RDONLY|FA_DIREC|FA_SYSTEM;
+    if (!(dir->flags & __OPENDIR_NO_HIDDEN))
+      ff_flags |= FA_HIDDEN;
+    if (dir->flags & __OPENDIR_FIND_LABEL)
+      ff_flags |= FA_LABEL;
+    APPEND_STAR_DOT_STAR(dir_name, dir->name);
+    done = findfirst(dir_name, &dir->ff, ff_flags);
+  }
+  if (done)
+  {
+    if (errno == ENMFILE)
+      errno = oerrno;
+    return 0;
+  }
+  dir->num_read++;
+  if (!(dir->flags & __OPENDIR_PRESERVE_CASE))
+  {
+    char *cp, fsh[13];
+
+    if (!strcmp(_lfn_gen_short_fname(dir->ff.ff_name, fsh), dir->ff.ff_name))
+      for (cp=dir->ff.ff_name; *cp; cp++)
+#if 1
+	{
+	  mbsize = mblen (cp, MB_CUR_MAX);
+	  if (mbsize > 1)
+	    {
+	      cp += mbsize - 1;
+	      continue;
+	    }
+	  else if (*cp >= 'A' && *cp <= 'Z')
+	    *cp += 'a' - 'A';
+	}
+#else
+	if (*cp >= 'A' && *cp <= 'Z')
+	  *cp += 'a' - 'A';
+#endif
+  }
+  strcpy(dir->de.d_name, dir->ff.ff_name);
+  dir->de.d_namlen = strlen(dir->de.d_name);
+  if ((__opendir_flags & __OPENDIR_NO_D_TYPE) == 0)
+    {
+      unsigned char attrib = dir->ff.ff_attrib;
+
+      if ((attrib & FA_DIREC) == FA_DIREC)
+	dir->de.d_type = DT_DIR;
+      else if ((attrib & FA_LABEL) == FA_LABEL)
+	dir->de.d_type = DT_LABEL;
+      else if ((attrib & 0x40) == 0x40)
+	dir->de.d_type = DT_CHR;
+      /* FIXME: anything else DOS can return? */
+      else
+	dir->de.d_type = DT_REG;
+    }
+  else
+    dir->de.d_type = DT_UNKNOWN;
+  return &dir->de;
+}
+
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/readdir.c libsupp-6.2/src/posix/dirent/readdir.c
--- libsupp-6.2.orig/src/posix/dirent/readdir.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/dirent/readdir.c	2009-11-22 04:01:02 +0000
@@ -5,33 +5,21 @@
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <dirent.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
 #include <io.h>
 #include <libc/symlink.h>
-#include "dirstruc.h"
 
-#define APPEND_STAR_DOT_STAR(dst, src)  \
-  do {                                  \
-    int _i;                             \
-                                        \
-    for (_i = 0; (src)[_i]; _i++)       \
-      (dst)[_i] = (src)[_i];            \
-    (dst)[_i++] = '/';                  \
-    (dst)[_i++] = '*';                  \
-    (dst)[_i++] = '.';                  \
-    (dst)[_i++] = '*';                  \
-    (dst)[_i++] = '\0';                 \
-  } while(0)
+#include "libsupp.h"
+#include "dirstruc.h"
 
 struct dirent *
-readdir(DIR *dir)
+libsupp_readdir(DIR *dir)
 {
   int done;
   int oerrno = errno;
   int mbsize;
 
diff -aprNU5 libsupp-6.2.orig/src/posix/dirent/rewinddi.c libsupp-6.2/src/posix/dirent/rewinddi.c
--- libsupp-6.2.orig/src/posix/dirent/rewinddi.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/dirent/rewinddi.c	2009-11-22 04:01:02 +0000
@@ -1,21 +1,23 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
-#include <dirent.h>
 #include <fcntl.h>
+
+#include "libsupp.h"
 #include "dirstruc.h"
 
 void
-rewinddir(DIR *dir)
+libsupp_rewinddir(DIR *dir)
 {
   /* If we are using LFN-aware functions, close the handle used by
      Windows 9X during the search (readdir will open a new one).  */
   if (_USE_LFN && dir->ff.lfn_handle)
   {
     _lfn_find_close(dir->ff.lfn_handle);
     dir->ff.lfn_handle = 0;	/* 0 means it's closed */
   }
 
   /* Recompute need_fake_dot_dotdot member.  See comments in opendir.c.  */
-  __set_need_fake_dot_dotdot(dir);
+  libsupp___set_need_fake_dot_dotdot(dir);
   dir->num_read = 0;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/fcntl/fcntl-2.03.c libsupp-6.2/src/posix/fcntl/fcntl-2.03.c
--- libsupp-6.2.orig/src/posix/fcntl/fcntl-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/fcntl/fcntl-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,105 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <dpmi.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/fsext.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+int libsupp_fcntl_2_03(int _fd, int _cmd, ...);
+int libsupp_dup2_2_03(int _fd, int _newfd);
+
+
+static int
+is_used_fd(int fd)
+{
+  __dpmi_regs regs;
+
+  regs.x.ax = 0x4400;
+  regs.x.bx = fd;
+  __dpmi_int(0x21, &regs);
+  if (regs.x.flags & 1)
+    return 0;
+
+  return 1;
+}
+
+int
+libsupp_fcntl_2_03(int fd, int cmd, ...)
+{
+  int tofd, open_max;
+  va_list ap;
+  __FSEXT_Function *func = __FSEXT_get_function(fd);
+  if (func)
+  {
+    int rv;
+    if (__FSEXT_func_wrapper(func, __FSEXT_fcntl, &rv, fd))
+      return rv;
+  }
+
+  switch (cmd)
+  {
+  case F_DUPFD:
+    va_start(ap, cmd);
+    tofd = va_arg(ap, int);
+    va_end(ap);
+
+    open_max = getdtablesize();
+    if (tofd < 0 || tofd >= open_max)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+    while (tofd < open_max)
+    {
+      if (! is_used_fd(tofd))
+	break;
+      tofd++;
+    }
+
+    if (tofd >= open_max)
+    {
+      errno = EMFILE;
+      return -1;
+    }
+
+    return libsupp_dup2_2_03(fd, tofd);
+    
+  case F_GETFD:
+    /* DOS only passes the first 20 handles to child programs.  In
+       addition, handles 19 and 18 will be closed by the stub of the
+       child program (if it is a DJGPP program).
+
+       FIXME: we should look at the no-inherit bit stashed in the SFT
+       entry pointed to by the handle, since some of the first 18
+       handles could have been opened with a no-inherit bit.  */
+    return fd >= 18 ? FD_CLOEXEC : 0;
+  case F_SETFD:
+    if ((fd < 18) ^ ((cmd & FD_CLOEXEC) != 0))
+      return 0;
+    else
+      {
+	errno = ENOSYS;
+	return -1;
+      }
+  case F_GETFL:
+    return 0;	/* FIXME: should use the data in the SFT */
+  case F_SETFL:
+    errno = ENOSYS;
+    return -1;
+  case F_GETLK:
+  case F_SETLK:
+  case F_SETLKW:
+    errno = ENOSYS;
+    return -1;
+  }
+  errno = ENOSYS;
+  return -1;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/fcntl/fcntl.c libsupp-6.2/src/posix/fcntl/fcntl.c
--- libsupp-6.2.orig/src/posix/fcntl/fcntl.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/fcntl/fcntl.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -10,18 +11,20 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <io.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <sys/movedata.h>
 #include <libc/farptrgs.h>
 #include <libc/dosio.h>
 #include <libc/getdinfo.h>
-#include <libc/fd_props.h>
 #include <go32.h>
 
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
 
 static unsigned long _get_sft_entry_ptr(int fd)
 {
   __dpmi_regs regs;
   unsigned char ind;
@@ -111,11 +114,11 @@ _fcntl_lk64(int fd, int cmd, struct floc
   long long int ret64 = -1L;
   offset_t pos, cur_pos, lock_pos, len;
   long long int flen;
 
   /* Is this a directory? If so, fail. */
-  if (__get_fd_flags(fd) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fd) & FILE_DESC_DIRECTORY)
   {
     errno = EINVAL;
     return -1;
   }
 
@@ -129,15 +132,15 @@ _fcntl_lk64(int fd, int cmd, struct floc
 
     return ret;
   }
   else ret = -1; /* Restore default value */
 
-  cur_pos = llseek(fd, 0L, SEEK_CUR);
+  cur_pos = libsupp_llseek(fd, 0L, SEEK_CUR);
   if (cur_pos < 0)
     return -1;      /* Assumes llseek has set errno */
 
-  lock_pos = llseek (fd, lock_r64->l_start, lock_r64->l_whence);
+  lock_pos = libsupp_llseek (fd, lock_r64->l_start, lock_r64->l_whence);
   if (lock_pos < 0)
     return -1;      /* Assumes llseek has set errno */
 
   len = lock_r64->l_len;
 
@@ -145,15 +148,15 @@ _fcntl_lk64(int fd, int cmd, struct floc
   /* If l_len is zero, then the lock is to be set from the position
      represented by l_start/l_whence to the current end-of-file.
   */
   if (len == 0L)
   {
-    flen = lfilelength(fd); /* Hold lfilelength in case len < 0 */
-    len = flen - lock_pos;  /* len > 0      lock_pos before EOF
-                               len == 0     lock_pos at     EOF
-                               len < 0      lock_pos after  EOF
-                            */
+    flen = libsupp_lfilelength(fd); /* Hold lfilelength in case len < 0 */
+    len = flen - lock_pos;          /* len > 0      lock_pos before EOF
+                                       len == 0     lock_pos at     EOF
+                                       len < 0      lock_pos after  EOF
+                                     */
 
     /* If now len < 0, then lock_pos is beyond EOF, and
        the code below will calculate the correct region.
     */
     if (len < 0L)
@@ -164,11 +167,11 @@ _fcntl_lk64(int fd, int cmd, struct floc
     }
   }
 
 
   /* Return to saved position */
-  ret64 = llseek (fd, cur_pos, SEEK_SET);
+  ret64 = libsupp_llseek (fd, cur_pos, SEEK_SET);
   if (ret64 < 0L)
     return -1;      /* Assumes llseek has set errno */
   else
     ret64 = -1;     /* Restore default value */
 
@@ -253,11 +256,11 @@ _fcntl_lk64(int fd, int cmd, struct floc
   return ret;
 }
 
 
 int
-fcntl(int fd, int cmd, ...)
+libsupp_fcntl(int fd, int cmd, ...)
 {
   int tofd, open_max;
   va_list ap;
   __FSEXT_Function *func;
   short dev_info = _get_dev_info(fd);
@@ -308,11 +311,11 @@ fcntl(int fd, int cmd, ...)
         return -1;
       }
 
 
       errno = errno_save;
-      return dup2(fd, tofd);
+      return libsupp_dup2(fd, tofd);
     }
 
 
     case F_GETFD:
     {
@@ -454,13 +457,13 @@ fcntl(int fd, int cmd, ...)
 	 * is read-write, since that's most likely to be correct. */
 	flags |= O_RDWR;
       }
 
       /* Check the FILE_DESC_APPEND flag in __fd_properties. */
-      if (__has_fd_properties(fd))
+      if (libsupp___has_fd_properties(fd))
       {
-	unsigned long fd_flags = __get_fd_flags(fd);
+	unsigned long fd_flags = libsupp___get_fd_flags(fd);
 
 	if (fd_flags & FILE_DESC_APPEND)
 	  flags |= O_APPEND;
       }
 
diff -aprNU5 libsupp-6.2.orig/src/posix/fcntl/open-2.03.c libsupp-6.2/src/posix/fcntl/open-2.03.c
--- libsupp-6.2.orig/src/posix/fcntl/open-2.03.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/fcntl/open-2.03.c	2009-11-22 04:01:02 +0000
@@ -1,43 +1,60 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
-#include <libc/symlink.h>
-#include <libc/unconst.h>
 #include <limits.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <io.h>
 #include <sys/fsext.h>
 
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/stdbool.h"
+#include "../include/libc/fd_props.h"
+#include "../include/libc/unconst.h"
+#include "libsupp.h"
+
+#define IS_DRIVE_SPECIFIER(path)  ((path)[0] && ((path)[1] == ':'))
+#define IS_ROOT_DIR(path)         ((IS_DRIVE_SPECIFIER(path) && IS_SLASH(path[2]) && ((path)[3] == '\0')) || \
+                                   (IS_SLASH(path[0]) && ((path)[1] == '\0')))
+#define IS_SLASH(path)            ((path) == '/' || (path) == '\\')
+
 
 /* Extra share flags that can be indicated by the user */
 int __djgpp_share_flags;
 
+int   libsupp_open_2_03(const char* _filename, int _oflag, ...);
+int   libsupp_access_2_03(const char *_fn, int _flags);
+int   libsupp_close_2_03(int _handle);
+int   libsupp_fcntl_2_03(int _fd, int _cmd, ...);
+int   libsupp__close_2_03(int _handle);
+int   libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
 /* Move a file descriptor FD such that it is at least MIN_FD.
    If the file descriptor is changed (meaning it was origially
    *below* MIN_FD), the old one will be closed.
    If the operation failed (no more handles available?), -1 will
    be returned, in which case the original descriptor is still
    valid.
 
    This jewel is due to Morten Welinder <terra@diku.dk>.  */
 static int
-move_fd (int fd, int min_fd)
+move_fd(int fd, int min_fd)
 {
   int new_fd, tmp_fd;
 
   if (fd == -1 || fd >= min_fd)
     return fd;
@@ -46,23 +63,23 @@ move_fd (int fd, int min_fd)
   if (tmp_fd == -1)
     return tmp_fd;
 
   new_fd = move_fd (tmp_fd, min_fd);
   if (new_fd != -1)
-    close (fd);		/* success--get rid of the original descriptor */
+    libsupp_close_2_03(fd);      /* success--get rid of the original descriptor */
   else
-    close (tmp_fd);	/* failure--get rid of the temporary descriptor */
+    libsupp_close_2_03(tmp_fd);  /* failure--get rid of the temporary descriptor */
   return new_fd;
 }
 
 static int
-opendir_as_fd (const char *filename, const int oflag)
+opendir_as_fd(const char *filename, const int oflag)
 {
   int fd, old_fd, flags, ret;
 
   /* Check the flags. */
-  if ((oflag & (O_RDONLY|O_WRONLY|O_RDWR)) != O_RDONLY)
+  if ((oflag & (O_RDONLY | O_WRONLY | O_RDWR)) != O_RDONLY)
   {
     /* Only read-only access is allowed. */
     errno = EISDIR;
     return -1;
   }
@@ -85,131 +102,65 @@ opendir_as_fd (const char *filename, con
     return -1; /* Pass through errno. */
 
   fd = move_fd(old_fd, 20);
   if (fd < 0)
   {
-    close(old_fd);
+    libsupp_close_2_03(old_fd);
     errno = EMFILE;
     return -1;
   }
 
-  __set_fd_properties(fd, filename, 0);
-  __set_fd_flags(fd, FILE_DESC_DIRECTORY);
+  libsupp___set_fd_properties(fd, filename, 0);
+  libsupp___set_fd_flags(fd, FILE_DESC_DIRECTORY);
 
-  flags = fcntl(fd, F_GETFD);
+  flags = libsupp_fcntl_2_03(fd, F_GETFD);
   if (flags < 0)
     return -1; /* Pass through errno. */
   flags |= FD_CLOEXEC;
-  ret = fcntl(fd, F_SETFD, flags);
+  ret = libsupp_fcntl_2_03(fd, F_SETFD, flags);
   if (ret < 0)
     return -1; /* Pass through errno. */
 
   return fd;
 }
 
 int
-open(const char* filename, int oflag, ...)
+libsupp_open_2_03(const char* filename, int oflag, ...)
 {
   const int original_oflag = oflag;
-  int fd, dmode, bintext, dont_have_share;
-  char real_name[FILENAME_MAX + 1];
-  int should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
-  int dirs_solved = 0; /* Only directories resolved in real_name? */
+  int fd, dmode, bintext;
+  bool should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
+  bool dont_have_share, is_root_dir;
+  size_t length;
+
 
-  /* Solve symlinks and honor O_NOLINK flag  */
-  if (oflag & O_NOLINK)
+  if (!(length = strlen(filename)))
   {
-     if (!__solve_dir_symlinks(filename, real_name))
-        return -1; /* errno from from __solve_dir_symlinks() */
-     dirs_solved = 1;
+    errno = EINVAL;
+    return -1;
   }
   else
-  {
-     if (!__solve_symlinks(filename, real_name))
-        return -1; /* errno from from __solve_symlinks() */
-  }
+    is_root_dir = IS_ROOT_DIR(filename);
 
-  /* Honor O_NOFOLLOW flag. */
-  if (oflag & O_NOFOLLOW)
+  /* According to POSIX: If the filename contains at least one
+     non-slash character and ends with one or more trailing slashes
+     and one of O_CREAT, O_WRONLY, O_RDWR is specified, then fail.  */
+  if (((oflag & (O_RDONLY | O_CREAT | O_WRONLY | O_RDWR)) != O_RDONLY) && \
+      !is_root_dir && IS_SLASH(filename[length - 1]))
   {
-      /* O_NOFOLLOW, as defined in glibc, requires open() to fail if the
-       * last path component is a symlink.  However, it still requires to 
-       * resolve all other path components.
-       * We check if there were any symlinks by comparing __solve_symlinks()
-       * input and output.  That function does not perform any path 
-       * canonicalization so it should be safe.  */
-      if (strcmp(filename, real_name))
-      {
-         /* Yes, there were symlinks in the path.  Now take all but the last
-          * path component from `real_name', add last path component from
-          * `filename', and try to resolve that mess. 
-          */
-         char   temp[FILENAME_MAX + 1];
-         char   resolved[2];
-         char * last_separator;
-         int    old_errno = errno;
-         strcpy(temp, real_name);
-         last_separator = basename(temp);
-         *last_separator = '\0';
-         last_separator = basename(filename);
-         strcat(temp, "/");
-         strcat(temp, last_separator);
-         if ((readlink(temp, resolved, 1) != -1) || (errno != EINVAL))
-         {
-            /* Yes, the last path component was a symlink. */
-            errno = ELOOP;
-            return -1;
-         }
-         errno = old_errno;
-      }
+    errno = EISDIR;
+    return -1;
   }
 
   /* Check this up front, to reduce cost and minimize effect */
   if (should_create)
-  {
-    /* Symlink: We're not allowed to follow a symlink, when creating a file
-     * with the same name as the symlink.
-     */
-    char temp_name[FILENAME_MAX + 1];
-#define IRD_BUF_SIZE FILENAME_MAX + 1
-    char ird_buf[IRD_BUF_SIZE];
-    const size_t ird_bufsize = IRD_BUF_SIZE;
-#undef IRD_BUF_SIZE
-
-    if (!dirs_solved)
-    {
-      if (!__solve_dir_symlinks(filename, temp_name))
-        return -1; /* errno from from __solve_dir_symlinks() */
-    }
-    else
-    {
-      strcpy(temp_name, real_name);
-    }
-
-    if (__internal_readlink(temp_name, 0, ird_buf, ird_bufsize) < 0)
-    {
-      /* If the error is something other than "doesn't exist"
-       * or "isn't a symlink", return it.
-       */
-      if ((errno != ENOENT) && (errno != EINVAL))
-	return -1; /* errno from __internal_readlink() */
-    }
-    else
-    {
-      /* It's a symlink. */
-      errno = EEXIST;
-      return -1;
-    }
-
-    /* Normal file */
-    if (__file_exists(real_name))
+    if (__file_exists(filename))
     {
       /* file exists and we didn't want it to */
       errno = EEXIST;
       return -1;
     }
-  }
 
   /* figure out what mode we're opening the file in */
   bintext = oflag & (O_TEXT | O_BINARY);
   if (!bintext)
     bintext = _fmode & (O_TEXT | O_BINARY);
@@ -223,81 +174,88 @@ open(const char* filename, int oflag, ..
 
   /* Merge the share flags if they are specified */
   dont_have_share = ((oflag &
                      (SH_DENYNO | SH_DENYRW | SH_DENYRD | SH_DENYWR)) == 0);
   if (dont_have_share && __djgpp_share_flags)
-    {
-     dont_have_share=0;
-     oflag|=__djgpp_share_flags;
-    }
+  {
+    dont_have_share = false;
+    oflag |= __djgpp_share_flags;
+  }
 
   if (should_create)
-    fd = _creatnew(real_name, dmode, oflag & 0xff);
+    fd = _creatnew(filename, dmode, oflag & 0xff);
   else
   {
-    fd = _open(real_name, oflag);
+    fd = _open(filename, oflag);
 
     if (fd == -1)
     {
       /* It doesn't make sense to try anything else if there are no
 	 more file handles available.  */
       if (errno == EMFILE || errno == ENFILE)
-	return fd;
+        return fd;
 
-      if (__file_exists(real_name))
+      if (__file_exists(filename))
       {
-	/* Under multi-taskers, such as Windows, our file might be
-	   open by some other program with DENY-NONE sharing bit,
-	   which fails the `_open' call above.  Try again with
-	   DENY-NONE bit set, unless some sharing bits were already
-	   set in the initial call.  */
-	if (dont_have_share)
-	  fd = _open(real_name, oflag | SH_DENYNO);
+        /* Under multi-taskers, such as Windows, our file might be
+           open by some other program with DENY-NONE sharing bit,
+           which fails the `_open' call above.  Try again with
+           DENY-NONE bit set, unless some sharing bits were already
+           set in the initial call.  */
+        if (dont_have_share)
+          fd = _open(filename, oflag | SH_DENYNO);
       }
       /* Don't call _creat on existing files for which _open fails,
          since the file could be truncated as a result.  */
       else if ((oflag & O_CREAT))
-	fd = _creat(real_name, dmode);
+        fd = _creat(filename, dmode);
     }
+    else
+      /* According to POSIX: If the named file without the slash
+         is not a directory, open() must fail with ENOTDIR.  */
+      if (!is_root_dir && IS_SLASH(filename[length - 1]) && libsupp_access_2_03(filename, D_OK))
+      {
+        libsupp_close_2_03(fd);
+        errno = ENOTDIR;
+        return -1;
+      }
   }
 
   /* Is the target a directory? If so, generate a file descriptor
    * for the directory. Skip the rest of `open', because it does not
    * apply to directories. */
-  if ((fd == -1) && (access(real_name, D_OK) == 0))
-    return opendir_as_fd(real_name, original_oflag);
+  if ((fd == -1) && (libsupp_access_2_03(filename, D_OK) == 0))
+    return opendir_as_fd(filename, original_oflag);
 
   if (fd == -1)
     return fd;	/* errno already set by _open or _creat */
 
   if ((oflag & O_TRUNC) && !should_create)
 #ifndef TRUNC_CHECK
-    _write(fd, 0, 0);
+    libsupp__write_2_03(fd, 0, 0);
 #else
     /* Windows 2000/XP will fail 0 byte writes (truncate) on a character
        device (nul, con) if opened with lfn calls.  We can either ignore
        the return completely or ignore errors on NT.  Since a truncate
        fail should never happen (and if it does we expect an error on
        the next write) this probably doesn't make much difference. */
 
-    if (_write(fd, 0, 0) < 0 && _os_trueversion != 0x532)
+    if (libsupp__write_2_03(fd, 0, 0) < 0 && _os_trueversion != 0x532)
     {
-      _close(fd);
+      libsupp__close_2_03(fd);
       return -1;
     }
 #endif
 
   /* we do this last because _open and _create set it also. */
   /* force setmode() to do ioctl() for cooked/raw */
   __file_handle_set(fd, bintext ^ (O_BINARY|O_TEXT));
   /* this will do cooked/raw ioctl() on character devices */
   setmode(fd, bintext);
-  __set_fd_properties(fd, real_name, oflag);
+  libsupp___set_fd_properties(fd, filename, oflag);
 
-  if ( oflag & O_APPEND )
-  {
-    llseek(fd, 0, SEEK_END);
-  }
+  if (oflag & O_APPEND)
+    libsupp_lseek_2_03(fd, 0, SEEK_END);
 
   return fd;
 }
 
diff -aprNU5 libsupp-6.2.orig/src/posix/fcntl/open.c libsupp-6.2/src/posix/fcntl/open.c
--- libsupp-6.2.orig/src/posix/fcntl/open.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/fcntl/open.c	2009-11-22 04:01:02 +0000
@@ -1,29 +1,38 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <libc/symlink.h>
-#include <libc/unconst.h>
 #include <limits.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <io.h>
 #include <sys/fsext.h>
 
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/stdbool.h"
+#include "../include/libc/fd_props.h"
+#include "../include/libc/unconst.h"
+#include "libsupp.h"
+
+#define IS_DRIVE_SPECIFIER(path)  ((path)[0] && ((path)[1] == ':'))
+#define IS_ROOT_DIR(path)         ((IS_DRIVE_SPECIFIER(path) && IS_SLASH(path[2]) && ((path)[3] == '\0')) || \
+                                   (IS_SLASH(path[0]) && ((path)[1] == '\0')))
+#define IS_SLASH(path)            ((path) == '/' || (path) == '\\')
+
 
 /* Extra share flags that can be indicated by the user */
 int __djgpp_share_flags;
 
 /* Move a file descriptor FD such that it is at least MIN_FD.
@@ -33,11 +42,11 @@ int __djgpp_share_flags;
    be returned, in which case the original descriptor is still
    valid.
 
    This jewel is due to Morten Welinder <terra@diku.dk>.  */
 static int
-move_fd (int fd, int min_fd)
+move_fd(int fd, int min_fd)
 {
   int new_fd, tmp_fd;
 
   if (fd == -1 || fd >= min_fd)
     return fd;
@@ -46,23 +55,23 @@ move_fd (int fd, int min_fd)
   if (tmp_fd == -1)
     return tmp_fd;
 
   new_fd = move_fd (tmp_fd, min_fd);
   if (new_fd != -1)
-    close (fd);		/* success--get rid of the original descriptor */
+    libsupp_close(fd);		/* success--get rid of the original descriptor */
   else
-    close (tmp_fd);	/* failure--get rid of the temporary descriptor */
+    libsupp_close(tmp_fd);	/* failure--get rid of the temporary descriptor */
   return new_fd;
 }
 
 static int
-opendir_as_fd (const char *filename, const int oflag)
+opendir_as_fd(const char *filename, const int oflag)
 {
   int fd, old_fd, flags, ret;
 
   /* Check the flags. */
-  if ((oflag & (O_RDONLY|O_WRONLY|O_RDWR)) != O_RDONLY)
+  if ((oflag & (O_RDONLY | O_WRONLY | O_RDWR)) != O_RDONLY)
   {
     /* Only read-only access is allowed. */
     errno = EISDIR;
     return -1;
   }
@@ -85,84 +94,105 @@ opendir_as_fd (const char *filename, con
     return -1; /* Pass through errno. */
 
   fd = move_fd(old_fd, 20);
   if (fd < 0)
   {
-    close(old_fd);
+    libsupp_close(old_fd);
     errno = EMFILE;
     return -1;
   }
 
-  __set_fd_properties(fd, filename, 0);
-  __set_fd_flags(fd, FILE_DESC_DIRECTORY);
+  libsupp___set_fd_properties(fd, filename, 0);
+  libsupp___set_fd_flags(fd, FILE_DESC_DIRECTORY);
 
-  flags = fcntl(fd, F_GETFD);
+  flags = libsupp_fcntl(fd, F_GETFD);
   if (flags < 0)
     return -1; /* Pass through errno. */
   flags |= FD_CLOEXEC;
-  ret = fcntl(fd, F_SETFD, flags);
+  ret = libsupp_fcntl(fd, F_SETFD, flags);
   if (ret < 0)
     return -1; /* Pass through errno. */
 
   return fd;
 }
 
 int
-open(const char* filename, int oflag, ...)
+libsupp_open(const char* filename, int oflag, ...)
 {
   const int original_oflag = oflag;
-  int fd, dmode, bintext, dont_have_share;
+  int fd, dmode, bintext;
   char real_name[FILENAME_MAX + 1];
-  int should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
-  int dirs_solved = 0; /* Only directories resolved in real_name? */
+  bool should_create = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL);
+  bool dirs_solved = false; /* Only directories resolved in real_name? */
+  bool dont_have_share, is_root_dir;
+  size_t length;
+
+
+  if (!(length = strlen(filename)))
+  {
+    errno = EINVAL;
+    return -1;
+  }
+  else
+    is_root_dir = IS_ROOT_DIR(filename);
+
+  /* According to POSIX: If the filename contains at least one
+     non-slash character and ends with one or more trailing slashes
+     and one of O_CREAT, O_WRONLY, O_RDWR is specified, then fail.  */
+  if (((oflag & (O_RDONLY | O_CREAT | O_WRONLY | O_RDWR)) != O_RDONLY) && \
+      !is_root_dir && IS_SLASH(filename[length - 1]))
+  {
+    errno = EISDIR;
+    return -1;
+  }
 
   /* Solve symlinks and honor O_NOLINK flag  */
   if (oflag & O_NOLINK)
   {
-     if (!__solve_dir_symlinks(filename, real_name))
-        return -1; /* errno from from __solve_dir_symlinks() */
-     dirs_solved = 1;
+    if (!__solve_dir_symlinks(filename, real_name))
+      return -1; /* errno from from __solve_dir_symlinks() */
+    dirs_solved = 1;
   }
   else
   {
-     if (!__solve_symlinks(filename, real_name))
-        return -1; /* errno from from __solve_symlinks() */
+    if (!__solve_symlinks(filename, real_name))
+      return -1; /* errno from from __solve_symlinks() */
   }
 
   /* Honor O_NOFOLLOW flag. */
   if (oflag & O_NOFOLLOW)
   {
-      /* O_NOFOLLOW, as defined in glibc, requires open() to fail if the
-       * last path component is a symlink.  However, it still requires to 
-       * resolve all other path components.
-       * We check if there were any symlinks by comparing __solve_symlinks()
-       * input and output.  That function does not perform any path 
-       * canonicalization so it should be safe.  */
-      if (strcmp(filename, real_name))
+    /* O_NOFOLLOW, as defined in glibc, requires open() to fail if the
+     * last path component is a symlink.  However, it still requires to 
+     * resolve all other path components.
+     * We check if there were any symlinks by comparing __solve_symlinks()
+     * input and output.  That function does not perform any path 
+     * canonicalization so it should be safe.  */
+    if (strcmp(filename, real_name))
+    {
+      /* Yes, there were symlinks in the path.  Now take all but the last
+       * path component from `real_name', add last path component from
+       * `filename', and try to resolve that mess. 
+       */
+      char  temp[FILENAME_MAX + 1];
+      char  resolved[2];
+      char *last_separator;
+      int   old_errno = errno;
+      strcpy(temp, real_name);
+      last_separator = basename(temp);
+      *last_separator = '\0';
+      last_separator = basename(filename);
+      strcat(temp, "/");
+      strcat(temp, last_separator);
+      if ((readlink(temp, resolved, 1) != -1) || (errno != EINVAL))
       {
-         /* Yes, there were symlinks in the path.  Now take all but the last
-          * path component from `real_name', add last path component from
-          * `filename', and try to resolve that mess. 
-          */
-         char   temp[FILENAME_MAX + 1];
-         char   resolved[2];
-         char * last_separator;
-         int    old_errno = errno;
-         strcpy(temp, real_name);
-         last_separator = basename(temp);
-         *last_separator = '\0';
-         last_separator = basename(filename);
-         strcat(temp, "/");
-         strcat(temp, last_separator);
-         if ((readlink(temp, resolved, 1) != -1) || (errno != EINVAL))
-         {
-            /* Yes, the last path component was a symlink. */
-            errno = ELOOP;
-            return -1;
-         }
-         errno = old_errno;
+        /* Yes, the last path component was a symlink. */
+        errno = ELOOP;
+        return -1;
       }
+      errno = old_errno;
+    }
   }
 
   /* Check this up front, to reduce cost and minimize effect */
   if (should_create)
   {
@@ -223,14 +253,14 @@ open(const char* filename, int oflag, ..
 
   /* Merge the share flags if they are specified */
   dont_have_share = ((oflag &
                      (SH_DENYNO | SH_DENYRW | SH_DENYRD | SH_DENYWR)) == 0);
   if (dont_have_share && __djgpp_share_flags)
-    {
-     dont_have_share=0;
-     oflag|=__djgpp_share_flags;
-    }
+  {
+    dont_have_share = false;
+    oflag |= __djgpp_share_flags;
+  }
 
   if (should_create)
     fd = _creatnew(real_name, dmode, oflag & 0xff);
   else
   {
@@ -239,65 +269,72 @@ open(const char* filename, int oflag, ..
     if (fd == -1)
     {
       /* It doesn't make sense to try anything else if there are no
 	 more file handles available.  */
       if (errno == EMFILE || errno == ENFILE)
-	return fd;
+        return fd;
 
       if (__file_exists(real_name))
       {
-	/* Under multi-taskers, such as Windows, our file might be
-	   open by some other program with DENY-NONE sharing bit,
-	   which fails the `_open' call above.  Try again with
-	   DENY-NONE bit set, unless some sharing bits were already
-	   set in the initial call.  */
-	if (dont_have_share)
-	  fd = _open(real_name, oflag | SH_DENYNO);
+        /* Under multi-taskers, such as Windows, our file might be
+           open by some other program with DENY-NONE sharing bit,
+           which fails the `_open' call above.  Try again with
+           DENY-NONE bit set, unless some sharing bits were already
+           set in the initial call.  */
+        if (dont_have_share)
+          fd = _open(real_name, oflag | SH_DENYNO);
       }
       /* Don't call _creat on existing files for which _open fails,
          since the file could be truncated as a result.  */
       else if ((oflag & O_CREAT))
-	fd = _creat(real_name, dmode);
+        fd = _creat(real_name, dmode);
     }
+    else
+      /* According to POSIX: If the named file without the slash
+         is not a directory, open() must fail with ENOTDIR.  */
+      if (!is_root_dir && IS_SLASH(filename[length - 1]) && libsupp_access(real_name, D_OK))
+      {
+        libsupp_close(fd);
+        errno = ENOTDIR;
+        return -1;
+      }
   }
 
   /* Is the target a directory? If so, generate a file descriptor
    * for the directory. Skip the rest of `open', because it does not
    * apply to directories. */
-  if ((fd == -1) && (access(real_name, D_OK) == 0))
+  if ((fd == -1) && (libsupp_access(real_name, D_OK) == 0))
     return opendir_as_fd(real_name, original_oflag);
 
   if (fd == -1)
     return fd;	/* errno already set by _open or _creat */
 
   if ((oflag & O_TRUNC) && !should_create)
 #ifndef TRUNC_CHECK
-    _write(fd, 0, 0);
+    libsupp__write(fd, 0, 0);
 #else
     /* Windows 2000/XP will fail 0 byte writes (truncate) on a character
        device (nul, con) if opened with lfn calls.  We can either ignore
        the return completely or ignore errors on NT.  Since a truncate
        fail should never happen (and if it does we expect an error on
        the next write) this probably doesn't make much difference. */
 
-    if (_write(fd, 0, 0) < 0 && _os_trueversion != 0x532)
+    if (libsupp__write(fd, 0, 0) < 0 && _os_trueversion != 0x532)
     {
-      _close(fd);
+      libsupp__close(fd);
       return -1;
     }
 #endif
 
   /* we do this last because _open and _create set it also. */
   /* force setmode() to do ioctl() for cooked/raw */
   __file_handle_set(fd, bintext ^ (O_BINARY|O_TEXT));
   /* this will do cooked/raw ioctl() on character devices */
   setmode(fd, bintext);
-  __set_fd_properties(fd, real_name, oflag);
+  libsupp___set_fd_properties(fd, real_name, oflag);
 
-  if ( oflag & O_APPEND )
-  {
-    llseek(fd, 0, SEEK_END);
-  }
+  if (oflag & O_APPEND)
+    libsupp_llseek(fd, 0, SEEK_END);
 
   return fd;
 }
 
diff -aprNU5 libsupp-6.2.orig/src/posix/stdio/fdopen-2.03.c libsupp-6.2/src/posix/stdio/fdopen-2.03.c
--- libsupp-6.2.orig/src/posix/stdio/fdopen-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/stdio/fdopen-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,99 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <io.h>
+#include <libc/local.h>
+
+#include "../include/libc/file-2.03.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+FILE *libsupp_fdopen_2_03(int _fildes, const char *_mode);
+
+
+FILE *
+libsupp_fdopen_2_03(int fildes, const char *mode)
+{
+  FILE *f;
+  int rw, oflags = 0;
+  char tbchar;
+
+  f = __alloc_file();
+  if (f == NULL)
+    return NULL;
+
+  rw = (mode[1] == '+') || (mode[1] && (mode[2] == '+'));
+
+  switch (*mode)
+  {
+  case 'a':
+    oflags = O_CREAT | (rw ? O_RDWR : O_WRONLY);
+    break;
+  case 'r':
+    oflags = rw ? O_RDWR : O_RDONLY;
+    break;
+  case 'w':
+    oflags = O_TRUNC | O_CREAT | (rw ? O_RDWR : O_WRONLY);
+    break;
+  default:
+    return (NULL);
+  }
+  if (mode[1] == '+')
+    tbchar = mode[2];
+  else
+    tbchar = mode[1];
+  if (tbchar == 't')
+    oflags |= O_TEXT;
+  else if (tbchar == 'b')
+    oflags |= O_BINARY;
+  else
+    oflags |= (_fmode & (O_TEXT|O_BINARY));
+
+  f->_cnt = 0;
+  f->_file = fildes;
+  f->_bufsiz = 0;
+  if (rw)
+    f->_flag = _IORW;
+  else if (*mode == 'r')
+    f->_flag = _IOREAD;
+  else
+    f->_flag = _IOWRT;
+
+  f->_base = f->_ptr = NULL;
+
+  /* If this is a FILE for a directory, we need to make sure certain
+   * flags are clear and certain flags are set. Namely:
+   *
+   * - The read flag should be clear, since reads aren't allowed.
+   * - The write flag should be clear, since writes aren't allowed.
+   * - The read-write flag should be clear, because of the above.
+   * - The EOF flag should be set, so that certain functions
+   *   fail reads and writes. (Easier than modifying the functions).
+   */
+  if (libsupp___get_fd_flags(fildes) & FILE_DESC_DIRECTORY)
+  {
+    f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
+    f->_flag |= _IOEOF;
+  }
+
+  /* If the FILE is for a directory, leave its mode alone.
+   * Otherwise, set the mode to the one requested by the caller.
+   */
+  if ((libsupp___get_fd_flags(fildes) & FILE_DESC_DIRECTORY) == 0)
+    setmode(fildes, oflags & (O_TEXT|O_BINARY));
+
+  /* Set or clear the append flag according to the mode.  */
+  if (libsupp___has_fd_properties(fildes))
+  {
+    if (*mode == 'a')
+      libsupp___set_fd_flags(fildes, FILE_DESC_APPEND);
+    else
+      libsupp___clear_fd_flags(fildes, FILE_DESC_APPEND);
+  }
+
+  return f;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/stdio/fdopen.c libsupp-6.2/src/posix/stdio/fdopen.c
--- libsupp-6.2.orig/src/posix/stdio/fdopen.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/stdio/fdopen.c	2009-11-22 04:01:02 +0000
@@ -1,20 +1,24 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <sys/types.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <io.h>
-#include <libc/file.h>
 #include <libc/local.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/file.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 FILE *
-fdopen(int fildes, const char *mode)
+libsupp_fdopen(int fildes, const char *mode)
 {
   FILE *f;
   int rw, oflags = 0;
   char tbchar;
 
@@ -68,28 +72,28 @@ fdopen(int fildes, const char *mode)
    * - The write flag should be clear, since writes aren't allowed.
    * - The read-write flag should be clear, because of the above.
    * - The EOF flag should be set, so that certain functions
    *   fail reads and writes. (Easier than modifying the functions).
    */
-  if (__get_fd_flags(fildes) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(fildes) & FILE_DESC_DIRECTORY)
   {
     f->_flag &= ~(_IORW|_IOREAD|_IOWRT);
     f->_flag |= _IOEOF;
   }
 
   /* If the FILE is for a directory, leave its mode alone.
    * Otherwise, set the mode to the one requested by the caller.
    */
-  if ((__get_fd_flags(fildes) & FILE_DESC_DIRECTORY) == 0)
+  if ((libsupp___get_fd_flags(fildes) & FILE_DESC_DIRECTORY) == 0)
     setmode(fildes, oflags & (O_TEXT|O_BINARY));
 
   /* Set or clear the append flag according to the mode.  */
-  if (__has_fd_properties(fildes))
+  if (libsupp___has_fd_properties(fildes))
   {
     if (*mode == 'a')
-      __set_fd_flags(fildes, FILE_DESC_APPEND);
+      libsupp___set_fd_flags(fildes, FILE_DESC_APPEND);
     else
-      __clear_fd_flags(fildes, FILE_DESC_APPEND);
+      libsupp___clear_fd_flags(fildes, FILE_DESC_APPEND);
   }
 
   return f;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/stdlib/realpath.c libsupp-6.2/src/posix/stdlib/realpath.c
--- libsupp-6.2.orig/src/posix/stdlib/realpath.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/stdlib/realpath.c	2009-11-22 04:01:02 +0000
@@ -1,16 +1,19 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <limits.h>
 #include <libc/symlink.h>
 #include <errno.h>
 
+#include "libsupp.h"
+
 /* Return the canonicalized form of the path in variable IN.  */
 char *
-realpath(const char *in, char *out)
+libsupp_realpath(const char *in, char *out)
 {
   char in1[PATH_MAX];
 
   if (in == NULL || out == NULL)
   {
@@ -25,10 +28,10 @@ realpath(const char *in, char *out)
   }
 
   if (!__solve_symlinks(in, in1))
     return NULL; /* Return errno from from __solve_dir_symlinks().  */
 
-  if (__canonicalize_path(in1, out, PATH_MAX) == NULL)
+  if (libsupp___canonicalize_path(in1, out, PATH_MAX) == NULL)
     return NULL; /* Return errno from __canonicalize_path().  */
 
   return out;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/fchmod.c libsupp-6.2/src/posix/sys/stat/fchmod.c
--- libsupp-6.2.orig/src/posix/sys/stat/fchmod.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/fchmod.c	2009-11-22 04:01:02 +0000
@@ -1,21 +1,24 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <errno.h>
 #include <io.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
-#include <libc/fd_props.h>
 #include <libc/getdinfo.h>
 #include <fcntl.h>
 #include <dpmi.h>
 #include <go32.h>
 #include <libc/farptrgs.h>
 
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 static int
 get_current_mode (const int fd)
 {
   __dpmi_regs r;
   int         mode = 0; /* Fail by default */
@@ -39,15 +42,15 @@ get_current_mode (const int fd)
 
   return(mode);
 }
 
 int
-fchmod (int fd, mode_t mode)
+libsupp_fchmod(int fd, mode_t mode)
 {
   __FSEXT_Function    *func     = __FSEXT_get_function(fd);
-  const char          *filename = __get_fd_name(fd);
-  const unsigned long  flags    = __get_fd_flags(fd);
+  const char          *filename = libsupp___get_fd_name(fd);
+  const unsigned long  flags    = libsupp___get_fd_flags(fd);
   int                  dev_info;
   int                  current_mode;
   int                  rv;
 
   if (   func
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/fixpath-2.03.c libsupp-6.2/src/posix/sys/stat/fixpath-2.03.c
--- libsupp-6.2.orig/src/posix/sys/stat/fixpath-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/fixpath-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,358 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>		/* For FILENAME_MAX */
+#include <stdlib.h>
+#include <errno.h>		/* For errno */
+#include <string.h>		/* For strlen() */
+#include <fcntl.h>		/* For LFN stuff */
+#include <go32.h>
+#include <dpmi.h>		/* For dpmisim */
+#include <crt0.h>		/* For crt0 flags */
+#include <dos.h>		/* For Win NT version check */
+#include <sys/stat.h>
+#include <libc/dosio.h>
+
+#include "libsupp.h"
+
+#define IS_DRIVE_SPECIFIER(path)  (((path[0] == (drive_number + 'A')) || (path[0] == (drive_number + 'a'))) && (path[1] == ':'))
+#define IS_ABSOLUTE(path)         ((path[2] == '\\') && (path[3] == '\0'))
+
+
+static unsigned use_lfn;
+
+static char *__get_current_directory(char *_out, int _drive_number);
+void libsupp__fixpath_2_03(const char *_in, char *_out);
+
+static char *
+__get_current_directory(char *out, int drive_number)
+{
+  __dpmi_regs r;
+  char tmpbuf[FILENAME_MAX];
+
+  memset(&r, 0, sizeof(r));
+  r.x.flags = 1;		/* Set carry for safety */
+  if(use_lfn)
+    r.x.ax = 0x7147;
+  else
+    r.h.ah = 0x47;
+  r.h.dl = drive_number + 1;
+  r.x.si = __tb_offset;
+  r.x.ds = __tb_segment;
+  __dpmi_int(0x21, &r);
+
+  if (r.x.flags & 1)
+  {
+#ifdef TEST
+    errno = __doserr_to_errno(r.x.ax);
+    perror("Get dir failed in fixpath");
+#endif
+    *out++ = '.';	/* Return relative path (lfn=n on Win9x) */
+    return out;
+  }
+  else
+  {
+    dosmemget(__tb, sizeof(tmpbuf), tmpbuf);
+    strcpy(out + 1, tmpbuf);
+
+    if (*(out + 1) != '\0')
+    {
+      *out = '/';
+      return out + strlen(out);
+    } 
+    else if (!use_lfn || _get_dos_version(1) != 0x532)
+      /* Root path, don't insert "/", it'll be added later */
+      return out;
+  }
+
+  /* Root path under WinNT/2K/XP with lfn (may be silent failure).
+     If the short name equivalent of the current path is greater than
+     64 characters, Windows 2000 and XP do not return the correct long
+     path name - they return the root directory instead without any
+     failure code.  Since this can be disastrous in deep directories
+     doing an rm -rf, we check for this bug and try and fix the path. */
+
+  r.x.ax = 0x7160;
+  r.x.cx = 0x8002;	/* Get Long Path Name, using subst drive basis */
+  r.x.es = __tb_segment;
+  r.x.di = __tb_offset + FILENAME_MAX;
+  
+  tmpbuf[0] = drive_number + 'A';
+  tmpbuf[1] = ':';
+  tmpbuf[2] = '.';
+  tmpbuf[3] = 0;
+  _put_path(tmpbuf);
+
+  __dpmi_int(0x21, &r);
+
+  if (!(r.x.flags & 1))
+  {
+    dosmemget(__tb + FILENAME_MAX, sizeof(tmpbuf), tmpbuf);
+
+    /* Validate return form and drive matches what _fixpath expects. */
+    if (IS_DRIVE_SPECIFIER(tmpbuf))
+    {
+      if (IS_ABSOLUTE(tmpbuf))
+        /* Root path, don't insert "/", it'll be added later */
+        return out;
+      else
+      {
+        strcpy(out, tmpbuf + 2);  /* Trim drive, just directory */
+        return out + strlen(out);
+      }
+    }
+  } 
+#ifdef TEST
+  else
+  {
+    errno = __doserr_to_errno(r.x.ax);
+    perror("Truename failed in fixpath");
+  }
+#endif
+
+  /* Fixpath failed or returned inconsistent info.  Return relative path. */
+  *out++ = '.';
+  return out;
+}
+
+__inline__ static int
+is_slash(int c)
+{
+  return c == '/' || c == '\\';
+}
+
+__inline__ static int
+is_term(int c)
+{
+  return c == '/' || c == '\\' || c == '\0';
+}
+
+/* Takes as input an arbitrary path.  Fixes up the path by:
+   1. Removing consecutive slashes
+   2. Removing trailing slashes
+   3. Making the path absolute if it wasn't already
+   4. Removing "." in the path
+   5. Removing ".." entries in the path (and the directory above them)
+   6. Adding a drive specification if one wasn't there
+   7. Converting all slashes to '/'
+ */
+void
+libsupp__fixpath_2_03(const char *in, char *out)
+{
+  int		drive_number;
+  char		in1[FILENAME_MAX];
+  char		*ip;
+  char		*op = out;
+  int		preserve_case = _preserve_fncase();
+  char		*name_start;
+  int		mbsize;
+  int		previous_errno;
+
+  previous_errno = errno;
+  use_lfn = _use_lfn(in);
+  errno = previous_errno;  /*  Do not signal that LFN API is not available (ENOSYS).  */
+
+  /* Perform the same magic conversions that _put_path does.  */
+  _put_path(in);
+  dosmemget(__tb, sizeof(in1), in1);
+  ip = in1;
+
+  /* Add drive specification to output string */
+  if (((*ip >= 'a' && *ip <= 'z') ||
+       (*ip >= 'A' && *ip <= 'Z'))
+      && (*(ip + 1) == ':'))
+  {
+    if (*ip >= 'a' && *ip <= 'z')
+    {
+      drive_number = *ip - 'a';
+      *op++ = *ip++;
+    }
+    else
+    {
+      drive_number = *ip - 'A';
+      if (*ip <= 'Z')
+	*op++ = drive_number + 'a';
+      else
+	*op++ = *ip;
+      ++ip;
+    }
+    *op++ = *ip++;
+  }
+  else
+  {
+    __dpmi_regs r;
+    r.h.ah = 0x19;
+    __dpmi_int(0x21, &r);
+    drive_number = r.h.al;
+    *op++ = drive_number + (drive_number < 26 ? 'a' : 'A');
+    *op++ = ':';
+  }
+
+  /* Convert relative path to absolute */
+  if (!is_slash(*ip))
+    op = __get_current_directory(op, drive_number);
+
+  /* Step through the input path */
+  while (*ip)
+  {
+    /* Skip input slashes */
+    if (is_slash(*ip))
+    {
+      ip++;
+      continue;
+    }
+
+    /* Skip "." and output nothing */
+    if (*ip == '.' && is_term(*(ip + 1)))
+    {
+      ip++;
+      continue;
+    }
+
+    /* Skip ".." and remove previous output directory */
+    if (*ip == '.' && *(ip + 1) == '.' && is_term(*(ip + 2)))
+    {
+      ip += 2;
+      if(out[2] == '.' && *(op - 1) == '.') 
+      { 				/* relative path not skipped */
+        *op++ = '/';
+        *op++ = '.';
+        *op++ = '.';
+      } else
+      /* Don't back up over drive spec */
+      if (op > out + 2)
+	/* This requires "/" to follow drive spec */
+	while (!is_slash(*--op));
+      continue;
+    }
+
+    /* Copy path component from in to out */
+    *op++ = '/';
+#if 0
+    while (!is_term(*ip)) *op++ = *ip++;
+#else
+    while (!is_term(*ip))
+      {
+	mbsize = mblen (ip, MB_CUR_MAX);
+	if (mbsize > 1)
+	  {
+	    /* copy multibyte character */
+	    while (--mbsize >= 0)
+	      *op++ = *ip++;
+	  }
+	else
+	  *op++ = *ip++;
+      }
+#endif
+  }
+
+  /* If root directory, insert trailing slash */
+  if (op == out + 2) *op++ = '/';
+
+  /* Null terminate the output */
+  *op = '\0';
+
+  /* switch FOO\BAR to foo/bar, downcase where appropriate */
+  for (op = out + 3, name_start = op - 1; *name_start; op++)
+  {
+    char long_name[FILENAME_MAX], short_name[13];
+
+#if 1
+    /* skip multibyte character */
+    mbsize = mblen (op, MB_CUR_MAX);
+    if (mbsize > 1)
+      {
+	op += mbsize - 1;
+	continue;
+      }
+#endif
+    if (*op == '\\')
+      *op = '/';
+    if (!preserve_case && (*op == '/' || *op == '\0'))
+    {
+      memcpy(long_name, name_start+1, op - name_start - 1);
+      long_name[op - name_start - 1] = '\0';
+      if (!strcmp(_lfn_gen_short_fname(long_name, short_name), long_name))
+      {
+#if 0
+	while (++name_start < op)
+	  if (*name_start >= 'A' && *name_start <= 'Z')
+	    *name_start += 'a' - 'A';
+#else
+	while (++name_start < op)
+	  {
+	    mbsize = mblen (name_start, MB_CUR_MAX);
+	    if (mbsize > 1)
+	      {
+		/* skip multibyte character */
+		name_start += mbsize - 1;
+		continue;
+	      }
+	    else if (*name_start >= 'A' && *name_start <= 'Z')
+	      *name_start += 'a' - 'A';
+	  }
+#endif
+      }
+      else
+	name_start = op;
+    }
+    else if (*op == '\0')
+      break;
+  }
+}
+
+#ifdef TEST
+
+int main (int argc, char *argv[])
+{
+  char fixed[FILENAME_MAX];
+  __dpmi_regs r;
+
+  if (argc > 2) {
+    _put_path(argv[1]);
+    if(_USE_LFN)
+      r.x.ax = 0x713b;
+    else
+      r.h.ah = 0x3b;
+    r.x.dx = __tb_offset;
+    r.x.ds = __tb_segment;
+    __dpmi_int(0x21, &r);
+    if(r.x.flags & 1) {
+      errno = __doserr_to_errno(r.x.ax);
+      sprintf(fixed, "Change dir to %s failed (lfn=%d)", argv[1], _USE_LFN);
+      perror(fixed);
+    } else
+      printf("Set dir: %s\n", argv[1]);
+    argc--;
+    argv++;
+  }
+
+  if(_USE_LFN)
+    r.x.ax = 0x7147;
+  else
+    r.h.ah = 0x47;
+  r.h.dl = 0;
+  r.x.si = __tb_offset;
+  r.x.ds = __tb_segment;
+  __dpmi_int(0x21, &r);
+  if (r.x.flags & 1) {
+    errno = __doserr_to_errno(r.x.ax);
+    perror("getcwd failed");
+  } else {
+    dosmemget(__tb, sizeof(fixed), fixed);
+    printf("Get dir[%d]: \\%s\n", strlen(fixed), fixed);
+  }
+
+  if (argc > 1)
+    {
+      libsupp__fixpath_2_03 (argv[1], fixed);
+      printf ("Fixpath: %s\n", fixed);
+    }
+  return 0;
+}
+
+#endif
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/fixpath.c libsupp-6.2/src/posix/sys/stat/fixpath.c
--- libsupp-6.2.orig/src/posix/sys/stat/fixpath.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/fixpath.c	2009-11-22 04:01:02 +0000
@@ -16,10 +16,12 @@
 #include <crt0.h>		/* For crt0 flags */
 #include <dos.h>		/* For Win NT version check */
 #include <sys/stat.h>
 #include <libc/dosio.h>
 
+#include "libsupp.h"
+
 #define IS_DRIVE_SPECIFIER(path)  ((((path)[0] == (drive_number + 'A')) || ((path)[0] == (drive_number + 'a'))) && ((path)[1] == ':'))
 #define IS_ROOT_DIR(path)         (((path)[2] == '\\') && ((path)[3] == '\0'))
 
 
 static unsigned use_lfn;
@@ -139,11 +141,11 @@ is_term(int c)
    6. Adding a drive specification if one wasn't there
    7. Converting all slashes to '/'
 */
 
 char *
-__canonicalize_path(const char *in, char *out, size_t path_max)
+libsupp___canonicalize_path(const char *in, char *out, size_t path_max)
 {
   int		drive_number;
   char		in1[FILENAME_MAX];
   char		*ip;
   char		*op = out;
@@ -333,13 +335,13 @@ __canonicalize_path(const char *in, char
 
   return out;
 }
 
 void
-_fixpath(const char *in, char *out)
+libsupp__fixpath(const char *in, char *out)
 {
-  __canonicalize_path(in, out, FILENAME_MAX);
+  libsupp___canonicalize_path(in, out, FILENAME_MAX);
 }
 
 #ifdef TEST
 
 int main (int argc, char *argv[])
@@ -382,11 +384,11 @@ int main (int argc, char *argv[])
     printf("Get dir[%d]: \\%s\n", strlen(fixed), fixed);
   }
 
   if (argc > 1)
     {
-      _fixpath (argv[1], fixed);
+      libsupp__fixpath (argv[1], fixed);
       printf ("Fixpath: %s\n", fixed);
     }
   return 0;
 }
 
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/fstat-2.03.c libsupp-6.2/src/posix/sys/stat/fstat-2.03.c
--- libsupp-6.2.orig/src/posix/sys/stat/fstat-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/fstat-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,954 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* This is file FSTAT.C */
+/*
+ *   Almost a 100% U**X-compatible fstat() substitute.
+ *
+ * Usage:
+ *
+ *   That's easy: just put this in libc.a, and then call fstat() as usual.
+ *
+ * Rationale:
+ *
+ *   Many Unix-born programs make heavy use of fstat() library
+ *   function to make decisions on files' equality, size, access
+ *   attributes etc.  In the MS-DOS environment, many implementations
+ *   of fstat() are crippled, because DOS makes it very hard to get to
+ *   certain pieces of information about files and directories.  Thus
+ *   porting a program to DOS is usually an exercise in #ifdef'ing.
+ *   This implementation facilitates porting Unix programs to MS-DOS
+ *   by providing an fstat() which is much more Unix-compatible than
+ *   those of most DOS-based C compilers (e.g., Borland's).
+ *   Specifically, the following issues are taken care of:
+ *
+ *      1. Mode bits are returned for the actual file, files are NOT
+ *         reported read-only (as in Borland's library fstat()).
+ *      2. Mode bits are set for all 3 groups (user, group, other).
+ *      3. Device code (st_dev, st_rdev) is correctly reported (0 = 'A',
+ *         1 = 'B' etc.).
+ *      4. Character device names (such as /dev/con, lpt1, aux etc.) are
+ *         treated as if they were on a special drive called `@:'
+ *         (st_dev = -1).  The "character special" mode bit is set
+ *         for these devices.
+ *      5. The inode number (st_ino) is taken from the starting cluster
+ *         number of the file.  If the cluster number is unavailable, it
+ *         is invented using the file's name in a manner that minimizes
+ *         the possibility of inventing an inode which already belongs
+ *         to another file.  See below for details.
+ *      6. Executable files are found based on files' extensions and
+ *         magic numbers present at their beginning, and their execute
+ *         bits are set.
+ *
+ *   Lossage:
+ *
+ *      Beautiful as the above sounds, this implementation does fail
+ *      under certain circumstances.  The following is a list of known
+ *      problems:
+ *
+ *      1. Files open on networked drives mounted by Novell Netware
+ *         before revision 4.x cannot be traced using DOS System File
+ *         Table.  Therefore, name, extension, file attributes and the
+ *         drive letter are not available for these.  Until somebody
+ *         tells me how this information can be obtained under Novell,
+ *         nothing could be done here.  For the time being, these files
+ *         will get st_dev of -2.
+ *      2. For files which reside on networked drives, the inode number
+ *         is always invented, because network redirectors usually do
+ *         not bring that info with them.
+ *      3. Empty files do not have a starting cluster number, because
+ *         DOS doesn't allocate one until you actually write something
+ *         to a file.  For these the inode is also invented.
+ *      4. If the st_ino field is a 16 bit number, the invented inode
+ *         numbers are from 65535 and down, assuming that most disks have
+ *         unised portions near their end.  Valid cluster numbers are 16-bit
+ *         unisgned integers, so a possibility of a clash exists, although
+ *         the last 80 or more cluster numbers are unused on all drives
+ *         I've seen.  If the st_ino is 32 bit, then invented inodes are
+ *         all greater than 64k, which totally eliminates a possibility
+ *         of a clash with an actual cluster number.
+ *      5. As this implementation relies heavily on undocumented DOS
+ *         features, it will fail to get actual file info in environments
+ *         other than native DOS, such as DR-DOS, OS/2 etc.  For these,
+ *         the function will return whatever info is available with
+ *         conventional DOS calls, which is no less than any other
+ *         implementation could do.  This fstat() might also fail for
+ *         future DOS versions, if the layout of DOS System File Table
+ *         is changed; however, this seems unlikely.
+ *
+ * Copyright (c) 1994-1996 Eli Zaretskii <eliz@is.elta.co.il>
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact.  There is no warranty on this software.
+ *
+ */
+
+/*
+ * Tested with DJGPP port of GNU C compiler, versions 1.11maint5 and 1.12m2,
+ * under MS-DOS 3.3, 4.01, 5.0, 6.20 (with and without DoubleSpace) and
+ * with networked drives under XFS 1.76, Novell Netware 3.22, and
+ * TSoft NFS 0.24Beta.
+ *
+ */
+
+#include <libc/stubs.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <dpmi.h>
+#include <go32.h>
+#include <libc/farptrgs.h>
+#include <libc/bss.h>
+#include <sys/fsext.h>
+#include "xstat.h"
+
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+
+#define _STAT_INODE         1   /* should we bother getting inode numbers? */
+#define _STAT_EXEC_EXT      2   /* get execute bits from file extension? */
+#define _STAT_EXEC_MAGIC    4   /* get execute bits from magic signature? */
+#define _STAT_DIRSIZE       8   /* compute directory size? */
+#define _STAT_ROOT_TIME  0x10   /* try to get root dir time stamp? */
+#define _STAT_WRITEBIT   0x20   /* fstat() needs write bit? */
+
+/* Should we bother about executables at all? */
+#define _STAT_EXECBIT       (_STAT_EXEC_EXT | _STAT_EXEC_MAGIC)
+
+/* Should we bother about any access bits?  */
+#define _STAT_ACCESS        (_STAT_WRITEBIT | _STAT_EXECBIT)
+
+/* Do we need SFT info at all? */
+#define _STAT_NEEDS_SFT     (_STAT_WRITEBIT | _STAT_EXEC_EXT | _STAT_INODE)
+
+/*
+ * Lower-level assist functions to get a starting cluster of a file,
+ * which will serve as an inode number.  The starting cluster is
+ * found in the System File Table entry (an internal structure of
+ * DOS) which belongs to our file.
+ *
+ * Much of the following code is derived from file H2NAME.C, which
+ * came with ``Undocumented DOS'', 1st edition.
+ */
+
+/* Array of SFT entry sizes as function of DOS version. */
+static size_t sft_size_list[] = {0, 0x28, 0x35, 0x3b};
+
+/* Actual size of SFT entry for the version of DOS under
+   which we are running.  */
+static size_t sft_size;
+
+/* Static array to hold a copy of SFT entry.  Should be at
+   least as long as the largest number in sft_size_list[].  */
+static unsigned char sft_buf[0x40];
+
+/* Linear address of pointer to Job File Table (JFT) which
+   is an array of indices into the SFT which correspond to
+   open file handles.  */
+static unsigned long htbl_ptr_addr;
+
+/* True version of DOS (not the one simulated by SETVER).  */
+static unsigned short dos_major, dos_minor;
+
+/* Segment and offset of first SFT sub-table.  All searches
+   start from this address.  */
+static unsigned short sft_start_seg, sft_start_off;
+
+/* This holds the failure bits from last call to fstat_init(),
+   so we can return them each time fstat_assist() is called.  */
+static unsigned short fstat_init_bits;
+
+/* Holds the last seen value of __bss_count, to be safe for
+   restarted programs (emacs).  */
+static int fstat_count = -1;
+
+/* The address of the PSP of the caller.  */
+static unsigned long  psp_addr;
+
+int libsupp_fstat_2_03(int _handle, struct stat *_statbuf);
+int libsupp_stat_2_03(const char *_path, struct stat *_statbuf);
+
+
+/* Initialization routine, called once per program run.
+ * Finds DOS version, SFT entry size and addresses of
+ * program handle table and first SFT sub-table.
+ */
+static int
+fstat_init(void)
+{
+  __dpmi_regs    regs;
+  int            sft_ptr_addr;
+  unsigned short true_dos_version;
+
+  /* Each DOS program has a table of file handles which are used by
+   * DOS open() call.  This table holds, for each handle which is in
+   * use, the index into the System File Tables' list which contains
+   * data about this handle.  The pointer to that handle table is found
+   * at offset 34h in the program's PSP.
+   */
+
+  /* Linear address of pointer to the handle table.  We postpone
+   * dereferencing this pointer to obtain the address of the handle
+   * table until we're actually called for a specific handle, because
+   * somebody could in the meanwhile change that address, e.g. by
+   * calling INT 21h/AX=67h to enlarge the maximum number of file
+   * handles.
+   */
+  htbl_ptr_addr = psp_addr + 0x34;
+
+  /*
+   * Find the pointer to the first subtable in the list of SFT's.
+   * It is stored at offset 4 in the DOS List-of-Lists area, a ptr
+   * to which is returned by the undocumented DOS function 52h.
+   * We don't check FLAGS after 52h returns because Ralph Brown's
+   * Interrupt List doesn't say FLAGS are set to indicate a
+   * failure.
+   */
+  regs.h.ah = 0x52;
+  __dpmi_int(0x21, &regs);
+
+  /* Linear addres of pointer to SFT list.  */
+  sft_ptr_addr = MK_FOFF(regs.x.es, regs.x.bx + 4);
+  
+  /* SFT entry size depends on DOS version.
+     We need exact knowledge about DOS internals, so we need the
+     TRUE DOS version (not the simulated one by SETVER), if that's
+     available.  */
+  true_dos_version = _get_dos_version(1);
+  dos_major = true_dos_version >> 8;
+  dos_minor = true_dos_version & 0xff;
+  sft_size = sft_size_list[dos_major > 4 ? 3 : dos_major - 1];
+  if (!sft_size)        /* unsupported DOS version */
+    {
+      _djstat_fail_bits |= _STFAIL_OSVER;
+      return 0;
+    }
+
+  /* Segment and offset of start of SFT list.  */
+  sft_start_off = _farpeekw(_dos_ds, sft_ptr_addr);
+  sft_start_seg = _farpeekw(_dos_ds, sft_ptr_addr + 2);
+
+  return 1;
+}
+
+/* Given a handle, copy contents of System File Table entry which
+ * belongs to that handle into a local buffer, and return the index
+ * into the SFT array where our entry was found.  In case of failure
+ * to use SFT, return -2.  If FHANDLE is illegal, return -1.
+ */
+static short
+get_sft_entry(int fhandle)
+{
+  unsigned long  sft_seg;
+  unsigned short sft_off;
+  unsigned long  htbl_addr;
+  short          sft_idx, retval;
+  unsigned short _my_ds_base = _my_ds();
+
+  __dpmi_regs	 regs;
+  _djstat_fail_bits = fstat_init_bits;
+
+  /* Force initialization if we were restarted (emacs).  */
+  if (fstat_count != __bss_count)
+    {
+      fstat_count = __bss_count;
+      dos_major = 0;
+    }
+
+  /* Find the PSP address of the current process.  */
+  regs.h.ah = 0x62;	/* Get PSP address */
+  __dpmi_int(0x21, &regs);
+  psp_addr = (unsigned long)regs.x.bx << 4;
+
+  /* If first time called, initialize.  */
+  if (!dos_major && !fstat_init())
+    {
+      fstat_init_bits = _djstat_fail_bits;
+      return -2;
+    }
+
+  /* Test file handle for validity.
+   * For DOS 3.x and later, the number of possible file handles
+   * is at offset 32h in the PSP; for prior versions, it is 20.
+   */
+  if (fhandle < 0
+      || fhandle >= (_osmajor < 3 ?
+		     20
+		     : _farpeekw(_dos_ds, psp_addr + 0x32)))
+    return -1;
+
+  /* Linear address of the handle table. */
+  htbl_addr = MK_FOFF(_farpeekw(_dos_ds, htbl_ptr_addr + 2),
+                      _farpeekw(_dos_ds, htbl_ptr_addr));
+
+  /* Index of the entry for our file handle in the SFT array.  */
+  retval = sft_idx = _farpeekb(_dos_ds, htbl_addr + fhandle);
+
+  if (sft_idx < 0)      /* invalid file handle or bad handle table */
+    {
+      _djstat_fail_bits |= _STFAIL_SFTIDX;
+      return -1;
+    }
+
+  /* Given the index into the SFT list, find our SFT entry.
+   * The list consists of arrays (sub-tables) of entries, each sub-
+   * table preceeded by a header.  The header holds a pointer to the
+   * next sub-table in the list and number of entries in this sub-table.
+   * The list is searched until the sub-table which contains our
+   * target is found, then the sub-table entries are skipped until
+   * we arrive at our target.
+   */
+
+  /* Segment (shifted 4 bits left) and offset of start of SFT list.  */
+  sft_off = sft_start_off;
+  sft_seg = MK_FOFF(sft_start_seg, 0);
+
+  while (sft_off != 0xFFFF)
+    {
+      unsigned long entry_addr   = sft_seg + sft_off;
+      short         subtable_len = _farpeekw(_dos_ds, entry_addr + 4);
+
+      if (sft_idx < subtable_len)
+        { /* Our target is in this sub-table.  Pull in the entire
+           * SFT entry for use by fstat_assist().
+           */
+	  movedata(_dos_ds,
+                   entry_addr + 6 + sft_idx * sft_size,
+		   _my_ds_base, (unsigned int)sft_buf, sft_size);
+          return retval;
+        }
+      /* Our target not in this subtable.
+       * Subtract the number of entries in this sub-table from the
+       * index of our entry, and proceed to next sub-table.
+       */
+      sft_idx -= subtable_len;
+      sft_off  = _farpeekw(_dos_ds, entry_addr);
+      sft_seg  = MK_FOFF(_farpeekw(_dos_ds, entry_addr + 2), 0);
+    }
+
+  /* Get here only by error, which probably means unsupported DOS version. */
+  _djstat_fail_bits |= _STFAIL_SFTNF;
+  return -2;
+}
+
+/* On LFN platforms, we can get all the 3 time-related fields.  */
+
+static void
+set_fstat_times (int fhandle, struct stat *stat_buf)
+{
+  if (_USE_LFN)
+    {
+      time_t access_time;
+      unsigned int create_time;
+
+      /* Access time is currently date only (time is zeroed).  */
+      access_time = _file_time_stamp (_lfn_get_ftime (fhandle, _LFN_ATIME));
+      if (access_time > stat_buf->st_atime)
+	stat_buf->st_atime = access_time;
+
+      /* Creation time might be zero if the file was created
+	 by a DOS program which doesn't support LFN API.  */
+      create_time = _lfn_get_ftime (fhandle, _LFN_CTIME);
+      if (create_time)
+	stat_buf->st_ctime = _file_time_stamp (create_time);
+    }
+}
+
+/* fstat_assist() is where all the actual work is done.
+ * It uses SFT entry, if available and its contents are verified.
+ * Otherwise, it finds all the available info by conventional
+ * DOS calls.
+ */
+
+static int
+fstat_assist(int fhandle, struct stat *stat_buf)
+{
+  short          have_trusted_values = 1;
+  unsigned int   dos_ftime;
+  char           drv_no;
+  short          dev_info;
+  unsigned char  is_dev;
+  unsigned char  is_remote;
+  short          sft_idx = -1;
+  unsigned short sft_fdate, sft_ftime;
+  long           sft_fsize;
+  unsigned short trusted_ftime = 0, trusted_fdate = 0;
+  long           trusted_fsize = 0;
+
+  if ((dev_info = _get_dev_info(fhandle)) == -1)
+    return -1;	/* errno set by _get_dev_info() */
+
+  _djstat_fail_bits = 0;
+
+  /* Get pointer to an SFT entry which holds data for our handle. */
+  if ( (_djstat_flags & _STAT_NEEDS_SFT) == 0 &&
+       (sft_idx = get_sft_entry(fhandle)) == -1)
+    {
+      errno = EBADF;
+      return -1;
+    }
+
+  /* Initialize buffers. */
+  memset(stat_buf, 0, sizeof(struct stat));
+  dos_ftime = 0;
+
+  /* Get some info about this handle by conventional DOS calls.  These
+   * will serve as verification of SFT entry contents and also as
+   * fall-back in case SFT method fails.
+   */
+  if (_getftime(fhandle, &dos_ftime) == 0 &&
+      (trusted_fsize = __filelength(fhandle)) != -1L)
+    {
+      trusted_ftime = dos_ftime & 0xffff;
+      trusted_fdate = dos_ftime >> 16;
+    }
+  else
+    have_trusted_values = 0;
+
+  if (dev_info & 0x0080)
+    {
+      is_dev = 1;
+      is_remote = 0;	/* device can't be remote */
+    }
+  else
+    {
+      is_dev = 0;
+      if (dev_info & 0x8000)
+	is_remote = 1;
+      else
+	is_remote = 0;
+      
+      if(!have_trusted_values && dev_info == 0 && _get_dos_version(1) == 0x532)
+        is_dev = 1;   /* Device under NT or Win2K with pre-open/lfn handle. */
+    }
+
+  /* First, fill the fields which are constant under DOS. */
+  stat_buf->st_uid = getuid();
+  stat_buf->st_gid = getgid();
+  stat_buf->st_nlink = 1;
+#ifndef  NO_ST_BLKSIZE
+  stat_buf->st_blksize = _go32_info_block.size_of_transfer_buffer;
+#endif
+
+  /* If SFT entry for our handle is required and available, we will use it.  */
+  if ( (_djstat_flags & _STAT_NEEDS_SFT) == 0 && sft_idx >= 0)
+    {
+      /* Determine positions of data items in the SFT. */
+      size_t fattr_ofs, name_ofs, ext_ofs, fsize_ofs, fdate_ofs,
+             ftime_ofs, clust_ofs;
+
+      switch (dos_major)
+        {
+          case 2:
+              fattr_ofs  = 2;
+              drv_no     = sft_buf[3] - 1;      /* 1 = 'A' etc. */
+              name_ofs   = 4;
+              ext_ofs    = 0x0b;
+              fsize_ofs  = 0x13;
+              fdate_ofs  = 0x17;
+              ftime_ofs  = 0x19;
+              clust_ofs  = 0x1c;
+              is_remote  = 0;   /* DOS 2.x didn't have remote files */
+              break;
+
+          case 3:
+              fattr_ofs  = 4;
+              drv_no     = sft_buf[5] & 0x3f;
+              if (dos_minor == 0)
+                {
+                  name_ofs = 0x21;
+                  ext_ofs  = 0x29;
+                }
+              else      /* DOS 3.1 - 3.3x */
+                {
+                  name_ofs = 0x20;
+                  ext_ofs  = 0x28;
+                }
+              clust_ofs  = 0x0b;
+              ftime_ofs  = 0x0d;
+              fdate_ofs  = 0x0f;
+              fsize_ofs  = 0x11;
+              break;
+
+          default:      /* DOS 4 and up */
+              fattr_ofs  = 4;
+              drv_no     = sft_buf[5] & 0x3f;
+              clust_ofs  = 0x0b;
+              ftime_ofs  = 0x0d;
+              fdate_ofs  = 0x0f;
+              fsize_ofs  = 0x11;
+              name_ofs   = 0x20;
+              ext_ofs    = 0x28;
+
+        }
+
+      if (is_dev)
+        {
+          /* We have a character device.
+           * We will pretend as if they all reside on a special
+           * drive `@:', which is illegal in DOS, and just happens
+           * to give a neat st_dev (= '@' - 'A') = -1.
+           */
+
+          stat_buf->st_dev = -1;
+#ifdef  HAVE_ST_RDEV
+          stat_buf->st_rdev = -1;
+#endif
+
+          if ( (_djstat_flags & _STAT_INODE) == 0 )
+            {
+              /* Character device names are all at most 8-character long. */
+              short i   = 8;
+              unsigned char *src = sft_buf + name_ofs;
+              char dev_name[16], *dst = dev_name + 7;
+
+              strcpy(dev_name, "@:\\dev\\        "); /* pad with 8 blanks */
+              while (i-- && *src != ' ')             /* copy non-blank chars */
+                *dst++ = *src++;
+
+              stat_buf->st_ino = _invent_inode(dev_name, 0, 0);
+            }
+
+          /* Should we make printer devices write-only here? */
+          stat_buf->st_mode |= (S_IFCHR | READ_ACCESS | WRITE_ACCESS);
+
+          /* We will arrange things so that devices have current time in
+           * the access-time and modified-time fields of struct stat.
+           */
+          stat_buf->st_atime = stat_buf->st_mtime = time(0);
+
+          /* MS-DOS returns the time of boot when _getftime() is called
+           * for character devices, but this is undocumented and
+           * unsupported by DOS clones (e.g. DR-DOS).  It is also
+           * inconsistent with our stat().  Therefore, we will arrange
+           * things so that devices have zero (the beginning of times)
+           * in creation-time field.
+           */
+          dos_ftime = 0;
+          stat_buf->st_ctime = _file_time_stamp(dos_ftime);
+
+          return 0;
+        }
+
+      /* Files are not allowed to fail DOS calls for their time
+       * stamps and size.
+       */
+      else if (have_trusted_values)
+        {
+	  unsigned char *pname = sft_buf + name_ofs;
+
+          /* This is a regular, existing file.  It cannot be a
+           * directory, because DOS won't let us open() a directory.
+           * Each file under MS-DOS is always readable by everyone.
+           */
+          stat_buf->st_mode |= (S_IFREG | READ_ACCESS);
+          
+          /* We will be extra careful in trusting SFT data: it must be
+           * consistent with date, time and size of the file as known
+           * from conventional DOS calls.
+           */
+          sft_fdate = *((unsigned short *)(sft_buf + fdate_ofs));
+          sft_ftime = *((unsigned short *)(sft_buf + ftime_ofs));
+          sft_fsize = *((long *)(sft_buf + fsize_ofs));
+
+	  /* In addition, it seems that 32-bit File Access, at least
+	   * in Windows 95, creates fake SFT entries for some files,
+	   * which have bogus cluster numbers and all-blank file name
+	   * and extension.  (It is unclear to me when exactly are
+	   * these fake SFT entries created.)
+	   * So, in addition, we check the file's name in the SFT to
+	   * be non-blank, since file names in the FCB format cannot
+	   * be all-blank, even on Windows 95.  */
+	  while (pname < sft_buf + name_ofs + 8 + 3 && *pname == ' ')
+	    pname++;
+
+          if (pname < sft_buf + name_ofs + 8 + 3 &&
+	      sft_ftime == trusted_ftime &&
+              sft_fdate == trusted_fdate &&
+              sft_fsize == trusted_fsize)
+            { /* Now we are ready to get the SFT info. */
+              char           sft_extension[4], *dst = sft_extension + 2;
+              unsigned char *src = sft_buf + ext_ofs + 2;
+              int i = 3;
+
+              /* Get the file's extension.  It is held in the SFT entry
+               * as a blank-padded 3-character string without terminating
+               * zero.  Some crazy files have embedded blanks in their
+               * extensions, so only TRAILING blanks are insignificant.
+               */
+              memset(sft_extension, 0, sizeof(sft_extension));;
+              while (*src == ' ' && i--)    /* skip traling blanks */
+                {
+                  dst--; src--;
+                }
+
+              if (i >= 0)
+                while (i--)                 /* move whatever left */
+                  *dst-- = *src--;
+
+              /* Build Unix-style file permission bits. */
+              if ( !(sft_buf[fattr_ofs] & 0x07) ) /* no R, S or H bits set */
+                stat_buf->st_mode |= WRITE_ACCESS;
+
+              /* Execute permission bits.  fstat() cannot be called on
+               * directories under DOS, so only executable programs/batch
+               * files should be considered.
+               */
+              if (_is_executable((const char *)0, fhandle, sft_extension))
+                stat_buf->st_mode |= EXEC_ACCESS;
+
+              /* DOS 4.x and above seems to know about named pipes. */
+              if (dos_major > 3 && (sft_buf[6] & 0x20))
+                stat_buf->st_mode |= S_IFIFO;
+
+              /* Device code. */
+              stat_buf->st_dev = drv_no;
+#ifdef  HAVE_ST_RDEV
+              stat_buf->st_rdev = drv_no;
+#endif
+
+              /* The file's starting cluster number will serve as its
+               * inode number.
+               */
+              if ( (_djstat_flags & _STAT_INODE) == 0 && !is_remote)
+                stat_buf->st_ino = *((unsigned short *)(sft_buf + clust_ofs));
+
+              /* If the cluster number returns zero (e.g., for empty files,
+               * because DOS didn't allocate it a cluster yet) we have to
+               * invent the inode using the file's name.  We will use the
+               * index into the SFT as part of unique identifier for our
+               * file, so a possibility of two files with the same name
+               * but different paths getting the same inode number is
+               * minimized.
+               * If we have a remote file, we invent inode even if there
+               * is a non-zero number in the SFT, because it usually is
+               * bogus (a left-over from last local file handle which used
+               * the same SFT entry).
+               * Note that we invent the inode even if is_remote is -1
+               * (i.e., IOCTL Func 0Ah failed), because that should mean
+               * some network redirector grabs IOCTL functions in an
+               * incompatible way.
+               */
+              if ( (_djstat_flags & _STAT_INODE) == 0 &&
+                   (stat_buf->st_ino == 0 || is_remote))
+                {
+                  static char     name_pat[]   = " :sft-   \\            ";
+                  char name_buf[sizeof(name_pat)];
+                  unsigned char  *src_p        = sft_buf + name_ofs + 7;
+                  char           *dst_p        = name_buf + 17;
+                  int             j            = 8;
+                  char           *name_end;
+                  int             first_digit  = sft_idx / 100;
+                  int             second_digit = (sft_idx - first_digit * 100) / 10;
+                  int             third_digit  = sft_idx - first_digit * 100
+                                                         - second_digit * 10;
+
+                  /* Initialize the name buffer with zeroes, then
+                   * put in the drive letter and ``sft-XXX'', where
+                   * XXX is the index of our file entry in the SFT.
+                   */
+                  strcpy(name_buf, name_pat);
+                  memset(name_buf + 10, 0, sizeof(name_buf) - 10);
+                  name_buf[0] = drv_no + 'A';
+                  name_buf[6] = first_digit  + '0';
+                  name_buf[7] = second_digit + '0';
+                  name_buf[8] = third_digit  + '0';
+
+                  /* Copy filename from SFT entry to local storage.
+                   * It is stored there in the infamous DOS format:
+                   * both name and extension are blank-padded, and no dot.
+                   * We cannot use strcpy, because the name might
+                   * include embedded blanks.  Therefore we move the
+                   * characters from the end towards the beginning.
+                   */
+                  while (*src_p == ' ' && j--)   /* skip traling blanks */
+                    {
+                      dst_p--;
+                      src_p--;
+                    }
+                  name_end = dst_p + 1;
+
+                  if (j >= 0)                  /* move whatever left */
+                    while (j--)
+                      *dst_p-- = *src_p--;
+
+                  /* We've already got the extension.  If it is non-empty,
+                   * insert a dot and copy the extension itself.
+                   */
+                  if (sft_extension[0])
+                    {
+                      *name_end++ = '.';
+                      strcpy(name_end, sft_extension);
+                    }
+                  stat_buf->st_ino =
+                    _invent_inode(name_buf, dos_ftime, sft_fsize);
+                  _djstat_fail_bits |= _STFAIL_HASH;
+                }
+
+              /* Size, date and time. */
+              stat_buf->st_size = sft_fsize;
+              stat_buf->st_atime = stat_buf->st_ctime = stat_buf->st_mtime =
+                _file_time_stamp(dos_ftime);
+
+	      /* Additional time info for LFN platforms.  */
+	      set_fstat_times (fhandle, stat_buf);
+              return 0;
+            }
+
+          _djstat_fail_bits |= _STFAIL_BADSFT;
+
+        }
+
+      /* Regular file, but DOS calls to find its length and time stamp
+       * failed.  This must be an illegal file handle, or something
+       * else very, very funny...
+       */
+      else
+        return -1;    /* errno set by filelength() or getftime() */
+
+    }
+
+  /* Can't get SFT itself or can't find SFT entry belonging to our file.
+   * This is probably unsupported variety of DOS, or other (not-so-
+   * compatible) OS.
+   * For these we supply whatever info we can find by conventional calls.
+   */
+  if (have_trusted_values)
+    {
+      if (is_dev)
+        {
+          if (_djstat_flags & _STAT_INODE)
+            {
+              /* We need the name of the device to invent an inode for it.
+               * We cannot get the REAL name, because SFT info is unavailable.
+               * If IOCTL tells us this is one of the standard devices, we
+               * can make an educated guess.  If not, we will invent inode
+               * with no name.  This will at least ensure that no two calls
+               * accidentally get the same inode number.
+               * We will also pretend devices belong to a special drive
+               * named `@'.
+               */
+              if (dev_info & 0xf)
+                {
+                  char dev_name[16];
+
+                  strcpy(dev_name, "@:\\dev\\");
+                  if (dev_info & 3)         /* either STDIN or STDOUT */
+                    strcat(dev_name, "CON     ");
+                  else if (dev_info & 4)    /* NULL device */
+                    strcat(dev_name, "NUL     ");
+                  else if (dev_info & 8)    /* CLOCK device */
+                    strcat(dev_name, "CLOCK$  ");
+
+                  stat_buf->st_ino = _invent_inode(dev_name, 0, 0);
+                }
+              else
+                stat_buf->st_ino = _invent_inode("", 0, 0);
+
+              _djstat_fail_bits |= _STFAIL_HASH;
+            }
+
+          stat_buf->st_dev = -1;
+#ifdef  HAVE_ST_RDEV
+          stat_buf->st_rdev = -1;
+#endif
+
+          stat_buf->st_mode |= (S_IFCHR | READ_ACCESS | WRITE_ACCESS);
+
+          stat_buf->st_atime = stat_buf->st_mtime = time(0);
+          dos_ftime = 0;
+          stat_buf->st_ctime = _file_time_stamp(dos_ftime);
+        }
+      else
+        {
+          /* Regular file.  The inode will be arbitrary, as we don't have
+           * this file's name.  Sigh...
+           */
+          if ( (_djstat_flags & _STAT_INODE) == 0 )
+            {
+              _djstat_fail_bits |= _STFAIL_HASH;
+              stat_buf->st_ino = _invent_inode("", dos_ftime, trusted_fsize);
+            }
+
+          /* Return the minimum access bits every file has under DOS. */
+          stat_buf->st_mode |= (S_IFREG | READ_ACCESS);
+          if (_djstat_flags & _STAT_ACCESS)
+            _djstat_fail_bits |= _STFAIL_WRITEBIT;
+
+	  /* If we are runing on Windows 9X, NT 4.0 with LFN or 2000 or XP
+	     with LFN is enabled, try harder. Note that we deliberately do
+	     NOT use this call when LFN is disabled, even if we are on
+	     Windows, because then we open the file with function 3Ch, and
+	     such handles aren't supported by 71A6h call we use here.  */
+	  if  (_USE_LFN)
+	    {
+	      __dpmi_regs r;
+
+	      r.x.ax = 0x71a6;	/* file info by handle */
+	      r.x.bx = fhandle;
+	      r.x.ds = __tb >> 4;
+	      r.x.dx = 0;
+	      __dpmi_int(0x21, &r);
+	      if ((r.x.flags & 1) == 0
+		  && (_farpeekl(_dos_ds, __tb) & 0x07) == 0)
+		stat_buf->st_mode |= WRITE_ACCESS; /* no R, S or H bits set */
+	    }
+
+          /* Executables are detected if they have magic numbers.  */
+          if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 &&
+               _is_executable((const char *)0, fhandle, (const char *)0))
+            stat_buf->st_mode |= EXEC_ACCESS;
+
+          /* Lower 6 bits of IOCTL return value give the device number. */
+          stat_buf->st_dev = dev_info & 0x3f;
+#ifdef  HAVE_ST_RDEV
+          stat_buf->st_rdev = dev_info & 0x3f;
+#endif
+
+          /* Novell Netware does not return the drive number in the
+           * lower 6 bits of dev_info.  But we cannot do anything with
+           * that, since any value in these 6 bits could be correct...
+           * In particular, 0 there means the A: drive.
+           */
+          stat_buf->st_size  = trusted_fsize;
+          stat_buf->st_atime = stat_buf->st_ctime = stat_buf->st_mtime =
+            _file_time_stamp(dos_ftime);
+
+	  /* Additional time info for LFN platforms.  */
+	  set_fstat_times (fhandle, stat_buf);
+        }
+      return 0;
+    }
+
+  /* Don't have even values from conventional DOS calls.
+   * Give up completely on this funny handle.  ERRNO is already
+   * set by filelength() and/or getftime().
+   */
+  else
+    return -1;
+}
+
+/*
+ * Main entry point.  This is a substitute for library fstat() function.
+ */
+
+int
+libsupp_fstat_2_03(int handle, struct stat *statbuf)
+{
+  int            e = errno;     /* save previous value of errno */
+  __FSEXT_Function* func;
+  int rv;
+
+  if (!statbuf)
+    {
+      errno = EFAULT;
+      return -1;
+    }
+
+  /* see if this is file system extension file */
+  func = __FSEXT_get_function(handle);
+  if (func && __FSEXT_func_wrapper(func, __FSEXT_fstat, &rv, handle, statbuf))
+    {
+       return rv;
+    }
+
+  /* See if this is a file descriptor for a directory. If so, just
+   * use a normal stat call. */
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+    {
+      const char *filename = libsupp___get_fd_name(handle);
+
+      if (filename)
+	return libsupp_stat_2_03(filename, statbuf);
+    }
+
+  if (fstat_assist(handle, statbuf) == -1)
+    {
+      return -1;      /* already have ERRNO set by fstat_assist() */
+    }
+  else
+    {
+      errno = e;
+      return 0;
+    }
+}
+
+#ifdef  TEST
+
+#include <stdio.h>
+#include <fcntl.h>
+
+unsigned short _djstat_flags = 0;
+
+int main(int argc, char *argv[])
+{
+  struct stat stat_buf;
+  int fd = -1;
+  int i;
+  char *endp;
+
+  argc--; argv++;
+  _djstat_flags = (unsigned short)strtoul(*argv, &endp, 0);
+
+  /* Display 4 standard handles which are already open. */
+  for (i = 0; i <= 4; i++)
+    {
+      fstat(i, &stat_buf);
+      fprintf(stderr, "handle-%d: %d %6u %o %d %d %ld %lu %s", i,
+              stat_buf.st_dev,
+              (unsigned)stat_buf.st_ino,
+              stat_buf.st_mode,
+              stat_buf.st_nlink,
+              stat_buf.st_uid,
+              (long)stat_buf.st_size,
+              (unsigned long)stat_buf.st_mtime,
+              ctime(&stat_buf.st_mtime));
+      _djstat_describe_lossage(stderr);
+    }
+
+  /* Now call fstat() for each command-line argument. */
+  while (++argv, --argc)
+    {
+      if (fd >= 19)
+        close(fd);
+      fd = open(*argv, O_RDONLY);
+      if (fd != -1 && !fstat(fd, &stat_buf))
+        {
+          fprintf(stderr, "%s (%d): %d %6u %o %d %d %ld %lu %s", *argv, fd,
+                  stat_buf.st_dev,
+                  (unsigned)stat_buf.st_ino,
+                  stat_buf.st_mode,
+                  stat_buf.st_nlink,
+                  stat_buf.st_uid,
+                  (long)stat_buf.st_size,
+                  (unsigned long)stat_buf.st_mtime,
+                  ctime(&stat_buf.st_mtime));
+	  fprintf (stderr, "\t\t\tTimes: %lu %lu\n",
+		   (unsigned long)stat_buf.st_atime,
+		   (unsigned long)stat_buf.st_ctime);
+          _djstat_describe_lossage(stderr);
+        }
+      else
+        {
+          fputs(*argv, stderr);
+          perror(": failed to open/fstat");
+          _djstat_describe_lossage(stderr);
+        }
+    }
+  return 0;
+}
+
+#endif  /* TEST */
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/fstat.c libsupp-6.2/src/posix/sys/stat/fstat.c
--- libsupp-6.2.orig/src/posix/sys/stat/fstat.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/fstat.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
@@ -108,22 +109,24 @@
 #include <fcntl.h>
 #include <dos.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <limits.h>
-#include <libc/fd_props.h>
 #include <libc/getdinfo.h>
 
 #include <dpmi.h>
 #include <go32.h>
 #include <libc/farptrgs.h>
 #include <libc/bss.h>
 #include <libc/symlink.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include "xstat.h"
 
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
 /* Should we bother about executables at all? */
 #define _STAT_EXECBIT       (_STAT_EXEC_EXT | _STAT_EXEC_MAGIC)
 
 /* Should we bother about any access bits?  */
 #define _STAT_ACCESS        (_STAT_WRITEBIT | _STAT_EXECBIT)
@@ -436,11 +439,11 @@ fstat_assist(int fhandle, struct stat *s
   stat_buf->st_gid = getgid();
   stat_buf->st_nlink = 1;
 
   /* Get the file name from the file descriptor properties (fd_props),
    * if possible, and fix it up. */
-  fd_name = __get_fd_name(fhandle);
+  fd_name = libsupp___get_fd_name(fhandle);
   if (fd_name != NULL)
     filename = fd_name;
 
   /* Get the block size for the device associated with `fhandle'. */
 #ifndef  NO_ST_BLKSIZE
@@ -895,11 +898,11 @@ fstat_assist(int fhandle, struct stat *s
 /*
  * Main entry point.  This is a substitute for library fstat() function.
  */
 
 int
-fstat(int handle, struct stat *statbuf)
+libsupp_fstat(int handle, struct stat *statbuf)
 {
   int            e = errno;     /* save previous value of errno */
   __FSEXT_Function* func;
   int rv;
 
@@ -916,16 +919,16 @@ fstat(int handle, struct stat *statbuf)
        return rv;
     }
 
   /* See if this is a file descriptor for a directory. If so, just
    * use a normal stat call. */
-  if (__get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
     {
-      const char *filename = __get_fd_name(handle);
+      const char *filename = libsupp___get_fd_name(handle);
 
       if (filename)
-	return stat(filename, statbuf);
+	return libsupp_stat(filename, statbuf);
     }
 
   if (fstat_assist(handle, statbuf) == -1)
     {
       return -1;      /* already have ERRNO set by fstat_assist() */
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/lfilelen.c libsupp-6.2/src/posix/sys/stat/lfilelen.c
--- libsupp-6.2.orig/src/posix/sys/stat/lfilelen.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/lfilelen.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* This is file LFILELEN.C */
 /*
  * Copyright (c) 1994 Eli Zaretskii <eliz@is.elta.co.il>
  *
@@ -16,12 +17,15 @@
 #include <libc/farptrgs.h>
 #include <dos.h>
 #include <fcntl.h>
 #include <io.h>
 
+#include "libsupp.h"
+
+
 long long
-lfilelength(int fhandle)
+libsupp_lfilelength(int fhandle)
 {
   __dpmi_regs    regs;
   unsigned short fpos_high, fpos_low;
   long long      retval;
 
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/lstat.c libsupp-6.2/src/posix/sys/stat/lstat.c
--- libsupp-6.2.orig/src/posix/sys/stat/lstat.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/lstat.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
@@ -113,20 +114,22 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dos.h>
 #include <dir.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <dpmi.h>
 #include <go32.h>
 #include <libc/farptrgs.h>
 #include <libc/bss.h>
 #include <libc/dosio.h>
 #include <libc/symlink.h>
 
 #include "xstat.h"
 
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
 int __getdisk(void);
 int __findfirst(const char *, struct ffblk *, int);
 int __findnext(struct ffblk *);
 
 #define ALL_FILES   (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_DIREC|FA_ARCH)
@@ -456,11 +459,11 @@ stat_assist(const char *path, struct sta
   /* Make the path explicit.  This makes the rest of our job much
      easier by getting rid of some constructs which, if present,
      confuse `_truename' and/or `findfirst'.  In particular, it
      deletes trailing slashes, makes "d:" explicit, and allows us
      to make an illusion of having a ".." entry in root directories.  */
-  _fixpath (path, pathname);
+  libsupp__fixpath (path, pathname);
 
   /* Get the block size for the device associated with `pathname'. */
 #ifndef  NO_ST_BLKSIZE
   statbuf->st_blksize = _get_cached_blksize(pathname);
   if (statbuf->st_blksize == -1)
@@ -895,11 +898,11 @@ stat_assist(const char *path, struct sta
 
 /* Main entry point.  This is library lstat() function.
  */
 
 int
-lstat(const char *path, struct stat *statbuf)
+libsupp_lstat(const char *path, struct stat *statbuf)
 {
   int  e = errno;
   int  pathlen, ret;
   char real_path[FILENAME_MAX];
 
@@ -959,22 +962,22 @@ main(int argc, char *argv[])
     {
       fprintf (stderr, "Usage: %s <_djstat_flags> <file...>\n", argv[0]);
       return (EXIT_FAILURE);
     }
 
-  if (lstat(*argv, &stat_buf) != 0)
+  if (libsupp_lstat(*argv, &stat_buf) != 0)
     perror ("lstat failed on argv[0]");
   else
     fprintf(stderr, "DOS %d.%d (%s)\n", _osmajor, _osminor, _os_flavor);
   argc--; argv++;
 
   _djstat_flags = (unsigned short)strtoul(*argv, &endp, 0);
   argc--; argv++;
 
   while (argc--)
     {
-      if (!lstat(*argv, &stat_buf))
+      if (!libsupp_lstat(*argv, &stat_buf))
         {
           fprintf(stderr, "%s: %d %6u %o %d %d %ld %lu %s", *argv,
                   stat_buf.st_dev,
                   (unsigned)stat_buf.st_ino,
                   stat_buf.st_mode,
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/stat-2.03.c libsupp-6.2/src/posix/sys/stat/stat-2.03.c
--- libsupp-6.2.orig/src/posix/sys/stat/stat-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/stat-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,972 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+/* This is file STAT.C */
+/*
+ *   Almost a 100% U**X-compatible stat() substitute.
+ *
+ * Usage:
+ *
+ *   That's easy: put this into libc.a, then just call stat() as usual.
+ *
+ * Rationale:
+ *
+ *   Many Unix-born programs make heavy use of stat() library
+ *   function to make decisions on files' equality, size, access
+ *   attributes etc.  In the MS-DOS environment, many implementations
+ *   of stat() are crippled, because DOS makes it very hard to get to
+ *   certain pieces of information about files and directories.  Thus
+ *   porting a program to DOS is usually an exercise in #ifdef'ing.
+ *   This implementation facilitates porting Unix programs to MS-DOS
+ *   by providing stat() which is much more Unix-compatible than those
+ *   of most DOS-based C compilers (e.g., Borland's).
+ *   Specifically, the following issues are taken care of:
+ *
+ *      1. This stat() doesn't fail for root directories, returning
+ *         valid information.
+ *      2. Directory size is not reported zero; the number of used
+ *         directory entries multiplied by entry size is returned instead.
+ *      3. Mode bits are set for all 3 groups (user, group, other).
+ *      4. Directories are NOT reported read-only, unless one of R, H or S
+ *         attributes is set.
+ *      5. Directories have their execute bit set, as they do under Unix.
+ *      6. Device names (such as /dev/con, lpt1, aux etc.) are treated as
+ *         if they were on a special drive called `@:' (st_dev = -1).
+ *         The "character special" mode bit is set for these devices.
+ *      7. The inode number (st_ino) is taken from the starting cluster
+ *         number of the file.  If the cluster number is unavailable, it
+ *         is invented using the file's name in a manner that minimizes
+ *         the possibility of inventing an inode which already belongs
+ *         to another file.  See below for details.
+ *      8. Executable files are found based on files' extensions and
+ *         magic numbers present at their beginning, and their execute
+ *         bits are set.
+ *
+ *   Lossage:
+ *
+ *      Beautiful as the above sounds, this implementation does fail
+ *      under certain circumstances.  The following is a list of known
+ *      problems:
+ *
+ *      1. The time fields for a root directory cannot be obtained, so
+ *         they are set to the beginning of the Epoch.
+ *      2. For files which reside on networked drives, the inode number
+ *         is invented, because network redirectors usually do not
+ *         bring that info with them.  This is not a total lossage, but
+ *         it could get us a different inode for each program run.
+ *      3. Empty files do not have a starting cluster number, because
+ *         DOS doesn't allocate one until you actually write something
+ *         to a file.  For these the inode is also invented.
+ *      4. If the st_ino field is a 16 bit number, the invented inode
+ *         numbers are from 65535 and down, assuming that most disks have
+ *         unused portions near their end.  Valid cluster numbers are 16-bit
+ *         unsigned integers, so a possibility of a clash exists, although
+ *         the last 80 or more cluster numbers are unused on all drives
+ *         I've seen.  If the st_ino is 32 bit, then invented inodes are
+ *         all greater than 64k, which totally eliminates a possibility
+ *         of a clash with an actual cluster number.
+ *      5. The method of computing directory size is an approximation:
+ *         a directory might consume much more space, if it has many
+ *         deleted entries.  Still, this is a close approximation, and
+ *         it does follow the logic of reporting size for a regular file:
+ *         only the actually used space is returned.
+ *      6. As this implementation relies heavily on undocumented DOS
+ *         features, it will fail to get actual file info in environments
+ *         other than native DOS, such as DR-DOS, OS/2 etc.  For these,
+ *         the function will return whatever info is available with
+ *         conventional DOS calls, which is no less than any other
+ *         implementation could do.  This stat() might also fail for
+ *         future DOS versions, if the layout of internal DOS data
+ *         area is changed; however, this seems unlikely.
+ *
+ * Copyright (c) 1994-96 Eli Zaretskii <eliz@is.elta.co.il>
+ *
+ * This software may be used freely so long as this copyright notice is
+ * left intact.  There is no warranty on this software.
+ *
+ */
+
+/*
+ * Tested with DJGPP port of GNU C compiler, versions 1.11maint5 and 1.12,
+ * under MS-DOS 3.3, 4.01, 5.0, 6.20 (with and without DoubleSpace) and
+ * with networked drives under XFS 1.86, Novell Netware 3.22, and
+ * TSoft NFS 0.24Beta.
+ *
+ */
+
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dos.h>
+#include <dir.h>
+#include <sys/fsext.h>
+#include <dpmi.h>
+#include <go32.h>
+#include <libc/farptrgs.h>
+#include <libc/bss.h>
+#include <libc/dosio.h>
+
+#include "xstat.h"
+
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+
+int __getdisk(void);
+int __findfirst(const char *, struct ffblk *, int);
+int __findnext(struct ffblk *);
+
+int  libsupp_stat_2_03(const char *_path, struct stat *_statbuf);
+void libsupp__fixpath_2_03(const char *_in, char *_out);
+
+#define ALL_FILES   (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_DIREC|FA_ARCH)
+
+#define _STAT_INODE         1   /* should we bother getting inode numbers? */
+#define _STAT_EXEC_EXT      2   /* get execute bits from file extension? */
+#define _STAT_EXEC_MAGIC    4   /* get execute bits from magic signature? */
+#define _STAT_DIRSIZE       8   /* compute directory size? */
+#define _STAT_ROOT_TIME  0x10   /* try to get root dir time stamp? */
+#define _STAT_WRITEBIT   0x20   /* fstat() needs write bit? */
+
+/* Should we bother about executables at all? */
+#define _STAT_EXECBIT       (_STAT_EXEC_EXT | _STAT_EXEC_MAGIC)
+
+/* The structure of the full directory entry.  This is the 32-byte
+   record present for each file/subdirectory in a DOS directory.
+   Although the ``packed'' attribute seems to be unnecessary, I use
+   it to be sure it will still work for future versions of GCC.  */
+
+struct full_dirent {
+  char           fname[8];
+  char           fext[3];
+  unsigned char  fattr;
+  unsigned char  freserved[10];
+  unsigned short ftime;
+  unsigned short fdate;
+  unsigned short fcluster;
+  unsigned int   fsize;
+}
+__attribute__ ((packed));
+
+
+/* Static variables to speed up SDA DOS Swappable Data Area access on
+   subsequent calls.  */
+
+/* The count of number of SDA's we have.  It is more than 1 for DOS
+   4.x only.  If it has a value of 0, the function init_dirent_table()
+   will be called to compute the addresses where we are to look for
+   directory entry of our file.  A value of -1 means this method is
+   unsupported for this version of DOS.  */
+static int  dirent_count;
+
+/* The table of places to look for our directory entry.
+   Each entry in the table is a linear offset from the beginning of
+   conventional memory which points to a particular location within
+   one of the SDA's, where the entry of a file being stat()'ed could
+   appear.  The offsets are computed once (when the routine is first
+   called) and then reused for other calls.  The actual storage for
+   the table is malloc()'ed when this function is first called.  */
+static unsigned int * dirent_table;
+
+/* When we have only one SDA, this is where its only place to look for
+   directory entry is stored.  */
+static unsigned int   dirent_place;
+
+/* This holds the fail bits from the last call to init_dirent_table(),
+   so we can return them every time get_inode_from_sda() is called.  */
+static unsigned short init_dirent_table_bits;
+
+/* Holds the last seen value of __bss_count, to be safe for
+   restarted programs (emacs).  */
+static int stat_count = -1;
+
+/*
+ * Parts of the following code is derived from file DOSSWAP.C,
+ * which came with ``Undocumented DOS'', 1st edition.
+ */
+
+/* Compute table of pointers to look for directory entry of a file.  */
+static int
+init_dirent_table (void)
+{
+  short          get_sda_func;
+  unsigned short dirent_offset;
+  unsigned short true_dos_version;
+  unsigned short dos_major, dos_minor;
+  __dpmi_regs    regs;
+
+  if (dirent_count == -1)     /* we already tried and found we can't */
+    return 0;
+
+  /* Compute INT 21h function number and offset of directory entry
+     from start of SDA.  These depend on the DOS version.
+     We need exact knowledge about DOS internals, so we need the
+     TRUE DOS version (not the simulated one by SETVER), if that's
+     available.  */
+  true_dos_version = _get_dos_version(1);
+  dos_major = true_dos_version >> 8;
+  dos_minor = true_dos_version & 0xff;
+
+  if ((dos_major == 3) && (dos_minor >= 10))
+    {
+      get_sda_func  = 0x5d06;
+      dirent_offset = 0x1a7;
+    }
+  else if (dos_major == 4)
+    {
+      /* According to ``Undocumented DOS, 2nd edition'', I could have
+         used 5d06 here, as for DOS 5 and above, but I like to be
+         defensive.  In fact, the above book itself uses 5d0b, contrary
+         to its own recommendation.  */
+      get_sda_func  = 0x5d0b;
+      dirent_offset = 0x1b3;
+    }
+  else if (dos_major >= 5)
+    {
+      get_sda_func  = 0x5d06;
+      dirent_offset = 0x1b3;
+    }
+  else
+    {
+      _djstat_fail_bits |= _STFAIL_OSVER;
+      dirent_count = -1;
+      return 0;
+    }
+
+  _djstat_fail_bits &= ~_STFAIL_OSVER;  /* version is OK */
+
+  /* Get the pointer to SDA by calling undocumented function 5dh of INT 21. */
+  regs.x.ax = get_sda_func;
+  __dpmi_int(0x21, &regs);
+  if (regs.x.flags & 1)
+    {
+      _djstat_fail_bits |= _STFAIL_SDA;
+      dirent_count = -1;      /* if the call failed, never try this later */
+      return 0;
+    }
+
+  _djstat_fail_bits &= ~_STFAIL_SDA;    /* Get SDA succeeded */
+
+  /* DOS 4.x might have several SDA's, which means we might have more
+     than one place to look into.  (It is typical of DOS 4 to complicate
+     things.)
+     Compute all the possible addresses where we will have to look.  */
+  if (dos_major == 4)
+    {
+      /* The pointer returned by INT 21h, AX=5D0b points to a header
+         which holds a number of SDA's and then an array of that number
+         of records each one of which includes address of an SDA (DWORD)
+         and its length and type (encoded in a WORD).
+         While walking this list of SDA's, we add to each pointer the
+         offset of directory entry and stash the resulting address in
+         our table for later use.  */
+
+      int  sda_list_walker = MK_FOFF(regs.x.ds, regs.x.si);
+      int  i;
+      int *tbl;
+
+      dirent_count = _farpeekw(_dos_ds, sda_list_walker); /* number of SDA's */
+
+      /* Allocate storage for table.  */
+      dirent_table = (unsigned *)malloc(dirent_count*sizeof(int));
+      tbl = (int *) dirent_table;
+      if (!dirent_table)
+        {
+          /* If malloc() failed, maybe later it will succeed, so don't
+             store -1 in dirent_count.  */
+          dirent_count = 0;
+          _djstat_fail_bits |= _STFAIL_DCOUNT;
+          return 0;
+        }
+
+      memset(dirent_table, 0, dirent_count*sizeof(int));
+      _djstat_fail_bits &= ~_STFAIL_DCOUNT; /* dirent_count seems OK */
+
+      /* Walk the array of pointers, computing addresses of directory
+         entries and stashing them in our table.  */
+      _farsetsel(_dos_ds);
+      for (i = dirent_count, sda_list_walker += 2; i--; sda_list_walker += 6)
+        {
+          int            sda_start = _farnspeekl(sda_list_walker);
+          unsigned short sda_len   = _farnspeekw(sda_list_walker + 4) & 0x7fff;
+
+          /* Let's be defensive here: if this SDA is too short to have
+             place for directory entry, we won't use it.  */
+          if (sda_len > dirent_offset)
+            *tbl++ = sda_start + dirent_offset;
+          else
+            dirent_count--;
+        }
+    }
+
+  /* DOS 3.1 and 5.0 or later.  We have only one SDA pointed to by
+     whatever INT 21h, AH=5d returns.  */
+  else
+    {
+      dirent_count = 1;
+      dirent_place = MK_FOFF(regs.x.ds, regs.x.si) + dirent_offset;
+      dirent_table = &dirent_place;
+    }
+
+  return 1;
+}
+
+/* Get inode number by searching DOS Swappable Data Area.
+   The entire directory entry for a file found by FindFirst/FindNext
+   appears at a certain (version-dependent) offset in the SDA after
+   one of those function is called.
+   Should be called immediately after calling DOS FindFirst function,
+   before the info is overwritten by somebody who calls it again.  */
+static unsigned int
+get_inode_from_sda(const char *mybasename)
+{
+  int            count          = dirent_count;
+  unsigned int * dirent_p       = dirent_table;
+  unsigned short dos_mem_base   = _dos_ds;
+  unsigned short our_mem_base   = _my_ds();
+  char  * dot                   = strchr(mybasename, '.');
+  size_t  total_len             = strlen(mybasename);
+  int     name_len;
+  int     ext_len;
+  int     cluster_offset        = offsetof(struct full_dirent, fcluster);
+
+  if( dot )
+    {
+      name_len = dot - mybasename;
+      ext_len = total_len - name_len - 1;
+    }
+  else
+    {
+      name_len = total_len;
+      ext_len = 0;
+    }
+
+  /* Restore failure bits set by last call to init_dirent_table(), so
+     they will be reported as if it were called now.  */
+  _djstat_fail_bits |= init_dirent_table_bits;
+
+  /* Force reinitialization in restarted programs (emacs).  */
+  if (stat_count != __bss_count)
+    {
+      stat_count = __bss_count;
+      dirent_count = 0;
+    }
+
+  /* Initialize the table of SDA entries where we are to look for
+     our file.  */
+  if (!dirent_count && !init_dirent_table())
+    {
+      /* Don't save the truename failure bit.  */
+      init_dirent_table_bits = (_djstat_fail_bits & ~_STFAIL_TRUENAME);
+      return 0;
+    }
+  init_dirent_table_bits = (_djstat_fail_bits & ~_STFAIL_TRUENAME);
+  if (dirent_count == -1)
+    return 0;
+
+  count = dirent_count;
+  dirent_p = dirent_table;
+
+  _farsetsel(dos_mem_base);
+
+  /* This is DOS 4.x lossage: this loop might execute many times.
+     For other DOS versions it is executed exactly once.  */
+  while (count--)
+    {
+      unsigned int  src_address = *dirent_p;
+      char          cmp_buf[sizeof(struct full_dirent)];
+
+      /* Copy the directory entry from the SDA to local storage.
+         The filename is stored there in infamous DOS format: name and
+         extension blank-padded to 8/3 characters, no dot between them.  */
+      movedata(dos_mem_base, src_address, our_mem_base, (unsigned int)cmp_buf,
+               sizeof(struct full_dirent));
+
+      /* If this is the filename we are looking for, return
+         its starting cluster. */
+      if (!strncmp(cmp_buf, mybasename, name_len) &&
+          (ext_len == 0 || !strncmp(cmp_buf + 8, dot + 1, ext_len)))
+        return (unsigned int)_farnspeekw(*dirent_p + cluster_offset);
+
+      /* This is not our file.  Search more, if more addresses left. */
+      dirent_p++;
+    }
+
+  /* If not found, give up.  */
+  _djstat_fail_bits |= _STFAIL_BADSDA;
+  return 0;
+}
+
+
+/* Get the number of the first cluster of PATHNAME using
+   the IOCTL call Int 21h/AX=440Dh/CX=0871h, if that call
+   is supported by the OS.  Return the cluster number, or
+   a negative number if this service isn't supported.  */
+
+static int
+_ioctl_get_first_cluster(const char *pathname)
+{
+  __dpmi_regs r;
+
+  /* See if the IOCTL GetFirstCluster call is supported.  */
+  r.x.ax = 0x4411;	       /* query generic IOCTL capability by drive */
+  r.h.bl = pathname[0] & 0x1f; /* drive number (1=A:) */
+  r.x.cx = 0x871;
+  __dpmi_int(0x21, &r);
+  if ((r.x.flags & 1) == 0 && r.x.ax == 0)
+    {
+      r.x.ax = 0x440d;	       /* Generic IOCTL */
+      r.x.cx = 0x0871;	       /* category code 08h, minor code 71h */
+      r.x.bx = 1;	       /* pathname uses current OEM character set */
+      r.x.ds = __tb >> 4;
+      r.x.dx = __tb & 0x0f;
+      _put_path(pathname);
+      __dpmi_int(0x21, &r);
+      if ((r.x.flags & 1) == 0)
+	return ( ((int)r.x.dx << 16) + r.x.ax );
+    }
+  return -1;
+}
+
+static char blanks_8[] = "        ";
+
+static int
+stat_assist(const char *path, struct stat *statbuf)
+{
+  struct   ffblk ff_blk;
+  char     canon_path[MAX_TRUE_NAME];
+  char     pathname[MAX_TRUE_NAME];
+  short    drv_no;
+  unsigned dos_ftime;
+
+  _djstat_fail_bits = 0;
+
+  memset(statbuf, 0, sizeof(struct stat));
+  memset(&dos_ftime, 0, sizeof(dos_ftime));
+
+  /* Fields which are constant under DOS.  */
+  statbuf->st_uid     = getuid();
+  statbuf->st_gid     = getgid();
+  statbuf->st_nlink   = 1;
+#ifndef  NO_ST_BLKSIZE
+  statbuf->st_blksize = _go32_info_block.size_of_transfer_buffer;
+#endif
+
+  /* Make the path explicit.  This makes the rest of our job much
+     easier by getting rid of some constructs which, if present,
+     confuse `_truename' and/or `findfirst'.  In particular, it
+     deletes trailing slashes, makes "d:" explicit, and allows us
+     to make an illusion of having a ".." entry in root directories.  */
+  libsupp__fixpath_2_03 (path, pathname);
+
+  /* Get the drive number.  It is always explicit, since we
+     called `_fixpath' on the original pathname.  */
+  drv_no = toupper((unsigned char)pathname[0]) - 'A';
+
+  /* Produce canonical pathname, with all the defaults resolved and
+     all redundant parts removed.  This calls undocumented DOS
+     function 60h.  */
+  if (_truename(path, canon_path) || _truename(pathname, canon_path))
+    {
+      /* Detect character device names which must be treated specially.
+         We could simply call FindFirst and test the 6th bit, but some
+         versions of DOS have trouble with this (see Ralph Brown's
+         Interrupt List, ``214E'', under `Bugs').  Instead we use
+         truename() which calls INT 21/AX=6000H.  For character devices
+         it returns X:/DEVNAME, where ``X'' is the current drive letter
+         (note the FORWARD slash!).  E.g., for CON or \dev\con it will
+         return C:/CON.
+         We will pretend that devices all reside on a special drive
+         called `@', which corresponds to st_dev = -1.  This is because
+         these devices have no files, and we must invent inode numbers
+         for them; this scheme allows to lower a risk of clash between
+         invented inode and one which belongs to a real file.  This is
+         also compatible with what our fstat() does.
+      */
+    char_dev:
+      if (canon_path[2] == '/')
+        {
+          char dev_name[9];     /* devices are at most 8 characters long */
+
+          strncpy(dev_name, canon_path + 3, 8); /* the name without `X:/' */
+          dev_name[8] = '\0';
+          strcpy(canon_path, "@:\\dev\\");
+          strcat(canon_path, dev_name);
+          strncat(canon_path, blanks_8, 8 - strlen(dev_name)); /* blank-pad */
+          canon_path[15] = '\0';   /* ensure zero-termination */
+
+          /* Invent inode */
+          statbuf->st_ino = _invent_inode(canon_path, 0, 0);
+
+          /* Device code. */
+          statbuf->st_dev = -1;
+#ifdef  HAVE_ST_RDEV
+          statbuf->st_rdev = -1;
+#endif
+
+          /* Set mode bits, including character special bit.
+             Should we treat printer devices as write-only?  */
+          statbuf->st_mode |= (S_IFCHR | READ_ACCESS | WRITE_ACCESS);
+
+          /* We will arrange things so that devices have current time in
+             the access-time and modified-time fields of struct stat, and
+             zero (the beginning of times) in creation-time field.  This
+             is consistent with what DOS FindFirst function returns for
+             character device names (if it succeeds--see above).  */
+          statbuf->st_atime = statbuf->st_mtime = time(0);
+          statbuf->st_ctime = _file_time_stamp(dos_ftime);
+
+          return 0;
+        }
+      else if (canon_path[0] >= 'A' && canon_path[0] <= 'z' &&
+               canon_path[1] == ':' && canon_path[2] == '\\')
+        {
+          /* _truename() returned a name with a drive letter.  (This is
+             always so for local drives, but some network redirectors
+             also do this.)  We will take this to be the TRUE drive
+             letter, because _truename() knows about SUBST and JOIN.
+             If the canonicalized path returns in the UNC form (which
+             means the drive is remote), it cannot be SUBSTed or JOINed,
+             because SUBST.EXE and JOIN.EXE won't let you do it; so, for
+             these cases, there is no problem in believing the drive
+             number we've got from the original path (or is there?).  */
+          drv_no = toupper((unsigned char)canon_path[0]) - 'A';
+        }
+    }
+  else
+    {
+      /* _truename() failed.  (This really shouldn't happen, but who knows?)
+         At least uppercase all letters, convert forward slashes to backward
+         ones, and pray... */
+      register const char *src = pathname;
+      register       char *dst = canon_path;
+
+      while ( (*dst = (*src > 'a' && *src < 'z'
+                       ? *src++ - ('a' - 'A')
+                       : *src++)) != '\0')
+        {
+          if (*dst == '/')
+            *dst = '\\';
+          dst++;
+        }
+
+      _djstat_fail_bits |= _STFAIL_TRUENAME;
+    }
+
+  /* Call DOS FindFirst function, which will bring us most of the info.  */
+  if (!__findfirst(pathname, &ff_blk, ALL_FILES))
+    {
+      /* Time fields. */
+      dos_ftime =
+        ( (unsigned short)ff_blk.ff_fdate << 16 ) +
+          (unsigned short)ff_blk.ff_ftime;
+
+      /* If the IOCTL GetFirstCluster call is available, try it first.  */
+      if ( (_djstat_flags & _STAT_INODE) == 0
+	   && (statbuf->st_ino = _ioctl_get_first_cluster(pathname)) <= 0)
+        {
+
+          /* For networked drives, don't believe the starting cluster
+             that the network redirector feeds us; always invent inode.
+             This is because network redirectors leave bogus values there,
+             and we don't have enough info to decide if the starting
+             cluster value is real or just a left-over from previous call.
+             For local files, try first using DOS SDA to get the inode from
+             the file's starting cluster number; if that fails, invent inode.
+             Note that the if clause below tests for non-zero value returned
+             by is_remote_drive(), which includes possible failure (-1).
+             This is because findfirst() already succeeded for our pathname,
+             and therefore the drive is a legal one; the only possibility that
+             is_remote_drive() fails is that some network redirector takes
+             over IOCTL functions in an incompatible way, which means the
+             drive is remote.  QED.  */
+          if (statbuf->st_ino == 0  /* don't try SDA if IOCTL call succeeded */
+	      || _is_remote_drive(drv_no)
+              || (statbuf->st_ino = get_inode_from_sda(ff_blk.ff_name)) == 0)
+            {
+              _djstat_fail_bits |= _STFAIL_HASH;
+              statbuf->st_ino =
+                _invent_inode(canon_path, dos_ftime, ff_blk.ff_fsize);
+            }
+	  else if (toupper ((unsigned char)canon_path[0]) != toupper ((unsigned char)pathname[0])
+		   && canon_path[1] == ':'
+		   && canon_path[2] == '\\'
+		   && canon_path[3] == '\0')
+	    /* The starting cluster in SDA for the root of JOINed drive
+	       actually belongs to the directory where that drive is
+	       ``mounted''.  This can potentially be the cluster of
+	       another file on the JOINed drive.  We cannot allow this.  */
+	    statbuf->st_ino = 1;
+        }
+
+      /* File size. */
+      statbuf->st_size = ff_blk.ff_fsize;
+
+      /* Mode bits. */
+      statbuf->st_mode |= READ_ACCESS;
+      if ( !(ff_blk.ff_attrib & 0x07) )  /* no R, H or S bits set */
+        statbuf->st_mode |= WRITE_ACCESS;
+
+      /* Sometimes `_truename' doesn't return X:/FOO for character
+	 devices.  However, FindFirst returns attribute 40h for them.  */
+      if (ff_blk.ff_attrib == 0x40)
+	{
+	  size_t cplen = strlen (canon_path);
+	  char *pslash = canon_path + cplen - 1;
+
+	  while (pslash > canon_path + 2 && *pslash != '\\')
+	    pslash--;
+
+	  /* Force it into X:/FOO form.  */
+	  if (canon_path[1] == ':')
+	    {
+	      if (pslash > canon_path + 2)
+		memmove (canon_path + 2, pslash,
+			 cplen - (pslash - canon_path) + 1);
+	      canon_path[2] = '/';
+	      goto char_dev;
+	    }
+	}
+
+      /* Directories should have Execute bits set. */
+      if (ff_blk.ff_attrib & 0x10)
+        statbuf->st_mode |= (S_IFDIR | EXEC_ACCESS);
+
+      else
+        {
+          /* This is a regular file. */
+          char *extension  = strrchr(ff_blk.ff_name, '.');
+
+          /* Set regular file bit.  */
+          statbuf->st_mode |= S_IFREG;
+
+          if ((_djstat_flags & _STAT_EXECBIT) != _STAT_EXECBIT)
+            {
+              /* Set execute bits based on file's extension and
+                 first 2 bytes. */
+              if (extension)
+                extension++;    /* get past the dot */
+              if (_is_executable(pathname, -1, extension))
+                statbuf->st_mode |= EXEC_ACCESS;
+            }
+        }
+    }
+  else if ((_djstat_fail_bits & _STFAIL_TRUENAME))
+    {
+      /* If both `findfirst' and `_truename' failed, this must
+	 be a non-existent file or an illegal/inaccessible drive.  */
+      if (errno == ENMFILE)
+	errno = ENODEV;
+      return -1;
+    }
+  else if (pathname[3] == '\0')
+    {
+      /* Detect root directories.  These are special because, unlike
+	 subdirectories, FindFirst fails for them.  We look at PATHNAME
+	 because a network redirector could tweak what `_truename'
+	 returns to be utterly unrecognizable as root directory.  PATHNAME
+	 always begins with "d:/", so it is root if PATHNAME[3] = 0.  */
+
+      /* Mode bits. */
+      statbuf->st_mode |= (S_IFDIR|READ_ACCESS|WRITE_ACCESS|EXEC_ACCESS);
+
+      /* Root directory will have an inode = 1.  Valid cluster numbers
+         for real files under DOS start with 2. */
+      statbuf->st_ino = 1;
+
+      /* Simulate zero size.  This is what FindFirst returns for every
+         sub-directory.  Later we might compute a better approximation
+         (see below).  */
+      ff_blk.ff_fsize = 0L;
+
+      /* The time fields are left to be zero, unless the user wants us
+         to try harder.  In the latter case, we check if the root has
+         a volume label entry, and use its time if it has. */
+
+      if ( (_djstat_flags & _STAT_ROOT_TIME) == 0 )
+	{
+	  char buf[7];
+	  int volume_found = 0;
+
+	  strcpy(buf, pathname);
+	  strcat(buf, "*.*");
+	  /* Floppies written by Windows 9X and NT include entries
+	     that have volume label bit set, but are actually parts
+	     of an LFN entry.  Non-LFN platforms might be fooled to
+	     take them as volume labels, and report bogus time stamps.  */
+	  volume_found = __findfirst(buf, &ff_blk, FA_LABEL) == 0;
+	  while (volume_found
+		 && (ff_blk.ff_attrib & (FA_HIDDEN|FA_SYSTEM)) != 0)
+	    volume_found = __findnext(&ff_blk) == 0;
+	  if (volume_found)
+	    dos_ftime = ( (unsigned)ff_blk.ff_fdate << 16 ) + ff_blk.ff_ftime;
+	  else
+	    _djstat_fail_bits |= _STFAIL_LABEL;
+	}
+    }
+  else
+    {
+      int e = errno;	/* errno value from original FindFirst on PATHNAME */
+      int i = 0;
+      int j = strlen (pathname) - 1;
+
+      /* Check for volume labels.  We did not mix FA_LABEL with
+	 other attributes in the call to `__findfirst' above,
+	 because some environments will return bogus info in
+	 that case.  For instance, Win95 and WinNT seem to
+	 ignore `pathname' and return the volume label even if it
+	 doesn't fit the name in `pathname'.  This fools us to
+	 think that a non-existent file exists and is a volume
+	 label.  Hence we test the returned name to be PATHNAME.  */
+      if (!__findfirst(pathname, &ff_blk, FA_LABEL))
+	{
+	  i = strlen (ff_blk.ff_name) - 1;
+
+	  if (j >= i)
+	    {
+	      for ( ; i >= 0 && j >= 0; i--, j--)
+		if (toupper ((unsigned char)ff_blk.ff_name[i]) != toupper ((unsigned char)pathname[j]))
+		  break;
+	    }
+	}
+
+      if (i < 0 && pathname[j] == '/')
+	{
+	  /* Indeed a label.  */
+	  statbuf->st_mode = READ_ACCESS;
+#ifdef  S_IFLABEL
+	  statbuf->st_mode |= S_IFLABEL;
+#endif
+	  statbuf->st_ino = 1;
+	  statbuf->st_size = 0;
+	  dos_ftime = ( (unsigned)ff_blk.ff_fdate << 16 ) + ff_blk.ff_ftime;
+	}
+      else
+	{
+	  /* FindFirst on volume labels might set errno to ENMFILE or even
+	     to something more strange like EINVAl; correct that.  */
+	  errno = e;	/* restore errno from the original FindFirst */
+	  if (errno == ENMFILE)
+	    errno = ENOENT;
+	  return -1;
+	}
+    }
+
+  /* Device code. */
+  statbuf->st_dev = drv_no;
+#ifdef  HAVE_ST_RDEV
+  statbuf->st_rdev = drv_no;
+#endif
+
+  /* Time fields. */
+  statbuf->st_atime = statbuf->st_mtime = statbuf->st_ctime =
+    _file_time_stamp(dos_ftime);
+
+  if ( ! strcmp(ff_blk.lfn_magic,"LFN32") )
+    {
+      unsigned xtime;
+      xtime = ff_blk.lfn_ctime | (((unsigned)ff_blk.lfn_cdate) << 16);
+      if(xtime)			/* May be zero if file written w/o lfn active */
+        statbuf->st_ctime = _file_time_stamp(xtime);
+      xtime = ff_blk.lfn_atime | (((unsigned)ff_blk.lfn_adate) << 16);
+      if(xtime > dos_ftime)	/* Accessed time is date only, no time */
+        statbuf->st_atime = _file_time_stamp(xtime);
+    }
+
+  if ( (statbuf->st_mode & S_IFMT) == S_IFDIR
+       && (_djstat_flags & _STAT_DIRSIZE) == 0 )
+    {
+      /* Under DOS, directory entries for subdirectories have
+         zero size.  Therefore, FindFirst brings us zero size
+         when called on a directory.  (Some network redirectors
+         might do a better job, thus below we also test for zero size
+         actually being returned.)  If we have zero-size directory,
+         we compute here the actual directory size by reading its
+         entries, then multiply their number by 32 (the size of a
+         directory entry under DOS).  This might lose in the case
+         that many files were deleted from a once huge directory,
+         because AFAIK, directories don't return unused clusters to
+         the disk pool.  Still, it is a good approximation of the
+         actual directory size.
+
+         We also take this opportunity to return the number of links
+         for directories as Unix programs expect it to be: the number
+         of subdirectories, plus 2 (the directory itself and the ``.''
+         entry).
+
+         The (max) size of the root directory could also be taken from
+         the disk BIOS Parameter Block (BPB) which can be obtained
+         by calling IOCTL (INT 21/AH=44H), subfunction 0DH, minor
+         function 60H.  But we will treat all directories the same,
+         even at performance cost, because it's more robust for
+         networked drives.  */
+
+      size_t pathlen = strlen (pathname);
+      char   lastc   = pathname[pathlen - 1];
+      char  *search_spec = (char *)alloca (pathlen + 10); /* need only +5 */
+      int nfiles = 0, nsubdirs = 0, done;
+      size_t extra = 0;
+      int add_extra = 0;
+
+      strcpy(search_spec, pathname);
+      if (lastc == '/')
+        strcat(search_spec, "*.*");
+      else
+        strcat(search_spec, "/*.*");
+
+      if (statbuf->st_size == 0 && _USE_LFN)
+	{
+	  /* VFAT filesystems use additional directory entries to
+	     store the long filenames.  */
+	  char fstype[40];
+
+	  if ((_get_volume_info(pathname,0,0,fstype) & _FILESYS_LFN_SUPPORTED)
+	      && strncmp(fstype, "FAT", 4) == 0)
+	    add_extra = 1;
+	}
+
+      /* Count files and subdirectories.  */
+      for (done = __findfirst(search_spec, &ff_blk, ALL_FILES);
+	   !done;
+	   done = __findnext(&ff_blk))
+	{
+	  register char *fname = ff_blk.ff_name;
+
+	  /* Don't count "." and ".." entries.  This will show empty
+	     directories as size 0.  */
+	  if (! (fname[0] == '.'
+		 && (fname[1] == '\0'
+		     || (fname[1] == '.'
+			 && fname[2] == '\0'))))
+	    {
+	      char fn[13];
+
+	      nfiles++;
+	      if (ff_blk.ff_attrib & 0x10)
+		nsubdirs++;
+	      /* For each 13 characters of the long filename, a
+		 32-byte directory entry is used.  */
+	      if (add_extra && strcmp(_lfn_gen_short_fname(fname, fn), fname))
+		extra += (strlen(fname) + 12) / 13;
+	    }
+	}
+
+      statbuf->st_nlink = nsubdirs + 2;
+      if (statbuf->st_size == 0)
+	statbuf->st_size  = (nfiles + extra) * sizeof(struct full_dirent);
+    }
+
+  return 0;
+}
+
+/* Main entry point.  This is library stat() function.
+ */
+
+int
+libsupp_stat_2_03(const char *path, struct stat *statbuf)
+{
+  int  e = errno;
+  int  pathlen, ret;
+
+  if (!path || !statbuf)
+    {
+      errno = EFAULT;
+      return -1;
+    }
+
+  if ((pathlen = strlen (path)) >= MAX_TRUE_NAME)
+    {
+      errno = ENAMETOOLONG;
+      return -1;
+    }
+
+  /* Fail if PATH includes wildcard characters supported by FindFirst,
+     or if it is empty.  */
+  if (memchr(path, '*', pathlen) || memchr(path, '?', pathlen)
+      || path[0] == '\0')
+    {
+      errno = ENOENT;	/* since no such filename is possible */
+      return -1;
+    }
+
+  if (__FSEXT_call_open_handlers_wrapper(__FSEXT_stat, &ret, path, statbuf))
+    return ret;
+
+  if (stat_assist(path, statbuf) == -1)
+    {
+      return -1;      /* errno set by stat_assist() */
+    }
+  else
+    {
+      errno = e;
+      return 0;
+    }
+}
+
+#ifdef  TEST
+
+unsigned short _djstat_flags = 0;
+
+void
+main(int argc, char *argv[])
+{
+  struct stat stat_buf;
+  char *endp;
+
+  if (argc < 2)
+    {
+      fprintf (stderr, "Usage: %s <_djstat_flags> <file...>\n", argv[0]);
+      exit(0);
+    }
+
+  if (libsupp_stat_2_03(*argv, &stat_buf) != 0)
+    perror ("stat failed on argv[0]");
+  else
+    fprintf(stderr, "DOS %d.%d (%s)\n", _osmajor, _osminor, _os_flavor);
+  argc--; argv++;
+
+  _djstat_flags = (unsigned short)strtoul(*argv, &endp, 0);
+  argc--; argv++;
+
+  while (argc--)
+    {
+      if (!libsupp_stat_2_03(*argv, &stat_buf))
+        {
+          fprintf(stderr, "%s: %d %6u %o %d %d %ld %lu %s", *argv,
+                  stat_buf.st_dev,
+                  (unsigned)stat_buf.st_ino,
+                  stat_buf.st_mode,
+                  stat_buf.st_nlink,
+                  stat_buf.st_uid,
+                  (long)stat_buf.st_size,
+                  (unsigned long)stat_buf.st_mtime,
+                  ctime(&stat_buf.st_mtime));
+          _djstat_describe_lossage(stderr);
+        }
+      else
+        {
+          fprintf(stderr, "%s: lossage", *argv);
+          perror(" ");
+          _djstat_describe_lossage(stderr);
+        }
+
+      ++argv;
+    }
+
+    exit (0);
+}
+
+#endif
+
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/stat.c libsupp-6.2/src/posix/sys/stat/stat.c
--- libsupp-6.2.orig/src/posix/sys/stat/stat.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/stat.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
@@ -13,23 +14,25 @@
 #include <sys/stat.h>
 #include <errno.h>
 #include <stdio.h>
 #include <libc/symlink.h>
 
+#include "libsupp.h"
+
 #ifdef TEST
 #include "xstat.h"
 #endif
 
 int
-stat(const char *path, struct stat *statbuf)
+libsupp_stat(const char *path, struct stat *statbuf)
 {
    char name_copy[FILENAME_MAX];
    
    if (!__solve_symlinks(path, name_copy))
       return -1;
    
-   return lstat(name_copy, statbuf); /* Real file */
+   return libsupp_lstat(name_copy, statbuf); /* Real file */
 }
 
 #ifdef  TEST
 
 #include <stdlib.h>
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/stat/xstat.h libsupp-6.2/src/posix/sys/stat/xstat.h
--- libsupp-6.2.orig/src/posix/sys/stat/xstat.h	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/stat/xstat.h	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 /*
diff -aprNU5 libsupp-6.2.orig/src/posix/sys/statvfs/fstatvfs.c libsupp-6.2/src/posix/sys/statvfs/fstatvfs.c
--- libsupp-6.2.orig/src/posix/sys/statvfs/fstatvfs.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/sys/statvfs/fstatvfs.c	2009-11-22 04:01:02 +0000
@@ -1,22 +1,25 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 
 #include <libc/stubs.h>
-#include <libc/fd_props.h>
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/statvfs.h>
 
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 int
-fstatvfs (int fd, struct statvfs *outbuf)
+libsupp_fstatvfs(int fd, struct statvfs *outbuf)
 {
   const char *path = NULL;
 
-  if (__has_fd_properties(fd))
-    path = __get_fd_name(fd);
+  if (libsupp___has_fd_properties(fd))
+    path = libsupp___get_fd_name(fd);
 
   if (!path)
     {
       /* We can't find the path for `fd'. */
       errno = ENOENT;
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/access-2.03.c libsupp-6.2/src/posix/unistd/access-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/access-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/access-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,89 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <dir.h>
+#include <errno.h>
+#include <dirent.h>
+#include <string.h>
+
+#include "libsupp.h"
+
+int  libsupp_access_2_03(const char *_fn, int _flags);
+void libsupp__fixpath_2_03(const char *_in, char *_out);
+
+
+int libsupp_access_2_03(const char *fn, int flags)
+{
+  int attr = _chmod(fn, 0);
+
+  if (attr == -1) {
+    struct ffblk ff;
+    char fixed_path[FILENAME_MAX];
+
+    /* Root directories on some non-local drives (e.g. CD-ROM)
+       might fail `_chmod'.  `findfirst' to the rescue.  */
+    libsupp__fixpath_2_03(fn, fixed_path);
+    if (fixed_path[1] == ':' && fixed_path[2] == '/' && fixed_path[3] == 0)
+      {
+        char *fp = fixed_path + 3;
+
+        *fp++ = '*';
+        *fp++ = '.';
+        *fp++ = '*';
+        *fp++ = '\0';
+        /* Use _lfn_close_handle so we don't lose a handle.  */
+        if (findfirst(fixed_path, &ff, FA_DIREC) == 0)
+        {
+          if (strcmp(ff.lfn_magic, "LFN32") == 0)
+            _lfn_find_close(ff.lfn_handle);
+          return 0;
+        }
+      }
+
+    /* Devices also fail `_chmod'; some programs won't write to
+       a device unless `access' tells them they are writeable.  */
+    if (findfirst(fn, &ff, FA_RDONLY | FA_ARCH) == 0
+	&& (ff.ff_attrib & 0x40) == 0x40
+	&& (flags & (X_OK | D_OK)) == 0)
+    {
+      if (strcmp(ff.lfn_magic, "LFN32") == 0)
+        _lfn_find_close(ff.lfn_handle);
+      return 0;
+    }
+
+    errno = ENOENT;
+    return -1;
+  }
+ 
+  if (attr & 0x10)		/* directory? */
+      return 0;			/* directories always OK */
+  if (flags & D_OK)
+  {
+    errno = EACCES;
+    return -1;			/* not a directory */
+  }
+
+  if ((flags & W_OK) && (attr & 3)) /* read-only, system or hidden */
+  {
+    errno = EACCES;
+    return -1;			/* not writable */
+  }
+
+  if (flags & X_OK)
+  {
+    if (!_is_executable(fn, 0, 0))
+    {
+      errno = EACCES;
+      return -1;
+    }
+  }
+
+  return 0;			/* everything else is OK */
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/access.c libsupp-6.2/src/posix/unistd/access.c
--- libsupp-6.2.orig/src/posix/unistd/access.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/access.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -14,11 +15,14 @@
 #include <dir.h>
 #include <errno.h>
 #include <dirent.h>
 #include <limits.h>
 
-int access(const char *fn, int flags)
+#include "libsupp.h"
+
+
+int libsupp_access(const char *fn, int flags)
 {
   int attr;
   char file_name[FILENAME_MAX];
 
   if (!__solve_symlinks(fn, file_name))
@@ -30,11 +34,11 @@ int access(const char *fn, int flags)
     struct ffblk ff;
     char fixed_path[FILENAME_MAX];
 
     /* Root directories on some non-local drives (e.g. CD-ROM)
        might fail `_chmod'.  `findfirst' to the rescue.  */
-    _fixpath(file_name, fixed_path);
+    libsupp__fixpath(file_name, fixed_path);
     if (fixed_path[1] == ':' && fixed_path[2] == '/' && fixed_path[3] == 0)
       {
         char *fp = fixed_path + 3;
 
         *fp++ = '*';
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/chdir-2.03.c libsupp-6.2/src/posix/unistd/chdir-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/chdir-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/chdir-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,72 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <stdio.h>
+#include <limits.h>
+#include <libc/dosio.h>
+#include <libc/farptrgs.h>
+
+#include "libsupp.h"
+
+int  libsupp___chdir_2_03(const char *_mydirname);
+void libsupp__fixpath_2_03(const char *_in, char *_out);
+
+int
+libsupp___chdir_2_03(const char *mydirname)
+{
+  __dpmi_regs r;
+  int drv_no = -1;
+  char path[FILENAME_MAX];
+
+  libsupp__fixpath_2_03(mydirname, path);
+
+  if (path[0] == 0)
+  {
+    errno = ENOENT;
+    return -1;
+  }
+
+  _put_path(path);
+
+  /* _put_path performs some magic conversions of file names, so
+     the path in the transfer buffer can include a drive even though
+     MYDIRNAME doesn't seem to.  */
+  if (_farpeekb(_dos_ds, __tb + 1) == ':')
+    drv_no = (_farpeekb(_dos_ds, __tb) & 0x1f) - 1;
+
+  if (drv_no != -1)	/* Must do this first for Windows 2000 */
+  {
+    /* Change current drive.  The directory change below checks it. */
+    r.h.ah = 0x0e;
+    r.h.dl = drv_no;
+    __dpmi_int(0x21, &r);
+  }
+
+  if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0)
+  {
+    if(_USE_LFN)
+      r.x.ax = 0x713b;
+    else
+      r.h.ah = 0x3b;
+    r.x.dx = __tb_offset;
+    r.x.ds = __tb_segment;
+    __dpmi_int(0x21, &r);
+    if(r.x.flags & 1)
+    {
+      errno = __doserr_to_errno(r.x.ax);
+      return -1;
+    }
+  }
+
+  return 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/chdir.c libsupp-6.2/src/posix/unistd/chdir.c
--- libsupp-6.2.orig/src/posix/unistd/chdir.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/chdir.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -14,21 +15,24 @@
 #include <stdio.h>
 #include <limits.h>
 #include <libc/dosio.h>
 #include <libc/farptrgs.h>
 
+#include "libsupp.h"
+
+
 int
-__chdir (const char *mydirname)
+libsupp___chdir(const char *mydirname)
 {
   __dpmi_regs r;
   int drv_no = -1;
   char real_name[FILENAME_MAX];
   char path[FILENAME_MAX];
 
   if (!__solve_symlinks(mydirname, real_name))
      return -1;
-  _fixpath(real_name, path);
+  libsupp__fixpath(real_name, path);
 
   if (path[0] == 0)
   {
     errno = ENOENT;
     return -1;
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/close-2.03.c libsupp-6.2/src/posix/unistd/close-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/close-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/close-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,21 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <io.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_close_2_03(int _handle);
+
+
+int
+libsupp_close_2_03(int handle)
+{
+  int error = _close(handle);
+
+  if (!error && libsupp___has_fd_properties(handle))
+    libsupp___clear_fd_properties(handle);
+  return error;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/close.c libsupp-6.2/src/posix/unistd/close.c
--- libsupp-6.2.orig/src/posix/unistd/close.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/close.c	2009-11-22 04:01:02 +0000
@@ -1,10 +1,14 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
 #include <io.h>
 
+#include "libsupp.h"
+
+
 int
-close(int handle)
+libsupp_close(int handle)
 {
-  return _close(handle);
+  return libsupp__close(handle);
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/dup-2.03.c libsupp-6.2/src/posix/unistd/dup-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/dup-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/dup-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,38 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <dpmi.h>
+#include <errno.h>
+#include <io.h>
+#include <sys/fsext.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_dup_2_03(int _fd);
+
+
+int
+libsupp_dup_2_03(int fd)
+{
+  __dpmi_regs r;
+  r.h.ah = 0x45;
+  r.x.bx = fd;
+  __dpmi_int(0x21, &r);
+  if (r.x.flags & 1)
+  {
+    errno = __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+
+  /* Copy the fsext hook, the handle modes, and the properties.  */
+  __FSEXT_set_function(r.x.ax, __FSEXT_get_function(fd));
+  setmode(r.x.ax, __file_handle_modes[fd]);
+  if (libsupp___has_fd_properties(fd))
+    libsupp___dup_fd_properties(fd, r.x.ax);
+
+  return r.x.ax;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/dup.c libsupp-6.2/src/posix/unistd/dup.c
--- libsupp-6.2.orig/src/posix/unistd/dup.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/dup.c	2009-11-22 04:01:02 +0000
@@ -1,18 +1,22 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
 #include <dpmi.h>
 #include <errno.h>
 #include <io.h>
 #include <sys/fsext.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-dup(int fd)
+libsupp_dup(int fd)
 {
   __dpmi_regs r;
   r.h.ah = 0x45;
   r.x.bx = fd;
   __dpmi_int(0x21, &r);
@@ -23,10 +27,10 @@ dup(int fd)
   }
 
   /* Copy the fsext hook, the handle modes, and the properties.  */
   __FSEXT_set_function(r.x.ax, __FSEXT_get_function(fd));
   setmode(r.x.ax, __file_handle_modes[fd]);
-  if (__has_fd_properties(fd))
-    __dup_fd_properties(fd, r.x.ax);
+  if (libsupp___has_fd_properties(fd))
+    libsupp___dup_fd_properties(fd, r.x.ax);
 
   return r.x.ax;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/dup2-2.03.c libsupp-6.2/src/posix/unistd/dup2-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/dup2-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/dup2-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,54 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dpmi.h>
+#include <errno.h>
+#include <io.h>
+#include <sys/fsext.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_dup2_2_03(int _fd, int _newfd);
+
+
+int
+libsupp_dup2_2_03(int fd, int newfd)
+{
+  __dpmi_regs r;
+  if (fd == newfd)
+    return newfd;
+  /* Reset the text/binary modes and the fsext, since
+     DOS function 46h closes newfd.  */
+  __file_handle_set(newfd, __file_handle_modes[fd] ^ (O_BINARY|O_TEXT));
+  __FSEXT_set_function(newfd, 0);
+  r.h.ah = 0x46;
+  r.x.bx = fd;
+  r.x.cx = newfd;
+  __dpmi_int(0x21, &r);
+  if (r.x.flags & 1)
+  {
+    errno = __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+
+  /* The properties may be cleared only after the file has been
+     forcibly closed because the file associated with the
+     descriptor may be deleted if it has the temporary attribute
+     and if newfd is the last reference to it.  */
+  if (libsupp___has_fd_properties(newfd))
+    libsupp___clear_fd_properties(newfd);
+
+  /* Copy the fsext hook, the handle modes, and the properties.  */
+  __FSEXT_set_function(newfd, __FSEXT_get_function(fd));
+  setmode(newfd, __file_handle_modes[fd]);
+  if (libsupp___has_fd_properties(fd))
+    libsupp___dup_fd_properties(fd, newfd);
+
+  return newfd;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/dup2.c libsupp-6.2/src/posix/unistd/dup2.c
--- libsupp-6.2.orig/src/posix/unistd/dup2.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/dup2.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
@@ -7,14 +8,17 @@
 #include <dpmi.h>
 #include <errno.h>
 #include <io.h>
 #include <sys/fsext.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 int
-dup2(int fd, int newfd)
+libsupp_dup2(int fd, int newfd)
 {
   __dpmi_regs r;
   if (fd == newfd)
     return newfd;
   /* Reset the text/binary modes, the fsext, and the properties, since
@@ -33,16 +37,16 @@ dup2(int fd, int newfd)
 
   /* The properties may be cleared only after the file has been
      forcibly closed because the file associated with the
      descriptor may be deleted if it has the temporary attribute
      and if newfd is the last reference to it.  */
-  if (__has_fd_properties(newfd))
-    __clear_fd_properties(newfd);
+  if (libsupp___has_fd_properties(newfd))
+    libsupp___clear_fd_properties(newfd);
 
   /* Copy the fsext hook, the handle modes, and the properties.  */
   __FSEXT_set_function(newfd, __FSEXT_get_function(fd));
   setmode(newfd, __file_handle_modes[fd]);
-  if (__has_fd_properties(fd))
-    __dup_fd_properties(fd, newfd);
+  if (libsupp___has_fd_properties(fd))
+    libsupp___dup_fd_properties(fd, newfd);
 
   return newfd;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/fchdir.c libsupp-6.2/src/posix/unistd/fchdir.c
--- libsupp-6.2.orig/src/posix/unistd/fchdir.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/fchdir.c	2009-11-22 04:01:02 +0000
@@ -1,26 +1,34 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
 #include <io.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+int libsupp_fchdir_2_03(int _fd);
+int libsupp___chdir_2_03(const char *_mydirname);
+
 
 int
-fchdir (int fd)
+libsupp_fchdir_2_03(int fd)
 {
-  const char *filename = __get_fd_name(fd);
-  const int   flags    = __get_fd_flags(fd);
+  const char *filename = libsupp___get_fd_name(fd);
+  const int   flags    = libsupp___get_fd_flags(fd);
 
   /* Check that it's a valid file descriptor. */
   if (_get_dev_info(fd) == -1)
-    return(-1);
+    return (-1);
 
   /* Is it actually a directory? */
-  if (((flags & FILE_DESC_DIRECTORY) == 0) || (filename == NULL)) {
+  if (((flags & FILE_DESC_DIRECTORY) == 0) || (filename == NULL))
+  {
     errno = ENOTDIR;
-    return(-1);
+    return (-1);
   }
 
-  return(chdir(filename));
+  return (libsupp___chdir_2_03(filename));
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/lseek-2.03.c libsupp-6.2/src/posix/unistd/lseek-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/lseek-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/lseek-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,42 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <errno.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <sys/fsext.h>
+#include <libc/dosio.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+off_t libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
+off_t
+libsupp_lseek_2_03(int handle, off_t offset, int whence)
+{
+  __dpmi_regs r;
+  __FSEXT_Function *func = __FSEXT_get_function(handle);
+  if (func)
+  {
+    int rv;
+    if (__FSEXT_func_wrapper(func, __FSEXT_lseek, &rv, handle, offset, whence))
+      return rv;
+  }
+
+  r.h.ah = 0x42;
+  r.h.al = whence;
+  r.x.bx = handle;
+  r.x.cx = offset >> 16;
+  r.x.dx = offset & 0xffff;
+  __dpmi_int(0x21, &r);
+  if (r.x.flags & 1)
+  {
+    errno = __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+  return (r.x.dx << 16) + r.x.ax;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/lseek.c libsupp-6.2/src/posix/unistd/lseek.c
--- libsupp-6.2.orig/src/posix/unistd/lseek.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/lseek.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -8,16 +9,19 @@
 #include <unistd.h>
 #include <errno.h>
 #include <go32.h>
 #include <dpmi.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <libc/dosio.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 off_t
-lseek(int handle, off_t offset, int whence)
+libsupp_lseek(int handle, off_t offset, int whence)
 {
   offset_t llseek_offset;
 
   __FSEXT_Function *func = __FSEXT_get_function(handle);
   if (func)
@@ -25,11 +29,11 @@ lseek(int handle, off_t offset, int when
     int rv;
     if (__FSEXT_func_wrapper(func, __FSEXT_lseek, &rv, handle, offset, whence))
       return rv;
   }
 
-  llseek_offset = llseek(handle, offset, whence);
+  llseek_offset = libsupp_llseek(handle, offset, whence);
   if( llseek_offset == -1 )
   {
     return -1; /* llseek sets errno. */
   }
 
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/pipe.c libsupp-6.2/src/posix/unistd/pipe.c
--- libsupp-6.2.orig/src/posix/unistd/pipe.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/pipe.c	2009-11-22 04:01:02 +0000
@@ -1,43 +1,47 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/stat.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 /* Emulate a pipe using a temporary file.  */
 int
-pipe(int fildes[2])
+libsupp_pipe(int fildes[2])
 {
   int ifd, ofd;
   char temp_name[FILENAME_MAX + 1];
   char *tname;
 
   tname = tmpnam(temp_name);
   if (tname == NULL)
     return -1;
     
-  ofd = open(tname, O_WRONLY | O_CREAT | O_TRUNC | O_TEMPORARY,
+  ofd = libsupp_open(tname, O_WRONLY | O_CREAT | O_TRUNC | O_TEMPORARY,
              S_IWUSR);
   if (ofd < 0)
     return -1;
     
-  ifd = open(tname, O_RDONLY | O_TEMPORARY);
+  ifd = libsupp_open(tname, O_RDONLY | O_TEMPORARY);
   if (ifd < 0)
   {
-    close(ofd);
+    libsupp_close(ofd);
     return -1;
   }
 
-  if (__has_fd_properties(ofd))
-    __set_fd_flags(ofd, FILE_DESC_PIPE);
-  if (__has_fd_properties(ifd))
-    __set_fd_flags(ifd, FILE_DESC_PIPE);
+  if (libsupp___has_fd_properties(ofd))
+    libsupp___set_fd_flags(ofd, FILE_DESC_PIPE);
+  if (libsupp___has_fd_properties(ifd))
+    libsupp___set_fd_flags(ifd, FILE_DESC_PIPE);
 
   fildes[0] = ifd;
   fildes[1] = ofd;
     
   return 0;
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/read-2.03.c libsupp-6.2/src/posix/unistd/read-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/read-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/read-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,65 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <io.h>
+
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
+ssize_t libsupp_read_2_03(int _handle, void* _buffer, size_t _count);
+off_t   libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+
+
+ssize_t
+libsupp_read_2_03(int handle, void* buffer, size_t count)
+{
+  ssize_t ngot;
+
+  /* termios special hook */
+  if (__libc_read_termios_hook != NULL)
+    {
+      ssize_t rv;
+      if (__libc_read_termios_hook(handle, buffer, count, &rv) != 0)
+        return rv;
+    }
+
+  /* Directory? If so, fail, which indicates that the caller should use
+   * readdir() instead. */
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+  {
+    errno = EISDIR;
+    return -1;
+  }
+
+  ngot = _read(handle, buffer, count);
+  if(ngot <= 0)
+    return ngot;
+  if (__file_handle_modes[handle] & O_TEXT)
+  {
+    /* check for Ctrl-Z EOF character */
+    int i;
+    for (i=0; i<ngot; i++)
+      if (((char *)buffer)[i] == 0x1a) /* Ctrl-Z */
+      {
+	libsupp_lseek_2_03(handle, i-ngot, SEEK_CUR); /* back up to make ^Z first char read next time */
+	ngot = i;
+	break;
+      }
+
+    if (ngot > 0)
+    {
+      /* convert CR/LF to NL */
+      ngot = crlf2nl(buffer, ngot);
+      if(!ngot)
+	return libsupp_read(handle, buffer, count);		/* if all CR's read more data */
+    }
+  }
+  return ngot;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/read.c libsupp-6.2/src/posix/unistd/read.c
--- libsupp-6.2.orig/src/posix/unistd/read.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/read.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <stdlib.h>
@@ -8,14 +9,17 @@
 #include <io.h>
 #include <errno.h>
 
 #include <libc/dosio.h>
 #include <libc/ttyprvt.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 ssize_t
-read(int handle, void* buffer, size_t count)
+libsupp_read(int handle, void* buffer, size_t count)
 {
   ssize_t ngot;
 
   /* termios special hook */
   if (__libc_read_termios_hook != NULL)
@@ -25,11 +29,11 @@ read(int handle, void* buffer, size_t co
         return rv;
     }
 
   /* Directory? If so, fail, which indicates that the caller should use
    * readdir() instead. */
-  if (__get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
   {
     errno = EISDIR;
     return -1;
   }
 
@@ -41,20 +45,20 @@ read(int handle, void* buffer, size_t co
     /* check for Ctrl-Z EOF character */
     int i;
     for (i=0; i<ngot; i++)
       if (((char *)buffer)[i] == 0x1a) /* Ctrl-Z */
       {
-	lseek(handle, i-ngot, SEEK_CUR); /* back up to make ^Z first char read next time */
+	libsupp_lseek(handle, i-ngot, SEEK_CUR); /* back up to make ^Z first char read next time */
 	ngot = i;
 	break;
       }
 
     if (ngot > 0)
     {
       /* convert CR/LF to NL */
       ngot = crlf2nl(buffer, ngot);
       if(!ngot)
-	return read(handle, buffer, count);		/* if all CR's read more data */
+	return libsupp_read(handle, buffer, count);		/* if all CR's read more data */
     }
   }
   return ngot;
 }
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/symlink-2.03.c libsupp-6.2/src/posix/unistd/symlink-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/symlink-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/symlink-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,188 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/system.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <dpmi.h>
+#include <go32.h>
+
+#include "libsupp.h"
+
+int  libsupp_symlink_2_03(const char *_source, const char *_dest);
+void libsupp__fixpath_2_03(const char *_in, char *_out);
+
+static char EXE_SUFFIX[] = ".exe";
+static char STUBIFY[]	 = "stubify.exe";
+static char STUBEDIT[]	 = "stubedit.exe";
+
+
+/* Return a pointer to the tail of the pathname.  */
+static const char *
+tail (const char *path)
+{
+  const char *p = path && path[0] ? path + strlen (path) - 1 : path;
+
+  if (p)
+    {
+      while (p > path && *p != '/' && *p != '\\' && *p != ':')
+	p--;
+      if (p > path)
+	p++;
+    }
+  return p;
+}
+
+/*
+   This returns
+              -1, when the file does not exist
+               0, when it is not a v2 executable
+               1, when it is a v2 executable
+*/
+
+static int is_v2_prog(const char *program)
+{
+  const _v2_prog_type *type;
+
+  type = _check_v2_prog (program, -1);
+
+  if (!type->valid)
+    return -1;
+
+  if (type->object_format != _V2_OBJECT_FORMAT_COFF)
+    return 0;
+
+  if (type->version.v.major < 2)
+    return 0;
+
+  return 1;
+}
+
+/* Support the DJGPP ``symlinks'' for .exe files.  */
+int
+libsupp_symlink_2_03(const char *source, const char *dest)
+{
+  char src_abs[FILENAME_MAX+5], src_short[FILENAME_MAX+5];
+  char dest_abs[FILENAME_MAX+5];
+  char *np, ropt[FILENAME_MAX+15]; /* some extra for ``runfile='' */
+  const char *src_base, *dest_base;
+
+  int v2_prog = 0;
+
+  libsupp__fixpath_2_03 (source, src_abs);
+  libsupp__fixpath_2_03 (dest, dest_abs);
+  src_base = tail (src_abs);
+  dest_base = tail (dest_abs);
+
+  /* DJGPP symlinks must be in the same directory.  */
+  if (src_base - src_abs != dest_base - dest_abs
+      || strnicmp (src_abs, dest_abs, src_base - src_abs))
+    {
+      errno = EXDEV;
+      return -1;
+    }
+
+  /* Any file is already a link to itself.  */
+  if (stricmp (src_abs, dest_abs) == 0)
+    return 0;
+
+  /* Check at first, if the given name is a v2 executable (may be
+     unstubbed COFF image) */
+  v2_prog = is_v2_prog(src_abs);
+
+  /* It is an existing file but no v2 executable */
+  if (v2_prog == 0)
+  {
+    errno = EXDEV;
+    return -1;
+  }
+
+  /* Allow to say `ln -s src dest' when we really
+     mean `src.exe' and `dest.exe'  */
+  np = src_abs + strlen (src_abs);
+  if (np - src_abs > 4 && stricmp (np - 4, EXE_SUFFIX) != 0)
+  {
+    strcat (src_abs, EXE_SUFFIX);
+    /* Now test again for v2 executable, but only if not already
+       succeed. */
+    v2_prog = v2_prog == 1 ? v2_prog : is_v2_prog(src_abs);
+  }
+
+  /* It is an existing file but no v2 executable */
+  if (v2_prog == 0)
+  {
+    errno = EXDEV;
+    return -1;
+  }
+
+  /* When we are here, either the file exists and is a v2 executable
+     or it does not exist and we hope, the the user knows what he
+     does. */
+
+  /* Under LFN, we need the short version of the program name, since that
+     is what the stub stores (and what a program gets in its argv[0]).  */
+  if (_USE_LFN)
+    {
+      if (__file_exists (src_abs))
+	{
+	  /* File exists.  Get its 8+3 alias.  */
+	  __dpmi_regs r;
+
+	  dosmemput(src_abs, strlen (src_abs)+1, __tb);
+	  r.x.ax = 0x7160;		/* Truename */
+	  r.x.cx = 1;			/* Get short name */
+	  r.x.ds = r.x.es = __tb / 16;
+	  r.x.si = r.x.di = __tb & 15;
+	  __dpmi_int(0x21, &r);
+	  if (r.x.flags & 1 || r.x.ax == 0x7100)
+	    /* Shouldn't happen: LFN *is* supported and file *does* exist.  */
+	    {
+	      errno = EIO;
+	      return -1;
+	    }
+	  dosmemget (__tb, FILENAME_MAX, src_short);
+	}
+      else
+	{
+	  /* File doesn't exist.  Generate short name that would be used.
+	     FIXME: this will lose if the generated name collides with
+	     another file already in that directory; however, the only
+	     alternative is to disallow symlinks to non-existing files.  */
+	  char *p = strncpy (src_short, src_abs, src_base - src_abs);
+	  _lfn_gen_short_fname (src_base, p + (src_base - src_abs));
+	}
+    }
+  else
+    strcpy (src_short, src_abs);
+
+  /* Need the basename of SRC_SHORT sans the extension.  */
+  strcpy (ropt, "runfile=");
+  strcat (ropt, tail (src_short));
+  for (np = ropt + strlen (ropt) - 1; np > ropt; np--)
+    if (*np == '.')
+      {
+	*np = '\0';
+	break;
+      }
+
+  /* `stubedit' needs its argument with the .EXE suffix explicit.  */
+  np = dest_abs + strlen (dest_abs);
+  if (np - dest_abs > 4 && stricmp (np - 4, EXE_SUFFIX) != 0)
+    strcat (dest_abs, EXE_SUFFIX);
+
+  /* Any file is already a link to itself.  */
+  if (stricmp (src_abs, dest_abs) == 0)
+    return 0;
+
+  if (spawnlp (P_WAIT, STUBIFY, STUBIFY, "-g", dest_abs, (char *)0)
+      || spawnlp (P_WAIT, STUBEDIT, STUBEDIT, dest_abs, ropt, (char *)0))
+    return -1;
+  return 0;
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/write-2.03.c libsupp-6.2/src/posix/unistd/write-2.03.c
--- libsupp-6.2.orig/src/posix/unistd/write-2.03.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/src/posix/unistd/write-2.03.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,114 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <io.h>
+#include <errno.h>
+#include <libc/farptrgs.h>
+#include <sys/fsext.h>
+#include <libc/dosio.h>
+#include <libc/ttyprvt.h>
+
+#include "../include/libc/fd_props.h"
+#include "../include/libc/fsexthlp.h"
+#include "libsupp.h"
+
+#define tblen _go32_info_block.size_of_transfer_buffer
+
+ssize_t libsupp_write_2_03(int _handle, const void* _buffer, size_t _count);
+off_t   libsupp_lseek_2_03(int _handle, off_t _offset, int _whence);
+int     libsupp__write_2_03(int _handle, const void* _buffer, size_t _count);
+
+
+ssize_t
+libsupp_write_2_03(int handle, const void* buffer, size_t count)
+{
+  const char *buf = (const char *)buffer;
+  size_t bytes_in_tb = 0;
+  size_t offset_into_buf = 0;
+  __dpmi_regs r;
+
+  ssize_t rv;
+  int i_rv;
+ __FSEXT_Function *func = __FSEXT_get_function(handle);
+
+  /* termios special hook */
+  if (__libc_write_termios_hook != NULL)
+      if (__libc_write_termios_hook(handle, buffer, count, &rv) != 0)
+        return rv;
+
+  if (count == 0)
+    return 0; /* POSIX.1 requires this */
+
+  /* Directory? If so, fail. */
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+  {
+    errno = EBADF;
+    return -1;
+  }
+
+  if (libsupp___has_fd_properties(handle)
+  && (__libsupp_fd_properties[handle]->flags & FILE_DESC_APPEND))
+  {
+    if (libsupp_lseek_2_03(handle, 0, SEEK_END) == -1)
+    {
+      /* lseek() sets errno. */
+      return -1;
+    }
+  }
+
+  if(__file_handle_modes[handle] & O_BINARY)
+    return libsupp__write_2_03(handle, buf, count);
+
+  /* Let's handle FSEXT_write ! */
+  if(func &&                                                                   /* if handler is installed, ...*/
+     __FSEXT_func_wrapper(func, __FSEXT_write, &i_rv, handle, buffer, count))  /* ... call extension ... */
+      return rv;                                                               /* ... and exit if handled. */
+
+  while (offset_into_buf < count)
+  {
+    _farsetsel(_dos_ds);
+    while (bytes_in_tb < tblen && offset_into_buf < count)
+    {
+      if (buf[offset_into_buf] == '\n')
+      {
+	if (bytes_in_tb == tblen - 1)
+	  break; /* can't fit two more */
+	_farnspokeb(__tb + bytes_in_tb, '\r');
+	bytes_in_tb++;
+      }
+      _farnspokeb(__tb + bytes_in_tb, buf[offset_into_buf]);
+      bytes_in_tb++;
+      offset_into_buf++;
+    }
+
+    /* we now have a transfer buf stuffed with data; write it out */
+    r.x.ax = 0x4000;
+    r.x.bx = handle;
+    r.x.cx = bytes_in_tb;
+    r.x.dx = __tb & 15;
+    r.x.ds = __tb / 16;
+    __dpmi_int(0x21, &r);
+    if (r.x.flags & 1)
+    {
+      errno = __doserr_to_errno(r.x.ax);
+      return -1;
+    }
+
+    if (r.x.ax < bytes_in_tb) /* disk full? */
+    {
+      offset_into_buf += r.x.ax;
+      errno = ENOSPC;
+      return count - offset_into_buf;
+    }
+
+    bytes_in_tb = 0;
+  }
+
+  return count;	/* Don't return count with CR's (TC) */
+}
diff -aprNU5 libsupp-6.2.orig/src/posix/unistd/write.c libsupp-6.2/src/posix/unistd/write.c
--- libsupp-6.2.orig/src/posix/unistd/write.c	2009-11-22 04:01:00 +0000
+++ libsupp-6.2/src/posix/unistd/write.c	2009-11-22 04:01:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2009 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2002 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -12,17 +13,20 @@
 #include <dpmi.h>
 #include <io.h>
 #include <errno.h>
 #include <libc/farptrgs.h>
 #include <sys/fsext.h>
-#include <libc/fsexthlp.h>
 #include <libc/dosio.h>
 #include <libc/ttyprvt.h>
-#include <libc/fd_props.h>
+
+#include "../include/libc/fsexthlp.h"
+#include "../include/libc/fd_props.h"
+#include "libsupp.h"
+
 
 ssize_t
-write(int handle, const void* buffer, size_t count)
+libsupp_write(int handle, const void* buffer, size_t count)
 {
   const char *buf = (const char *)buffer;
   size_t bytes_in_tb = 0;
   size_t offset_into_buf = 0;
   int out;
@@ -37,39 +41,39 @@ write(int handle, const void* buffer, si
 
   if (count == 0)
     return 0; /* POSIX.1 requires this */
 
   /* Directory? If so, fail. */
-  if (__get_fd_flags(handle) & FILE_DESC_DIRECTORY)
+  if (libsupp___get_fd_flags(handle) & FILE_DESC_DIRECTORY)
   {
     errno = EBADF;
     return -1;
   }
 
-  if ( __has_fd_properties(handle)
-  && ( __fd_properties[handle]->flags & FILE_DESC_APPEND ) )
+  if (libsupp___has_fd_properties(handle)
+  && (__libsupp_fd_properties[handle]->flags & FILE_DESC_APPEND))
   {
-    if ( llseek(handle, 0, SEEK_END) == -1 )
+    if (libsupp_llseek(handle, 0, SEEK_END) == -1)
     {
       /* llseek() sets errno. */
       return -1;
     }
   }
 
   if(__file_handle_modes[handle] & O_BINARY)
-    return _write(handle, buf, count);
+    return libsupp__write(handle, buf, count);
 
   /* Let's handle FSEXT_write ! */
   /* if handler is installed, call extension and exit if handled. */
   if(func &&				
      __FSEXT_func_wrapper(func, __FSEXT_write, &i_rv, handle, buffer, count))
       return i_rv;
 
-  if (__has_fd_properties(handle)
-      && (__fd_properties[handle]->flags & FILE_DESC_ZERO_FILL_EOF_GAP))
+  if (libsupp___has_fd_properties(handle)
+      && (__libsupp_fd_properties[handle]->flags & FILE_DESC_ZERO_FILL_EOF_GAP))
   {
-    if (_write_fill_seek_gap(handle) < 0)
+    if (libsupp__write_fill_seek_gap(handle) < 0)
       return -1;
   }
   
   while (offset_into_buf < count)
   {
@@ -87,11 +91,11 @@ write(int handle, const void* buffer, si
       bytes_in_tb++;
       offset_into_buf++;
     }
 
     /* Write out the contents of the transfer buffer. */
-    out = _write_int(handle, NULL, bytes_in_tb);
+    out = libsupp__write_int(handle, NULL, bytes_in_tb);
     if (out < 0)
       return -1;
     if ((size_t)out < bytes_in_tb)
     {
       offset_into_buf += out;
diff -aprNU5 libsupp-6.2.orig/tests/test.c libsupp-6.2/tests/test.c
--- libsupp-6.2.orig/tests/test.c	1970-01-01 00:00:00 +0000
+++ libsupp-6.2/tests/test.c	2009-11-22 04:01:02 +0000
@@ -0,0 +1,2071 @@
+#include <sys/version.h>
+#undef USE_DJGPP_STRL_FCTNS  /*  Use libsupp strlcat and strlcpy.  */
+#define TEST_LIBSUPP  1
+#if TEST_LIBSUPP
+# if (__DJGPP__  == 2) && (__DJGPP_MINOR__ < 4)
+#  include <libsupp.h>
+# else
+#  include "../include/libsupp.h"
+# endif
+#else
+# include <stdio.h>
+#endif
+#include <float.h>
+#include <limits.h>
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+# include <stdint.h>
+#endif
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libc/ieee.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include "../include/libc/unconst.h"
+
+
+void flags_test(FILE *out)
+{
+  fprintf(out, "Testing all flags.\n"
+               "==================\n");
+#if TEST_LIBSUPP
+  fprintf(out, "Flag: \"'\"\n"
+               "      The integer portion of the result of a decimal conversion (%%i, %%d, %%u, %%f,\n"
+               "      %%F, %%g, or %%G) shall be formatted with thousands' grouping characters.\n"
+               "      For other conversions the behavior is undefined. The non-monetary grouping\n"
+               "      character is used.\n"
+               "arg: %d   format string: \"%%'d\"   <%'d>\n"
+               "arg: %d   format string: \"%%'i\"   <%'i>\n"
+               "arg: %d   format string: \"%%'u\"   <%'u>\n"
+               "arg: %.1f format string: \"%%'f\"   <%'f>\n"
+               "arg: %.1f format string: \"%%'F\"   <%'F>\n"
+               "arg: %.1f format string: \"%%'g\"   <%'g>\n"
+               "arg: %.1f format string: \"%%'G\"   <%'G>\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0);
+#endif
+
+
+
+  fprintf(out, "Flag: \"-\"\n"
+               "      The result of the conversion shall be left-justified within the field. The\n"
+               "      conversion is right-justified if this flag is not specified.\n"
+               "arg: %d   format string: \"%%-5d\"   <%-5d>\n"
+               "arg: %d   format string: \"%%5d\"    <%5d>\n"
+               "arg: %d   format string: \"%%-5i\"   <%-5i>\n"
+               "arg: %d   format string: \"%%5i\"    <%5i>\n"
+               "arg: %d   format string: \"%%-5o\"   <%-5o>\n"
+               "arg: %d   format string: \"%% 5o\"   <%5o>\n"
+               "arg: %d   format string: \"%%-5u\"   <%-5u>\n"
+               "arg: %d   format string: \"%%5u\"    <%5u>\n"
+               "arg: %d  format string: \"%%-5x\"   <%-5x>\n"
+               "arg: %d  format string: \"%%5X\"    <%5X>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%-10a\"  <%-10a>\n"
+               "arg: %.1f format string: \"%%10A\"   <%10A>\n"
+#endif
+               "arg: %.1f format string: \"%%-15e\"  <%-15e>\n"
+               "arg: %.1f format string: \"%%15E\"   <%15E>\n"
+               "arg: %.1f format string: \"%%-10f\"  <%-10f>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%10F\"   <%10F>\n"
+#else
+               "arg: %.1f format string: \"%%10f\"   <%10f>\n"
+#endif
+               "arg: %.1f format string: \"%%-10g\"  <%-10g>\n"
+               "arg: %.1f format string: \"%%10G\"   <%10G>\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               10, 10,
+               15, 15,
+#if TEST_LIBSUPP
+               1.0, 1.0,
+               1.0, 1.0,
+#endif
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0);
+
+
+
+  fprintf(out, "Flag: \"+\"\n"
+               "      The result of a signed conversion shall always begin with a sign ('+' or\n"
+               "      '-'). The conversion shall begin with a sign only when a negative value\n"
+               "      is converted if this flag is not specified.\n"
+               "arg: %d   format string: \"%%+d\"   <%+d>\n"
+               "arg: %d   format string: \"%%i\"    <%i>\n"
+               "arg: %d   format string: \"%%+o\"   <%+o>    WARNING: Sign flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%+u\"   <%+u>    WARNING: Sign flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d  format string: \"%%+x\"   <%+x>    WARNING: Sign flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d  format string: \"%%+X\"   <%+X>    WARNING: Sign flag used with unsigned magnitude. Flag ignored.\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%+a\"   <%+a>\n"
+               "arg: %.1f format string: \"%%A\"    <%A>\n"
+#endif
+               "arg: %.1f format string: \"%%+e\"   <%+e>\n"
+               "arg: %.1f format string: \"%%E\"    <%E>\n"
+               "arg: %.1f format string: \"%%+f\"   <%+f>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%F\"    <%F>\n"
+#else
+               "arg: %.1f format string: \"%%f\"    <%f>\n"
+#endif
+               "arg: %.1f format string: \"%%+g\"   <%+g>\n"
+               "arg: %.1f format string: \"%%G\"    <%G>\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               10, 10,
+               15, 15,
+#if TEST_LIBSUPP
+               1.0, 1.0,
+               1.0, 1.0,
+#endif
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0);
+
+
+
+  fprintf(out, "Flag: \"<space>\"\n"
+               "      If the first character of a signed conversion is not a sign or if a signed\n"
+               "      conversion results in no characters, a <space> shall be prefixed to the\n"
+               "      result. This means that if the <space> and '+' flags both appear, the\n"
+               "      <space> flag shall be ignored.\n"
+               "arg: %d   format string: \"%% i\"   <% i>\n"
+               "arg: %d   format string: \"%%+ i\"  <%+ i>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+               "arg: %d   format string: \"%% d\"   <% d>\n"
+               "arg: %d   format string: \"%% +d\"  <% +d>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+               "arg: %d   format string: \"%% o\"   <% o>    WARNING: Space flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%+ o\"  <%+ o>    WARNING: Sign and space flags used with unsigned magnitude. Flags ignored.\n"
+               "arg: %d   format string: \"%% u\"   <% u>    WARNING: Space flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%+ u\"  <%+ u>    WARNING: Sign and space flags used with unsigned magnitude. Flags ignored.\n"
+               "arg: %d  format string: \"%% x\"   <% x>    WARNING: Space flag used with unsigned magnitude. Flag ignored.\n"
+               "arg: %d  format string: \"%%+ X\"  <%+ X>    WARNING: Sign and space flags used with unsigned magnitude. Flags ignored.\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%% a\"   <% a>\n"
+               "arg: %.1f format string: \"%%+ A\"  <%+ A>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+#endif
+               "arg: %.1f format string: \"%% e\"   <% e>\n"
+               "arg: %.1f format string: \"%% +E\"  <% +E>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+               "arg: %.1f format string: \"%% f\"   <% f>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%+ F\"  <%+ F>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+#else
+               "arg: %.1f format string: \"%% +f\"  <% +f>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n"
+#endif
+               "arg: %.1f format string: \"%% g\"   <% g>\n"
+               "arg: %.1f format string: \"%% +G\"  <% +G>   WARNING: Sign and space flags used simultaneously. Space flag ignored.\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               10, 10,
+               15, 15,
+#if TEST_LIBSUPP
+               1.0, 1.0,
+               1.0, 1.0,
+#endif
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0);
+
+
+
+  fprintf(out, "Flag: \"#\"\n"
+               "      Specifies that the value is to be converted to an alternative form. For o\n"
+               "      conversion, it increases the precision (if necessary) to force the first\n"
+               "      digit of the result to be zero. For x or X conversion specifiers, a non-\n"
+               "      zero result shall have 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g,\n"
+               "      and G conversion specifiers, the result shall always contain a radix\n"
+               "      character, even if no digits follow the radix character. Without this\n"
+               "      flag, a radix character appears in the result of these conversions only if\n"
+               "      a digit follows it. For g and G conversion specifiers, trailing zeros\n"
+               "      shall not be removed from the result as they normally are. For other\n"
+               "      conversion specifiers, the behavior is undefined.\n"
+               "arg: %d   format string: \"%%#d\"   <%#d>   WARNING: # flag used with decimal magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%#i\"   <%#i>   WARNING: # flag used with decimal magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%#u\"   <%#u>   WARNING: # flag used with decimal magnitude. Flag ignored.\n"
+               "arg: %d   format string: \"%%#o\"   <%#o>\n"
+               "arg: %d   format string: \"%%#o\"   <%#o>\n"
+               "arg: %d   format string: \"%%#x\"   <%#x>\n"
+               "arg: %d   format string: \"%%#X\"   <%#X>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%a\"    <%a>\n"
+               "arg: %.1f format string: \"%%#A\"   <%#A>\n"
+#endif
+               "arg: %.1f format string: \"%%1.e\"  <%1.e>\n"
+               "arg: %.1f format string: \"%%#1.E\" <%#1.E>\n"
+               "arg: %.1f format string: \"%%1.f\"  <%1.f>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f format string: \"%%#1.F\" <%#1.F>\n"
+#else
+               "arg: %.1f format string: \"%%#1.f\" <%#1.f>\n"
+#endif
+               "arg: %.1f format string: \"%%g\"    <%g>\n"
+               "arg: %.1f format string: \"%%#G\"   <%#G>\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               0, 0,
+               1, 1,
+               0, 0,
+#if TEST_LIBSUPP
+               1.0, 1.0,
+               0.0, 0.0,
+#endif
+               1.0, 1.0,
+               0.0, 0.0,
+               1.0, 1.0,
+               0.0, 0.0,
+               1.0, 1.0,
+               0.0, 0.0);
+
+
+
+  fprintf(out, "Flag: \"0\"\n"
+               "      For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers,\n"
+               "      leading zeros (following any indication of sign or base) are used to pad\n"
+               "      to the field width; no space padding is performed. If the '0' and '-'\n"
+               "      flags both appear, the '0' flag is ignored. For d, i, o, u, x, and X\n"
+               "      conversion specifiers, if a precision is specified, the '0' flag is\n"
+               "      ignored. If the '0' and ''' flags both appear, the grouping characters are\n"
+               "      inserted before zero padding. For other conversions, the behavior is\n"
+               "      undefined.\n"
+               "arg: %d    format string: \"%%05d\"    <%05d>\n"
+               "arg: %d    format string: \"%%-05d\"   <%-05d>            WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d    format string: \"%%05.d\"   <%05.d>\n"
+               "arg: %d    format string: \"%%05i\"    <%05i>\n"
+               "arg: %d    format string: \"%%-05i\"   <%-05i>            WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d    format string: \"%%05.i\"   <%05.i>\n"
+               "arg: %d    format string: \"%%05o\"    <%05o>\n"
+               "arg: %d    format string: \"%%-05o\"   <%-05o>            WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d    format string: \"%%05.o\"   <%05.o>\n"
+               "arg: %d    format string: \"%%05u\"    <%05u>\n"
+               "arg: %d    format string: \"%%-05u\"   <%-05u>            WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d    format string: \"%%05.u\"   <%05.u>\n"
+               "arg: %d   format string: \"%%05x\"    <%05x>\n"
+               "arg: %d   format string: \"%%-05x\"   <%-05x>             WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d   format string: \"%%05.x\"   <%05.x>\n"
+               "arg: %d   format string: \"%%05X\"    <%05X>\n"
+               "arg: %d   format string: \"%%-05X\"   <%-05X>             WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %d   format string: \"%%05.X\"   <%05.X>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f  format string: \"%%0-10a\"  <%0-10a>        WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %.1f  format string: \"%%0+10A\"  <%0+10A>\n"
+               "arg: %.1f  format string: \"%%010A\"   <%010A>\n"
+#endif
+               "arg: %.1f  format string: \"%%0-15e\"  <%0-15e>   WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %.1f  format string: \"%%0+15E\"  <%0+15E>\n"
+               "arg: %.1f  format string: \"%%015E\"   <%015E>\n"
+               "arg: %.1f  format string: \"%%0-10f\"  <%0-10f>        WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+#if TEST_LIBSUPP
+               "arg: %.1f  format string: \"%%0+10F\"  <%0+10F>\n"
+               "arg: %.1f  format string: \"%%010F\"   <%010F>\n"
+#else
+               "arg: %.1f  format string: \"%%0+10f\"  <%0+10f>\n"
+               "arg: %.1f  format string: \"%%010f\"   <%010f>\n"
+#endif
+               "arg: %.1f  format string: \"%%0-10g\"  <%0-10g>        WARNING: - and 0 flags used simultaneously. 0 flag ignored.\n"
+               "arg: %.1f  format string: \"%%0+10G\"  <%0+10G>\n"
+               "arg: %.1f  format string: \"%%010G\"   <%010G>\n\n",
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               1, 1,
+               10, 10,
+               10, 10,
+               10, 10,
+               15, 15,
+               15, 15,
+               15, 15,
+#if TEST_LIBSUPP
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+#endif
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0,
+               1.0, 1.0);
+}
+
+
+void  length_modifiers_test(FILE *out)
+{
+  char cv, *pcv;
+  short int siv, *psiv;
+  long int liv, *pliv;
+  long long int lliv, *plliv;
+  intmax_t jiv, *pjiv;
+  size_t ziv, *pziv;
+  ptrdiff_t piv, *ppiv;
+  pcv = &cv;
+  psiv = &siv;
+  pliv = &liv;
+  plliv = &lliv;
+  pjiv = &jiv;
+  pziv = &ziv;
+  ppiv = &piv;
+
+
+  fprintf(out, "\n\nTesting all length modifiers.\n"
+               "=============================\n");
+  fprintf(out, "Length modifier: \"hh\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a signed char or unsigned char argument\n"
+               "                 (the argument will have been promoted according to the integer\n"
+               "                 promotions, but its value shall be converted to signed char or\n"
+               "                 unsigned char before printing); or that a following n conversion\n"
+               "                 specifier applies to a pointer to a signed char argument.\n"
+               "arg: CHAR_MAX    format string: \"%%hhd\"   <%hhd>\n"
+               "arg: CHAR_MIN    format string: \"%%hhi\"   <%hhi>\n"
+               "arg: UCHAR_MAX   format string: \"%%hho\"   <%hho>\n"
+               "arg: UCHAR_MAX   format string: \"%%hhu\"   <%hhu>\n"
+               "arg: CHAR_MIN    format string: \"%%hhx\"   <%hhx>\n"
+               "arg: CHAR_MAX    format string: \"%%hhX\"   <%hhX>\n"
+               "arg: -           format string: \"%%hhn\"   (pointer to cv)%hhn\n",
+               CHAR_MAX,
+               CHAR_MIN,
+               UCHAR_MAX,
+               UCHAR_MAX ,
+               CHAR_MIN,
+               CHAR_MAX,
+               pcv);
+  fprintf(out, "cv=%i\n\n", *pcv);
+
+
+
+  fprintf(out, "Length modifier: \"h\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a short or unsigned short argument (the\n"
+               "                 argument will have been promoted according to the integer\n"
+               "                 promotions, but its value shall be converted to short or\n"
+               "                 unsigned short before printing); or that a following n\n"
+               "                 conversion specifier applies to a pointer to a short argument.\n"
+               "arg: SHRT_MAX    format string: \"%%hd\"   <%hd>\n"
+               "arg: SHRT_MIN    format string: \"%%hi\"   <%hi>\n"
+               "arg: USHRT_MAX   format string: \"%%ho\"   <%ho>\n"
+               "arg: USHRT_MAX   format string: \"%%hu\"   <%hu>\n"
+               "arg: SHRT_MIN    format string: \"%%hx\"   <%hx>\n"
+               "arg: SHRT_MAX    format string: \"%%hX\"   <%hX>\n"
+               "arg: -           format string: \"%%hn\"   (pointer to siv)%hn\n",
+               SHRT_MAX,
+               SHRT_MIN,
+               USHRT_MAX,
+               USHRT_MAX,
+               SHRT_MIN,
+               SHRT_MAX,
+               psiv);
+  fprintf(out, "siv=%i\n\n", *psiv);
+
+
+
+  fprintf(out, "Length modifier: \"l\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a long or unsigned long argument; that a\n"
+               "                 following n conversion specifier applies to a pointer to a long\n"
+               "                 argument; that a following c conversion specifier applies to a\n"
+               "                 wint_t argument; that a following s conversion specifier\n"
+               "                 applies to a pointer to a wchar_t argument; or has no effect on\n"
+               "                 a following a, A, e, E, f, F, g, or G conversion specifier.\n"
+               "arg: LONG_MAX    format string: \"%%ld\"   <%ld>\n"
+               "arg: LONG_MIN    format string: \"%%li\"   <%li>\n"
+               "arg: ULONG_MAX   format string: \"%%lo\"   <%lo>\n"
+               "arg: ULONG_MAX   format string: \"%%lu\"   <%lu>\n"
+               "arg: LONG_MIN    format string: \"%%lx\"   <%lx>\n"
+               "arg: LONG_MAX    format string: \"%%lX\"   <%lX>\n"
+               "arg: -           format string: \"%%ln\"   (pointer to liv)%ln\n"
+#if TEST_LIBSUPP
+               "arg: %.1f         format string: \"%%la\"   <%la>\n"
+               "arg: %.1f         format string: \"%%A\"    <%A>\n"
+#endif
+               "arg: %.1f         format string: \"%%le\"   <%le>\n"
+               "arg: %.1f         format string: \"%%E\"    <%E>\n"
+               "arg: %.1f         format string: \"%%lf\"   <%lf>\n"
+#if TEST_LIBSUPP
+               "arg: %.1f         format string: \"%%F\"    <%F>\n"
+#else
+               "arg: %.1f         format string: \"%%f\"    <%f>\n"
+#endif
+               "arg: %.1f         format string: \"%%lg\"   <%lg>\n"
+               "arg: %.1f         format string: \"%%G\"    <%G>\n",
+               LONG_MAX,
+               LONG_MIN,
+               ULONG_MAX,
+               ULONG_MAX,
+               LONG_MIN,
+               LONG_MAX,
+               pliv,
+               1.1, 1.1,
+               1.1, 1.1,
+               2.2, 2.2,
+               2.2, 2.2,
+               3.3, 3.3,
+               3.3, 3.3,
+               4.4, 4.4,
+               4.4, 4.4);
+  fprintf(out, "liv=%li\n\n", *pliv);
+
+
+
+  fprintf(out, "Length modifier: \"ll\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a long long or unsigned long long argument;\n"
+               "                 or that a following n conversion specifier applies to a pointer\n"
+               "                 to a long long argument.\n"
+               "arg: LONG_LONG_MAX   format string: \"%%lld\"   <%lld>\n"
+               "arg: LONG_LONG_MIN   format string: \"%%lli\"   <%lli>\n"
+               "arg: ULONG_LONG_MAX  format string: \"%%llo\"   <%llo>\n"
+               "arg: ULONG_LONG_MAX  format string: \"%%llu\"   <%llu>\n"
+               "arg: LONG_LONG_MIN   format string: \"%%llx\"   <%llx>\n"
+               "arg: LONG_LONG_MAX   format string: \"%%llX\"   <%llX>\n"
+               "arg: -               format string: \"%%lln\"   (pointer to lliv)%lln\n",
+               LONG_LONG_MAX,
+               LONG_LONG_MIN,
+               ULONG_LONG_MAX,
+               ULONG_LONG_MAX,
+               LONG_LONG_MIN,
+               LONG_LONG_MAX,
+               plliv);
+  fprintf(out, "lliv=%lli\n\n", *plliv);
+
+
+
+  fprintf(out, "Length modifier: \"j\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to an intmax_t or uintmax_t argument; or that\n"
+               "                 a following n conversion specifier applies to a pointer to an\n"
+               "                 intmax_t argument.\n"
+               "arg: LONG_LONG_MAX   format string: \"%%jd\"   <%jd>\n"
+               "arg: LONG_LONG_MIN   format string: \"%%ji\"   <%ji>\n"
+               "arg: ULONG_LONG_MAX  format string: \"%%jo\"   <%jo>\n"
+               "arg: ULONG_LONG_MAX  format string: \"%%ju\"   <%ju>\n"
+               "arg: LONG_LONG_MIN   format string: \"%%jx\"   <%jx>\n"
+               "arg: LONG_LONG_MAX   format string: \"%%jX\"   <%jX>\n"
+               "arg: -               format string: \"%%jn\"   (pointer to jiv)%jn\n",
+               (intmax_t)LONG_LONG_MAX,
+               (intmax_t)LONG_LONG_MIN,
+               (uintmax_t)ULONG_LONG_MAX,
+               (uintmax_t)ULONG_LONG_MAX,
+               (intmax_t)LONG_LONG_MIN,
+               (intmax_t)LONG_LONG_MAX,
+               pjiv);
+  fprintf(out, "jiv=%ji\n\n", *pjiv);
+
+
+
+  fprintf(out, "Length modifier: \"z\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a size_t or the corresponding signed\n"
+               "                 integer type argument; or that a following n conversion\n"
+               "                 specifier applies to a pointer to a signed integer type\n"
+               "                 corresponding to a size_t argument.\n"
+               "arg: LONG_MAX    format string: \"%%zd\"   <%zd>\n"
+               "arg: LONG_MIN    format string: \"%%zi\"   <%zi>\n"
+               "arg: LONG_MAX    format string: \"%%zo\"   <%zo>\n"
+               "arg: LONG_MAX    format string: \"%%zu\"   <%zu>\n"
+               "arg: LONG_MIN    format string: \"%%zx\"   <%zx>\n"
+               "arg: LONG_MAX    format string: \"%%zX\"   <%zX>\n"
+               "arg: -           format string: \"%%zn\"   (pointer to ziv)%zn\n",
+               (size_t)LONG_MAX,
+               (size_t)LONG_MIN,
+               (size_t)LONG_MAX,
+               (size_t)LONG_MAX,
+               (size_t)LONG_MIN,
+               (size_t)LONG_MAX,
+               pziv);
+  fprintf(out, "ziv=%zi\n\n", *pziv);
+
+
+
+  fprintf(out, "Length modifier: \"t\"\n"
+               "                 Specifies that a following d, i, o, u, x, or X conversion\n"
+               "                 specifier applies to a ptrdiff_t or the corresponding\n"
+               "                 unsigned type argument; or that a following n conversion\n"
+               "                 specifier applies to a pointer to a ptrdiff_t argument.\n"
+               "arg: LONG_MAX    format string: \"%%td\"   <%td>\n"
+               "arg: LONG_MIN    format string: \"%%ti\"   <%ti>\n"
+               "arg: LONG_MAX    format string: \"%%to\"   <%to>\n"
+               "arg: ULONG_MAX   format string: \"%%tu\"   <%tu>\n"
+               "arg: LONG_MIN    format string: \"%%tx\"   <%tx>\n"
+               "arg: LONG_MAX    format string: \"%%tX\"   <%tX>\n"
+               "arg: -           format string: \"%%tn\"   (pointer to piv)%tn\n",
+               (ptrdiff_t)LONG_MAX,
+               (ptrdiff_t)LONG_MIN,
+               (ptrdiff_t)LONG_MAX,
+               (ptrdiff_t)ULONG_MAX,
+               (ptrdiff_t)LONG_MIN,
+               (ptrdiff_t)LONG_MAX,
+               ppiv);
+  fprintf(out, "piv=%ti\n\n", *ppiv);
+
+
+
+  fprintf(out, "Length modifier: \"L\"\n"
+               "---------1---------2---------3---------4---------5---------6---------7---------8\n"
+               "                 Specifies that a following a, A, e, E, f, F, g, or G conversion\n"
+               "                 specifier applies to a long double argument.\n"
+#if TEST_LIBSUPP
+               "arg: LDBL_MAX    format string: \"%%La\"   <%La>\n"
+               "arg: LDBL_MIN    format string: \"%%LA\"   <%LA>\n"
+#endif
+               "arg: LDBL_MAX    format string: \"%%Le\"   <%Le>\n"
+               "arg: LDBL_MIN    format string: \"%%LE\"   <%LE>\n"
+               "arg: LDBL_MAX    format string: \"%%Lf\"   <%Lf>\n"
+#if TEST_LIBSUPP
+               "arg: LDBL_MIN    format string: \"%%LF\"   <%LF>\n"
+#endif
+               "arg: LDBL_MAX    format string: \"%%Lg\"   <%Lg>\n"
+               "arg: LDBL_MIN    format string: \"%%LG\"   <%LG>\n\n",
+               LDBL_MAX,
+               LDBL_MIN,
+               LDBL_MAX,
+               LDBL_MIN,
+               LDBL_MAX,
+               LDBL_MIN,
+               LDBL_MAX,
+               LDBL_MIN);
+}
+
+
+void numeric_conversion_specifiers_test(FILE *out)
+{
+  int i, width, precision;
+  double darg[] = {1.1, 2.2, 3.3};
+  char *title[] = {"En castellano:", "Auf deutsch:", "In english:"};
+  char *format[] = {
+   "%5$s, %2$d de %1$s, %3$*6$.*7$d:%4$*6$.*7$d\n",
+   "%5$s, %2$d. %1$s, %3$*6$.*7$d:%4$*6$.*7$d\n",
+   "%5$s, %1$s %2$d, %3$*6$.*7$d:%4$*6$.*7$d\n"
+  };
+  char *weekday[] = {"Sabado", "Samstag", "Saturday"};
+  char *month[] = {"febrero", "Februar", "february"};
+  int day = 2;
+  int hour = 12;
+  int min = 34;
+
+
+  fprintf(out, "\n\nTesting numeric conversion specifiers.\n"
+               "======================================\n");
+
+  width = 10;
+  precision = 1;
+  fprintf(out, "Printing a sequence of numbers using a given field width and precision\n"
+               "accessing the variables a multiple times in different order.\n"
+               "The sequence of arguments after the format string is:\n"
+               "  width, precision, darg[0], darg[1], darg[2]\n"
+               "with the values:\n"
+               "  width:     %d\n"
+               "  precision: %d\n"
+               "  darg[0]:   %f\n"
+               "  darg[1]:   %f\n"
+               "  darg[2]:   %f\n",
+               width, precision, darg[0], darg[1], darg[2]);
+  fprintf(out, "Format string: \"%%3$-*1$.*2$f###%%4$*1$.*2$f###%%5$*1$.*2$f\"     <%3$-*1$.*2$f###%4$*1$.*2$f###%5$*1$.*2$f>\n"
+               "Printing again but accessing the arguments in inverse order:\n"
+               "Format string: \"%%5$-*1$.*2$f###%%4$*1$.*2$f###%%3$*1$.*2$f\"     <%5$-*1$.*2$f###%4$*1$.*2$f###%3$*1$.*2$f>\n\n\n",
+               width, precision, darg[0], darg[1], darg[2]);
+
+
+  width = 2;
+  precision = 2;
+  fprintf(out, "Printing Language-Independent Date and Time.\n\n");
+  for (i = 0; i < 3; i++)
+  {
+    int len = strlen(format[i]);
+    fprintf(out, "%s  ", title[i]);
+    fprintf(out, format[i], month[i], day, hour, min, weekday[i], width, precision);
+    format[i][--len] = '\0';
+    fprintf(out, "Produced with:\n"
+                 "  printf(\"%1$s\\n\", month[%2$i], day, hour, min, weekday[%2$i], width, precision);\n\n",
+                 format[i], i);
+  }
+}
+
+
+void printf_test(FILE *out)
+{
+  char buf[100], *strbuf;
+  union {
+    unsigned int word[3];
+    long double value;
+  } x;
+  int strlng;
+
+
+
+  fprintf(out, "\n\nGeneral test of the printf familiy of functions.\n"
+               "================================================\n");
+
+  fprintf(out, "Infinity.\n");
+  sprintf(buf, "%La", 1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%La\"   arg: 1.0L / 0.0L\n"
+               "Shall return: \"inf\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LA", -1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LA\"   arg: -1.0L / 0.0L\n"
+               "Shall return: \"-INF\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Lf", 1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Lf\"   arg: 1.0L / 0.0L\n"
+               "Shall return: \"inf\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LF", -1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LF\"   arg: -1.0L / 0.0L\n"
+               "Shall return: \"-INF\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Le", 1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Le\"   arg: 1.0L / 0.0L\n"
+               "Shall return: \"inf\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LE", -1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LE\"   arg: -1.0L / 0.0L\n"
+               "Shall return: \"-INF\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Lg", 1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Lg\"   arg: 1.0L / 0.0L\n"
+               "Shall return: \"inf\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LG", -1.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LG\"   arg: -1.0L / 0.0L\n"
+               "Shall return: \"-INF\"   returns: \"%s\"\n\n", buf);
+
+  fprintf(out, "NaN.\n");
+  sprintf(buf, "%La", 0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%La\"   arg: 0.0L / 0.0L\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LA", -0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LA\"   arg: -0.0L / 0.0L\n"
+               "Shall return: \"NAN\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Lf", 0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Lf\"   arg: 0.0L / 0.0L\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LF", -0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LF\"   arg: -0.0L / 0.0L\n"
+               "Shall return: \"NAN\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Le", 0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Le\"   arg: 0.0L / 0.0L\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LE", -0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LE\"   arg: -0.0L / 0.0L\n"
+               "Shall return: \"NAN\"   returns: \"%s\"\n", buf);
+  sprintf(buf, "%Lg", 0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%Lg\"   arg: 0.0L / 0.0L\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", buf);
+  sprintf(buf, "%LG", -0.0L / 0.0L);
+  fprintf(out, "fmt str: \"%%LG\"   arg: -0.0L / 0.0L\n"
+               "Shall return: \"NAN\"   returns: \"%s\"\n\n", buf);
+
+
+  x.word[2] = 0x7FFF;
+  x.word[1] = 0xC000000C;
+  x.word[0] = 0x10000001;
+  fprintf(out, "Quiet NaN\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0x7FFF;
+  x.word[1] = 0x80000008;
+  x.word[0] = 0x10000001;
+  fprintf(out, "Signalling NaN\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0x7FFF;
+  x.word[1] = 0x40000004;
+  x.word[0] = 0x10000001;
+  fprintf(out, "Pseudo-NaN\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0xFFFF;
+  x.word[1] = 0x00000000;
+  x.word[0] = 0x00000000;
+  fprintf(out, "Pseudo-Infinity\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0x4004;
+  x.word[1] = 0x00000000;
+  x.word[0] = 0x00000000;
+  fprintf(out, "Pseudo-Zero\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0x0440;
+  x.word[1] = 0x60000006;
+  x.word[0] = 0x10000001;
+  fprintf(out, "Unnormalized number\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+  x.word[2] = 0x0000;
+  x.word[1] = 0x80000008;
+  x.word[0] = 0x10000001;
+  fprintf(out, "Pseudo-Denormal\n");
+  sprintf(buf, "%La", x.value);
+  fprintf(out, "fmt str: \"%%La\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Le", x.value);
+  fprintf(out, "fmt str: \"%%Le\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lf", x.value);
+  fprintf(out, "fmt str: \"%%Lf\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n", x.word[2], x.word[1], x.word[0], buf);
+  sprintf(buf, "%Lg", x.value);
+  fprintf(out, "fmt str: \"%%Lg\"   exp: %#.4x  manthi: %#.8x  mantlo: %#.8x\n"
+               "Shall return: \"nan\"    returns: \"%s\"\n\n", x.word[2], x.word[1], x.word[0], buf);
+
+
+  fprintf(out, "Testing asprintf.\n");
+  fprintf(out, "Code line:   strlng = asprintf(&strbuf, \"Pi = %%.15Lf\", 3.1415926535897932384626433832795L);\n");
+  strlng = asprintf(&strbuf, "Pi = %.15Lf", 3.1415926535897932384626433832795L);
+  fprintf(out, "Result:      strbuf: \"%s\"   strlng: %d\n", strbuf, strlng);
+  free(strbuf);
+
+  fprintf(out, "Testing asnprintf.\n");
+  strbuf = NULL;
+  fprintf(out, "Code line:   strlng = asnprintf(&strbuf, 0, \"Pi = %%.15Lf\", 3.1415926535897932384626433832795L);\n");
+  strlng = asnprintf(&strbuf, 0, "Pi = %.15Lf", 3.1415926535897932384626433832795L);
+  fprintf(out, "Result:      strbuf: %s  strlng: %d\n", strbuf, strlng);
+  fprintf(out, "Code line:   strlng = asnprintf(&strbuf, 10, \"Pi = %%.15Lf\", 3.1415926535897932384626433832795L);\n");
+  strlng = asnprintf(&strbuf, 10, "Pi = %.15Lf", 3.1415926535897932384626433832795L);
+  fprintf(out, "Result:      strbuf: 0x%p  strlng: %d\n", strbuf, strlng);
+  fprintf(out, "             strbuf: \"%s\"  mallocated buffer length is %zd chars long plus 1 nul char\n\n", strbuf, strlen(strbuf));
+  free(strbuf);
+
+  fprintf(out, "Testing flags in combination with Infinity and NaN.\n");
+  fprintf(out, "Code line:   sprintf(buf, \"%%0*Lf\", 10, 1.0L / 0.0L);\n");
+  sprintf(buf, "%0*Lf", 10, 1.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "inf");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%+*Lf\", 10, 1.0L / 0.0L);\n");
+  sprintf(buf, "%+*Lf", 10, 1.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "+inf");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%-*Lf\", 10, 1.0L / 0.0L);\n");
+  sprintf(buf, "%-*Lf", 10, 1.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "inf       ");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%% *Lf\", 10, 1.0L / 0.0L);\n");
+  sprintf(buf, "% *Lf", 10, 1.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "inf");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%#*Lf\", 10, 1.0L / 0.0L);\n");
+  sprintf(buf, "%#*Lf", 10, 1.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "inf");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%0*Lf\", 10, 0.0L / 0.0L);\n");
+  sprintf(buf, "%0*Lf", 10, 0.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "nan");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%+*Lf\", 10, 0.0L / 0.0L);\n");
+  sprintf(buf, "%+*Lf", 10, 0.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "+nan");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%-*Lf\", 10, 0.0L / 0.0L);\n");
+  sprintf(buf, "%-*Lf", 10, 0.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "nan       ");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%% *Lf\", 10, 0.0L / 0.0L);\n");
+  sprintf(buf, "% *Lf", 10, 0.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "nan");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+  fprintf(out, "Code line:   sprintf(buf, \"%%#*Lf\", 10, 0.0L / 0.0L);\n");
+  sprintf(buf, "%#*Lf", 10, 0.0L / 0.0L);
+  asprintf(&strbuf, "%*s", (int)strlen(buf), "nan");
+  fprintf(out, "Shall return: <%s>    returns: <%s>  %s\n", strbuf, buf, strcmp(strbuf, buf) ? "Not OK" : "OK");
+  free(strbuf);
+}
+
+
+void signbit_test(FILE *out)
+{
+  fprintf(out, "\n\nTest of signbit and internal implementations.\n"
+               "=============================================\n");
+
+  fprintf(out, "signbit(%+.1fF):     %d\n"
+               "__signbitf(%+.1fF):  %d\n",  0.0F, signbit(0.0F), -0.0F, __signbitf(-0.0F));
+  fprintf(out, "signbit(%+.1f):      %d\n"
+               "__signbitd(%+.1f):   %d\n",  0.0, signbit(0.0), -0.0, __signbitd(-0.0));
+  fprintf(out, "signbit(%+.1LfL):     %d\n"
+               "__signbitld(%+.1LfL): %d\n", 0.0L, signbit(0.0L), -0.0L, __signbitld(-0.0L));
+}
+
+
+#define BUFFER1 "TEXT TO BE APPENDED"
+#define BUFFER2 "NEW:TEST:STRING"
+#define BUFFER3 "TAIL"
+#define BUFFER4 "CENTRAL"
+#define BUFFER5 "HEAD"
+#define BUFFER  ""
+
+void print_result(FILE *out, char *argz, size_t argz_len)
+{
+  size_t index, len;
+
+
+  fprintf(out, "argz_len: %zd\n", argz_len);
+  if (argz_len)
+    for (index = 0; index < argz_len;)
+    {
+      fprintf(out, "argz[%zd] = <", index);
+      len = index;
+      index += fprintf(out, "%s", argz + index);
+      fprintf(out, "\\0>\t\tlength = %zd\n", ++index - len);
+    }
+  else
+    fprintf(out, "argz[0] = %s", argz);
+}
+
+
+void argz_test(FILE *out)
+{
+  char *const glibc_compatibility_test_argv[] = {
+    NULL
+  };
+  char *glibc_compatibility_test_string = "";
+  char *const test_argv[] = {
+    "Test",
+    "string",
+    "for",
+    "argz_create",
+    NULL
+  };
+  const char *test_string1 = "Test#string#1# #for#argz_create_sep#";
+  const char *test_string2 = "Test#string#2# #for#argz_create_sep";
+  const char *test_string3 = "TO BE REPLACED#string 1#TO BE REPLACED#string 2#string 3#TO BE REPLACED#string 4#string 5#TO BE REPLACED";
+  int delimiter = '#';
+  char *argz, **argvp = NULL, *before, *entry;
+  size_t argz_len, counts, entry_index, i;
+  error_t error;
+
+
+  fprintf(out, "\n\nTest of argz family of functions.\n"
+               "=================================\n");
+
+
+  /*
+   *  argz_create test.
+   */
+  fprintf(out, "Test: argz_create.\n"
+               "==================\n"
+               "An argz vector shall be created using the following UNIX-style argv array:\n");
+  for (i = 0; test_argv[i]; i++)
+    fprintf(out, "test_argv[%zi]: \"%s\"\n", i, test_argv[i]);
+  fprintf(out, "test_argv[%zi]: \"%s\"\n", i, test_argv[i]);
+  fprintf(out, "\n");
+
+  error = argz_create(test_argv, &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "argz_create test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "argz_create test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_count test.
+   */
+  fprintf(out, "Test: argz_count.\n"
+               "=================\n"
+               "Count the strings contained in an argz vector.\n");
+  for (counts = 0; test_argv[counts]; counts++)
+    ;
+  if (counts != argz_count(argz, argz_len))
+  {
+    fprintf(out, "argz_count test failed.\n");
+    exit(1);
+  }
+  else
+  {
+    fprintf(out, "\nargz_count test passed.\n");
+    fprintf(out, "counts: %zd\n", counts);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_create_sep test.
+   */
+  fprintf(out, "Test 1: argz_create_sep.\n"
+               "========================\n"
+               "An argz vector shall be created using the following test string:\n"
+               "\"%s\"\n"
+               "The delimiter character \'%c\' will be used as string separator\n"
+               "in the test string and will be replaced with \'\\0\' in the argz vector.\n", test_string1, delimiter);
+  free(argz);
+  error = argz_create_sep(test_string1, delimiter, &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "\nargz_create_sep test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_create_sep test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n");
+
+  fprintf(out, "Test 2: argz_create_sep.\n"
+               "========================\n"
+               "An argz vector shall be created using the following test string:\n"
+               "\"%s\"\n"
+               "The delimiter character \'%c\' will be used as string separator\n"
+               "in the test string and will be replaced with \'\\0\' in the argz vector.\n", test_string2, delimiter);
+  free(argz);
+  error = argz_create_sep(test_string2, delimiter, &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "argz_create_sep failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_create_sep test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_add test.
+   */
+  fprintf(out, "Test: argz_add.\n"
+               "===============\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be added to the end of an argz vector.\n", BUFFER1);
+  entry_index = argz_len;  /*  Remember the position of the entry that later will be deleted.  */
+  error = argz_add(&argz, &argz_len, BUFFER1);
+  if (error)
+  {
+    fprintf(out, "\nargz_add test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_add test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_add_sep test.
+   */
+  delimiter = ':';
+  fprintf(out, "Test: argz_add_sep.\n"
+               "===================\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be added to the end of an argz vector.\n"
+               "The delimiter character \'%c\' will be used as string separator\n"
+               "in the test string and will be replaced with \'\\0\' in the argz vector.\n", BUFFER2, delimiter);
+  error = argz_add_sep(&argz, &argz_len, BUFFER2, delimiter);
+  if (error)
+  {
+    fprintf(out, "\nargz_add_sep test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_add_sep test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_delete test.
+   */
+  fprintf(out, "Test: argz_delete.\n"
+               "==================\n"
+               "The entry:\n"
+               "\"%s\"\n"
+               "will be deleted from argz vector.\n", BUFFER1);
+  argz_delete(&argz, &argz_len, argz + entry_index);
+  fprintf(out, "\nargz_delete test passed.\n");
+  print_result(out, argz, argz_len);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_append test.
+   */
+  fprintf(out, "Test: argz_append.\n"
+               "==================\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be appended to the end of an argz vector.\n", BUFFER1);
+  error = argz_append(&argz, &argz_len, BUFFER1, sizeof(BUFFER1));
+  if (error)
+  {
+    fprintf(out, "\nargz_append test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_append test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_extract test.
+   */
+  fprintf(out, "Test: argz_extract.\n"
+               "===================\n"
+               "Store pointers to each string contained in the argz vector in an UNIX-style argv array,\n"
+               "which must be large enough to contain them inclusive the terminating NULL pointer.\n");
+  counts = argz_count(argz, argz_len) + 1;
+  argvp = malloc(counts * sizeof(*argvp));
+  fprintf(out, "\nargz_extract test passed.\n");
+  argz_extract(argz, argz_len, argvp);
+  fprintf(out, "argz_len: %zd\n", argz_len);
+  for (i = 0; i < counts; i++)
+    fprintf(out, "argvp[%zi]: \"%s\"\n", i, argvp[i]);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_next test.
+   */
+  fprintf(out, "Test: argz_next.\n"
+               "================\n"
+               "Get a pointer to the next entry in the argz vector after the entry passed to the function.\n");
+  fprintf(out, "\nargz_extract test passed.\n");
+  entry = NULL;
+  do {
+    fprintf(out, "entry passed (0x%p):  \"%s\"\t\t", entry, entry);
+    entry = argz_next(argz, argz_len, entry);
+    fprintf(out, "entry returned (0x%p):  \"%s\"\n", entry, entry);
+  } while (entry);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_insert test.
+   */
+  fprintf(out, "Test: argz_insert.\n"
+               "==================\n"
+               "Insert entry in the argz vector before the string pointed by the pointer passed to the function.\n");
+  before = NULL;
+  error = argz_insert(&argz, &argz_len, before, BUFFER3);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nFirst argz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  thus  entry \"%s\" will be appended at the end of argz.\n", before, before, BUFFER3);
+    print_result(out, argz, argz_len);
+  }
+  before = argz + entry_index;
+  entry = strdup(before);
+  error = argz_insert(&argz, &argz_len, before, BUFFER4);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nSecond argz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  >  argz (0x%p): \"%s\"  thus  entry \"%s\" will be inserted before \"%s\".\n", entry, entry, argz, argz, BUFFER4, entry);
+    print_result(out, argz, argz_len);
+  }
+  free(entry);
+  before = argz;
+  error = argz_insert(&argz, &argz_len, before, BUFFER5);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nThird argz_insert test passed.\n");
+    fprintf(out, "before (0x%p) == argz (0x%p)  thus  entry \"%s\" will be inserted before the beginnig of argz.\n", before, argz, BUFFER5);
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_stringify test.
+   */
+  delimiter = '/';
+  fprintf(out, "Test: argz_stringify.\n"
+               "=====================\n"
+               "Make a '\\0' separated argz vector printable by converting all the '\\0's\n"
+               "except the last into the character '%c'.\n", delimiter);
+  argz_stringify(argz, argz_len, delimiter);
+  fprintf(out, "\nargz_stringify test passed.\n");
+  print_result(out, argz, argz_len);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_replace test.
+   */
+  free(argz);
+  error = argz_create_sep(test_string3, '#', &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "argz_create_sep failed: ENOMEM\n");
+    exit(error);
+  }
+  entry = malloc(argz_len);
+  memcpy(entry, argz, argz_len);
+  argz_stringify(argz, argz_len, '/');
+  fprintf(out, "Test: argz_replace.\n"
+               "===================\n"
+               "Replace any occurrences of string:\n"
+               "\"%s\"\n"
+               "in the argz vector:\n"
+               "\"%s\"\n"
+               "with:\n"
+               "\"%s\",\n"
+               "reallocating the argz vector as necessary.\n", "TO BE REPLACED", argz, "REPLACEMENT STRING");
+  free(argz);
+  argz = entry;
+  error = argz_replace(&argz, &argz_len, "TO BE REPLACED", "REPLACEMENT STRING", NULL);
+  if (error)
+  {
+    fprintf(out, "\nargz_replace test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_replace test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+
+
+  /*
+   *
+   *  The same test but with (NULL, 0) to check if no SIGSEGV happens.
+   *
+   */
+  free(argz);
+  fprintf(out, "#\n#\n#\n#  The same tests but with an argz vector of the form (NULL, 0).\n#\n#\n#\n\n\n");
+
+  /*
+   *  argz_create test.
+   */
+  fprintf(out, "Test: argz_create.\n"
+               "==================\n"
+               "An argz vector shall be created using the following argv array:\n");
+  for (i = 0; glibc_compatibility_test_argv[i]; i++)
+    fprintf(out, "test_argv[%zi]: \"%s\"\n", i, glibc_compatibility_test_argv[i]);
+  fprintf(out, "test_argv[%zi]: \"%s\"\n", i, glibc_compatibility_test_argv[i]);
+  fprintf(out, "\n");
+
+  error = argz_create(glibc_compatibility_test_argv, &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "argz_create test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "argz_create test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_create_sep test.
+   */
+  fprintf(out, "Test: argz_create_sep.\n"
+               "======================\n"
+               "An argz vector shall be created using the following test string:\n"
+               "\"%s\"\n"
+               "The delimiter character \'%c\' will be used as string separator\n"
+               "in the test string and will be replaced with \'\\0\' in the argz vector.\n", glibc_compatibility_test_string, delimiter);
+  error = argz_create_sep(glibc_compatibility_test_string, delimiter, &argz, &argz_len);
+  if (error)
+  {
+    fprintf(out, "\nargz_create_sep test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_create_sep test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_count test.
+   */
+  fprintf(out, "Test: argz_count.\n"
+               "=================\n"
+               "Count the strings contained in an argz vector.\n");
+  for (counts = 0; glibc_compatibility_test_argv[counts]; counts++)
+    ;
+  if (counts != argz_count(argz, argz_len))
+  {
+    fprintf(out, "argz_count test failed.\n");
+    exit(1);
+  }
+  else
+  {
+    fprintf(out, "\nargz_count test passed.\n");
+    fprintf(out, "counts: %zd\n", counts);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_add test.
+   */
+  fprintf(out, "Test: argz_add.\n"
+               "===============\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be added to the end of an argz vector.\n", BUFFER);
+  entry_index = argz_len;  /*  Remember the position of the entry that later will be deleted.  */
+  error = argz_add(&argz, &argz_len, BUFFER);
+  if (error)
+  {
+    fprintf(out, "\nargz_add test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_add test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_add_sep test.
+   */
+  delimiter = ':';
+  fprintf(out, "Test: argz_add_sep.\n"
+               "======================\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be added to the end of an argz vector.\n"
+               "The delimiter character \'%c\' will be used as string separator\n"
+               "in the test string and will be replaced with \'\\0\' in the argz vector.\n", BUFFER, delimiter);
+  error = argz_add_sep(&argz, &argz_len, BUFFER, delimiter);
+  if (error)
+  {
+    fprintf(out, "\nargz_add_sep test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_add_sep test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_delete test.
+   */
+  fprintf(out, "Test: argz_delete.\n"
+               "==================\n"
+               "The entry:\n"
+               "\"%s\"\n"
+               "will be deleted from argz vector.\n", BUFFER);
+  argz_delete(&argz, &argz_len, argz + entry_index);
+  fprintf(out, "\nargz_delete test passed.\n");
+  fprintf(out, "argz_len: %zd\n", argz_len);
+  fprintf(out, "argz:     %s\n", argz);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_append test.
+   */
+  fprintf(out, "Test: argz_append.\n"
+               "==================\n"
+               "The test string:\n"
+               "\"%s\"\n"
+               "shall be appended to the end of an argz vector.\n", BUFFER);
+  error = argz_append(&argz, &argz_len, BUFFER, sizeof(BUFFER));
+  if (error)
+  {
+    fprintf(out, "\nargz_append test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_append test passed.\n");
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_extract test.
+   */
+  fprintf(out, "Test: argz_extract.\n"
+               "===================\n"
+               "Store pointers to each string contained in the argz vector in an argv array,\n"
+               "which must be large enough to contain them inclusive the terminating NULL pointer.\n");
+  error = argz_add(&argz, &argz_len, BUFFER);
+  error = argz_add(&argz, &argz_len, BUFFER);
+  error = argz_add(&argz, &argz_len, BUFFER);
+  error = argz_add(&argz, &argz_len, BUFFER);
+  counts = argz_count(argz, argz_len) + 1;
+  argvp = malloc(counts * sizeof(*argvp));
+  fprintf(out, "\nargz_extract test passed.\n");
+  argz_extract(argz, 0, argvp);
+  fprintf(out, "argz_len=0\n");
+  fprintf(out, "argvp[0]: \"%s\"\n", argvp[0]);
+  fprintf(out, "\n");
+  argz_extract(argz, 1, argvp);
+  fprintf(out, "argz_len=1\n");
+  for (i = 0; i < 2; i++)
+    fprintf(out, "argvp[%zi]: \"%s\"\n", i, argvp[i]);
+  fprintf(out, "\n");
+  argz_extract(argz, argz_len, argvp);
+  fprintf(out, "argz_len: %zd\n", argz_len);
+  for (i = 0; i < counts; i++)
+    fprintf(out, "argvp[%zi]: \"%s\"\n", i, argvp[i]);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_next test.
+   */
+  fprintf(out, "Test: argz_next.\n"
+               "================\n"
+               "Get a pointer to the next entry in the argz vector after the entry passed to the function.\n");
+  fprintf(out, "\nargz_extract test passed.\n");
+  entry = NULL;
+  do {
+    fprintf(out, "entry passed (0x%p):  \"%s\"\t\t", entry, entry);
+    entry = argz_next(argz, argz_len, entry);
+    fprintf(out, "entry returned (0x%p):  \"%s\"\n", entry, entry);
+  } while (entry);
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_insert test.
+   */
+  fprintf(out, "Test 1: argz_insert.\n"
+               "====================\n"
+               "Insert entry in the argz vector before the string pointed by the pointer passed to the function.\n");
+  before = NULL;
+  error = argz_insert(&argz, &argz_len, before, BUFFER);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  thus  entry \"%s\" will be appended at the end of argz.\n", before, before, BUFFER);
+    print_result(out, argz, argz_len);
+  }
+  before = argz + argz_len / 2;
+  entry = strdup(before);
+  error = argz_insert(&argz, &argz_len, before, BUFFER);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  >  argz (0x%p): \"%s\"  thus  entry \"%s\" will be inserted before \"%s\".\n", entry, entry, argz, argz, BUFFER, entry);
+    print_result(out, argz, argz_len);
+  }
+  free(entry);
+  before = argz;
+  error = argz_insert(&argz, &argz_len, before, BUFFER);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p) == argz (0x%p)  thus  entry \"%s\" will be inserted before the beginnig of argz.\n", before, argz, BUFFER);
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_insert test.
+   */
+  fprintf(out, "Test 2: argz_insert.\n"
+               "==================\n"
+               "Insert entry in the argz vector before the string pointed by the pointer passed to the function.\n");
+  before = NULL;
+  error = argz_insert(&argz, &argz_len, before, BUFFER3);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  thus  entry: \"%s\" will be appended to the end of argz.\n", before, before, BUFFER3);
+    print_result(out, argz, argz_len);
+  }
+  before = argz + argz_len / 2;
+  entry = strdup(before);
+  error = argz_insert(&argz, &argz_len, before, BUFFER4);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p): \"%s\"  >  argz (0x%p): \"%s\"  thus  entry: \"%s\" will be inserted before \"%s\".\n", entry, entry, argz, argz, BUFFER4, entry);
+    print_result(out, argz, argz_len);
+  }
+  free(entry);
+  before = argz;
+  error = argz_insert(&argz, &argz_len, before, BUFFER5);
+  if (error)
+  {
+    fprintf(out, "\nargz_insert test failed: ENOMEM\n");
+    exit(error);
+  }
+  else
+  {
+    fprintf(out, "\nargz_insert test passed.\n");
+    fprintf(out, "before (0x%p) == argz (0x%p)  thus  entry (0x%p): \"%s\" will be inserted before the beginnig of argz.\n", before, argz, BUFFER5, BUFFER5);
+    print_result(out, argz, argz_len);
+  }
+  fprintf(out, "\n################################################################################\n\n\n");
+
+
+  /*
+   *  argz_stringify test.
+   */
+  delimiter = '/';
+  fprintf(out, "Test: argz_stringify.\n"
+               "=====================\n"
+               "Make a '\\0' separated argz vector printable by converting all the '\\0's\n"
+               "except the last into the character '%c'.\n", delimiter);
+  argz_stringify(argz, argz_len, delimiter);
+  fprintf(out, "\nargz_stringify test passed.\n");
+  print_result(out, argz, argz_len);
+  fprintf(out, "\n################################################################################\n\n\n");
+}
+
+
+void fixpath_and_realpath_test(FILE *out)
+{
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  fprintf(out, "\n\nTest of fixpath and realpath.\n"
+               "=============================\n");
+#else
+  fprintf(out, "\n\nTest of fixpath.\n"
+               "================\n");
+#endif
+
+  char *old_path = ".\\foo\\bar///";
+  char new_path[FILENAME_MAX];
+  char *this_dir;
+
+
+  /*
+   *  The broken version of _fixpath/realpath
+   *  only fails if the CWD is the root dir.
+   */
+  this_dir = getcwd(NULL, FILENAME_MAX);
+  if (!this_dir)
+  {
+    fprintf(out, "getcwd failed.\n");
+    return;
+  }
+  if (errno = 0, chdir("/"))
+  {
+    fprintf(out, "Cannot chdir to root dir (errno=%d).\n", errno);
+    goto finished;
+  }
+
+  errno = 0;
+  _fixpath(old_path, new_path);
+  if (errno == ENAMETOOLONG)
+  {
+    fprintf(out, "fixpath failed with ENAMETOOLONG.\n");
+    goto finished;
+  }
+  fprintf(out, "fixpath test:\n"
+               "old path=%s\n"
+               "new path=%s\n", old_path, new_path);
+  
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  errno = 0;
+  realpath(old_path, new_path);
+  if (errno == ENAMETOOLONG)
+  {
+    fprintf(out, "realpath failed with ENAMETOOLONG.\n");
+    goto finished;
+  }
+  fprintf(out, "\nrealpath test:\n"
+               "old path=%s\n"
+               "new path=%s\n", old_path, new_path);
+#endif
+
+finished:
+  if (errno = 0, chdir(this_dir))
+  {
+    fprintf(out, "Cannot chdir to \"%s\" (errno=%d).\n", this_dir, errno);
+    exit(1);
+  }
+  free(this_dir);
+}
+
+
+void lstat_and_stat_test(FILE *out)
+{
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  fprintf(out, "\n\nTest of lstat.\n"
+               "==============\n");
+#else
+  fprintf(out, "\n\nTest of stat.\n"
+               "================\n");
+#endif
+
+  struct stat s;
+  char *this_dir;
+  int e, r;
+
+
+  /*
+   *  The broken version of lstat or stat
+   *  only fails if the CWD is the root dir.
+   */
+  this_dir = getcwd(NULL, FILENAME_MAX);
+  if (!this_dir)
+  {
+    fprintf(out, "getcwd failed.\n");
+    return;
+  }
+  if (errno = 0, chdir("/"))
+  {
+    fprintf(out, "Cannot chdir to root dir (errno=%d).\n", errno);
+    goto finished;
+  }
+
+  errno = 0;
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  r = lstat(".", &s);
+#else
+  r = stat(".", &s);
+#endif
+  e = errno;
+
+  if (r)
+    fprintf(out, "lstat/stat failed with return value = %d and errno = %d.\n", r, e);
+  else
+    fprintf(out, "lstat/stat passed with return value = %d and errno = %d.\n", r, e);
+
+finished:
+  if (errno = 0, chdir(this_dir))
+  {
+    fprintf(out, "Cannot chdir to \"%s\" (errno=%d).\n", this_dir, errno);
+    exit(1);
+  }
+  free(this_dir);
+}
+
+
+void strlcat_and_strlcpy_test(FILE *out)
+{
+#define I_MAX 4
+
+  char *src = "string";
+  char dst[10] = "";
+  int i;
+  size_t len, size[I_MAX] = {10, 5, 1, 0};
+
+  fprintf(out, "\n\nTest of strlcat and strlcpy.\n"
+               "============================\n");
+
+  fprintf(out, "Testing:  len = strlcpy(dst, src, size);\n");
+  for (i = 0; i < I_MAX; i++)
+  {
+    fprintf(out, "src = \"%s\"   dst = \"%s\"   ", src, dst);
+    len = strlcpy(dst, src, size[i]);
+    fprintf(out, "res = \"%s\"   size = %zu   len = %zu\n", dst, size[i], len);
+  }
+  src[0] = 'x'; src[1] = ' '; src[2] = '\0';
+  dst[0] = 's'; dst[1] = 't'; dst[2] = 'r'; dst[3] = 'i'; dst[4] = 'n'; dst[5] = 'g'; dst[6] = '\0';
+  fprintf(out, "src = \"%s\"   dst = \"%s\"   ", src, dst);
+  len = strlcpy(dst, src, 3);
+  fprintf(out, "res = \"%s\"   size = %u   len = %zu\n", dst, 3, len);
+  src[0] = 'x'; src[1] = ' '; src[2] = '\0';
+  dst[0] = 'a'; dst[1] = ' '; dst[2] = 's'; dst[3] = 't'; dst[4] = 'r'; dst[5] = 'i'; dst[6] = 'n'; dst[7] = 'g'; dst[8] = '\0';
+  fprintf(out, "src = \"%s\"   dst = \"%s\"   ", src, dst);
+  len = strlcpy(dst, src, 10);
+  fprintf(out, "res = \"%s\"   size = %u   len = %zu\n", dst, 10, len);
+}
+
+
+void memmem_test(FILE *out)
+{
+#define LENGTH_OF(s)      (sizeof(s) - 1)  /*  Without the terminating zero.  */
+
+#define HAYSTACK_STRING   "\0001234567890\xB0"
+#define HAYSTACK_LENGTH   LENGTH_OF(HAYSTACK_STRING)
+
+
+  typedef const struct {
+    const char   *str;
+    const size_t  len;
+  } substring_t;
+  substring_t needle[] = {
+    {"456",       LENGTH_OF("456")},
+    {"\00012",    LENGTH_OF("\00012")},
+    {"90\xB0",    LENGTH_OF("90\xB0")},
+    {"ABC",       LENGTH_OF("ABC")},
+    {"0\xB0\000", LENGTH_OF("0\xB0\000")},
+    {"\xB0",      LENGTH_OF("\xB0")},
+    {NULL,  0}
+  };
+  char *begin;
+  const char haystack[HAYSTACK_LENGTH + 1] = HAYSTACK_STRING;
+  int i;
+
+  fprintf(out, "\n\nTest of memmem.\n"
+               "===============\n");
+
+  for (i = 0; needle[i].str; i++)
+  {
+    int j;
+
+    fprintf(out, "Searching for \"");
+    for (j = 0; j < needle[i].len; j++)
+      if (needle[i].str[j] != '\0')
+        fprintf(out, "%c", needle[i].str[j]);
+      else
+        fprintf(out, "\\0");
+    fprintf(out, "\" in \"");
+    for (j = 0; j < HAYSTACK_LENGTH; j++)
+      if (haystack[j] != '\0')
+        fprintf(out, "%c", haystack[j]);
+      else
+        fprintf(out, "\\0");
+    fprintf(out, "\":  ");
+    if ((begin = memmem(haystack, HAYSTACK_LENGTH, needle[i].str, needle[i].len)))
+      fprintf(out, "found at position %u.\n", begin - haystack);
+    else
+      fprintf(out, "not found.\n");
+  }
+}
+
+
+void mbtowc_test(FILE *out)
+{
+  int ret_value;
+  fprintf(out, "\n\nTest of mb/wc family of functions.\n"
+               "==================================\n");
+
+  /*  Testing mblen.  */
+  ret_value = mblen(NULL, 1);
+  if (ret_value != 0)
+    fprintf(out, "mblen(NULL, 1) should return 0 but returned %d.\n", ret_value);
+  else
+  {
+    ret_value = mblen("", 1);
+    if (ret_value != 0)
+      fprintf(out, "mblen(\"\", 1) should return 0 but returned %d.\n", ret_value);
+    else
+    {
+      char *string = "FOOBAR";
+      ret_value = mblen(string, 0);
+      if (ret_value != -1)
+        fprintf(out, "mblen(\"%s\", 0) should return -1 but returned %d.\n", string, ret_value);
+      else
+      {
+        ret_value = mblen(string, 1);
+        if (ret_value != 1)
+          fprintf(out, "mblen(\"%s\", 1) should return 1 but returned %d.\n", string, ret_value);
+        else
+        {
+          /*  Testing mbtowc.  */
+          ret_value = mbtowc(NULL, NULL, 0);
+          if (ret_value != 0)
+            fprintf(out, "mbtowc(NULL, NULL, 0) should return 0 but returned %d.\n", ret_value);
+          else
+          {
+            ret_value = mbtowc(NULL, string, 0);
+            if (ret_value != -1)
+              fprintf(out, "mbtowc(NULL, \"%s\", 0) should return -1 but returned %d.\n", string, ret_value);
+            else
+            {
+              ret_value = mbtowc(NULL, string, 1);
+              if (ret_value != 0)
+                fprintf(out, "mbtowc(NULL, \"%s\", 1) should return 0 but returned %d.\n", string, ret_value);
+              else
+              {
+                wchar_t awc[8];
+                ret_value = mbtowc(awc, string, 1);
+                if (ret_value != 1)
+                  fprintf(out, "mbtowc(\"%ls\", \"%s\", 1) should return 1 but returned %d.\n", awc, string, ret_value);
+                else
+                {
+                  /*  Testing mbsinit.  */
+                  mbstate_t mbs;
+                  ret_value = mbsinit(NULL);
+                  if (ret_value != 1)
+                    fprintf(out, "mbsinit(NULL) should return 1 but returned %d.\n", ret_value);
+                  else
+                  {
+                    mbs.__count = 0;
+                    ret_value = mbsinit(&mbs);
+                    if (ret_value != 1)
+                      fprintf(out, "mbsinit(&mbs) should return 1 but returned %d.\n", ret_value);
+                    else
+                    {
+                      mbs.__count = 1;
+                      ret_value = mbsinit(&mbs);
+                      if (ret_value != 0)
+                        fprintf(out, "mbsinit(&mbs) should return 0 but returned %d.\n", ret_value);
+                      else
+                      {
+                        /*  Testing mbrtowc.  */
+                        ret_value = mbrtowc(awc, NULL, 1, &mbs);
+                        if (ret_value != 0)
+                          fprintf(out, "mbrtowc(\"%ls\", NULL, 1, &mbs) should return 0 but returned %d.\n", awc, ret_value);
+                        else
+                        {
+                          ret_value = mbrtowc(awc, string, 1, &mbs);
+                          if (ret_value != 1)
+                            fprintf(out, "mbrtowc(\"%ls\", \"%s\", 1, &mbs) should return 1 but returned %d.\n", awc, string, ret_value);
+                          else
+                            fprintf(out, "All tests passed.\n");
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+void scanf_test(FILE *out)
+{
+#define BUFFER_LENGTH  32
+#define PI             3.1415926535897932384626433832795L
+#define EULER          2.7182818284590452353602874713527L
+
+  char buffer[BUFFER_LENGTH];
+  long double test_out, test_in = PI;
+
+
+  fprintf(out, "\n\nTest of %%A and %%a support of the scanf family of functions.\n"
+               "===========================================================\n");
+
+  snprintf(buffer, BUFFER_LENGTH, "%.15LA%c", test_in, '\0');
+  sscanf(buffer, "%La", &test_out);
+  if (test_in != test_out)
+    fprintf(out, "Test value = 3.1415926535897932384626433832795L\nscanf(\"%%LA\") should have got %.15LA but got %.15LA.\n", test_in, test_out);
+  else
+  {
+    test_in = EULER;
+    snprintf(buffer, BUFFER_LENGTH, "%.15LA %c", test_in, '\0');
+    sscanf(buffer, "%LA", &test_out);
+    if (test_in != test_out)
+      fprintf(out, "Test value = 2.7182818284590452353602874713527L\nscanf(\"%%LA\") should have got %.15LA but got %.15LA.\n", test_in, test_out);
+    else
+      fprintf(out, "All tests passed.\n");
+  }
+}
+
+
+void open_test(FILE *out)
+{
+  const char *filename = "foobar.dir";
+  const char *filename_with_slash = "foobar.dir/";
+  int fd;
+
+  fprintf(out, "\n\nTest of POSIX conforming behaviour of open for pathnames with trailing slash.\n"
+               "=============================================================================\n");
+
+  fd = open(filename, O_CREAT | O_WRONLY | O_RDWR);
+  close(fd);
+  
+  errno = 0;
+  fd = open(filename_with_slash, O_CREAT | O_WRONLY | O_RDWR);
+  if (fd != -1)
+    fprintf(out, "Test failed - unexpected open() success writing to file \"%s\"\n", filename_with_slash);
+  if (errno != EISDIR)
+    fprintf(out, "Test failed - wrong errno returned: %s\n", strerror(errno));
+
+  fd = open(filename_with_slash, O_RDONLY);
+  if (fd != -1)
+    fprintf(out, "Test failed - unexpected open() success reading from file \"%s\"\n", filename_with_slash);
+  if (errno != ENOTDIR)
+    fprintf(out, "Test failed - wrong errno returned: %s\n", strerror(errno));
+
+  fd = open("", O_RDONLY);
+  if (fd != -1)
+    fprintf(out, "Test failed - unexpected open() success reading from dir \"\"\n");
+  if (errno != EINVAL)
+    fprintf(out, "Test failed - wrong errno returned: %s\n", strerror(errno));
+
+  fprintf(out, "All tests passed.\n");
+  unlink(filename);
+}
+
+
+void fopen_freopen_fflush_fseek_ftell_fclose_rewind_test(FILE *out)
+{
+  FILE *test_file;
+  long value;
+
+
+  fprintf(out, "\n\nTest of fopen/freopen/fflush/fseek/ftell/fclose/rewind.\n"
+               "=======================================================\n");
+  errno = 0;
+  test_file = fopen("./tfile1.txt", "w");
+  if (!test_file)
+  {
+    fprintf(out, "File opening failed with errno =%d\n", errno);
+    return;
+  }
+
+  fprintf(test_file, "123456foobar");
+
+  errno = 0;
+  rewind(test_file);
+ 
+  fprintf(test_file, "raboof");
+
+  errno = 0;
+  value = fflush(test_file);
+  if (value)
+  {
+    fprintf(out, "File flushing failed with errno =%d\n", errno);
+    return;
+  }
+
+  errno = 0;
+  test_file = freopen("./tfile2.txt", "w", test_file);
+  if (!test_file)
+  {
+    fprintf(out, "File reopening failed with errno =%d\n", errno);
+    return;
+  }
+
+  errno = 0;
+  value = ftell(test_file);
+  if (value == -1)
+  {
+    fprintf(out, "File telling failed with errno =%d\n", errno);
+    return;
+  }
+  errno = 0;
+  value = fseek(test_file, 6, SEEK_SET);
+  if (value)
+  {
+    fprintf(out, "File seeking failed with errno =%d\n", errno);
+    return;
+  }
+  fprintf(test_file, "XYZ");
+
+  errno = 0;
+  value = fclose(test_file);
+  if (value)
+  {
+    fprintf(out, "File closing failed with errno =%d\n", errno);
+    return;
+  }
+
+  fprintf(out, "All tests passed.\n");
+  unlink("./tfile2.txt");
+  unlink("./tfile1.txt");
+}
+
+
+int main(void)
+{
+  FILE *out;
+
+  out = fopen("test.txt", "w");
+  if (out == NULL)
+  {
+    printf("Can not open test.txt.  Test failed.\n");
+    return 1;
+  }
+
+  printf("Testing:\n"
+         "  printf family of functions...\n");
+  flags_test(out);
+  length_modifiers_test(out);
+  numeric_conversion_specifiers_test(out);
+  printf_test(out);
+
+  printf("  signbit...\n");
+  signbit_test(out);
+
+  printf("  argz...\n");
+  argz_test(out);
+
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  printf("  _fixpath and realpath...\n");
+#else
+  printf("  _fixpath...\n");
+#endif
+  fixpath_and_realpath_test(out);
+
+#if (__DJGPP__  == 2) && (__DJGPP_MINOR__ >= 4)
+  printf("  lstat...\n");
+#else
+  printf("  stat...\n");
+#endif
+  lstat_and_stat_test(out);
+#if 0
+  printf("  strlcat and strlcpy...\n");
+  strlcat_and_strlcpy_test(out);
+#endif
+  printf("  memmem...\n");
+  memmem_test(out);
+  printf("  mb/wc...\n");
+  mbtowc_test(out);
+  printf("  scanf...\n");
+  scanf_test(out);
+  printf("  open...\n");
+  open_test(out);
+  printf("  fopen/freopen/fflush/fseek/ftell/fclose/rewind...\n");
+  fopen_freopen_fflush_fseek_ftell_fclose_rewind_test(out);
+  fclose(out);
+
+  printf("The test output is in ./tests/test.txt\n");
+  return 0;
+}
