develooper Front page | perl.macperl.porters | Postings from July 2005

Re: Porting perl to (traditional) Mac OS via Genie

Thread Previous | Thread Next
From:
Joshua Juran
Date:
July 19, 2005 11:22
Subject:
Re: Porting perl to (traditional) Mac OS via Genie
Message ID:
7ee26a6f8b8ec50355a472d1ef0b07b9@gmail.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 
> rebuffed.

Apple phrased it this way:  "Open source is not a dumping ground for 
dead products."[1]

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 
statically.

> 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.[2]  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 
go there.

My interim solution requires as a compromise that code be written thus:

	#ifndef macintosh
	#define is_child_pid( pid )  ((pid) == 0)
	#endif
	
	pid_t pid;
	
	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 
caller's thread.)

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 
the reader.

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 
work.

Josh

[1] ...When asked to open-source HyperCard, at the 'Apple Handshake' 
session of MacHack 2000.

[2] http://www.sourceforge.net/projects/natty/

-- 
Joshua Juran
Metamage Software Creations - Mac Software and Consulting
http://www.metamage.com/

                * Creation at the highest state of the art *



Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About