I would like to add my work to the core (when it's ready) as a new
platform. Unless anyone objects, the platform name is 'Lamp',
unix-name 'lamp', custom header 'lampish.h', and preprocessor macro
MACOS_LAMP.
On Jul 19, 2005, at 11:31 AM, Joshua Juran wrote:
On Jul 19, 2005, at 5:43 AM, Dominic Dunlop wrote:
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.
Genie requires CFM...
Genie's sockets support requires Open Transport ...
I forgot to mention -- Genie builds and runs both as Carbon and
classic. I typically develop in OS X using Carbon, running either
natively or in Classic.
MachTen was delivered with gcc, so I didn't use MPW or CodeWarrior in
porting perl. If you search in old perl5-
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.
Mac OS doesn't have a malloc(), per se. It has NewPtr(), which is a
dreadfully bad substitute, and the standard C library has one. I don't
know how MSL's malloc() compares to MPW's.
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:
[snip]
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?
For trivial uses, yes, but perl's code is rather more involved. I
revisited Matthias' Natty project -- he writes:
#define vfork() setjmp( *NattyVFork() )
NattyVFork() dynamically allocates and returns a jmp_buf* which is
dereferenced and passed to setjmp(). One problem with this is that
there's no way to return -1 on failure. I did this:
#define vfork() ( SpawnVFork() ? -1 : setjmp(gVfork_jmp_buf) )
SpawnVFork() does almost the same thing that my old vfork() did, but
returns 0 on success. Genie programs have private globals, so we can
use a global for the jmp_buf. Execve() and _exit() save getpid(), call
their respective kernel routines, and (for execve(), if successful)
longjmp() with the saved pid. The standard library makes very weak
guarantees about setjmp(), but fortunately Metrowerks delivers what we
need.
We now have a working 'system' operator.
Josh
--
Joshua Juran
Metamage Software Creations - Mac Software and Consulting
http://www.metamage.com/
* Creation at the highest state of the art *