You are not logged in Log in Join
You are here: Home » Members » rbickers » Running Zope on BeOS

Log in
Name

Password

 

Running Zope on BeOS

Last Revised: February 27, 2000
Ron Bickers

Overview

This document describes setting up and using Zope (http://www.zope.org/) on BeOS. I wouldn't run this on BeOS to do any real serving, especially with BeOS's minimal select() support (see below).

It should also be noted that NetPositive doesn't behave with the Zope management interface for whatever reason. However, Opera does just fine.

NOTE: Since BeOS is now a dead operating system (unless the Open Source version of it takes off), this information is not worth much anymore.

Requirements

This has only been tested on BeOS Intel (4.5.2) with Zope 2.1.2 and without PCGI, so if you're running anything else, you may have problems. PCGI doesn't compile and I haven't tried to get it to since my use of Zope on BeOS is only for testing Zope products during development. Since Zope 2.x requires Python 1.5.2, you'll need to have Python installed. However, as of this writing, the binary distribution of Python for BeOS has a broken select(), so you'll need to either compile Python from the sources or download my binaries.

Compiling Python 1.5.2

Python compiles cleanly on BeOS. However, in the 1.5.2 release (and in the BeOS binary distribution available on the BeWare site) there is a problem with Modules/selectmodule.c which needs to be patched. Save the following patch as selectmodule.c.path:

--- selectmodule.c.dist	Sat Jan 15 00:49:54 2000
+++ selectmodule.c	Sat Jan 15 00:54:14 2000
@@ -141,7 +141,7 @@
 			"argument must be an int, or have a fileno() method.");
 			goto finally;
 		}
-#if defined(_MSC_VER) || defined(__BEOS__)
+#if defined(_MSC_VER)
 		max = 0;		     /* not used for Win32 */
 #else  /* !_MSC_VER */
 		if (v < 0 || v >= FD_SETSIZE) {
Then, place it in Modules/ and apply it as follows:

$ patch < selectmodule.c.patch

Note that revision 2.30 and later from the Python CVS repository includes the patch.

After applying the patch, follow the directions in BeOS/README carefully to complete the installation.

Zope also requires FCNTL.py which can be created by running h2py.py in the Tools/scripts directory as follows:

$ python h2py.py /boot/develop/headers/posix/fcntl.h

Then copy the resulting FCNTL.py file to /boot/home/config/lib/python1.5/.

The problem with select() on BeOS and a workaround for Zope

BeOS has limited support for select(). Very limited. It only supports sockets (not files or pipes or anything else), and it only works for "reads", which means you can only check a socket to see if there is incoming data, not outgoing. Unfortunately, Zope uses select() for reads and writes to sockets in ZServer/medusa/asyncore.py as well as a pipe in ZServer/medusa/select_trigger.py.

There is support in select_trigger.py to use a loopback socket instead of the pipe. So with a small patch to get BeOS to use the non-posix code, the lack of pipe support is no longer a problem.

However, I haven't found a clean fix for the lack of "write" support, and since poll() isn't supported at all in BeOS, we can't use that. So instead of a clean fix, there's a dirty, but usable, workaround. Since select() will never tell Zope there's something to send, we have to bypass select() for any outgoing data and just attempt to send every time. Fortunately, attempting to send if there really isn't anything to send will simply be ignored by Zope. Another problem is that anything waiting to be sent will not go out until either the select() timeout is reached (set to 30.0 seconds by default) or there is something else to read. To avoid this, we can set the timeout to some ridiculously low number, like 0.1 seconds. That's a lot of unnecessary work every 0.1 seconds, but with Pulse and other tools the load isn't noticable. Changing it to 0.0 seconds did put a strain on the CPU, so don't do it.

It's rumored that Be will provide more complete support for select() in an upcoming release, so all of these issues will go away and Zope should compile without modifications. Until then, however, this is a reasonable solution for using BeOS for developing Zope products. If for some reason you're using BeOS as a server, I would wait for a better select().

Compiling Zope

With better select() support, Zope would compile on BeOS without modifications. However, not living in a perfect world, we're left with this workaround.

To compile Zope you need to have the Python sources and you need to modify /boot/home/config/lib/python1.5/config/Makefile. Change LDSHARED to point to BeOS/linkmodule in your Python source tree, and change LINKCC to point to BeOS/ linkcc in your python source tree. By default they're relative paths that don't work when compiling Zope.

There are three files that need to be patched. Copy the following patches, select_trigger.py.patch and asyncore.py.patch, to ZServer/medusa/:

--- ZServer/medusa/select_trigger.py.dist       Fri Jan 14 17:48:40 2000
+++ ZServer/medusa/select_trigger.py    Fri Jan 14 17:51:40 2000
@@ -10,7 +10,8 @@
 import string
 import thread
 
-if os.name == 'posix':
+# Changed to != 'posix' as workaround for BeOS's incomplete posix select()
+if os.name != 'posix':
 
     class trigger (asyncore.file_dispatcher):
 
@@ -93,7 +94,7 @@
 
     class trigger (asyncore.dispatcher):
 
-        address = ('127.9.9.9', 19999)
+        address = ('127.0.0.1', 19999)
 
         def __init__ (self):
             a = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
@@ -103,7 +104,7 @@
             w.setsockopt(socket.IPPROTO_TCP, 1, 1)
 
             # tricky: get a pair of connected sockets
-            host='127.9.9.9'
+            host='127.0.0.1'
             port=19999
             while 1:
                 try:
--- ZServer/medusa/asyncore.py.dist     Fri Jan 14 17:48:15 2000
+++ ZServer/medusa/asyncore.py  Fri Jan 14 21:36:42 2000
@@ -52,7 +52,7 @@
                        if s.writable():
                                w.append (s)
 
-               (r,w,e) = select.select (r,w,e, timeout)
+               (r,None,None) = select.select (r,w,e, timeout)
 
                for x in r:
                        try:
Then apply them as follows:

$ patch < select_trigger.py.patch
$ patch < asyncore.py.patch

Copy the following patch to z2.py.patch at the top level source directory:

--- z2.py.dist  Sat Jan 15 01:27:34 2000
+++ z2.py       Sat Jan 15 01:27:47 2000
@@ -580,7 +580,7 @@
 
 # Start Medusa, Ye Hass!
 sys.ZServerExitCode=0
-asyncore.loop()
+asyncore.loop(timeout=0.1)
 sys.exit(sys.ZServerExitCode)
Then apply it as follows:

$ patch < z2.py.patch 

These patches are tiny, and serve only as the select() workaround.

From the top level source directory, run 'python wo_pcgi' to compile Zope.

You should now be able to modify 'start' as you wish and run Zope.