======================================================================
NOTE: I use vi with a tabstop value of 3. Using the same tabstop
		value will make the text/code look properly indented.
======================================================================


What is SIO ?

SIO is a library that provides _stream_ I/O which is what most Unix
programs do. As such it is a competitor to stdio.


Why you would care to use it ?

a. It is a little faster than stdio
b. It provides an easier-to-use interface (personal opinion)
c. It is capable of using memory mapping for reading files if the OS 
	supports it.
d. If you have a program that uses read(2)/write(2) it is trivial
   to convert it to use SIO (just replace read with Sread and 
   write with Swrite)
e. You get source



How to install the Stream I/O (SIO) library

There are 3 parts in installing SIO: setting up a sioconfig.h file,
setting up the Makefile and testing SIO.


1. Setting up sioconfig.h

The OS specific parts of SIO have been placed in the sioconfig.h file.
This file is a link to the actual configuration file in the Config 
directory. Configuration files for the following OS's are available:

SunOS 4.x, Ultrix 4.[12], UMIPS-BSD (BSD 4.3 derivative).

Currently the Makefile will create the sioconfig.h link correctly
if you use one of the above OS's, but you may want to disable
that Makefile target and create the link manually (this is recommended).
If there is no configuration file for your OS, you can create one by
using one of the existing ones as a template. Also, make sure you
disable the sioconfig.h target in the Makefile and create the link
manually.
Here is what needs to be defined in sioconfig.h:


1.1. Memory mapping

If your OS supports memory mapping of regular files and you want to 
use that option then define MEMORY_MAP. If you define MEMORY_MAP
you will also need to define the macros SIO_MMAP, SIO_MUNMAP and 
SIO_MNEED. Check the other configuration files for the arguments of 
these macros.
SIO_MNEED informs the OS about a part of the address space that 
will be needed shortly. Its existence is not mandatory; if your OS
does not support it, define it like this:
	#define SIO_MNEED( addr, len )			/* NOTHING */


1.2. Finalization function

The purpose of a finalization function is to do work after your
program has called exit(3). In the case of SIO, this means flushing
the SIO output buffers.
If your OS supports the installation of finalization functions you
should define HAS_FINALIZATION_FUNCTION. Then you must define the
macros SIO_FINALIZE and SIO_DEFINE_FIN. SIO_FINALIZE attempts
to install a finalization function and returns TRUE if successful, FALSE
if unsuccessful. SIO_DEFINE_FIN defines the finalization function
(the reason for this macro is that different systems pass different
number/type of arguments to the finalization function; the SIO finalization
function does not use any arguments). Check the other configuration
files for examples of how to define these macros.


1.3. General flags

The HAS_MEMOPS flag should be defined if your OS supports the mem* functions
(memcpy etc). If not, then you can define HAS_BCOPY if your OS supports bcopy.
At most one of HAS_MEMOPS, HAS_BCOPY should be defined.
You should define the flag HAS_ISATTY if the function isatty exists in
your C library. This library identifies if a desciptor refers to a
terminal.
You must define N_SIO_DESCRIPTORS to be equal to the maximum number of file
descriptors per process supported by your OS.


1.4. Sprint constants

These are constants that affect the Sprint function:
SMALLEST_INT is the smallest (negative) integer that fits in a machine word.
S_SMALLEST_INT is that integer in string form (without the '-' sign).
S_SMALLEST_INT_LEN is the length of that string.
You should also define LONG_IS_BIGGER if sizeof(long) > sizeof(int).
In that case you also need to write functions to
	a) convert a long to a string in decimal notation (similar to
		the function conv_10)
	b) convert a long to a string in octal or hexadecimal notation 
		(similar to the function conv_p2)

Currently the constants are set for a 32-bit 2's complement machine.


2. The SIO Makefile

The Makefile has a header that explains what the Makefile can do.
The only flag that you can define is -DDEBUG which enables 
assertions in the SIO code (if an assertion fails, the program is 
terminated with an error message that lists the SIO file and line 
number where the error occured).
A simple 'make' command creates libsio.a in the current directory.
If you want to install SIO at some other point of the directory
tree use 'make install'. That will cause the following:

a) libsio.a will be moved to LIBDIR
b) the necessary SIO header files will be copied to INCLUDEDIR
c) the SIO man pages will be copied to MANDIR

LIBDIR, INCLUDEDIR, and MANDIR are Makefile variables that you must
define.


3. Testing SIO

After you have successfully compiled SIO, you can use the programs
in the suite/ directory to test all SIO functions.
Testing should be done before installing the library.
The script testlib does everything; just type:

	testlib all

The script sprint_test (invoked by testlib) tests Sprint by using a variety 
of formats and comparing its output with that of an ANSI-compatible printf.
On Ultrix systems this test fails since printf is not ANSI-compatible.
You can test the rest of the SIO functions by typing:

	testlib all Sprint

(anything after the 'all' argument is interpreted as a function that
should not be tested)



Epilogue

Feel free to modify SIO to suit your needs. Please let me know of
any bugs you find.
If you want to distribute your patches, please read the COPYRIGHT file.
It basically says that you are free to redistribute as long as you make 
sure that your modifications are identifiable. In order to achieve this
I have reserved the first 3 components of the version number (e.g. 1.4.0)
and you can identify your mods by appending another component to that 
version number. Also, you take full responsibility for any bugs in
the code (not just your code; the whole thing).

