file: florist/README [$Revision: 1.8 $]

THIS SOFTWARE AND THE ACCOMPANYING DOCUMENTATION ARE DISTRIBUTED
IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY;
WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
FOR A PARTICULAR PURPOSE -- NOTWITHSTANDING ANY STATEMENTS MADE
BELOW IN THIS FILE.

FLORIST:

This directory contains the components of FLORIST, an
implementation of the IEEE Standards 1003.5: 1992 and IEEE STD
1003.5b: 1996, also known as the POSIX Ada Bindings.

All the code in this directory is copyrighted by the Florida
State University (FSU), except for any files that contain
statements indicating the copyright belongs to someone else.

The FSU-copyrighted code is free software; you can redistribute it
and/or modify it under terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or
(at your option) any later version.  FLORIST is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.  See the GNU General Public License for more
details.  You should have received a copy of the GNU General
Public License distributed with GNARL (see file COPYING).  If not,
write to the Free Software Foundation, 59 Temple Place - Suite
330, Boston, MA 02111-1307, USA.
                                                                          
As a special exception, if other files instantiate generics from
this unit, or you link this unit with other files to produce an
executable, this unit does not by itself cause the resulting
executable to be covered by the GNU General Public License. This
exception does not however invalidate any other reasons why the
executable file might be covered by the GNU Public License.

PREREQUISITES:

You will need the GNAT compiler and tools to install and compile
Florist.  If you happen to have another compiler, you still may
find Florist useful as a starting point, but some adaptation will
be necessary.

You will probably also need the Gnu "make" utility.  We have
periodically made attempts to "purify" the Makefile of Gnu
extensions, so that it would work with any POSIX-compliant make
utility.  However, the extensions (notably pattern-matching rules)
have a way of creeping back in.  If your "make" does not work on
this Makefile we recommend you download a copy of Gnu make to use
for the installation process; otherwise, you will have to modify
the Makefile's to work around the places where we are using Gnu
extensions.

The dependences on GNAT are to some extent unavoidable, though we
think that with more work we may be able to automate the treatment
better, as we have attempted manage dependences on the host
operating system.  This is the hard part, and the fundamental job,
of a POSIX Ada binding-- to make writing portable applications
easier, by taking into the implementation of the binding the
responsibility for dealing with the differences between various
operating systems and compilers, and hiding them from application
programs.

Any implementation of the POSIX Ada bindings will necessarily
contain some dependences on peculiar features of the Ada language
implementation with which it is intended to be used.  For example,
the two implementations must coordinate the way they manage
signals, and must work together to support task signal entries.
Another place where the two must work together is in the
implementation of Start_Process, which uses the underlying POSIX
fork() operation.  With POSIX threads, fork() creates only thread
in the child process, but it duplicates the entire parent process
address space, including the runtime system data structures that
contain references to the other threads of the parent process, and
locks that may appear to be holding.  The code in Start_Process
that executes between the fork() and exec() operations must have
some way to avoid invoking Ada runtime system operations that will
try to reference these nonexistent threads, or lock any locks that
they might appear to be holding.

In the case of Florist, there are also some other GNAT
dependences, which are for convenience and efficiency.  For
example, Florist relies that Duration and Calendar.Time are both
represented as a 64-bit count of nanoseconds, so as to simplify
conversions between these types and POSIX.Timespec.

----------------
--  WARNINGS  --
----------------

This Ada binding implementation depends on your underlying OS
having C header-files and libraries that conform to the POSIX
standards.  It will try to use constants, types, and functions
defined in POSIX.1, POSIX.1b, POSIX.1c, and the proposed POSIX.1g
standard.  The degree to which the Ada binding works and conforms
to the POSIX.5 and POSIX.5b standards will be limited by how well
your OS conforms to the corresponding C API's.

So far, we have not found any operating system that fully supports
the POSIX.1b and POSIX.1c standards, though they are getting
better.  Generally, you will get better results with newer OS
releases, since their C API's are closer to the POSIX standards.
It is also a good idea to make sure that your installation
includes the header files and libraries needed for the real-time
and threads extensions.  (The default "end user" OS installation
may try to save you disk space by not installing them.)

Do not attempt to use any of the packages POSIX_Sockets,
POSIX_Sockets.Internet, POSIX_Sockets.Local, POSIX_Sockets.ISO,
POSIX_XTI, POSIX_XTI.Internet, POSIX_XTI.ISO, POSIX_XTI.MOSI,
POSIX_Event_Management.  These are parts of a POSIX.5c prototype
effort that stalled during the ballot/revision process.  The
package specifications here DO NOT YET CONFORM to the approved
POSIX.5c standard, nor are they fully implemented.

NORMAL INSTALLATION:

Florist is intended to be self-configuring for systems that
conform to the POSIX C-language interface standards.  It has been
ported to a number of operating systems, including various
versions of Solaris, Linux, Digital Unix (OSF1), AIX, IRIX,and
HP-UX.  At FSU, we cannot regularly do regression testing on all
the systems to which Florist has been ported, so regressions are
possible.  Therefore, we do not claim that it will install
painlessly, even on those systems.  However, the autoconfiguration
script is likely to work at least partially on most mainstream
UNIX systems.

On the systems where the configure script and Makefile have been
tested, the following instructions should work.  For other
systems, give it a try.  It might work, at least partially,
possibly with a little bit of modification to fit your particular
system.  See "PORTING", further down this file, for more
suggestions on porting Florist to other systems, and more
explanation of the configuration process.  Also see the section
"MAINTENANCE" on whom to contact for advice on porting.

In order to install FLORIST, you should go through the following
steps.

0. Make sure you have GNAT and Gnu make installed,
   and that your environment variables are set up to provide GNAT
   with the appropriate paths.  You will need the tool "gnatprep".
   If it is not included in your GNAT distribution, you can make
   it from sources included here.

1. Configure FLORIST by typing "./configure".
   This may take a long time, perhaps an hour or more.
   You probably should capture the output, in case something goes
   wrong and the relevant error message scrolls off your screen,
   e.g.
        ./configure >& configure.log

   The configure script will try to find out information about the system
   you are using.  This includes information about the GNAT version,
   and whether each of the features of the POSIX C-language interfaces
   is supported.  This step generates the files:

   gnatprep.config       directives for gnatprep
   pconfig.h             #includes and #defines needed to use POSIX
   config.h              configuration for c-posix.c
   Config                definitions to be included in Makefile

   Note that if "configure" does not work for your system as-is,
   you can tailor it by editing the files "pconfig.h.in" and
   "Config".  Some examples of these can be found in the "configs"
   subdirectory.

   Along the way, configure will tell you about the various
   features it is checking, and whether it finds
   them.  Don't worry if it fails to find some features.
   That is normal, since no operating system we know has yet
   fully caught up to the POSIX standards.  Assuming the configuration
   process works correctly, the unsupported features will just
   raise POSIX_Error if you try to use them.

   The POSIX.1g (sockets and XTI) interfaces are still very new, and
   not supported widely; the configure stage will attempt to work around
   missing features.  If it fails badly, you can still build the rest of
   Florist.  (One should not be using the POSIX.5c interfaces anyway,
   as explained above.)

   NOTE:  If you change versions of GNAT, you will need to re-run the
   "configure" script, and recompile Florist, since the
   signal-handling and process primitives packages contain code that
   interacts with the Ada tasking runtime system.

   NOTE:  Do not delete the empty file "florist_sources".  The configure
   script checks for this file, to make sure it is in the right source
   directory.

2. Build and compile FLORIST by typing "make".  This will
   *automatically* perform many operations, including the following:

  a. Compile and execute the program "c-posix.c", which
     generates the source code for the Ada package specifications
     POSIX, POSIX.C, POSIX.LIMITS, and POSIX.OPTIONS.
     If this stage fails, you will need to do some work.
     The best thing is to capture the error messages,
     and e-mail them to me.  I will work with you to figure out
     what needs to be done to support your system.

  b. Compile several C-language programs "XXX-macros.c".

  c. Perhaps compile the GNAT preprocessor, "gnatprep", if you don't
     have it already.

  d. Use gnatprep to tailor some Ada source files to your system.

  e. Compile the various POSIX Ada package specifications and
     bodies.

  [We apologize for the complexity of the above configuration process,
   and how long it takes.  We have some ideas for simplifying it and
   speeding it up in future versions.]

3. If this all succeeds, try testing the installation.
   See below, for more explanation.

TESTING THE INSTALLAITON:

Florist contains an increasingly large and complete set of tests.
The tests are in subdirectory "tests".

DO NOT RUN THE TESTS AS ROOT, UNLESS YOU ARE VERY FOOLHARDY,
OR YOU HAVE EXAMINED THE TESTS AND ARE PREPARED TO ASSUME THE
RISK OF POSSIBLE DAMAGES IF THE TEST RUNS AMOK.

If you want to just compile and run all the tests, do "make
run_tests".  The tests will be run in subdirectory
tests/test.dir.  Even if everything works correctly, it
will take a long time to run.  There is a good chance that one of
the tests will hang or crash the test run.  If so, try removing
that test from the script "run_tests_1", and restarting,
or try running the tests individually.

It is easy to compile and run the tests individually.  For
example, p020400 is a test of the basic POSIX package.  That would
be a good one to start with.  When you are running a test you can
get more output by using the "-v" (verbose) command-line option,
e.g., "p020400 -v".

Even if you have installed everything correctly, you should expect
some tests to fail.  Some of apparent failures may not be real;
the tests try to perform operations that require special
privilege, and you will probably not be running them with that
privilege, at least for the first time.  There will be other
failures if the underlying OS does not fully support the POSIX
standards, or if Florist does not fully support a given
functionaliy. See the file PASSFAIL, for a summary of the known
(real) failures for Solaris 2.6, You should expect to find more
test failures if you are porting to a new system.

In the case of a test failure you will want more verbose output,
which you can obtain by running the tests with the "-v" option.
Using the information produced, you should locate the problem area
in the source code.  We have tried to provide explanations for all
the known failing/hanging problems. Please see the comments
provided in the test source. If you do not find any explanation
for the problem you are having, please report it to us.  We are
working on improving the tests, and welcome test contributions.

Chances are good that your installation will not pass all the
tests, and some may even hang.  This probability grows higher as
we extend Florist and improve the test suite, since most operating
systems seem to have some defects in their underlying support for
the POSIX (C-language) standards.  A few failures do not
necessarily mean you can't use Florist.  They just point out
places where you should beware that your system is not really
POSIX compliant.

See tests/README for more explanation.

COMPILING YOUR PROGRAMS WITH FLORIST:

To compile your own programs with Florist, take a look at
tests/Makefile, to see how the tests are compiled.  You will need
to include the gnatmake parameters that specify where to find the
Florist sources and object library file.

If you don't want to keep around the whole Florist installation
directory, you should be able to copy or move the subdirectory
"floristlib" to some other location, and then include it in
your GNAT source and object library search paths.

BACKGROUND:

The name FLORIST is a meld of "FLORIDA" and "FOREST", indicating
the dual origins of this implementation, which we hope combines
the virtues of two earlier implementations of the POSIX Ada
bindings: one being FOREST, done by Kenneth Almquist, and the
other being the FSU POSIX.5 implementation primarily by Lin
Wan-Hua and Li Yi-Gang.  My original intent was to literally merge
the code of these two versions, but they were so different that I
ended up writing essentially all new code.  However, the those
other implementations still formed the conceptual starting point
for FLORIST.

This work and the earlier POSIX Ada binding developments were
funded by the U.S. Department of Defense's Ada Joint Program
Office, originally through the U.S. Army CECOM HQ U.S. Army CECOM,
Software Engineering Directorate, and more recently through the
ICASE program.

PHILOSOPHY AND STYLE:

The FLORIST implementation of the POSIX Ada bindings attempts to
adhere to the following design and style rules:

1. Conform to the IEEE Standards 1003.5 and 1003.5b, to the extent they
   can be implemented.

2. Assume the underlying OS supports the POSIX C-language interfaces
   (i.e. IEEE STD 1003.1, 1003.1b, 1003.1c) correctly.
   That is, do not attempt to compensate via Ada "glue" for failures
   in the implementation of the C-language interface.

3. Map as directly as possible to these underlying C-language interfaces,
   so as not to impose any avoidable run-time or storage overhead.

4. Entirely avoid use of the Interfaces.C and Interfaces.C.Strings packages,
   using the (more complete) C interface package POSIX.C instead.

5. Limit dependences on specifics of the underlying OS
   to automatically configurable code (i.e. specs of packages
   POSIX, POSIX.Limits, POSIX.Options, and POSIX.C).

6. Use "access" parameter mode where the C interface uses a pointer
   to achieve the effect of an "out" or "in out" parameter; use
   "access constant" types where the C interface uses a pointer to
   achieve the effect of an "in" parameter passed by-reference.

7. Enclose C interface types in a tagged record where the standard
   Ada API specifies that they be passed as "out" or "in out" parameters
   and standard Ada API requires by-reference semantics.

8. Take advantage of knowledge about how GNAT and GNARL implement things.
   For example, rely on fact that Duration is a count of nanoseconds.

We have made a few small exceptions to these rules, where one rule
conflicted with another.  There are comments about these issues in
the code of the Florist packages, and under DEFECTS, below.  As
Florist evolves, we expect we may revisit some these compromises.

See other files in this directory for more information.

KNOWN DEFECTS:

The following is a list of some major known defects and weaknesses
in FLORIST.  Beware that the list has not been updated recently.

-- Defects in the underlying OS. 

We have not tried to compensate for cases where the C-language API
of the underlying OS fails to comply with the POSIX
specifications.  Mostly this shows up as simple lack of support
for a given feature.  In some cases it shows up as an incorrect
error code, or a more seriously incorrect action.  This is
especiallly noticeable with the Provenzano thread package which is
used in the early GNAT implementations for Linux; there are
several places where a single-threaded application works OK, but
linking in the Provenzano thread library alters the behavior so
that tests fail.  Likewise, the LeRoy Linux thread implementation
is very far from conformance to the POSIX standard.  To verify
some of these problems, we wrote several test programs in the C
language.  These include the programs listed as DEBUG_SOURCES in
the Makefile.  Each has a few comments to explain what it is
testing for.

One may imagine that we might have added code to the Ada binding
to detect and/or compensate for failures of the OS to conform to
the POSIX C API standards, so that the Ada binding would still
conform to the POSIX Ada API standard.  In some cases, this is
possible, but we have not attempted to do it.  The main reason is
that we could not afford to develop and maintain special code for
each OS version and release.  We do expect that over time the OS's
will improve their conformance to the POSIX C-API specs, and as
they do so, the conformance of Florist to the POSIX Ada semantics
will relect the same improvements.

-- Treatment of missing and unsupported features.

The treatment of features that are missing or unsupported in the
C-language interface is pretty rough-shod.  Dummy declarations are
automatically provided for missing C names.  Not a lot of thought,
and no testing, has so far been put into whether these will
generate POSIX_Error with the appropriate error code, if an
optional feature is missing - still less, what will happen if
any of the required POSIX features are missing.

Generally, each C function has its name declared as a constant,
with an identifier ending in "_LINKNAME", declared in package
POSIX.C.  If the C function was not found by the configure
process, this string is set to "nosys_neg_one", a function that
returns (int) -1 with error code ENOSYS.  This is the most common
POSIX treatment of an unsupported feature, but it is not always
correct.

Minimally, we need to check the handling of the not-supported case
for each C interface function, and be more precise about
not-supported treatment:

   some of them should return -1, but of a type that is a different
     size than "int"
   some of them should return ENOSYS directly, rather returning -1
     and setting errno to ENOSYS
   some of them may set errno to ENOSYS when they should set it
     to ENOTSUP

We also need to put in some conditional code, using constants in
POSIX.C of the form HAVE_xxx (generated by the configure script
and c-posix.c), for places where we have code that depends on an
optional type or constant.

Getting the treatment of all these optional features right is
going to take more time and effort.  (We appreciate your reporting
any problems, so we can fix them.)

-- POSIX.Group_Database

In general there is a problem in C with library routines that
return pointers to data (e.g. to strings).  Traditionally, these
return pointers to statically allocated data, which means they are
not safe for concurrent use.  If they are "fixed" to return pointers
to dynamically allocated storage, then we have storage leakage.

The best way to make such interfaces safe for Ada multitasking
use would be to make a copy of the data.  The problem is that
we need a way to recover the storage.

In the case of this package, POSIX.5 specifies that the type
Group_Database_Item is private (meaning we can copy values) but it
does not allow us to implement it as an access type (a requirement
based on a desire to avoid potential storage leakage).  This
leaves us with a problem.  There is no fixed size, so we would
like to make the size depend on a discriminant.  We can't do this,
as the interface stands.

This leaves us few options:

 (a) impose a fixed size limit, which might overflow;
 (b) use dynamic allocation, risking storage leakage;
 (c) use the raw C interfaces, risking tasking unsafety
     and also storage leakage.

With Ada'95 we have another possibility, of using a controlled
type.  In this way we can perhaps circumvent the intent of the
POSIX.5 rule about not using access types (i.e. not using heap
allocation), by arranging for storage to be recovered.

Note that using the new thread-safe operations, getgrgid_r and
getgrnam_r, does not solve our problem, since we would still have
to provide space to hold the strings.  We choose to use the raw C
interfaces, since the other alternatives are not significantly
more attractive.  See also POSIX.User_Database.

-- POSIX.User_Database

Same problem as POSIX.Group_Database.

-- POSIX.Process_Identification

Need to make Get_Login_Name "tasking-safe".
See POSIX.Group_Database for discussion of the general problem.

-- POSIX.Process_Primitives

A basic problem is that the child process will have only the
thread that called Fork.  Thus, if some other thread is holding a
runtime system lock and we need to lock it, we will have a
deadlock.  We have tried to handle this by switching back the
non-tasking versions of some runtime system routines by resetting
the "soft links".  It is unclear whether this is going to be
enough, especially as GNAT evolves to get rid of these soft links.

-- POSIX.Supplement_to_Ada_IO

This package interface is wicked!  The "flush" operations have no
parameters, which means we need some magical way of finding all
the buffers we are supposed to flush.  We can see no way to do
this without modifying the implementations of all the standard I/O
packages, so that we can get at a list of currently open files, and
their associated buffers.  Looking at these packages, it seems they
have some kind of list which might serve the purpose, if we export it,
possibly with some additional information.  However, those packages
appear to be like Pandora's Box.  Once we start looking at how they
attempt to handle concurrent access to shared data structures, we find
more and more things need attention, and we have trouble deciding how
far to go toward making "everything" tasking-safe.

-- POSIX.Timers

Perhaps Signal_Event should be made into a tagged type, so that
Create_Time (and other operations in other packages) can assume
the event is passed by reference.  This would help us avoid making
an aliased local copy for communication with the C interface.

-- POSIX

POSIX.String_List should probably be made into a controlled type,
so that we can avoid the potential storage leakage from the
function POSIX.Process_Environment.Argument_List.

-- FOREST Compatibility

We had originally intended that Florist be an upward-compatible
extension of K. Almquist's Forest packages.  This turned out to
conflict with our desire to conform to the IEEE POSIX.5 and
POSIX.5b standards, since Forest contained some extensions that
are not allowed by those standards.  No one has complained about
missing those extensions, so we have let them rest in peace.

-- LINUX Problems

For Linux, we ran into some incompatibilities between Kernel 2.0X
and the version of Pthreads we were using.  There were some
duplicate and incompatible declarations, between pthread_attr.h
and sched.h, that prevent the program c-posix.c from compiling.
To compile it, we had to modify pthread_attr.h to resolve these
conflicts.  The result may have some undesirable side-effects, but
we have not yet noticed them.  We also found a typo in
/usr/include/linux/sched.h, where one of the __P's was mis-typed
as _P.  This needed to be hand-edited.  The automatic
configuration script does not know how to make these changes; it
simply drops support for thread-operations if it detects a
conflict.

We have tried Florist with the new (Leroy) Linux native threads,
and glibc version 2 (which seems to be the default C library on
Red Hat Linux 5.x).  There are some fundamental differences
between the Leroy thread implementation and the POSIX.1c standard,
which derive from the differences between a Linux kernel "task"
and a POSIX thread.  In the Leroy implementation, several
attributes that are per-process in POSIX are implemented as
per-thread. For example, each thread has a separate process ID, so
getpid() returns a different value for each thread.  We have
attempted to hide this, making Get_Process_ID return the ID of the
process's initial thread, which we store in a global variable.  We
could not work around a deeper problem, which is that if a signal
is sent to a process it can only be delivered to the initial
thread of the process.  There are other problems, including a
defective implementation of sigwait(), which loses signal
instances that are pending when sigwait() is called.  Until the
Leroy thread implementation is redone, to comply with the POSIX
thread standard, Florist will not comply either.

PORTING:

The basic approach taken by Florist to achieving portability is to
rely on the existence of a C-language API that conforms to some
subset of POSIX.1, POSIX.1b, and POSIX.1c.  

The configuration scripts try to guess which features are
supported, and create "gnatprep.config" and the C header-files
"pconfig.h" and "config.h" to indicate what was found.

The first thing to try, on a new system, is to run the prebuilt
version of "configure", and redirect the (copious) output to a
file you can examine later e.g. "./configure >& configure.log".

The most likely failure will be that a feature is apparently not
found, but you know that it is supported by the OS.  Look in the
log file for features that were not found.  If you believe any of
them are really present on your system, you will need to find out
why "configure" was unable to find them.  

So far, this script has run successfully -- in various
incarnations -- on Solaris 2.x, Linux, HP-UX, AIX, OSF/I (DEC
Alpha), and IRIX.  We also tried ULTRIX (a BSD UNIX derivative),
but it was so far from POSIX that we just gave up.  Along thew
way, we observed the following common reasons for failure when
going to  a new system:

--  non-POSIX-compliant  dependences of POSIX header files
    on other header files, including non-POSIX headers

--  non POSIX-compliant order-dependences of #includes

--  special C preprocessor symbols that must be defined in the user program
    to activate POSIX compatibility features, especially real-time

--  macros defined in the C header files, for standard POSIX type
    and function names, that rewrite them to nonstandard names;
    this is especially a problem if it means the link-name of a
    standard POSIX C interface function name is different from the
    name given in the standard

--  special libraries that must be named to the linker (the -l option)

--  missing OS support for POSIX.1g (sockets and XTI) interfaces

The easiest way to handle these things at first will be to
hand-edit the files "pconfig.h" (which contains all the #includes
for the header files needed by c-posix.c), and possibly also
"Config.h" (though we are trying to phase the latter out).  You
can see examples of how these files have been tailored for several
systems by looking in the subdirectory "configs".

Eventually, it would be nice to fix "configure" to come up with
all the right values automatically for your system.  This can be
tricky, as it requires learning something about the "m4" macro
processor, "autoconf", and the special m4 macros we wrote to adapt
the autoconf process to checking for POSIX features.  To do it
"right" you would need to modify the files "aclocal.m4",
"config.h.in", and "configure.in".  The nasty part is that we have
seen such changes cause regressions for other systems, and our
ability to do regression testing is limited to the systems which
we are running locally.

We suggest people interested in porting Florist contact me (see
contact information at end of this file) by e-mail, so that we can
work together to make the necessary changes to the baseline
configuration.

See comments in file c-posix.c for further information.

SUPPORT:

Though FSU does not offer commercial support for Florist, such
support is available from Ada Core Technologies,
Inc. (www.gnat.com).  They deserve credit for working out the
details of porting Florist to several operating systems, including
AIX, OSF1, HP-UX, and IRIX.

MAINTENANCE:

I cooperate with Ada Core Technologies in maintaining Florist.  I
am also interested in receiving bug reports directly, from people
who are paying Ada Core Technologies for Florist support.

To the extent I am able, I will try to fix such bugs, add support
for new POSIX extensions, advise people who want to port Florist
to new systems, and to work with them to extend the
auto-configuration mechanism to cover those systems.

Please understand that my ability to do so will be limited, since
this is being done as a public service in my "spare time" from the
other demands my position as professor and department chair.

Ted Baker
FSU POSIX/Ada Realtime Project
baker@cs.fsu.edu
10 January 1999







