home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
programm
/
programi
/
ixemlib9.lha
/
README
< prev
Wrap
Text File
|
1992-01-13
|
21KB
|
449 lines
Markus M. Wild January 12, 1992
This is the first public release of my shared library, that should make
porting programs originally written to be run on a **IX/BSD system to be
much easier on the Amiga computer running AmigaDOS.
---------------------------------------------------------------------------
COPYRIGHT restrictions
The source code shipped with this library is subject to the GNU LIBRARY
GENERAL PUBLIC LICENSE, please look at the file COPYING.LIB that comes with
this distribution. If not, write to the
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
NOTE:
There are lots of files subject to other Copyrights, especially those
Copyright by the Regents of the University of California. In those cases,
the specified Copyright restriction applies TO EACH SUCH SINGLE FILE, but
not the arrangement of putting it in this library. With this restriction I
want to enforce consistency of this library.
After reading the COPYING.LIB file, you'll notice, that a program that just
uses the library by using OpenLibrary(), and calling functions in it, is to
be considered as a `work that uses the Library', and 5. of COPYING.LIB
says for this case: " Such a work, in isolation, is not a derivative work
of the Library, and therefore falls outside the scope of this License."
Since I declare the glue functions created by compiling and running
gen_glue.c (in lib/) to be in the Public Domain (thus not to be covered by
any license), and since the stdio/ functions are all subject to the
Berkeley Copyright restrictions, your compiled and linked executable will
NOT become a derivative of the library, and will thus not be subject to
this license. Thus, you may use the compiled version of the glue files and
the stdio functions, libc.a (except alloca.c, please see the copyright
notice in its header. Use the builtin alloca() (__builtin_alloca() to be
explicit) in all situations where this is possible) and crt0.o in a
commercial product without making it a derivative of the library and thus
make it subject to the library license. However, you must tell your
customers that ixemul.library is free software according to this license,
and where they can get a copy of its source code.
---------------------------------------------------------------------------
Now that the legal stuff is over, some comments to this library.
68000 users, take care!
=======================
I tried to be fully 68000 compatible (this is important in the signal code),
but since I don't have a 68000 equipped Amiga anymore, I can't test whether
the library really works under this environents. Please tell me, if you
encounter problems!
I always wanted a library, that would emulate as much as possible of a
**IX/BSD environment on the Amiga, so that programs (usually programming
tools) written for **IX/BSD could be ported quick and easy to the Amiga.
I guess the library accomplishes this goal fairly well.
What it is and what it isn't
============================
The design of the library was therefore guided towards **IX/BSD
compatibility, and *not* :
o to be too conservative with resources
(the malloc package is quite memory hungry...)
o to be particularly conformant to Amiga habits. Thus if I had to decide
whether I should make a function act more like an Amiga function or
more like a **IX/BSD one, I decided for the latter. As an example:
_cli_parse() does wildcard expansion, and tries to apply more or less
**IX/BSD shell semantics to an argument line, it doesn't call
ReadArgs().
The types used in my own source code are all from sys/types.h (except
BPTR). I don't think capitalized identifiers should be used for typedef'd
types. According to C-conventions, anything written in captials should
be `#undef'inable, which typedefs aren't. Thus if you write contributions
to be included into the official distribution of this library, code
according to this. Use `u_char' and not UBYTE, etc. I don't care that
this is against the Commodore coding standard, this is my code, and
I decide what I like and what not.
o to be particularly suited for inclusion into a shared library. Although
all of the system stuff IS included into the shared library, I didn't
bother to include the (current) stdio library. This simply because
transforming stdio into a form usable in a shared library would have
meant adding a significant portion of incompatibility to **IX/BSD
usage of stdio functions/macros. I'll perhaps reconsider this with the
new stdio library distributed in the 4.3BSD-net2 release later.
What I'd really want for the Amiga is the concept of a dynamic linker.
On the other hand, it should be:
o expandable. As an example, a file descriptor already can refer to `real'
files, directories, memory buffers treated as files. I plan to add
sockets in some next release (Commodore: please get out some examples
on how to use SANA-II stuff, so my sockets can be compatible!)
o patchable. If you want some function to behave differently, you can
SetFunction() it, and the rest of the library should use your new entry.
NOTE: I used this only for major functions, that may reasonably change.
I didn't call functions like strcmp(), strlen(), bcopy() that way for
efficiency reasons (and my lazyness to change the whole string/
and other libraries;-)))
Difference to `usual' Amiga shared libraries
============================================
The library is designed to be used by C, and not by assembly. So
parameters are passed on the stack rather than in registers. This also
means that there is no `fd' file, and you can't use any current library
call pragmas to access its functions. I will though soon publish an inline
header file for use with GCC, so you'll be able to call all functions
inline. Recall though, that calling functions of ixemul.library inline
will not result in an order of improvement as calling standard library
functions inline. The glue functions don't have to shuffle arguments from
and to the stack, they just do a jump over the base table and are therefore
very short and very fast.
I provided revision control in the startup code. Thus if you get a program
written for a newer revision of the library than you currently have, a
warning requester tells you about this, you can still use the program though.
I don't believe in bumping up the version counter because of every small
improvement. Bumping up the version means you can't use no older versions at
all. Bumping up the revision just gives you an annoying requester (and
perhaps an `illegal action' trap though..) that you should upgrade.
As some kind of replacement for an fd file, I use the <sys/syscall.def> file,
which is a symbolic link to `library/syscall.def' in the source directory.
It contains lines of the form
SYSTEM_CALL (name_of_call, entry_number)
Where `name_of_call' is the name you'd use in a C program using the library
(for example write, abort, unlink, etc), and `entry_number' gives the number
of the system call used in syscall(). You can convert this number into
a more common _LVO for the Amiga by doing:
_LVO = -6*(entry_number + 4)
For examples how <sys/syscall.def> can be used, look at <sys/syscall.h>,
`library/start.s' and `lib/gen_glue.c'.
Where to use it
===============
Libc.a should be the one and only C library you need to get most of your
programs linked correctly with the GNU CC compiler. For some math-
oriented stuff you'll also need a math library. Since Berkeley released a
new release of their software, I don't want to include my older math
library until I upgraded to the newer sources. You may get the newer or
older versions now, they are not particularly **IX/BSD dependant, and
should compile fine with GCC.
If you want to recompile
========================
I provided Makefiles for the most directories (all except lib/ in fact).
Those Makefiles assume a decent Make tool, I'm currently using a version
(hacked for the Amiga) of DMake (not the one from Matt Dillon, sources are
on wuarchive.wustl.edu), I'll publish this version separatly, but I won't
support it.
Sources are written for compilation by GCC. You might be able to compile
95% of them with any ordinary ANSI-C compiler, but there are cases where
you have to change things for non-GCC environments (mostly asm() situations).
The Makefiles all use gcc2 as CC. Release date of gcc2.0 depends on GNU,
not on myself. I can just say that Amiga versions keep up with releases
from GNU, and there should be an Amiga gcc2 release ready as soon as GNU
give their ok for distribution.
The subdirectories use `ar' and `ranlib', these are the tools from the
4.3BSD-net2 distribution. I found them to be lots more stable then my
earlier ports of GNU-ar from the GNU-binutils distribution. For now, only
the binaries are included, but you may get the sources at every site that
has 4.3BSD-net2 sources, for example nic.funet.fi.
For recompilation, see also the following comments in `How complete are the
headers'.
To generate libc.a, `ar' and `ranlib' all object files from
static_library/, stdio/, lib/ and lib/glue/. The latter you have to
generate by compiling and running lib/gen_glue.c. Don't include lib/crt0.o
in libc.a though, this should stay separate. Since there is no Makefile
(yet), crt0.c (and only this) should be compiled with `-fwritable-strings',
since you have to be sure that ENTRY() is the first thing in the generated
object file. If you don't specify `-fwritable-strings', you'll get string
constants at the first executable address in your programs, and this will
get you (and your computer) into meditation if you try to execute such
programs ;-))
To generate ixemul.library, cd into string/,gen_library/, stdlib/, gnulib/,
gnulib20 and at last library/, and type `make'. At the end, you should
get a current version of ixemul.library.
Note: the library is currently compiled in a way that makes it easy for me
to have a debugged version or not, ie. the debugging statements stay in
the code, but the kprintf() function is either linked with the library
to get a debugging version, or stubbed out to get a working version. When the
library gets more stable, parts of it can be compiled by inlining code
to the library, instead of going thru syscall().
If you want to write code that uses the library
===============================================
Code if you would on a **IX/BSD system, thus DON'T USE any information
private to the library, especially don't use any information that
tc_TrapData points to. This data is subject to change in every release of
the library, and you may only access its variables thru library access
functions! This restriction fully applies to applications as well that
SetFunction() some functions of the library. So if you for example write
your own memory allocation functions, you may NOT use the space the library
malloc() function uses for your own purpose. I may decide in a later
release of the library to use a different malloc() implementation that
uses different data in the user area, and then your code almost certainly
would trash innocent variables!
How complete are the headers
============================
The header files distributed in `include/' are all you need - except the
Amiga specific header files copyright by Commodore-Amiga. You either have
to get them from a commercial compiler, or order them from CATS.
If you don't intend to compile Amiga specific programs, you don't need
those headers at all.
You need to make one change to one of those Amiga headers to avoid
duplicate definition of a datatype:
The <devices/timer.h> file includes the following definition:
struct timeval {
ULONG tv_secs;
ULONG tv_micro;
};
Please comment this definition out, and add
#include <sys/time.h>
somewhere at the beginning of the file, and instead of the above definition,
put
#define tv_secs tv_sec
#define tv_micro tv_usec
That way, you can use the timeval structure defined in <sys/time.h> as well
as the one defined in <devices/timer.h>. The structures are identical, but
the field names are not (sigh..).
I included more or less all headers from 4.3BSD-net2, except those that
refer to really **IX/BSD specific material in the kernel. I included more
headers that are currently used and supported, just to make life easier for
people using **IX/BSD sources under AmigaDOS. Among the things not supported
currently are networking (sockets) and process management (fork, wait, exec*).
Signals on the other hand *are* implemented, see the special section for
restrictions.
How BSD signals are implemented
===============================
I tried to implement as much of Berkeley style signals as possible on the
Amiga. This includes a trap handler as well as an asynchronous signal
facility. The one thing not implemented is interruptible signal calls.
Since there are no `real' system calls on the Amiga (ie. no calls that are
executed in Supervisor mode), those calls can not normally be interrupted,
ie. forced to return to their caller. So all functions except sigpause()/
sigsuspend() will return to where they were interrupted, if a signal
occurs.
These 32 new signals are 32 new signals, not tied to any of the 32 Amiga
signals provided by Exec. The one exception is SIGBREAKB_CTRL_C, which is
by default bound to generate a SIGINT.
Signal handlers are called with the following arguments:
void
signal_handler (int signo, int code, void *address, struct sigcontext *sc)
Where
signo: is the signal number that occured, see <signal.h>
code: is a more specific characterization of signo available with some
signals. It is available with all signals that are generated
because of a processor exception, and then contains the format
identifier of the exception frame (this is correct even for the
68000, where such an identifier is faked, ie. it doesn't really
exist). Thus a `division by zero' exception would be invoked by
signal_handler (SIGFPE, 0x2014, address, sc)
address:address referrs to the instruction that caused the signal.
sc: please don't use sc, as it may change in the future. It contains
the context to restore after the signal handler returns.
If you use signals in your own code, PLEASE make sure that you never
generate a situation, that when interrupted, would leave resources allocated.
That is, the following example is BAD :
..
fh = Open ("foobar", MODE_OLDFILE);
if (fh)
{
.. do something with it ..
Close (fh);
}
If your program is interrupted and terminated after you got your file handle,
`fh' will never be closed! There are two sollution to get around this problem,
either use library functions from ixemul.library, or explicitly mask signals
while you have resources locked. Thus in this example, either do:
fd = open ("foobar", O_RDWR);
if (fd >= 0)
{
.. do something with it ..
close (fd);
}
in that case the library will do resource tracking on fd. Or explicitly mask
the signals:
omask = sigsetmask (~0); /* mask all signals */
fh = Open ("foobar", MODE_OLDFILE);
if (fh)
{
.. do something with it ..
Close (fh);
}
sigsetmask (omask);
Note that the last sollution is worse than the first one, because the user
may send the process a non-maskable signal, that would terminate the process
unconditionally (SIGKILL does this), and don't forget that the user isn't
able to break your program as long as you have signals masked!
Ixemul.library does resource tracking on all file-related functions (create(),
open(), dup(), pipe()) and on memory allocations thru malloc() and realloc().
Thus if you use those functions instead of dos.library and exec.library
functions, you don't need any clever resource tracking stuff to do on your
own, that's what the library is for ;-)
If you use Amiga specific resources like Windows and Screens from
Intuition, make sure to add an atexit() handler to close those resources,
if the user should decide to interrupt your program. Before the program is
left, the chain of registered atexit-handlers is called in exit(). So
PLEASE NEVER EVER call _exit() if you have registered any custom atexit()
handlers. It is a bad habbit anyway, but normally you may call _exit()
without resource lossage (stdio won't flush its buffers, but that's about
all), as long as you close ixemul.library after use, and this IS A MUST, as
for every Amiga shared library anyway.
I provided a new unique Amiga specific signal called SIGMSG. If you set up
a handler for this signal, than
o the default mapping from SIGBREAKB_CTRL_C into SIGINT will no longer
occur
o your handler is called with the following arguments
signal_handler (SIGMSG, new_exec_signal_mask)
In this case, you have to deal with Exec signals yourself, so don't forget
to clear those signals that you want to receive notification about again
later.
Thus if you'd want to handle SIGBREAKB_CTRL_C yourself, don't forget to
SetSignal (0, SIGBREAKF_CTRL_C)
at the end of the handler, or you'll never get notification about that
signal again.
If your program is interrupted by a signal and the default action of that
signal is to terminate your program, and you didn't set up a handler to deal
with that signal, your program is terminated by calling `exit (128 + signo)'.
There are no core-dumps yet, I first have to think about a useful format
for a debugger that takes care of the Amiga's memory architecture.
The signal implementation uses some of the Berkeley kernel sources of the
4.3BSD-reno release for the hp300. I didn't disable everything that isn't
implemented currently, so you might face strange behavior if you currently
try to send a SIGSTOP to a process using the library, you better not ;-))
Currently supported are the following signals:
SIGINT: bound to ^C (SIGBREAKB_CTRL_C) unless there is a SIGMSG handler
SIGILL: generated by some hardware exceptions
SIGFPE: generated by some hardware exceptions
SIGBUS: generated by some hardware exceptions
SIGALRM: if you use alarm() or the ITIMER_REAL interval timer
SIGVTALRM: if you use the ITIMER_VIRTUAL interval timer
SIGPROF: if you use the ITIMER_PROF interval timer
SIGMSG: if you provide a signal handler for it
more are to follow. You may send any of the 32 signals to a process using
the library with the `kill ()' function, the default behavior of a process
is described in a **IX/BSD man page for signals. As mentioned above,
stopping a process isn't currently implemented, and may produce strange
behavior...
Compatibility
=============
I tried to port some commonly used programs to the Amiga using this
library. And the following programs were quite easy to port:
o patch
o GNU tar-1.10 (the first Amiga tar that knows about symlinks ;-))
o GNU emacs 18.57 (currently without subprocesses of course ;-))
o GNU find-2.2 (replace the fork,exec-stuff with a call to ssystem() )
o BSD ar, ranlib (with DMake even things like VPATH=../ar work ;-))
o GNU cc ;-))
o DMake
o ...
As a guideline, if you find stuff that uses fork,exec,wait stuff, try to
replace it with a call to ssystem()/system(). System() corresponds to the
usual **IX/BSD library function, it runs the argument thru the current
shell. ssystem() is some lower level execution function, that under 1.3
uses ARPs SyncRun() function (that's where the name came from ;-)), and
under 2.0 uses my own code to find the executable (searches the users
PATH), and tries to do interpreter expansion on the file (the thing with #!
rsp. ;! as the first two characters. Please see the `library/__load_seg.c'
file for more details;-)).
Some final words
================
I wish you good luck using this library, it isn't that thoroughly tested
yet, but I did manage to recompile gcc with itself using the library, so
some basic reliability should be granted. But keep in mind:
This library 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
Library General Public License for more details.
See the BUGS file for any currently known bugs.
New versions of the library will first be released on amiga.physik.unizh.ch
in files/incoming/amiga/. This is my home site. Later there will also be
copies on nic.funet.fi, which is the home site of the GCC port to the Amiga.
If you like to contribute new functions to the library, please reread
the `What it is and what it isn't' section, and if you think that your
code contributes to those goals, I'd be very happy to include it in
the library in a later release.
Since indentation style is a great deal a thing of personal taste,
I make up the following rules:
o if you change one of the existing files, follow the style of the
file
o if you provide a completely new set of functions, you're at your own.
If you find bugs in the code (I'm absolutely sure there are some...), please
tell me about them!
Send your bug reports, enhancement requests and constructive remarks to
<wild@nessie.cs.id.ethz.ch> or <wild@amiga.physik.unizh.ch>
send flames to <bitbucket@nessie.cs.id.ethz.ch> ....
Markus M. Wild