Front page | perl.macperl.porters |
Postings from July 2005
Re: Porting perl to (traditional) Mac OS via Genie
From: Joshua Juran
July 19, 2005 11:22
Re: Porting perl to (traditional) Mac OS via Genie
Message ID: email@example.com
On Jul 19, 2005, at 5:43 AM, Dominic Dunlop wrote:
> On 19/07/2005, at 10:27 AM, Joshua Juran wrote:
>> I'm porting perl to a platform called Genie, which is a Unix-like
>> subsystem that runs in Mac OS. The purpose of this exercise is to
>> have a command-line perl tool available for Mac OS, in a stdio
>> environment with polymorphic file descriptors, without the
>> limitations of MPW.
> Good to hear. You don't say whether this is PPC or 68k Mac OS. I guess
> the former, though the FAQs on your site make me wonder.
I wonder too. I haven't looked at them in years. :-)
Genie requires CFM -- Genie programs are built as CFM drop-ins, or
plugins. CFM-68K Runtime Enabler 4.0 requires System 7.6.1, which
requires a 32-bit clean ROM (and perhaps a 68020 or better). This
leaves out the Mac II, IIx, IIcx, SE/30, and 68000-based machines
(unless an earlier version of the CFM-68K Runtime Enabler with an
earlier system works, which I don't plan to test any time soon). While
it might be possible to use code resources (with Genie fiddling the A4
register for plugin globals) I don't see the value, since much faster
Macs are readily available on the cheap. Genie does actually build and
run on 68K, although you have to patch a bug in Threads.h if you want
to use Thread Manager callbacks without crashing.
Genie's sockets support requires Open Transport -- MacTCP is not
supported. I don't think this will upset anyone.
One caveat is that Open Transport only supports CFM-68K as of version
1.3, which requires Mac OS 8.1, which in addition to ruling out
anything less than a 68040 nails you to a specific OS version.
Fortunately, the OTCFM68KGlue library hacks around this by calling OT
from a 68K code resource and should make it possible to support System
7.5.5 and 7.6.1. I haven't tried this yet.
> Back in the day, I worked on keeping Perl running on PPC MachTen, a
> commercial UNIX-under-Mac OS product from Tenon Intersystems
> (http://www.tenon.com). The product, though still apparently
> available, is, as far as I know, unsupported, and suffers from a
> number of long-standing bugs and security issues. Vague requests from
> some users that the code be open-sourced after support ended were
Apple phrased it this way: "Open source is not a dumping ground for
Most unfortunate, since I'm sure I could have found *something* useful
in the source code. ;-) Other closed Unix-on-Mac products include
Mac06 and (though this is a stretch) Apple's own MPW. Open-source
projects include MacMiNT and PATMOS.
> MachTen was delivered with gcc, so I didn't use MPW or CodeWarrior in
> porting perl. If you search in old perl5-
Genie requires a real C++ compiler to build, which rules out MrC/SC.
Plugins shouldn't require C++ at all, but I haven't investigated using
anything other than MW C. Perhaps I should -- I ran into some curious
MW linker issues that prevent me from linking Genie plugins against my
own shared libraries, and had to link in the standard library
> porters archives, you'll find mail about various issues I tripped
> over, including malloc() (once tweaked to work, Perl's own malloc was
> much faster than Mac OS' own); and fork() (MachTen, thanks to deep and
> probably dark magic, has both fork() and vfork(), but the latter is
> MUCH faster, as Mac OS does not support Copy on Write). You'll also
> find clues in hints/machten.sh.
One of the problems is returning twice. Matthias got the idea to
provide vfork() as a macro that calls setjmp(), which he implemented in
his Natty project. I opted against this for now, since what you'd
have to do with the return value of setjmp() to implement proper
vfork() semantics and what the standard says you're allowed to do with
it are not compatible. AFAICT you're not even allowed to assign the
return value to a variable. It might work anyway, but I didn't wish to
My interim solution requires as a compromise that code be written thus:
#define is_child_pid( pid ) ((pid) == 0)
while ( (pid = vfork()) == -1 ) sleep(5);
if ( is_child_pid( pid ) )
/* We're the child */
/* setenv, dup2, etc. */
execve( ... );
_exit( EXIT_FOO );
/* We're the parent */
waitpid( ... );
The trick here is that for a Genie plugin, vfork() saves the caller's
process context and returns the child pid (once), is_child_pid() is the
identity function (always true for a pid), and either execve() (unless
it fails) or _exit() restores the original process context AND RETURNS.
(Unless you call without forking, in which case it terminates the
Hey -- it works, doesn't it?
The third way is to decide you're not just an application but really
part of the operating system and actually implement per-process
address spaces, a la MachTen. This has been left as an exercise for
For implementing qx// and system, vfork() is sufficient. For fork, we
should be able to use the same perl_clone()-based emulation that
Windows uses. See perlfork. It may even be possible to clone into a
'real' Genie process (which is really a kind of pseudo-process) without
resorting to pseudo-(pseudo-)processes, such that 'fork and exit' would
 ...When asked to open-source HyperCard, at the 'Apple Handshake'
session of MacHack 2000.
Metamage Software Creations - Mac Software and Consulting
* Creation at the highest state of the art *