Description
This article is from the Apple II
GNO FAQ, by Devin Reade with numerous contributions by
others.
9.2: What are the common problems encountered when porting UNIX sourceto GNO?
A#9.2: The first thing to watch for is known compiler and library bugs.
Soenke Behrens maintains the current ORCA/C bug report list.
You should keep the contents of this list in mind when examining
the target source code. The ORCA/C bug report list may be found at
http://www.arrowweb.com/sbehrens/obugs.htm
This list has been considerably shorted since the release of
ORCA/C v2.1.0. If you have an earlier version of ORCA/C, you
should seriously consider an upgrade.
The following items should be watched for, in no particular order.
Since UNIX source is usually in C, that language is assumed for
the rest of this section, where relevant:
sizeof(int)
The size of the type "int" is implementation-defined.
While most modern C compilers use 32 bits, ORCA/C still
uses 16 bits since this is the "natural" integer size of
the 65816. This also results in more effective code
generation.
While the size of an int shouldn't make a difference to
any well-written code, there is some available source code
that assumes that ints are 32 bits. You should watch for
this in any code that does bit manipulations. You should
also watch for code that freely converts between integers
and pointers. GNU (Free Software Foundation) software
is often bad for this.
recursion
When possible, recursion should be avoided when programming
on the Apple IIgs. This is because recursion invariably
causes stack growth and the stack can only exist in bank
zero. This means that the maximum space available for
the stack is 64k. In practise, it is much smaller.
This problem is exacerbated under GNO where all processes
must share the available stack space (each process has its
own stack, though).
Any program that uses recursion can be rewritten to use
iteration instead. You should try to do this when possible.
If you do use recursion, don't allocate a huge stack;
this will keep other programs from executing. Also, you
should leave in stack checking and stack repair (if
programming with ORCA/C) to ensure that your recursion
does not crash the machine if it goes too far.
reference to absolute file descriptors
True UNIX machines invariably use the file descriptors 0, 1,
and 2 for standard input, standard output, and standard error,
respectively. Under GNO, the file descriptors used are 1,
2, and 3.
This causes a problem when source code is written to use
these descriptors directly. You should search your code
for references to these descriptors, typically in calls
to open, close, read, write, dup, dup2, and fcntl.
Instead of replacing these digits with other digits though,
you should use the macros STDIN_FILENO, STDOUT_FILENO, and
STDERR_FILENO defined in <unistd.h>. This will ensure
that your source is kept portable.
fork
Because of problems that are discussed in the fork(2) man
page and the kernel reference, the fork system call under
GNO is different than other versions of UNIX. Besides
having a different prototype, the parent and child process
share the same address space. In this respect, GNO is less
a multitasking environment than it is a multithreading
environment.
Search for calls to fork; you will have to rewrite these
sections of code. See also the man page for fork2(2); it
may be more suited to your purposes.
Also note than when compiling routines that make a call
to fork, you should turn off ORCA/C's stack repair code.
This means that you should be using an optimization level
of at least 8.
read/write of newline character
Most UNIX systems use LF (ASCII 0x0a) as the line delimiter.
Both Apple II and Macintosh computers use CR (ASCII 0x0d)
as the line delimiter. The C newline character is '\n';
ASCII 0x0a.
While the stdio routines (fprintf(3), fread(3), etc) usually
make this difference unnoticable by doing CR-->LF translation
on input and LF-->CR translation on output, no such
translation is done on files accessed through read(2) and
write(2). Specifically, the GNO open(2) does not recognize
the ORCA/C O_BINARY bit in it's second argument.
Therefore, if the program you are porting makes calls to
read(2) and write(2), watch for the '\n' character in your
code. You may have to change this to '\r'. Don't do it
blindly, because many programs will use both stdio and
operations on the bare file descriptors.
One suggestion is to modify your programs low-level I/O
routines to modify the I/O buffer prior to calling write(2)
and after calling read(2).
variadic functions
Some (poorly written) UNIX programs have variadic functions
where the number of provided arguments don't match the
number of arguments expected by the called routine. Even
though this is in some cases legal ANSI/C, versions of
ORCA/C prior to v2.1 would puke magnificently when encountering
such code. Some of these cases are now handled in a more
robust fashion by ORCA/C v2.1 and later.
If you are defining (as opposed to using) variadic functions,
you must turn off stack repair code around the definitions
of those functions.
The ORCA/C manual (and especially the release notes for
v2.1) have important and detailed information on this topic.
See the sections on the optimize and debug #pragmas.
open, chmod, fchmod, creat, st_mode, stat, fstat, lstat
In general, the bits in the mode parameter of these
functions do not directly map between UNIX and GNO
implementations. If your application is using macros
such as S_IREAD or S_IWRITE for the mode parameters, and
those macros are taken from the system header file
<sys/stat.h>, then you probably don't need to modify your
application.
If, on the other hand, your application is using its own
constants for the mode parameter, you should convert it
to use the standard macros. Failure to do so may result
in files with strange GS/OS flags set, or file tests failing
in your program.
/dev
One of the UNIX philosophies is that "everything is a file".
The /dev directory on UNIX systems contain device special
files. Accessing these files is the way to access the
relevant hardware.
For GNO programs, you should not access devices in the
/dev directory. For example, opening "/dev/console" for
writing will not have the expected effect. Instead you
should open the corresponding GS/OS device, ".ttyco".
The portable (and suggested) method of handling these cases
is not to change the value of the string (in this example)
from "/dev/console" to ".ttyco". Instead, use the macros
defined in the file <paths.h>. For this example, one would
use the macro _PATH_CONSOLE.
standard path assumptions
This one is closely tied in with the "/dev" description
above. The <paths.h> file contains macros for various
standard paths. The macros, instead of the actual paths,
should be used to maximize portability.
signal handlers
When a signal handler is called, the data bank register
may not have an expected value. If your program references
global scalars, it may crash. To avoid this, all functions
used as signal handlers should have their definition
preceded by
#pragma databank 1
and followed by
#pragma databank 0
validity of pathnames
Most programs make assumptions about what constitutes
a valid file name. For most modern Unices, a valid
file name follows the POSIX portable filename character
set: The characters a-z and A-Z, the digits 0-9, and
'.', '_', and '-'. The '-' is not used as the first
character of a file name, and '/' is the directory
separator character. The maximum filename length is
at least 14 characters, and the maximum pathname length
is at least 255 characters.
Now this is different from what is available under GNO.
The ProDOS FST provides only a subset of the above. The
HFS FST provides a superset, but HFS is too slow, too
buggy, and too unmaintainable for many users.
The problem is also compounded by the fact that under
GS/OS, the ':' is a directory separator. '/' may be used
but it is mapped internally to ':'.
Unfortunately, there is no general consensus on how to
handle pathnames under GNO. Here are some opinions, all
of which refer to user code; the GNO kernel treats pathnames
the same way that GS/OS does:
- the ':' character should be mapped to '/'. This prohibits
the use of '/' in file names. It also provides the
highest degree of "UNIX compatibility"; or
- the '/' character should be mapped to ':'. This is more
in line with GS/OS, but can require extensive rewrites
of ported UNIX programs; or
- use dynamic directory delimiters. The ':' character is
always considered to be a directory separator. The '/'
character is considered to be a directory separator unless
it was preceded at some point by a ':', in which case it
is part of the file name. Having a '/' appear before ':'
in a pathname is illegal. This is the closest to GS/OS,
but also has some problems with POSIX compliance. For
example, the PATH environment variable is supposed to
be a list of pathnames delimited by the ':' character.
This implies that one cannot use the ':' as a directory
delimiter when defining PATH, and that directories in
PATH must not contain '/' as a regular character.
Regardless of which method you use to do filename, pathname,
and directory separator mapping, you should verify that
the pathname is legal for your target filesystem. GS/OS
provides a mechanism to do this through the JudgeName
system call.
Also watch out for references to the root partition. For
other UNIXs, this is the pathname "/", which is a not legal
directory under GS/OS (and therefore GNO). Hopefully the
context of your program will give you an idea how to handle
such a directory reference in a sensible manner.
unlink
Many UNIX programs unlink (delete) files while they still
have them open. Under true UNIX systems, this means that
the file will be deleted as soon as it is closed. This is
is not done under GNO, and attempting to unlink an open file
will fail, and the file will remain on the file system after
it is closed. If your program relies on this behavior, you
will have to find a work-around. One partial solution is
to register a clean-up function via atexit(3) that deletes
your files for you. [This method is not suitable for
daemons or other long-running programs.]
 
Continue to:
Share and Enjoy
Bookmark this story so others can enjoy it:
Tags
pc, hardware, Apple II, Apple ][ or Apple //, apple, gno, unix