home *** CD-ROM | disk | FTP | other *** search
- 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
-