rpms/compat-python24/devel compat-Python-2.2.1-pydocnogui.patch, NONE, 1.1 compat-japanese-codecs-lib64.patch, NONE, 1.1 compat-python-2.3.4-lib64-regex.patch, NONE, 1.1 compat-python-2.3.4-optik.py, NONE, 1.1 compat-python-2.3.4-pydocnodoc.patch, NONE, 1.1 compat-python-2.4-distutils-bdist-rpm.patch, NONE, 1.1 compat-python-2.4-gen-assert.patch, NONE, 1.1 compat-python-2.4-webbrowser.patch, NONE, 1.1 compat-python-2.4.1-canonicalize.patch, NONE, 1.1 compat-python-2.4.3-cflags.patch, NONE, 1.1 compat-python-2.4.3-config.patch, NONE, 1.1 compat-python-2.4.3-locale.patch, NONE, 1.1 compat-python-2.4.4-db46.patch, NONE, 1.1 compat-python-2.4.4-lib64.patch, NONE, 1.1 compat-python24.spec, NONE, 1.1 shmmodule.c, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2

Thorsten Leemhuis thl at rpmfusion.org
Sat Aug 9 22:39:36 CEST 2008


Author: thl

Update of /cvs/free/rpms/compat-python24/devel
In directory se02.es.rpmfusion.net:/tmp/cvs-serv6592

Modified Files:
	.cvsignore sources 
Added Files:
	compat-Python-2.2.1-pydocnogui.patch 
	compat-japanese-codecs-lib64.patch 
	compat-python-2.3.4-lib64-regex.patch 
	compat-python-2.3.4-optik.py 
	compat-python-2.3.4-pydocnodoc.patch 
	compat-python-2.4-distutils-bdist-rpm.patch 
	compat-python-2.4-gen-assert.patch 
	compat-python-2.4-webbrowser.patch 
	compat-python-2.4.1-canonicalize.patch 
	compat-python-2.4.3-cflags.patch 
	compat-python-2.4.3-config.patch 
	compat-python-2.4.3-locale.patch 
	compat-python-2.4.4-db46.patch compat-python-2.4.4-lib64.patch 
	compat-python24.spec shmmodule.c 
Log Message:
initial import from livna

compat-Python-2.2.1-pydocnogui.patch:

--- NEW FILE compat-Python-2.2.1-pydocnogui.patch ---
--- Python-2.2.1/Lib/pydoc.py.nogui	2002-07-08 18:32:47.000000000 -0400
+++ Python-2.2.1/Lib/pydoc.py	2002-07-08 18:33:37.000000000 -0400
@@ -18,9 +18,6 @@
 Run "pydoc -p <port>" to start an HTTP server on a given port on the
 local machine to generate documentation web pages.
 
-For platforms without a command line, "pydoc -g" starts the HTTP server
-and also pops up a little window for controlling it.
-
 Run "pydoc -w <name>" to write out the HTML documentation for a module
 to a file named "<name>.html".
 """
@@ -2043,9 +2040,6 @@
         writing = 0
 
         for opt, val in opts:
-            if opt == '-g':
-                gui()
-                return
             if opt == '-k':
                 apropos(val)
                 return
@@ -2099,13 +2093,10 @@
 %s -p <port>
     Start an HTTP server on the given port on the local machine.
 
-%s -g
-    Pop up a graphical interface for finding and serving documentation.
-
 %s -w <name> ...
     Write out the HTML documentation for a module to a file in the current
     directory.  If <name> contains a '%s', it is treated as a filename; if
     it names a directory, documentation is written for all the contents.
-""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep)
+""" % (cmd, os.sep, cmd, cmd, cmd, os.sep)
 
  if __name__ == '__main__': cli()

compat-japanese-codecs-lib64.patch:

--- NEW FILE compat-japanese-codecs-lib64.patch ---
--- JapaneseCodecs-1.4.11/setup.py.lib64-j	Mon Feb 10 12:44:55 2003
+++ JapaneseCodecs-1.4.11/setup.py	Mon Feb 10 12:45:26 2003
@@ -25,12 +25,12 @@
 import os, sys
 
 if os.sep == '/':
-    sitedir = os.path.join("lib", "python" + sys.version[:3], "site-packages")
+    sitedir = os.path.join("lib64", "python" + sys.version[:3], "site-packages")
 elif os.sep == ':':
-    sitedir = os.path.join("lib", "site-packages")
+    sitedir = os.path.join("lib64", "site-packages")
 else:
     if sys.version_info[0:3] >= (2, 2, 0):
-        sitedir = os.path.join("lib", "site-packages")
+        sitedir = os.path.join("lib64", "site-packages")
     else:
         sitedir = "."
 

compat-python-2.3.4-lib64-regex.patch:

--- NEW FILE compat-python-2.3.4-lib64-regex.patch ---
--- Python-2.3.4/Lib/test/test_re.py			2004-04-20 23:32:33.000000000 +0200
+++ Python-2.3.4/Lib/test/test_re.py.lib64-regex	2004-05-29 17:36:52.000000000 +0200
@@ -497,6 +497,15 @@
         self.assert_(re.compile('bug_926075') is not
                      re.compile(eval("u'bug_926075'")))
 
+    def test_bug_931848(self):
+        try:
+            unicode
+        except NameError:
+            pass
+        pattern = eval('u"[\u002E\u3002\uFF0E\uFF61]"')
+        self.assertEqual(re.compile(pattern).split("a.b.c"),
+                         ['a','b','c'])
+
 def run_re_tests():
     from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR
     if verbose:


--- NEW FILE compat-python-2.3.4-optik.py ---
"""Backward-compatibility version of optparse

Export optparse under the name of optik, and issue a deprecation warning
"""

import warnings
warnings.warn("the optik interface is deprecated; please use optparse instead",
    DeprecationWarning)

import optparse
for s in dir(optparse):
    globals()[s] = getattr(optparse, s)

# Only export what optparse exports
__all__ = [ getattr(optparse, s) for s in dir(optparse) ]
del s
del optparse

compat-python-2.3.4-pydocnodoc.patch:

--- NEW FILE compat-python-2.3.4-pydocnodoc.patch ---
--- Python-2.3.4/Lib/pydoc.py.no-doc	2004-07-16 11:29:01.000000000 -0400
+++ Python-2.3.4/Lib/pydoc.py	2004-07-16 11:32:52.000000000 -0400
@@ -1524,6 +1524,7 @@
         homedir = os.environ.get('PYTHONHOME')
         for dir in [os.environ.get('PYTHONDOCS'),
                     homedir and os.path.join(homedir, 'doc'),
+                    '/usr/share/doc/python-docs-%s/html' % split(sys.version)[0],
                     os.path.join(execdir, 'doc'),
                     '/usr/doc/python-docs-' + split(sys.version)[0],
                     '/usr/doc/python-' + split(sys.version)[0],

compat-python-2.4-distutils-bdist-rpm.patch:

--- NEW FILE compat-python-2.4-distutils-bdist-rpm.patch ---
--- Python-2.4b1/Lib/distutils/command/bdist_rpm.py.bdist-rpm	2004-09-17 04:34:12.000000000 -0400
+++ Python-2.4b1/Lib/distutils/command/bdist_rpm.py	2004-11-04 16:15:52.406896823 -0500
@@ -334,29 +334,47 @@
         if not self.keep_temp:
             rpm_cmd.append('--clean')
         rpm_cmd.append(spec_path)
+        # Determine the binary rpm names that should be built out of this spec
+        # file
+        # Note that some of these may not be really built (if the file 
+        # list is empty)
+        nvr_string = "%{name}-%{version}-%{release}"
+        src_rpm = nvr_string + ".src.rpm"
+        non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm"
+        q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % (
+            src_rpm, non_src_rpm, spec_path)
+
+        out = os.popen(q_cmd)
+        binary_rpms = []
+        source_rpm = None
+        while 1:
+            line = out.readline()
+            if not line:
+                break
+            l = string.split(string.strip(line))
+            assert(len(l) == 2)
+            binary_rpms.append(l[1])
+            # The source rpm is named after the first entry in the spec file
+            if source_rpm is None:
+                source_rpm = l[0]
+
+        status = out.close()
+        if status:
+            raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd))
+
         self.spawn(rpm_cmd)
 
-        # XXX this is a nasty hack -- we really should have a proper way to
-        # find out the names of the RPM files created; also, this assumes
-        # that RPM creates exactly one source and one binary RPM.
         if not self.dry_run:
             if not self.binary_only:
-                srpms = glob.glob(os.path.join(rpm_dir['SRPMS'], "*.rpm"))
-                assert len(srpms) == 1, \
-                       "unexpected number of SRPM files found: %s" % srpms
-                self.move_file(srpms[0], self.dist_dir)
+                srpm = os.path.join(rpm_dir['SRPMS'], source_rpm)
+                assert(os.path.exists(srpm))
+                self.move_file(srpm, self.dist_dir)
 
             if not self.source_only:
-                rpms = glob.glob(os.path.join(rpm_dir['RPMS'], "*/*.rpm"))
-                debuginfo = glob.glob(os.path.join(rpm_dir['RPMS'], \
-                                                   "*/*debuginfo*.rpm"))
-                if debuginfo:
-                    rpms.remove(debuginfo[0])
-                assert len(rpms) == 1, \
-                       "unexpected number of RPM files found: %s" % rpms
-                self.move_file(rpms[0], self.dist_dir)
-                if debuginfo:
-                    self.move_file(debuginfo[0], self.dist_dir)
+                for rpm in binary_rpms:
+                    rpm = os.path.join(rpm_dir['RPMS'], rpm)
+                    if os.path.exists(rpm):
+                        self.move_file(rpm, self.dist_dir)
     # run()
 
 

compat-python-2.4-gen-assert.patch:

--- NEW FILE compat-python-2.4-gen-assert.patch ---
--- python/trunk/Objects/genobject.c    2005/08/02 00:46:46 39239
+++ python/trunk/Objects/genobject.c    2005/08/13 03:29:00 39279
@@ -82,7 +82,7 @@
	/* Don't keep the reference to f_back any longer than necessary.  It
	 * may keep a chain of frames alive or it could create a reference
	 * cycle. */
-	assert(f->f_back != NULL);
+	assert(f->f_back == tstate->frame);
	Py_CLEAR(f->f_back);

	/* If the generator just returned (as opposed to yielding), signal

compat-python-2.4-webbrowser.patch:

--- NEW FILE compat-python-2.4-webbrowser.patch ---
--- Lib/webbrowser.py~	2005-09-15 10:29:38.000000000 +0300
+++ Lib/webbrowser.py	2005-11-17 19:48:20.000000000 +0200
@@ -277,12 +277,17 @@
 
     # X browsers have more in the way of options
     if os.environ.get("DISPLAY"):
-        _tryorder = ["galeon", "skipstone",
+        _tryorder = ["htmlview", "firefox", "galeon", "skipstone",
                      "mozilla-firefox", "mozilla-firebird", "mozilla", "netscape",
                      "kfm", "grail"] + _tryorder
 
+        # Try htmlview (in order to honor user config) before anything else.
+        if _iscommand("htmlview"):
+            register("htmlview", None, GenericBrowser(
+                "htmlview '%s' >/dev/null &"))
+
         # First, the Netscape series
-        for browser in ("mozilla-firefox", "mozilla-firebird",
+        for browser in ("firefox", "mozilla-firefox", "mozilla-firebird",
                         "mozilla", "netscape"):
             if _iscommand(browser):
                 register(browser, None, Netscape(browser))

compat-python-2.4.1-canonicalize.patch:

--- NEW FILE compat-python-2.4.1-canonicalize.patch ---
--- Python-2.4.1/pyconfig.h.in.canonicalize	2004-10-13 11:30:55.000000000 -0400
+++ Python-2.4.1/pyconfig.h.in	2005-10-06 14:04:06.000000000 -0400
@@ -58,6 +58,9 @@
 /* Define if pthread_sigmask() does not work on your system. */
 #undef HAVE_BROKEN_PTHREAD_SIGMASK
 
+/* Define to 1 if you have the `canonicalize_file_name' function. */
+#undef HAVE_CANONICALIZE_FILE_NAME
+
 /* Define to 1 if you have the `chown' function. */
 #undef HAVE_CHOWN
 
--- Python-2.4.1/Python/sysmodule.c.canonicalize	2005-01-27 13:58:30.000000000 -0500
+++ Python-2.4.1/Python/sysmodule.c	2005-10-06 14:56:37.000000000 -0400
@@ -1168,11 +1168,13 @@
 void
 PySys_SetArgv(int argc, char **argv)
 {
+#ifndef HAVE_CANONICALIZE_FILE_NAME
 #if defined(HAVE_REALPATH)
 	char fullpath[MAXPATHLEN];
 #elif defined(MS_WINDOWS)
 	char fullpath[MAX_PATH];
 #endif
+#endif
 	PyObject *av = makeargvobject(argc, argv);
 	PyObject *path = PySys_GetObject("path");
 	if (av == NULL)
@@ -1184,6 +1186,64 @@
 		char *p = NULL;
 		int n = 0;
 		PyObject *a;
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+		char *link = NULL, *argv0copy = NULL;
+                
+                if (argc > 0 && argv0 != NULL) {
+			
+			link = canonicalize_file_name(argv0);
+			if (link == NULL) {
+				link = strdup(argv0);
+				if (!link)
+					Py_FatalError("no mem for sys.argv");
+			}
+		}
+		if (link) {
+			if (link[0] == SEP) /* Link to absolute path */
+				argv0 = link;
+			else if (strchr(link, SEP) == NULL) {
+				/* Link without path */
+				/* strdup argv0 so we can free it 
+				   unconditionally */
+				argv0 = strdup(argv0);
+				if (!argv0)
+					Py_FatalError("no mem for sys.argv");
+				free(link);
+			} else {
+				/* Must join(dirname(argv0), link) */
+				char *q = strrchr(argv0, SEP);
+				if (q == NULL) /* argv0 without path */
+					argv0 = link;
+				else {
+					/* Must make a copy */
+					argv0copy = calloc(
+                                                strlen(link) + strlen(q) +1,
+                                                sizeof (char));
+					if (!argv0copy)
+						Py_FatalError("no mem for sys.argv");
+					strcpy(argv0copy, argv0);
+					q = strrchr(argv0copy, SEP);
+					strcpy(argv0copy+1, link);
+					argv0 = argv0copy;
+					p = NULL;
+					free(link);
+				}
+			}
+		}
+		if (argc > 0 && argv0 != NULL) {
+			char *q;
+			p = strrchr(argv0, SEP);
+			/* Test for alternate separator */
+			q = strrchr(p ? p : argv0, '/');
+			if (q != NULL)
+				p = q;
+			if (p != NULL) {
+				n = p + 1 - argv0;
+				if (n > 1 && p[-1] != ':')
+					n--; /* Drop trailing separator */
+			}
+		}
+#else /* ! HAVE_CANONICALIZE_FILE_NAME */
 #ifdef HAVE_READLINK
 		char link[MAXPATHLEN+1];
 		char argv0copy[2*MAXPATHLEN+1];
@@ -1256,9 +1316,14 @@
 #endif /* Unix */
 		}
 #endif /* All others */
+#endif /* ! HAVE_CANONICALIZE_FILE_NAME */
 		a = PyString_FromStringAndSize(argv0, n);
 		if (a == NULL)
 			Py_FatalError("no mem for sys.path insertion");
+#ifdef HAVE_CANONICALIZE_FILE_NAME
+		if (argc > 0 && argv0 != NULL)
+			free(argv0);
+#endif /* HAVE_CANONICALIZE_FILE_NAME */
 		if (PyList_Insert(path, 0, a) < 0)
 			Py_FatalError("sys.path.insert(0) failed");
 		Py_DECREF(a);
--- Python-2.4.1/configure.in.canonicalize	2005-03-28 18:23:34.000000000 -0500
+++ Python-2.4.1/configure.in	2005-10-06 14:04:06.000000000 -0400
@@ -2096,8 +2096,8 @@
 AC_MSG_RESULT(MACHDEP_OBJS)
 
 # checks for library functions
-AC_CHECK_FUNCS(alarm bind_textdomain_codeset chown clock confstr ctermid \
- execv fork fpathconf ftime ftruncate \
+AC_CHECK_FUNCS(alarm bind_textdomain_codeset canonicalize_file_name chown \
+ clock confstr ctermid execv fork fpathconf ftime ftruncate \
  gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \
  getpriority getpwent getsid getwd \
  kill killpg lchown lstat mkfifo mknod mktime \

compat-python-2.4.3-cflags.patch:

--- NEW FILE compat-python-2.4.3-cflags.patch ---
--- Python-2.4.3/Makefile.pre.in.BAD	2006-07-13 18:22:35.000000000 -0400
+++ Python-2.4.3/Makefile.pre.in	2006-07-13 18:22:55.000000000 -0400
@@ -309,7 +309,7 @@
 
 # Build the interpreter
 $(BUILDPYTHON):	Modules/$(MAINOBJ) $(LIBRARY) $(LDLIBRARY)
-		$(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
+		$(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
 			Modules/$(MAINOBJ) \
 			$(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
 

compat-python-2.4.3-config.patch:

--- NEW FILE compat-python-2.4.3-config.patch ---
--- Python-2.4.3/Modules/Setup.dist.rhconfig	2005-12-27 12:37:16.000000000 -0500
+++ Python-2.4.3/Modules/Setup.dist	2006-04-06 12:33:28.000000000 -0400
@@ -149,7 +149,7 @@
 # modules are to be built as shared libraries (see above for more
 # detail; also note that *static* reverses this effect):
 
-#*shared*
+*shared*
 
 # GNU readline.  Unlike previous Python incarnations, GNU readline is
 # now incorporated in an optional module, configured in the Setup file
@@ -159,68 +159,68 @@
 # it, depending on your system -- see the GNU readline instructions.
 # It's okay for this to be a shared library, too.
 
-#readline readline.c -lreadline -ltermcap
+readline readline.c -lreadline -lncurses
 
 
 # Modules that should always be present (non UNIX dependent):
 
-#array arraymodule.c	# array objects
-#cmath cmathmodule.c # -lm # complex math library functions
-#math mathmodule.c # -lm # math library functions, e.g. sin()
-#struct structmodule.c	# binary structure packing/unpacking
-#time timemodule.c # -lm # time operations and variables
-#operator operator.c	# operator.add() and similar goodies
-#_weakref _weakref.c	# basic weak reference support
-#_testcapi _testcapimodule.c    # Python C API test module
-#_random _randommodule.c	# Random number generator
-#collections collectionsmodule.c # Container types
-#itertools itertoolsmodule.c	# Functions creating iterators for efficient looping 
-#strop stropmodule.c		# String manipulations
+array arraymodule.c	# array objects
+cmath cmathmodule.c # -lm # complex math library functions
+math mathmodule.c # -lm # math library functions, e.g. sin()
+struct structmodule.c	# binary structure packing/unpacking
+time timemodule.c # -lm # time operations and variables
+operator operator.c	# operator.add() and similar goodies
+_weakref _weakref.c	# basic weak reference support
+_testcapi _testcapimodule.c    # Python C API test module
+_random _randommodule.c	# Random number generator
+collections collectionsmodule.c # Container types
+itertools itertoolsmodule.c	# Functions creating iterators for efficient looping 
+strop stropmodule.c		# String manipulations
 
-#unicodedata unicodedata.c    # static Unicode character database
+unicodedata unicodedata.c    # static Unicode character database
 
 # access to ISO C locale support
-#_locale _localemodule.c  # -lintl
+_locale _localemodule.c  # -lintl
 
 
 # Modules with some UNIX dependencies -- on by default:
 # (If you have a really backward UNIX, select and socket may not be
 # supported...)
 
-#fcntl fcntlmodule.c	# fcntl(2) and ioctl(2)
-#grp grpmodule.c		# grp(3)
-#select selectmodule.c	# select(2); not on ancient System V
+fcntl fcntlmodule.c	# fcntl(2) and ioctl(2)
+grp grpmodule.c		# grp(3)
+select selectmodule.c	# select(2); not on ancient System V
 
 # Memory-mapped files (also works on Win32).
-#mmap mmapmodule.c
+mmap mmapmodule.c
 
 # CSV file helper
-#_csv _csv.c
+_csv _csv.c
 
 # Socket module helper for socket(2)
-#_socket socketmodule.c
+_socket socketmodule.c
 
 # Socket module helper for SSL support; you must comment out the other
 # socket line above, and possibly edit the SSL variable:
-#SSL=/usr/local/ssl
-#_ssl _ssl.c \
-#	-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-#	-L$(SSL)/lib -lssl -lcrypto
+SSL=/usr/local/ssl
+_ssl _ssl.c \
+	-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
+	-L$(SSL)/lib -lssl -lcrypto
 
 # The crypt module is now disabled by default because it breaks builds
 # on many systems (where -lcrypt is needed), e.g. Linux (I believe).
 #
 # First, look at Setup.config; configure may have set this for you.
 
-#crypt cryptmodule.c # -lcrypt	# crypt(3); needs -lcrypt on some systems
+crypt cryptmodule.c -lcrypt	# crypt(3); needs -lcrypt on some systems
 
 
 # Some more UNIX dependent modules -- off by default, since these
 # are not supported by all UNIX systems:
 
-#nis nismodule.c -lnsl	# Sun yellow pages -- not everywhere
-#termios termios.c	# Steen Lumholt's termios module
-#resource resource.c	# Jeremy Hylton's rlimit interface
+nis nismodule.c -lnsl	# Sun yellow pages -- not everywhere
+termios termios.c	# Steen Lumholt's termios module
+resource resource.c	# Jeremy Hylton's rlimit interface
 
 
 # Multimedia modules -- off by default.
@@ -228,21 +228,21 @@
 # #993173 says audioop works on 64-bit platforms, though.
 # These represent audio samples or images as strings:
 
-#audioop audioop.c	# Operations on audio samples
-#imageop imageop.c	# Operations on images
-#rgbimg rgbimgmodule.c	# Read SGI RGB image files (but coded portably)
+audioop audioop.c	# Operations on audio samples
+imageop imageop.c	# Operations on images
+rgbimg rgbimgmodule.c	# Read SGI RGB image files (but coded portably)
 
 
 # The md5 module implements the RSA Data Security, Inc. MD5
 # Message-Digest Algorithm, described in RFC 1321.  The necessary files
 # md5c.c and md5.h are included here.
 
-#md5 md5module.c md5c.c
+md5 md5module.c md5c.c
 
 
 # The sha module implements the SHA checksum algorithm.
 # (NIST's Secure Hash Algorithm.)
-#sha shamodule.c
+sha shamodule.c
 
 
 # SGI IRIX specific modules -- off by default.
@@ -289,12 +289,12 @@
 # A Linux specific module -- off by default; this may also work on 
 # some *BSDs.
 
-#linuxaudiodev linuxaudiodev.c
+linuxaudiodev linuxaudiodev.c
 
 
 # George Neville-Neil's timing module:
 
-#timing timingmodule.c
+timing timingmodule.c
 
 
 # The _tkinter module.
@@ -309,7 +309,7 @@
 # every system.
 
 # *** Always uncomment this (leave the leading underscore in!):
-# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
+_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
 # *** Uncomment and edit to reflect where your Tcl/Tk libraries are:
 #	-L/usr/local/lib \
 # *** Uncomment and edit to reflect where your Tcl/Tk headers are:
@@ -319,7 +319,7 @@
 # *** Or uncomment this for Solaris:
 #	-I/usr/openwin/include \
 # *** Uncomment and edit for Tix extension only:
-#	-DWITH_TIX -ltix8.1.8.2 \
+	-DWITH_TIX -ltix \
 # *** Uncomment and edit for BLT extension only:
 #	-DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \
 # *** Uncomment and edit for PIL (TkImaging) extension only:
@@ -328,7 +328,7 @@
 # *** Uncomment and edit for TOGL extension only:
 #	-DWITH_TOGL togl.c \
 # *** Uncomment and edit to reflect your Tcl/Tk versions:
-#	-ltk8.2 -ltcl8.2 \
+	-ltk -ltcl \
 # *** Uncomment and edit to reflect where your X11 libraries are:
 #	-L/usr/X11R6/lib \
 # *** Or uncomment this for Solaris:
@@ -338,7 +338,7 @@
 # *** Uncomment for AIX:
 #	-lld \
 # *** Always uncomment this; X11 libraries to link with:
-#	-lX11
+	-lX11
 
 # Lance Ellinghaus's syslog module
 #syslog syslogmodule.c		# syslog daemon interface
@@ -350,9 +350,9 @@
 #
 # First, look at Setup.config; configure may have set this for you.
 
-#_curses _cursesmodule.c -lcurses -ltermcap
+_curses _cursesmodule.c -lncurses
 # Wrapper for the panel library that's part of ncurses and SYSV curses.
-#_curses_panel _curses_panel.c -lpanel -lncurses 
+_curses_panel _curses_panel.c -lpanel -lncurses 
 
 
 # Generic (SunOS / SVR4) dynamic loading module.
@@ -360,7 +360,7 @@
 # it is a highly experimental and dangerous device for calling
 # *arbitrary* C functions in *arbitrary* shared libraries:
 
-#dl dlmodule.c
+dl dlmodule.c
 
 
 # Modules that provide persistent dictionary-like semantics.  You will
@@ -383,7 +383,7 @@
 #
 # First, look at Setup.config; configure may have set this for you.
 
-#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
+gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm
 
 
 # Sleepycat Berkeley DB interface.
@@ -398,11 +398,10 @@
 #
 # Edit the variables DB and DBLIBVERto point to the db top directory
 # and the subdirectory of PORT where you built it.
-#DB=/usr/local/BerkeleyDB.4.0
-#DBLIBVER=4.0
-#DBINC=$(DB)/include
-#DBLIB=$(DB)/lib
-#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
+DBLIBVER=4.6
+DBINC=/usr/include/db4
+DBLIB=/usr/lib
+_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
 
 # Historical Berkeley DB 1.85
 #
@@ -417,14 +416,14 @@
 
 
 # Helper module for various ascii-encoders
-#binascii binascii.c
+binascii binascii.c
 
 # Fred Drake's interface to the Python parser
-#parser parsermodule.c
+parser parsermodule.c
 
 # cStringIO and cPickle
-#cStringIO cStringIO.c
-#cPickle cPickle.c
+cStringIO cStringIO.c
+cPickle cPickle.c
 
 
 # Lee Busby's SIGFPE modules.
@@ -447,7 +446,7 @@
 # Andrew Kuchling's zlib module.
 # This require zlib 1.1.3 (or later).
 # See http://www.gzip.org/zlib/
-#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
+zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
 
 # Interface to the Expat XML parser
 #
@@ -467,14 +466,14 @@
 # Hye-Shik Chang's CJKCodecs
 
 # multibytecodec is required for all the other CJK codec modules
-#_multibytecodec cjkcodecs/multibytecodec.c
+_multibytecodec cjkcodecs/multibytecodec.c
 
-#_codecs_cn cjkcodecs/_codecs_cn.c
-#_codecs_hk cjkcodecs/_codecs_hk.c
-#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
-#_codecs_jp cjkcodecs/_codecs_jp.c
-#_codecs_kr cjkcodecs/_codecs_kr.c
-#_codecs_tw cjkcodecs/_codecs_tw.c
+_codecs_cn cjkcodecs/_codecs_cn.c
+_codecs_hk cjkcodecs/_codecs_hk.c
+_codecs_iso2022 cjkcodecs/_codecs_iso2022.c
+_codecs_jp cjkcodecs/_codecs_jp.c
+_codecs_kr cjkcodecs/_codecs_kr.c
+_codecs_tw cjkcodecs/_codecs_tw.c
 
 # Example -- included for reference only:
 # xx xxmodule.c

compat-python-2.4.3-locale.patch:

--- NEW FILE compat-python-2.4.3-locale.patch ---
--- python/trunk/Lib/logging/handlers.py	2006/06/27 07:34:37	47121
+++ python/trunk/Lib/logging/handlers.py	2006/07/20 23:20:12	50740
@@ -562,6 +562,18 @@
         "local7":   LOG_LOCAL7,
         }
 
+    #The map below appears to be trivially lowercasing the key. However,
+    #there's more to it than meets the eye - in some locales, lowercasing
+    #gives unexpected results. See SF #1524081: in the Turkish locale,
+    #"INFO".lower() != "info"
+    priority_map = {
+        "DEBUG" : "debug",
+        "INFO" : "info",
+        "WARNING" : "warning",
+        "ERROR" : "error",
+        "CRITICAL" : "critical"
+    }
+
     def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER):
         """
         Initialize a handler.
@@ -598,7 +610,7 @@
     #   necessary.
     log_format_string = '<%d>%s\000'
 
-    def encodePriority (self, facility, priority):
+    def encodePriority(self, facility, priority):
         """
         Encode the facility and priority. You can pass in strings or
         integers - if strings are passed, the facility_names and
@@ -619,6 +631,16 @@
             self.socket.close()
         logging.Handler.close(self)
 
+    def mapPriority(self, levelName):
+        """
+        Map a logging level name to a key in the priority_names map.
+        This is useful in two scenarios: when custom levels are being
+        used, and in the case where you can't do a straightforward
+        mapping by lowercasing the logging level name because of locale-
+        specific issues (see SF #1524081).
+        """
+        return self.priority_map.get(levelName, "warning")
+
     def emit(self, record):
         """
         Emit a record.
@@ -633,8 +655,8 @@
         """
         msg = self.log_format_string % (
             self.encodePriority(self.facility,
-                                string.lower(record.levelname)),
-            msg)
+                                self.mapPriority(record.levelname)),
+                                msg)
         try:
             if self.unixsocket:
                 try:

compat-python-2.4.4-db46.patch:

--- NEW FILE compat-python-2.4.4-db46.patch ---
diff -up ./setup.py.orig ./setup.py
--- ./setup.py.orig	2007-11-30 16:11:03.000000000 -0700
+++ ./setup.py	2007-11-30 16:11:10.000000000 -0700
@@ -522,7 +522,7 @@ class PyBuildExt(build_ext):
         #
         # http://www.sleepycat.com/update/index.html
 
-        max_db_ver = (4, 4)
+        max_db_ver = (4, 6)
         min_db_ver = (3, 2)
         db_setup_debug = False   # verbose debug prints from this script?
 
@@ -539,7 +539,7 @@ class PyBuildExt(build_ext):
             '/sw/include/db3',
         ]
         # 4.x minor number specific paths
-        for x in (0,1,2,3,4):
+        for x in (0,1,2,3,4,5,6):
             db_inc_paths.append('/usr/include/db4%d' % x)
             db_inc_paths.append('/usr/include/db4.%d' % x)
             db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
diff -up ./Modules/_bsddb.c.orig ./Modules/_bsddb.c
--- ./Modules/_bsddb.c.orig	2007-11-30 16:13:03.000000000 -0700
+++ ./Modules/_bsddb.c	2007-11-30 16:14:38.000000000 -0700
@@ -3831,6 +3831,7 @@ DBEnv_set_lk_detect(DBEnvObject* self, P
 }
 
 
+#if (DBVER < 45)
 static PyObject*
 DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
 {
@@ -3846,6 +3847,7 @@ DBEnv_set_lk_max(DBEnvObject* self, PyOb
     RETURN_IF_ERR();
     RETURN_NONE();
 }
+#endif
 
 
 #if (DBVER >= 32)
@@ -4532,7 +4534,9 @@ static PyMethodDef DBEnv_methods[] = {
     {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,       METH_VARARGS},
     {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,       METH_VARARGS},
     {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,    METH_VARARGS},
+#if (DBVER < 45)
     {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
+#endif
 #if (DBVER >= 32)
     {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
     {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
@@ -5039,7 +5043,9 @@ DL_EXPORT(void) init_bsddb(void)
     ADD_INT(d, DB_AFTER);
     ADD_INT(d, DB_APPEND);
     ADD_INT(d, DB_BEFORE);
+#if (DBVER < 45)
     ADD_INT(d, DB_CACHED_COUNTS);
+#endif
 #if (DBVER >= 41)
     _addIntToDict(d, "DB_CHECKPOINT", 0);
 #else
@@ -5074,7 +5080,9 @@ DL_EXPORT(void) init_bsddb(void)
     ADD_INT(d, DB_POSITION);
     ADD_INT(d, DB_PREV);
     ADD_INT(d, DB_PREV_NODUP);
+#if (DBVER < 45)
     ADD_INT(d, DB_RECORDCOUNT);
+#endif
     ADD_INT(d, DB_SET);
     ADD_INT(d, DB_SET_RANGE);
     ADD_INT(d, DB_SET_RECNO);

compat-python-2.4.4-lib64.patch:

--- NEW FILE compat-python-2.4.4-lib64.patch ---
--- Python-2.4.4/setup.py.lib64	2006-10-08 13:41:25.000000000 -0400
+++ Python-2.4.4/setup.py	2006-10-23 13:23:14.000000000 -0400
@@ -240,7 +240,7 @@
 
     def detect_modules(self):
         # Ensure that /usr/local is always used
-        add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
+        add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64')
         add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
 
         # Add paths to popular package managers on OS X/darwin
@@ -450,7 +450,7 @@
             elif self.compiler.find_library_file(lib_dirs, 'curses'):
                 readline_libs.append('curses')
             elif self.compiler.find_library_file(lib_dirs +
-                                               ['/usr/lib/termcap'],
+                                               ['/usr/lib64/termcap'],
                                                'termcap'):
                 readline_libs.append('termcap')
 
@@ -465,7 +465,7 @@
                 readline_extra_link_args = ()
 
             exts.append( Extension('readline', ['readline.c'],
-                                   library_dirs=['/usr/lib/termcap'],
+                                   library_dirs=['/usr/lib64/termcap'],
                                    extra_link_args=readline_extra_link_args,
                                    libraries=readline_libs) )
         if platform not in ['mac']:
@@ -495,8 +495,8 @@
             if krb5_h:
                 ssl_incs += krb5_h
         ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
-                                     ['/usr/local/ssl/lib',
-                                      '/usr/contrib/ssl/lib/'
+                                     ['/usr/local/ssl/lib64',
+                                      '/usr/contrib/ssl/lib64/'
                                      ] )
 
         if (ssl_incs is not None and
--- Python-2.4.4/Modules/getpath.c.lib64	2006-02-20 12:37:39.000000000 -0500
+++ Python-2.4.4/Modules/getpath.c	2006-10-23 13:21:40.000000000 -0400
@@ -112,8 +112,8 @@
 #endif
 
 #ifndef PYTHONPATH
-#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \
-              EXEC_PREFIX "/lib/python" VERSION "/lib-dynload"
+#define PYTHONPATH PREFIX "/lib64/python" VERSION ":" \
+              EXEC_PREFIX "/lib64/python" VERSION "/lib-dynload"
 #endif
 
 #ifndef LANDMARK
@@ -124,7 +124,7 @@
 static char exec_prefix[MAXPATHLEN+1];
 static char progpath[MAXPATHLEN+1];
 static char *module_search_path = NULL;
-static char lib_python[] = "lib/python" VERSION;
+static char lib_python[] = "lib64/python" VERSION;
 
 static void
 reduce(char *dir)
@@ -519,7 +519,7 @@
     }
     else
         strncpy(zip_path, PREFIX, MAXPATHLEN);
-    joinpath(zip_path, "lib/python00.zip");
+    joinpath(zip_path, "lib64/python00.zip");
     bufsz = strlen(zip_path);	/* Replace "00" with version */
     zip_path[bufsz - 6] = VERSION[0];
     zip_path[bufsz - 5] = VERSION[2];
@@ -529,7 +529,7 @@
             fprintf(stderr,
                 "Could not find platform dependent libraries <exec_prefix>\n");
         strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
-        joinpath(exec_prefix, "lib/lib-dynload");
+        joinpath(exec_prefix, "lib64/lib-dynload");
     }
     /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
 
--- Python-2.4.4/Modules/Setup.dist.lib64	2006-10-23 13:21:40.000000000 -0400
+++ Python-2.4.4/Modules/Setup.dist	2006-10-23 13:21:40.000000000 -0400
@@ -400,7 +400,7 @@
 # and the subdirectory of PORT where you built it.
 DBLIBVER=4.3
 DBINC=/usr/include/db4
-DBLIB=/usr/lib
+DBLIB=/usr/lib64
 _bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER)
 
 # Historical Berkeley DB 1.85
@@ -446,7 +446,7 @@
 # Andrew Kuchling's zlib module.
 # This require zlib 1.1.3 (or later).
 # See http://www.gzip.org/zlib/
-zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz
+zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib64 -lz
 
 # Interface to the Expat XML parser
 #
--- Python-2.4.4/Makefile.pre.in.lib64	2006-10-08 13:41:25.000000000 -0400
+++ Python-2.4.4/Makefile.pre.in	2006-10-23 13:21:40.000000000 -0400
@@ -79,11 +79,11 @@
 
 # Expanded directories
 BINDIR=		$(exec_prefix)/bin
-LIBDIR=		$(exec_prefix)/lib
+LIBDIR=		$(exec_prefix)/lib64
 MANDIR=		@mandir@
 INCLUDEDIR=	@includedir@
 CONFINCLUDEDIR=	$(exec_prefix)/include
-SCRIPTDIR=	$(prefix)/lib
+SCRIPTDIR=	$(prefix)/lib64
 
 # Detailed destination directories
 BINLIBDEST=	$(LIBDIR)/python$(VERSION)
--- Python-2.4.4/Lib/distutils/command/install.py.lib64	2005-01-20 14:15:39.000000000 -0500
+++ Python-2.4.4/Lib/distutils/command/install.py	2006-10-23 13:21:40.000000000 -0400
@@ -39,14 +39,14 @@
 INSTALL_SCHEMES = {
     'unix_prefix': {
         'purelib': '$base/lib/python$py_version_short/site-packages',
-        'platlib': '$platbase/lib/python$py_version_short/site-packages',
+        'platlib': '$platbase/lib64/python$py_version_short/site-packages',
         'headers': '$base/include/python$py_version_short/$dist_name',
         'scripts': '$base/bin',
         'data'   : '$base',
         },
     'unix_home': {
         'purelib': '$base/lib/python',
-        'platlib': '$base/lib/python',
+        'platlib': '$base/lib64/python',
         'headers': '$base/include/python/$dist_name',
         'scripts': '$base/bin',
         'data'   : '$base',
--- Python-2.4.4/Lib/distutils/sysconfig.py.lib64	2006-10-08 13:41:25.000000000 -0400
+++ Python-2.4.4/Lib/distutils/sysconfig.py	2006-10-23 13:21:40.000000000 -0400
@@ -99,8 +99,12 @@
         prefix = plat_specific and EXEC_PREFIX or PREFIX
 
     if os.name == "posix":
+        if plat_specific or standard_lib:
+            lib = "lib64"
+        else:
+            lib = "lib"
         libpython = os.path.join(prefix,
-                                 "lib", "python" + get_python_version())
+                                 lib, "python" + get_python_version())
         if standard_lib:
             return libpython
         else:
--- Python-2.4.4/Lib/site.py.lib64	2004-07-19 22:28:28.000000000 -0400
+++ Python-2.4.4/Lib/site.py	2006-10-23 13:21:40.000000000 -0400
@@ -179,9 +179,14 @@
                 sitedirs = [os.path.join(prefix, "Lib", "site-packages")]
             elif os.sep == '/':
                 sitedirs = [os.path.join(prefix,
-                                         "lib",
+                                         "lib64",
                                          "python" + sys.version[:3],
                                          "site-packages"),
+                            os.path.join(prefix,
+                                         "lib",
+                                         "python" + sys.version[:3],
+                                         "site-packages"),                            
+                            os.path.join(prefix, "lib64", "site-python"),
                             os.path.join(prefix, "lib", "site-python")]
             else:
                 sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")]


--- NEW FILE compat-python24.spec ---
%define unicode ucs4
%define tkinter compat-tkinter24

%define pybasever 2.4
%define jp_codecs 1.4.11
%define tools_dir %{_libdir}/python%{pybasever}/Tools
%define demo_dir %{_libdir}/python%{pybasever}/Demo
%define doc_tools_dir %{_libdir}/python%{pybasever}/Doc/tools

Summary: An interpreted, interactive, object-oriented programming language
Name: compat-python24
Version: %{pybasever}.5
Release: 1%{?dist}
License: Python Software Foundation License v2
Group: Development/Languages
Source: http://www.python.org/ftp/python/%{version}/Python-%{version}.tar.bz2
Source5: http://www.python.jp/pub/JapaneseCodecs/JapaneseCodecs-%{jp_codecs}.tar.gz
Source6: http://gigue.peabody.jhu.edu/~mdboom/omi/source/shm_source/shmmodule.c
Source7: compat-python-2.3.4-optik.py

Patch0: compat-python-2.4.3-config.patch
Patch3: compat-Python-2.2.1-pydocnogui.patch
Patch7: compat-python-2.3.4-lib64-regex.patch
Patch8: compat-python-2.4.4-lib64.patch
Patch9: compat-japanese-codecs-lib64.patch
Patch13: compat-python-2.4-distutils-bdist-rpm.patch
Patch14: compat-python-2.3.4-pydocnodoc.patch
Patch15: compat-python-2.4.1-canonicalize.patch
Patch16: compat-python-2.4-gen-assert.patch
Patch17: compat-python-2.4-webbrowser.patch
Patch18: compat-python-2.4.3-cflags.patch
Patch19: compat-python-2.4.3-locale.patch
Patch20: compat-python-2.4.4-db46.patch
#Patch21: compat-python-2.4.4-db4-debug.patch

BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: readline-devel, libtermcap-devel, openssl-devel, gmp-devel
BuildRequires: ncurses-devel, gdbm-devel, zlib-devel, expat-devel
BuildRequires: libGL-devel tk tix gcc-c++ libX11-devel glibc-devel
BuildRequires: bzip2 tar /usr/bin/find pkgconfig tcl-devel tk-devel
BuildRequires: tix-devel bzip2-devel
BuildRequires: autoconf
BuildRequires: db4-devel >= 4.3
URL: http://www.python.org/
Provides: python-abi = 2.4, python(abi) = 2.4

%description
Python is an interpreted, interactive, object-oriented programming
language often compared to Tcl, Perl, Scheme or Java. Python includes
modules, classes, exceptions, very high level dynamic data types and
dynamic typing. Python supports interfaces to many system calls and
libraries, as well as to various windowing systems (X11, Motif, Tk,
Mac and MFC).

Programmers can write new built-in modules for Python in C or C++.
Python can be used as an extension language for applications that need
a programmable interface. This package contains most of the standard
Python modules, as well as modules for interfacing to the Tix widget
set for Tk and RPM.

Note that documentation for Python is provided in the python-docs
package.

%package devel
Summary: The libraries and header files needed for Python development
Group: Development/Libraries
Requires: %{name} = %{version}-%{release}

%description devel
The Python programming language's interpreter can be extended with
dynamically loaded extensions and can be embedded in other programs.
This package contains the header files and libraries needed to do
these types of tasks.

Install python-devel if you want to develop Python extensions.  The
python package will also need to be installed.  You'll probably also
want to install the python-docs package, which contains Python
documentation.

%package tools
Summary: A collection of development tools included with Python
Group: Development/Tools
Requires: %{name} = %{version}-%{release}
Requires: %{tkinter} = %{version}-%{release}

%description tools
The Python package includes several development tools that are used
to build python programs.

%package -n %{tkinter}
Summary: A graphical user interface for the Python scripting language
Group: Development/Languages
BuildRequires:  tcl, tk
Requires: %{name} = %{version}-%{release}

%description -n %{tkinter}

The Tkinter (Tk interface) program is an graphical user interface for
the Python scripting language.

You should install the tkinter package if you'd like to use a graphical
user interface for Python programming.

%prep
%setup -q -n Python-%{version} -a 5

%patch0 -p1 -b .rhconfig
%patch3 -p1 -b .no_gui
%if %{_lib} == lib64
%patch7 -p1 -b .lib64-regex
%patch8 -p1 -b .lib64
%patch9 -p0 -b .lib64-j
%endif
%patch13 -p1 -b .bdist-rpm
%patch14 -p1 -b .no-doc
%patch15 -p1 -b .canonicalize
%patch16 -p2 -b .gen-assert
%patch17 -p0 -b .web-browser
%patch18 -p1 -b .cflags
%patch19 -p2 -b .locale
%patch20 -p1 -b .db4
#%%patch21 -p1 -b .db-debug

# This shouldn't be necesarry, but is right now (2.2a3)
find -name "*~" |xargs rm -f

# Temporary workaround to avoid confusing find-requires: don't ship the tests
# as executable files
chmod 0644 Lib/test/test_*.py

# shm module
cp %{SOURCE6} Modules
cat >> Modules/Setup.dist << EOF

# Shared memory module
shm shmmodule.c
EOF

# Backwards compatible optik
install -m 0644 %{SOURCE7} Lib/optik.py

%build
topdir=`pwd`
export CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC"
export CXXFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC"
export OPT="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC"
export LINKCC="gcc"
if pkg-config openssl ; then
    export CFLAGS="$CFLAGS `pkg-config --cflags openssl`"
    export LDFLAGS="$LDFLAGS `pkg-config --libs-only-L openssl`"
fi
# Force CC
export CC=gcc
# For patch 15, need to get a newer configure generated out of configure.in
autoconf
%configure --enable-ipv6 --enable-unicode=%{unicode} --enable-shared

make OPT="$CFLAGS" %{?_smp_mflags}
LD_LIBRARY_PATH=$topdir $topdir/python Tools/scripts/pathfix.py -i "%{_bindir}/env python%{pybasever}" .
make OPT="$CFLAGS" %{?_smp_mflags}

%install
[ -d $RPM_BUILD_ROOT ] && rm -fr $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr $RPM_BUILD_ROOT%{_mandir}

# Clean up patched .py files that are saved as .lib64
for f in distutils/command/install distutils/sysconfig; do
    rm -f Lib/$f.py.lib64
done

make install DESTDIR=$RPM_BUILD_ROOT
# Fix the interpreter path in binaries installed by distutils 
# (which changes them by itself)
# Make sure we preserve the file permissions
for fixed in $RPM_BUILD_ROOT%{_bindir}/pydoc; do
    sed 's,#!.*/python$,#!%{_bindir}/env python%{pybasever},' $fixed > $fixed- \
        && cat $fixed- > $fixed && rm -f $fixed-
done

# tools

mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/python%{pybasever}/site-packages

#modulator
cat > ${RPM_BUILD_ROOT}%{_bindir}/modulator << EOF
#!/bin/bash
exec %{_libdir}/python%{pybasever}/site-packages/modulator/modulator.py
EOF
chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/modulator
cp -r Tools/modulator \
  ${RPM_BUILD_ROOT}%{_libdir}/python%{pybasever}/site-packages/

#pynche
cat > ${RPM_BUILD_ROOT}%{_bindir}/pynche << EOF
#!/bin/bash
exec %{_libdir}/python%{pybasever}/site-packages/pynche/pynche
EOF
chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/pynche
rm -f Tools/pynche/*.pyw
cp -r Tools/pynche \
  ${RPM_BUILD_ROOT}%{_libdir}/python%{pybasever}/site-packages/

mv Tools/modulator/README Tools/modulator/README.modulator
mv Tools/pynche/README Tools/pynche/README.pynche

#gettext
install -m755  Tools/i18n/pygettext.py $RPM_BUILD_ROOT%{_bindir}/
install -m755  Tools/i18n/msgfmt.py $RPM_BUILD_ROOT%{_bindir}/

# Useful development tools
install -m755 -d $RPM_BUILD_ROOT%{tools_dir}/scripts
install Tools/README $RPM_BUILD_ROOT%{tools_dir}/
install Tools/scripts/*py $RPM_BUILD_ROOT%{tools_dir}/scripts/

# Documentation tools
install -m755 -d $RPM_BUILD_ROOT%{doc_tools_dir}
install -m755 Doc/tools/mkhowto $RPM_BUILD_ROOT%{doc_tools_dir}

# Useful demo scripts
install -m755 -d $RPM_BUILD_ROOT%{demo_dir}
cp -ar Demo/* $RPM_BUILD_ROOT%{demo_dir}

# Get rid of crap
find $RPM_BUILD_ROOT/ -name "*~"|xargs rm -f
find $RPM_BUILD_ROOT/ -name ".cvsignore"|xargs rm -f
find . -name "*~"|xargs rm -f
find . -name ".cvsignore"|xargs rm -f
#zero length
rm -f $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/site-packages/modulator/Templates/copyright

# Clean up the testsuite - we don't need compiled files for it
find $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/test \
    -name "*.pyc" -o -name "*.pyo" | xargs rm -f
rm -f $RPM_BUILD_ROOT%{_libdir}/python2.2/LICENSE.txt


#make the binaries install side by side with the main python
pushd $RPM_BUILD_ROOT%{_bindir}
mv idle idle%{pybasever}
mv modulator modulator%{pybasever}
mv pynche pynche%{pybasever}
mv pygettext.py pygettext%{pybasever}.py
mv msgfmt.py msgfmt%{pybasever}.py
mv smtpd.py smtpd%{pybasever}.py
mv pydoc pydoc%{pybasever}
popd

# Japanese codecs
pushd JapaneseCodecs-%{jp_codecs}
# We need to set LD_LIBRARY_PATH since python is now compiled as shared, and
# we always want to use the currently compiled one
LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir} \
    ../python setup.py install --root=$RPM_BUILD_ROOT
popd

find $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/lib-dynload -type d | sed "s|$RPM_BUILD_ROOT|%dir |" > dynfiles
find $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/lib-dynload -type f | grep -v "_tkinter.so$" | sed "s|$RPM_BUILD_ROOT||" >> dynfiles

# Fix for bug #136654
rm -f $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/email/test/data/audiotest.au $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/test/audiotest.au

# Fix bug #143667: python should own /usr/lib/python2.x on 64-bit machines
%if %{_lib} == lib64
install -d $RPM_BUILD_ROOT/usr/lib/python%{pybasever}/site-packages
%endif

# Make python-devel multilib-ready (bug #192747, #139911)
%define _pyconfig32_h pyconfig-32.h
%define _pyconfig64_h pyconfig-64.h

%ifarch ppc64 s390x x86_64 ia64
%define _pyconfig_h %{_pyconfig64_h}
%else
%define _pyconfig_h %{_pyconfig32_h}
%endif
mv $RPM_BUILD_ROOT%{_includedir}/python%{pybasever}/pyconfig.h \
   $RPM_BUILD_ROOT%{_includedir}/python%{pybasever}/%{_pyconfig_h}
cat > $RPM_BUILD_ROOT%{_includedir}/python%{pybasever}/pyconfig.h << EOF
#include <bits/wordsize.h>

#if __WORDSIZE == 32
#include "%{_pyconfig32_h}"
#elif __WORDSIZE == 64
#include "%{_pyconfig64_h}"
#else
#error "Unkown word size"
#endif
EOF

# Fix for bug 201434: make sure distutils looks at the right pyconfig.h file
sed -i -e "s/'pyconfig.h'/'%{_pyconfig_h}'/" $RPM_BUILD_ROOT%{_libdir}/python%{pybasever}/distutils/sysconfig.py

# Remove conflicting files
rm -f $RPM_BUILD_ROOT%{_bindir}/pydoc*
rm -rf $RPM_BUILD_ROOT%{_mandir}/*/*
rm -f $RPM_BUILD_ROOT%{_bindir}/python 


%clean
rm -fr $RPM_BUILD_ROOT

%files -f dynfiles
%defattr(-, root, root)
%doc LICENSE README
#%{_bindir}/pydoc*
%{_bindir}/python2.4
#%{_mandir}/*/*
%{_libdir}/libpython%{pybasever}.so*

%dir %{_libdir}/python%{pybasever}
%{_libdir}/python%{pybasever}/site-packages/japanese.pth
%dir %{_libdir}/python%{pybasever}/site-packages
%{_libdir}/python%{pybasever}/site-packages/japanese
%{_libdir}/python%{pybasever}/site-packages/README
%{_libdir}/python%{pybasever}/LICENSE.txt
%{_libdir}/python%{pybasever}/*.py*
%{_libdir}/python%{pybasever}/*.doc
%{_libdir}/python%{pybasever}/bsddb
%dir %{_libdir}/python%{pybasever}/config
%{_libdir}/python%{pybasever}/config/Makefile
%{_libdir}/python%{pybasever}/curses
%{_libdir}/python%{pybasever}/distutils
%{_libdir}/python%{pybasever}/encodings
%{_libdir}/python%{pybasever}/idlelib
%{_libdir}/python%{pybasever}/lib-old
%{_libdir}/python%{pybasever}/logging
%{_libdir}/python%{pybasever}/xml
%{_libdir}/python%{pybasever}/email
%{_libdir}/python%{pybasever}/compiler
%{_libdir}/python%{pybasever}/plat-linux2
%{_libdir}/python%{pybasever}/hotshot
%if %{_lib} == lib64
%attr(0755,root,root) %dir /usr/lib/python%{pybasever}
%attr(0755,root,root) %dir /usr/lib/python%{pybasever}/site-packages
%endif

%files devel
%defattr(-,root,root)
/usr/include/*
%{_libdir}/python%{pybasever}/config
%{_libdir}/python%{pybasever}/test

%files tools
%defattr(-,root,root,755)
%doc Tools/modulator/README.modulator
%doc Tools/pynche/README.pynche
%{_libdir}/python%{pybasever}/site-packages/modulator
%{_libdir}/python%{pybasever}/site-packages/pynche
%{_bindir}/smtpd*.py*
%{_bindir}/idle*
%{_bindir}/modulator*
%{_bindir}/pynche*
%{_bindir}/pygettext*.py*
%{_bindir}/msgfmt*.py*
%{tools_dir}
%{demo_dir}
%{_libdir}/python%{pybasever}/Doc

%files -n %{tkinter}
%defattr(-,root,root,755)
%{_libdir}/python%{pybasever}/lib-tk
%{_libdir}/python%{pybasever}/lib-dynload/_tkinter.so

%changelog
* Thu Mar 27 2008 Jonathan Steffan <jonathansteffan a gmail.com> 2.4.5-1
- Update to 2.4.5

* Fri Nov 30 2007 Jonathan Steffan <jonathansteffan a gmail.com> 2.4.4-3
- Update patch for db46
- Added patch to turn on debug printing for db detection
- Updated config patch for DB 4.6, this is not downstream compatible 

* Fri Aug 17 2007 Jonathan Steffan <jonathansteffan a gmail.com> 2.4.4-2
- Updated tkinter to be compat-tkinter

* Mon Jun 18 2007 Jonathan Steffan <jonathansteffan a gmail.com> 2.4.4-1
- Initial package based on fc6 srpm


--- NEW FILE shmmodule.c ---
/****************************************************************************
 *
 * « shmmodule.c © 1997, 1998 by INRIA. All rights reserved.
 *   
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *   
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *   
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY WARRANTIES, EXPRESS OR IMPLIED,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *   
 * IN NO EVENT SHALL THE INRIA OR THE AUTHORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES,
 * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
 * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION, HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT,
 * INCLUDING NEGLIGENCE OR OTHERWISE, ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. »
 *   
 ***************************************************************************/
/*
 *  If you have questions regarding this software, contact:
 *  Vladimir Marangozov, Vladimir.Marangozov at inrialpes.fr
 *  INRIA Rhône-Alpes, SIRAC project, 655 avenue de l'Europe
 *  38330 Montbonnot St. Martin, France.
 */


/* Python Shared Memory module */

/*
  This module provides an interface to System V shared memory IPC.


Module interface:

- shm.create_memory(int Key, int Size [,int Perm=0666]) --> object
- shm.create_semaphore(int Key [,int Value=1 [,int Perm=0666]]) --> object
- shm.error
- shm.ftok(string Path, int ProjId) --> int
- shm.getsemid(int Key) --> int
- shm.getshmid(int Key) --> int
- shm.memory(int Shmid) --> object
- shm.memory_haskey(int Key) --> int
- shm.remove_memory(int Shmid) --> None
- shm.remove_semaphore(int Semid) --> None
- shm.semaphore(int Semid) --> object
- shm.semaphore_haskey(int Key) --> int

Memory Objects:

+ Members:

- m.addr	- attachment address in the process address space
- m.attached	- 0|1
- m.cgid	- gid of creator
- m.cpid	- pid of creator
- m.cuid	- uid of creator
- m.gid		- gid of owner
- m.key		- segment key or IPC_PRIVATE (=0)
- m.lpid	- pid of last shmop
- m.nattch	- current # of attached processes
- m.perm	- operation permission
- m.shmid	- shared memory segment id
- m.size	- segment size
- m.uid		- uid of owner

+ Methods:

- m.attach([int Addr=0 [,int How=0]]) --> None
- m.detach() --> None
- m.read(int Nbytes [,int Offset=0]) --> string
- m.setgid(int Gid) --> None
- m.setperm(int Perm) --> None
- m.setuid(int Uid) --> None
- m.write(string Data [,int Offset=0]) --> None

Semaphore Objects:

+ Members:

- s.cgid	- gid of creator
- s.cuid	- uid of creator
- s.gid		- gid of owner
- s.key		- semaphore key or IPC_PRIVATE (=0)
- s.lpid	- pid of last semop
- s.ncnt	- current # of processes waiting for s.val > 0
- s.perm	- operation permission
- s.semid	- semaphore id
- s.uid		- uid of owner
- s.val		- value of the semaphore counter
- s.zcnt	- current # of processes waiting for s.val == 0

+ Methods:

- s.P() --> None		- blocks if s.val == 0; decrements s.val
- s.V() --> None		- increments s.val
- s.Z() --> None		- blocks until s.val == 0
- s.setblocking(0|1) --> None
- s.setgid(int Gid) --> None
- s.setperm(int Perm) --> None
- s.setuid(int Uid) --> None
- s.setundo(0|1) --> None
- s.setval(int Value) --> None

*/ 

/* Uncomment the following line if <sys/sem.h> defines "union semun" */

/* #define HAVE_UNION_SEMUN */

/* ------------------------------------------------------------------------- */
#include "Python.h"
#include "structmember.h"

#include <sys/types.h>
#include <sys/ipc.h>		/* for system's IPC_xxx definitions */
#include <sys/shm.h>		/* for shmget, shmat, shmdt, shmctl */
#include <sys/sem.h>		/* for semget, semctl, semop */

#if defined(__GLIBC__)
#define key __key
#endif /* __GLIBC__ */

/*
-- Exception type for errors detected by this module.
*/

static PyObject *PyShm_Error;

/*
-- Convenience function to raise an error according to errno.
*/

static PyObject *
PyShm_Err()
{
    return PyErr_SetFromErrno(PyShm_Error);
}

/*
-- The object holding a shared memory segment
*/

typedef struct {
    PyObject_HEAD
    int shmid;			/* shared memory id	*/
    int mode;			/* attachment mode	*/
    void *addr;			/* shmseg start address	*/
    struct shmid_ds ds;		/* data structure	*/
} PyShmMemoryObject;

staticforward PyTypeObject	PyShmMemory_Type;

#define PyShmObj		PyShmMemoryObject
#define PyShmMemory_Check(op)	((op)->ob_type == &PyShmMemory_Type)

/*
-- The object holding a semaphore
*/

typedef struct {
    PyObject_HEAD
    int semid;			/* semaphore id		*/
    short opflag;		/* IPC_NOWAIT, SEM_UNDO	*/
    struct semid_ds ds;		/* data structure	*/
} PyShmSemaphoreObject;

#ifndef HAVE_UNION_SEMUN
union semun {
    int val;                    /* used for SETVAL only */
    struct semid_ds *buf;       /* for IPC_STAT and IPC_SET */
    unsigned short *array;      /* used for GETALL and SETALL */
};
#endif

typedef union semun semctl_arg;

staticforward PyTypeObject	PyShmSemaphore_Type;

#define PyShmSemObj		PyShmSemaphoreObject
#define PyShmSemaphore_Check(op) ((op)->ob_type == &PyShmSemaphore_Type)

/*
-- Internal dictionaries for Python memory and semaphore objects
*/

static PyObject *shm_dict = NULL;
static PyObject *sem_dict = NULL;

/************************************************************/
/*                       Memory Objects                     */
/************************************************************/
  
/* This is to check the validity of a Python memory object
   (and to refresh its data status structure). Notably, we
   have to check that the real memory segment it points to
   is still in memory and hasn't changed (test its id and
   size). It could be that the segment has been removed and
   created again by someone else with the same key. This is
   fine as far as the segment (1) has the same id and size,
   and (2) is accessible via shmctl. If you have a better
   test, you're welcome :-) */
   
static int
check_memory_identity(o)
    PyShmObj *o;
{
    int new_shmid;
    int old_shmid = o->shmid;
    int old_size = o->ds.shm_segsz;
    key_t old_key = o->ds.shm_perm.key;

    /*
    -- 1. Try to get the segment identified by the old key (if not IPC_PRIVATE)
    -- 2. On failure or on mismatch of the new and the old id -> fail.
    -- 3. Try to refresh the object's status using the new id.
    -- 4. On failure (the segment cannot be accessed) -> fail.
    -- 5. Finaly, compare the old size and the one we got via the new id.
    */
    if (old_key != IPC_PRIVATE) {
	new_shmid = shmget(old_key, 0, 0);
	if (new_shmid != old_shmid)
	    return 0;
    }
    else
	new_shmid = old_shmid;
    if ((shmctl(new_shmid, IPC_STAT, &(o->ds)) != -1) &&
        (old_size == o->ds.shm_segsz) &&
	(old_key == o->ds.shm_perm.key))
        return 1;
    return 0;
}

/* Convenience macro for updating the shared memory data status structure */

#define refresh_memory_status(o)					\
    if (!check_memory_identity(o)) {					\
	PyErr_SetString(PyShm_Error,					\
			"can't access shared memory segment");		\
	return NULL;							\
    }

/*
-- attach([,address=0 [,how=0]])
*/

/* Attach the shared memory segment to the process address space */

static PyObject *
PyShmMemory_attach(self, args)
    PyShmObj *self;
    PyObject *args;
{
    unsigned long address = 0;
    int mode = 0;    
    void *addr, *old_addr;

    if (!PyArg_ParseTuple(args, "|li", &address, &mode))
	return NULL;
    refresh_memory_status(self);
    /* return if already attached with the same mode to the same address */
    if ((self->addr != NULL) &&
	(self->mode == mode) &&
	((address == 0) || (self->addr == (void *)address))) {
	Py_INCREF(Py_None);
	return Py_None;
    }
    /* perform the attach */
    addr = (void *)shmat(self->shmid, (void *)address, mode);
    if (addr  == (void *)-1)
	return PyShm_Err();
    old_addr = self->addr;
    self->addr = addr;
    self->mode = mode;
    /* XXX - multiple attachments of the same shared memory segment
             to different locations of the process address space is
	     not supported. */
    shmdt(old_addr);
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- detach()
*/

/* Detach the memory object from the process address space */

static PyObject *
PyShmMemory_detach(self, args)
    PyShmObj *self;
    PyObject *args;
{
    if (!PyArg_NoArgs(args))
	return NULL;
    if (self->addr != NULL) {
	refresh_memory_status(self);
	if (shmdt(self->addr) != 0)
	    return PyShm_Err();
	self->addr = NULL;		/* mark as detached */
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- read(int Nbytes [,int Offset=0]) --> string
*/

/* Return a string of n bytes peeked from the shared memory segment */

static PyObject *
PyShmMemory_read(self, args)
    PyShmObj *self;
    PyObject *args;
{
    unsigned long n, offset = 0;
    char buf[128];
    char *addr;

    if (!PyArg_ParseTuple(args, "l|l", &n, &offset))
	return NULL;
    refresh_memory_status(self);
    if (self->addr == NULL) {
	PyErr_SetString(PyShm_Error, "R/W operation on detached memory");
  	return NULL;
    }
    if ((unsigned long)self->ds.shm_segsz < (n + offset)) {
	sprintf(buf, "read() argument%s exceed%s upper memory limit",
		offset ? "s" : "", offset ? "" : "s");
	PyErr_SetString(PyShm_Error, buf);
	return NULL;
    }
    addr = (char *)((unsigned long)self->addr + offset);
    return PyString_FromStringAndSize(addr, n);
}

/*
-- setgid(int Gid)
*/

static PyObject *
PyShmMemory_setgid(self, args)
    PyShmObj *self;
    PyObject *args;
{
    long newgid, oldgid;

    if (!PyArg_ParseTuple(args, "l", &newgid))
	return NULL;
    refresh_memory_status(self);
    oldgid = (long)self->ds.shm_perm.gid;
    self->ds.shm_perm.gid = (gid_t)newgid;
    if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
	self->ds.shm_perm.gid = (gid_t)oldgid;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setperm(int Perm)
*/

static PyObject *
PyShmMemory_setperm(self, args)
    PyShmObj *self;
    PyObject *args;
{
    long newmode, oldmode;

    if (!PyArg_ParseTuple(args, "l", &newmode))
	return NULL;
    refresh_memory_status(self);
    newmode &= 0777;	/* permission bits only */
    oldmode = (mode_t)self->ds.shm_perm.mode;
    self->ds.shm_perm.mode ^= 0777;
    self->ds.shm_perm.mode |= (mode_t)newmode;
    if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
	self->ds.shm_perm.mode = (mode_t)oldmode;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setuid(int Uid)
*/

static PyObject *
PyShmMemory_setuid(self, args)
    PyShmObj *self;
    PyObject *args;
{
    long newuid, olduid;

    if (!PyArg_ParseTuple(args, "l", &newuid))
	return NULL;
    refresh_memory_status(self);
    olduid = (long)self->ds.shm_perm.uid;
    self->ds.shm_perm.gid = (uid_t)newuid;
    if (shmctl(self->shmid, IPC_SET, &(self->ds)) == -1) {
	self->ds.shm_perm.uid = (uid_t)olduid;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- write(string Data [, int Offset=0])
*/

/* Write a string to the shared memory segment. */

static PyObject *
PyShmMemory_write(self, args)
    PyShmObj *self;
    PyObject *args;
{
    char *data;
    unsigned long n, offset = 0;
    char buf[128];
    char *addr;

    if (!PyArg_ParseTuple(args, "s#|l", &data, &n, &offset))
	return NULL;
    refresh_memory_status(self);
    if (self->addr == NULL) {
	PyErr_SetString(PyShm_Error, "R/W operation on detached memory");
  	return NULL;
    }
    if (self->mode & SHM_RDONLY) {
	PyErr_SetString(PyShm_Error,
			"can't write on read-only attached memory");
	return NULL;
    }
    if ((unsigned long)self->ds.shm_segsz < (n + offset)) {
	sprintf(buf, "write() argument%s exceed%s upper memory limit",
		offset ? "s" : "", offset ? "" : "s");
	PyErr_SetString(PyShm_Error, buf);
	return NULL;	
    }
    addr = (void *)((unsigned long)self->addr + offset);
    memcpy(addr, data, n);
    Py_INCREF(Py_None);
    return Py_None;    
}

/* List of methods for shared memory objects */

static PyMethodDef memory_methods[] = {
    {"attach",	(PyCFunction)PyShmMemory_attach,	1,
     "attach([int Addr=0 [,int How=0]]) --> None | except shm.error"},
    {"detach",	(PyCFunction)PyShmMemory_detach,	0,
     "detach() --> None | except shm.error"},
    {"read",	(PyCFunction)PyShmMemory_read,		1,
     "read(int Nbytes [,int Offset=0]) --> string | except shm.error"},
    {"setgid",	(PyCFunction)PyShmMemory_setgid,	1,
     "setgid(int Gid) --> None | except shm.error"},
    {"setperm",	(PyCFunction)PyShmMemory_setperm,	1,
     "setperm(int Perm) --> None | except shm.error"},
    {"setuid",	(PyCFunction)PyShmMemory_setuid,	1,
     "setuid(int Uid) --> None | except shm.error"},
    {"write",	(PyCFunction)PyShmMemory_write,		1,
     "write(string Data [,int Offset=0]) --> None | except shm.error"},
    {NULL,	NULL}		/* sentinel */
};

#define OFF(x)	offsetof(PyShmMemoryObject, x)
#define OFF1(x)	OFF(ds) + offsetof(struct shmid_ds, x)
#define OFF2(x)	OFF1(shm_perm) + offsetof(struct ipc_perm, x)

/* List of members for shared memory objects */

/* Note: member types are set in the initshm function.
   Members which need separate processing are:
   - addr --> it is not part of the shmid_ds structure
   - attached --> function depending on addr
   - nattch  --> system dependent declaration in shmid_ds (unknown type)
   - perm --> return permission (lower 9) bits only of ds.shm_perm.mode
*/

static struct memberlist memory_memberlist[] = {
    {"cgid",	T_INT,	OFF2(cgid),		RO},	/* 0  (gid_t)  */
    {"cpid",	T_INT,	OFF1(shm_cpid),		RO},	/* 1  (pid_t)  */
    {"cuid",	T_INT,	OFF2(cuid),		RO},	/* 2  (uid_t)  */
    {"key",	T_INT,	OFF2(key),		RO},	/* 3  (key_t)  */
    {"lpid",	T_INT,	OFF1(shm_lpid),		RO},	/* 4  (pid_t)  */
    {"shmid",	T_INT,	OFF(shmid),		RO},	/* 5  (int)    */
    {"size",	T_INT,	OFF1(shm_segsz),	RO},	/* 6  (int)    */
    {"gid",	T_INT,	OFF2(gid),		RO},	/* 7  (gid_t)  */
    {"uid",	T_INT,	OFF2(uid),		RO},	/* 8  (uid_t)  */
    /* The following members are implemented without this table */
    {"addr",	T_INT,	0,			RO},	/* 9  (void *) */
    {"attached",T_INT,	0,			RO},	/* 10  (int)    */
    {"nattch",	T_INT,	0,			RO},	/* 11 sys.dep. */
    {"perm",	T_INT,	0,			RO},	/* 12 (mode_t) */
    {NULL}			/* sentinel */
};

#undef OFF
#undef OFF1
#undef OFF2

static void
PyShmMemory_dealloc(self)
    PyShmObj *self;
{
    /* del shm_dict[key], ignore if it fails */
    if (PyDict_DelItem(shm_dict, PyInt_FromLong(self->shmid)) == -1)
	PyErr_Clear();
    /* all references in the current process to the shared
       memory segment are lost, so if attached, detach it.
       XXX: This is not true when Python is embedded.

    if (self->addr != NULL) {
	shmdt(self->addr);
    }
    */
    PyMem_DEL(self);
}

static PyObject *
PyShmMemory_getattr(self, name)
    PyShmObj *self;
    char *name;
{
    PyObject *res;

    res = Py_FindMethod(memory_methods, (PyObject *)self, name);
    if (res != NULL)
	return res;
    PyErr_Clear();
    refresh_memory_status(self);
    if (strcmp(name, "attached") == 0)
	return PyInt_FromLong((self->addr == NULL) ? 0 : 1);
    if (strcmp(name, "addr") == 0) {
	if (self->addr != NULL)
	    return PyInt_FromLong((unsigned long)self->addr);
	else {
	    Py_INCREF(Py_None);
	    return Py_None;
	}
    }
    if (strcmp(name, "nattch") == 0)
	return PyInt_FromLong(self->ds.shm_nattch);
    if (strcmp(name, "perm") == 0)
	return PyInt_FromLong(self->ds.shm_perm.mode & 0777);
    return PyMember_Get((char *)self, memory_memberlist, name);
}

static PyObject *
PyShmMemory_repr(self, name)
    PyShmObj *self;
    char *name;
{
    char buf[100];
    char buf2[20];

    refresh_memory_status(self);
    if (self->addr == NULL)
	sprintf(buf2, "None");
    else
	sprintf(buf2, "0x%lx", self->addr);
    sprintf(buf, "<%s shared memory object, id=%d, size=%u, addr=%s>",
	    (self->addr == NULL) ? "detached" : (self->mode & SHM_RDONLY) ?
	    "attached RO" : "attached R/W",
	    self->shmid,
	    self->ds.shm_segsz,
	    buf2);
    return PyString_FromString(buf);
}

/* Type object for shared memory objects */

static PyTypeObject PyShmMemory_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,					/*ob_size*/
    "shared memory",			/*tp_name*/
    sizeof(PyShmObj),			/*tp_size*/
    0,					/*tp_itemsize*/
    /* methods */
    (destructor)PyShmMemory_dealloc,	/*tp_dealloc*/
    0,					/*tp_print*/
    (getattrfunc)PyShmMemory_getattr,	/*tp_getattr*/
    0,					/*tp_setattr*/
    0,					/*tp_compare*/
    (reprfunc)PyShmMemory_repr,		/*tp_repr*/
    0,					/*tp_as_number*/
    0,					/*tp_as_sequence*/
    0,					/*tp_as_mapping*/
};

/************************************************************/
/*                     Semaphore Objects                    */
/************************************************************/

/* This is to check the validity of a Python semaphore object */

static int
check_semaphore_identity(o)
    PyShmSemObj *o;
{
    int new_semid;
    int old_semid = o->semid;
    unsigned short old_nsems = o->ds.sem_nsems;
    key_t old_key = o->ds.sem_perm.key;
    semctl_arg arg;

    if (old_key != IPC_PRIVATE) {
	new_semid = semget(old_key, 0, 0);
	if (new_semid != old_semid)
	    return 0;
    }
    else
	new_semid = old_semid;
    arg.buf = &(o->ds);
    if ((semctl(new_semid, 0, IPC_STAT, arg) != -1) &&
        (old_nsems == o->ds.sem_nsems) &&
	(old_key == o->ds.sem_perm.key))
        return 1;
    return 0;
}

/* Convenience macro for updating the semaphore data status structure */

#define refresh_semaphore_status(o)					\
    if (!check_semaphore_identity(o)) {					\
	PyErr_SetString(PyShm_Error,					\
			"can't access semaphore");			\
	return NULL;							\
    }

/*
-- P()
*/

static PyObject *
PyShmSemaphore_P(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    struct sembuf op[1];
    int res;

    op[0].sem_num = 0;
    op[0].sem_op = -1;
    op[0].sem_flg = self->opflag;
    
    if (!PyArg_NoArgs(args))
	return NULL;
    refresh_semaphore_status(self);
    res = semop(self->semid, op, (size_t)1);
    if (res == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- V()
*/

static PyObject *
PyShmSemaphore_V(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    struct sembuf op[1];
    int res;

    op[0].sem_num = 0;
    op[0].sem_op = 1;
    op[0].sem_flg = self->opflag;
    
    if (!PyArg_NoArgs(args))
	return NULL;
    refresh_semaphore_status(self);
    res = semop(self->semid, op, (size_t)1);
    if (res == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- Z()
*/

static PyObject *
PyShmSemaphore_Z(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    struct sembuf op[1];
    int res;

    op[0].sem_num = 0;
    op[0].sem_op = 0;
    op[0].sem_flg = self->opflag;
    
    if (!PyArg_NoArgs(args))
	return NULL;
    refresh_semaphore_status(self);
    res = semop(self->semid, op, (size_t)1);
    if (res == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setblocking(0|1)
*/

static PyObject *
PyShmSemaphore_setblocking(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    int block;

    if (!PyArg_ParseTuple(args, "i", &block))
	return NULL;
    refresh_semaphore_status(self);
    if (block)
	self->opflag &= ~IPC_NOWAIT;
    else
	self->opflag |= IPC_NOWAIT;
    Py_INCREF(Py_None);
    return Py_None;   
}

/*
-- setgid(int Gid)
*/

static PyObject *
PyShmSemaphore_setgid(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    long newgid, oldgid;
    semctl_arg arg;

    if (!PyArg_ParseTuple(args, "l", &newgid))
	return NULL;
    refresh_semaphore_status(self);
    oldgid = (long)self->ds.sem_perm.gid;
    self->ds.sem_perm.gid = (gid_t)newgid;
    arg.buf = &(self->ds);
    if (semctl(self->semid, 0, IPC_SET, arg) == -1) {
	self->ds.sem_perm.gid = (gid_t)oldgid;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setperm(int Perm)
*/

static PyObject *
PyShmSemaphore_setperm(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    long newmode, oldmode;
    semctl_arg arg;

    if (!PyArg_ParseTuple(args, "l", &newmode))
	return NULL;
    refresh_semaphore_status(self);
    newmode &= 0777;	/* permission bits only */
    oldmode = (mode_t)self->ds.sem_perm.mode;
    self->ds.sem_perm.mode ^= 0777;
    self->ds.sem_perm.mode |= (mode_t)newmode;
    arg.buf = &(self->ds);
    if (semctl(self->semid, 0, IPC_SET, arg) == -1) {
	self->ds.sem_perm.mode = (mode_t)oldmode;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setuid(int Uid)
*/

static PyObject *
PyShmSemaphore_setuid(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    long newuid, olduid;
    semctl_arg arg;
    
    if (!PyArg_ParseTuple(args, "l", &newuid))
	return NULL;
    refresh_semaphore_status(self);
    olduid = (long)self->ds.sem_perm.uid;
    self->ds.sem_perm.gid = (uid_t)newuid;
    arg.buf = &(self->ds);
    if (semctl(self->semid, 0, IPC_SET, arg) == -1) {
	self->ds.sem_perm.uid = (uid_t)olduid;
	return PyShm_Err();
    }
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- setundo(0|1)
*/

static PyObject *
PyShmSemaphore_setundo(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    int undo;

    if (!PyArg_ParseTuple(args, "i", &undo))
	return NULL;
    refresh_semaphore_status(self);
    if (undo)
	self->opflag |= SEM_UNDO;
    else
	self->opflag &= ~SEM_UNDO;
    Py_INCREF(Py_None);
    return Py_None;   
}

/*
-- setval(int Value)
*/

static PyObject *
PyShmSemaphore_setval(self, args)
    PyShmSemObj *self;
    PyObject *args;
{
    int value;
    semctl_arg arg;

    if (!PyArg_ParseTuple(args, "i", &value))
	return NULL;
    refresh_semaphore_status(self);
    arg.val = value;
    if (semctl(self->semid, 0, SETVAL, arg) == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;   
}

/* List of methods for semaphore objects */

static PyMethodDef semaphore_methods[] = {
    {"P",		(PyCFunction)PyShmSemaphore_P,			0,
     "P() --> None | except shm.error"},
    {"V",		(PyCFunction)PyShmSemaphore_V,			0,
     "V() --> None | except shm.error"},
    {"Z",		(PyCFunction)PyShmSemaphore_Z,			0,
     "Z() --> None | except shm.error"},
    {"setblocking",	(PyCFunction)PyShmSemaphore_setblocking,	1,
     "setblocking(0|1) --> None"},
    {"setgid",		(PyCFunction)PyShmSemaphore_setgid,		1,
     "setgid(int Gid) --> None | except shm.error"},
    {"setperm",		(PyCFunction)PyShmSemaphore_setperm,		1,
     "setperm(int Perm) --> None | except shm.error"},
    {"setuid",		(PyCFunction)PyShmSemaphore_setuid,		1,
     "setuid(int Uid) --> None | except shm.error"},
    {"setundo",		(PyCFunction)PyShmSemaphore_setundo,		1,
     "setundo(0|1) --> None"},
    {"setval",		(PyCFunction)PyShmSemaphore_setval,		1,
     "setval(int Value) --> None | except shm.error"},
    {NULL,	NULL}		/* sentinel */
};

#define OFF(x)	offsetof(PyShmSemaphoreObject, x)
#define OFF1(x)	OFF(ds) + offsetof(struct semid_ds, x)
#define OFF2(x)	OFF1(sem_perm) + offsetof(struct ipc_perm, x)

/* List of members for semaphore objects */

/* Note: member types are set in the initshm function.
   Members which need separate processing are:
   - val, lpid, ncnt, zcnt --> in kernel memory, not accessible from a process
   - perm --> return permission (lower 9) bits only of ds.sem_perm.mode
*/

static struct memberlist semaphore_memberlist[] = {
    {"cgid",	T_INT,	OFF2(cgid),		RO},	/* 0  (gid_t)  */
    {"cuid",	T_INT,	OFF2(cuid),		RO},	/* 1  (uid_t)  */
    {"key",	T_INT,	OFF2(key),		RO},	/* 2  (key_t)  */
    {"semid",	T_INT,	OFF(semid),		RO},	/* 3  (int)    */
    {"gid",	T_INT,	OFF2(gid),		RO},	/* 4  (gid_t)  */
    {"uid",	T_INT,	OFF2(uid),		RO},	/* 5  (uid_t)  */
    /* The following members are implemented without this table */
    {"lpid",	T_INT,	0,			RO},	/* 6  (ushort) */
    {"ncnt",	T_INT,	0,			RO},	/* 7  (ushort) */
    {"perm",	T_INT,	0,			RO},	/* 8  (mode_t) */
    {"val",	T_INT,	0,			RO},	/* 9  (ushort) */
    {"zcnt",	T_INT,	0,			RO},	/* 10 (ushort) */
    {NULL}			/* sentinel */
};

#undef OFF
#undef OFF1
#undef OFF2

static void
PyShmSemaphore_dealloc(self)
    PyShmSemObj *self;
{
    /* del sem_dict[key], ignore if it fails */
    if (PyDict_DelItem(sem_dict, PyInt_FromLong(self->semid)) == -1)
	PyErr_Clear();
    PyMem_DEL(self);
}

static PyObject *
PyShmSemaphore_getattr(self, name)
    PyShmSemObj *self;
    char *name;
{
    PyObject *res;

    res = Py_FindMethod(semaphore_methods, (PyObject *)self, name);
    if (res != NULL)
	return res;
    PyErr_Clear();
    refresh_semaphore_status(self);
    if (strcmp(name, "val") == 0)
	return PyInt_FromLong(semctl(self->semid, 0, GETVAL, 0));
    if (strcmp(name, "lpid") == 0)
	return PyInt_FromLong(semctl(self->semid, 0, GETPID, 0));
    if (strcmp(name, "ncnt") == 0)
	return PyInt_FromLong(semctl(self->semid, 0, GETNCNT, 0));
    if (strcmp(name, "zcnt") == 0)
	return PyInt_FromLong(semctl(self->semid, 0, GETZCNT, 0));
    if (strcmp(name, "perm") == 0)
	return PyInt_FromLong(self->ds.sem_perm.mode & 0777);
    return PyMember_Get((char *)self, semaphore_memberlist, name);
}

static PyObject *
PyShmSemaphore_repr(self, name)
    PyShmSemObj *self;
    char *name;
{
    char buf[100];

    refresh_semaphore_status(self);
    sprintf(buf, "<semaphore object, id=%d, val=%d, ncnt=%d, zcnt=%d>",
	    self->semid,
	    semctl(self->semid, 0, GETVAL, 0),
	    semctl(self->semid, 0, GETNCNT, 0),
	    semctl(self->semid, 0, GETZCNT, 0));
    return PyString_FromString(buf);
}

/* Type object for semaphore objects */

static PyTypeObject PyShmSemaphore_Type = {
    PyObject_HEAD_INIT(&PyType_Type)
    0,					/*ob_size*/
    "semaphore",			/*tp_name*/
    sizeof(PyShmSemObj),		/*tp_size*/
    0,					/*tp_itemsize*/
    /* methods */
    (destructor)PyShmSemaphore_dealloc,	/*tp_dealloc*/
    0,					/*tp_print*/
    (getattrfunc)PyShmSemaphore_getattr,/*tp_getattr*/
    0,					/*tp_setattr*/
    0,					/*tp_compare*/
    (reprfunc)PyShmSemaphore_repr,	/*tp_repr*/
    0,					/*tp_as_number*/
    0,					/*tp_as_sequence*/
    0,					/*tp_as_mapping*/
};

/************************************************************/
/*                      Module Interface                    */
/************************************************************/

/*
-- ftok(string Path, int ProjId) -> int
*/

/* Compute a key by using the system's ftok algorithm */

static PyObject *
PyShm_ftok(self, args)
    PyObject *self;
    PyObject *args;
{
    char *path;
    char id;
    key_t key;
    
    if (!PyArg_ParseTuple(args, "sb", &path, &id))
	return NULL;
    key = ftok(path, id);
    return PyInt_FromLong((long)key);
}

/*
-- getshmid(int Key) --> int | except KeyError
*/

/* Return a shared memory segment id from a given key */

static PyObject *
PyShm_getshmid(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int shmid;

    if (!PyArg_ParseTuple(args, "l", &key))
	return NULL;
    shmid = shmget((key_t)key, 0, 0);
    if (shmid == -1) {
	PyErr_SetObject(PyExc_KeyError, PyInt_FromLong(key));
	return NULL;
    }
    return PyInt_FromLong(shmid);
}

/*
-- memory_haskey(int Key) --> int
*/

/* Check whether there is a shared memory segment with the given key */

static PyObject *
PyShm_memory_haskey(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int shmid;
    
    if (!PyArg_ParseTuple(args, "l", &key))
	return NULL;
    shmid = shmget((key_t)key, 0, 0);
    return PyInt_FromLong((shmid == -1) ? 0 : 1);
}

/*
-- memory(int Shmid) --> object | except shm.error
*/

/* Get an existing shared memory segment and return it as a python object. */

static PyObject *
PyShm_memory(self, args)
    PyObject *self;
    PyObject *args;
{
    int shmid;
    PyShmObj *o;
    PyObject *keyo;

    if (!PyArg_ParseTuple(args, "i", &shmid))
	return NULL;
    keyo = PyInt_FromLong(shmid);
    /* get the object from the dictionary */
    if (PyMapping_HasKey(shm_dict, keyo)) {
	o = (PyShmObj *)PyDict_GetItem(shm_dict, keyo);
	Py_INCREF(o);
    }
    else {
	/* not found, create it */
	if ((o = PyObject_NEW(PyShmObj, &PyShmMemory_Type)) == NULL)
	    return NULL;
	o->shmid = shmid;
	o->addr = NULL;
	o->mode = 0;
	/* shm_dict[shmid] = o */
	if (PyDict_SetItem(shm_dict, keyo, (PyObject *)o) == -1) {
	    Py_DECREF(o);
	    PyErr_SetString(PyShm_Error,
			    "can't initialize shared memory object");
	    return NULL;
	}
	Py_DECREF(o);	/* the owned reference in shm_dict doesn't count! */
    }
    /* set up the status data */
    if (shmctl(o->shmid, IPC_STAT, &(o->ds)) == -1) {
	Py_DECREF(o);
	PyErr_SetString(PyShm_Error,
			"can't access shared memory segment");
	return NULL;
    }
    return (PyObject *)o;
}

/*
-- create_memory(int Key, int Size [,int Perm=0666]) --> object
*/

/* Create a new shared memory segment. */

static PyObject *
PyShm_create_memory(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int size, shmid;
    int perm = 0666;	/* Default permission is -rw-rw-rw- */

    if (!PyArg_ParseTuple(args, "li|i", &key, &size, &perm))
	return NULL;
    shmid = shmget((key_t)key, size, perm | IPC_CREAT | IPC_EXCL);
    if (shmid == -1)
	return PyShm_Err();
    /* return PyInt_FromLong(shmid); */
    return PyShm_memory(self, Py_BuildValue("(i)", shmid));
}

/*
-- remove_memory(int Shmid) --> None | except shm.error
*/

/* Remove an existing shared memory segment. */

static PyObject *
PyShm_remove_memory(self, args)
    PyObject *self;
    PyObject *args;
{
    int shmid, res;

    if (!PyArg_ParseTuple(args, "i", &shmid))
	return NULL;
    res = shmctl(shmid, IPC_RMID, 0);	/* remove it */
    if (res == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;
}

/*
-- getsemid(int Key) --> int | except KeyError
*/

/* Return a semaphore id from a given key */

static PyObject *
PyShm_getsemid(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int semid;

    if (!PyArg_ParseTuple(args, "l", &key))
	return NULL;
    semid = semget((key_t)key, 0, 0);
    if (semid == -1) {
	PyErr_SetObject(PyExc_KeyError, PyInt_FromLong(key));
	return NULL;
    }
    return PyInt_FromLong(semid);
}

/*
-- semaphore_haskey(int Key) --> int
*/

/* Check whether there is a semaphore with the given key */

static PyObject *
PyShm_semaphore_haskey(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int semid;
    
    if (!PyArg_ParseTuple(args, "l", &key))
	return NULL;
    semid = semget((key_t)key, 0, 0);
    return PyInt_FromLong((semid == -1) ? 0 : 1);
}

/*
-- semaphore(int Semid) --> object
*/

/* Get an existing semaphore and return it as a python object. */

static PyObject *
PyShm_semaphore(self, args)
    PyObject *self;
    PyObject *args;
{
    int semid;
    PyShmSemObj *o;
    PyObject *keyo;
    semctl_arg arg;

    if (!PyArg_ParseTuple(args, "i", &semid))
	return NULL;
    keyo = PyInt_FromLong(semid);
    /* get the object from the dictionary */
    if (PyMapping_HasKey(sem_dict, keyo)) {
	o = (PyShmSemObj *)PyDict_GetItem(sem_dict, keyo);
	Py_INCREF(o);
    }
    else {
	/* not found, create it */
	if ((o = PyObject_NEW(PyShmSemObj, &PyShmSemaphore_Type)) == NULL)
	    return NULL;
	o->semid = semid;
	o->opflag = 0;
	/* sem_dict[semid] = o */
	if (PyDict_SetItem(sem_dict, keyo, (PyObject *)o) == -1) {
	    Py_DECREF(o);
	    PyErr_SetString(PyShm_Error,
			    "can't initialize semaphore object");
	    return NULL;
	}
	Py_DECREF(o);	/* the owned reference in sem_dict doesn't count! */
    }
    /* set up the status data */
    arg.buf = &(o->ds);
    if (semctl(o->semid, 0, IPC_STAT, arg) == -1) {
	Py_DECREF(o);
	PyErr_SetString(PyShm_Error,
			"can't access semaphore");
	return NULL;
    }
    return (PyObject *)o;
}

/*
-- create_semaphore(int Key, [,int Value=1 [,int Perm=0666]]) --> object
*/

/* Create a new semaphore. */

static PyObject *
PyShm_create_semaphore(self, args)
    PyObject *self;
    PyObject *args;
{
    long key;
    int semid;
    int value = 1;
    int perm = 0666;	/* Default permission is -rw-rw-rw- */
    semctl_arg arg;

    if (!PyArg_ParseTuple(args, "l|ii", &key, &value, &perm))
	return NULL;
    semid = semget((key_t)key, 1, perm | IPC_CREAT | IPC_EXCL);
    arg.val = value;
    if (!((semid != -1) &&
	  (semctl(semid, 0, SETVAL, arg) != -1)))
	return PyShm_Err();
    return PyShm_semaphore(self, Py_BuildValue("(i)", semid));
}

/*
-- remove_semaphore(int Semid) --> None | except shm.error
*/

/* Remove an existing semaphore. */

static PyObject *
PyShm_remove_semaphore(self, args)
    PyObject *self;
    PyObject *args;
{
    int semid, res;

    if (!PyArg_ParseTuple(args, "i", &semid))
	return NULL;
    res = semctl(semid, 0, IPC_RMID, 0);	/* remove it */
    if (res == -1)
	return PyShm_Err();
    Py_INCREF(Py_None);
    return Py_None;
}

/* List of functions exported by this module. */

static PyMethodDef PyShm_methods[] = {
    {"create_memory",		PyShm_create_memory,	1,
     "create_memory(int Key, int Size [,int Perm=0666]) --> object | except shm.error"},
    {"create_semaphore",	PyShm_create_semaphore,	1,
     "create_semaphore(int Key [,int Value=1 [,int Perm=0666]]) --> object | except shm.error"},
    {"ftok",			PyShm_ftok,		1,
     "ftok(string Path, int ProjId) --> int | except shm.error"},
    {"getsemid",		PyShm_getsemid,		1,
     "getsemid(int Key) --> int | except KeyError"},
    {"getshmid",		PyShm_getshmid,		1,
     "getshmid(int Key) --> int | except KeyError"},
    {"memory_haskey",		PyShm_memory_haskey,	1,
     "memory_haskey(int Key) --> int"},
    {"memory",			PyShm_memory,		1,
     "memory(int Shmid) --> object | except shm.error"},
    {"semaphore",		PyShm_semaphore,	1,
     "semaphore(int Semid) --> object | except shm.error"},
    {"semaphore_haskey",	PyShm_semaphore_haskey,	1,
     "semaphore_haskey(int Key) --> int"},
    {"remove_memory",		PyShm_remove_memory,	1,
     "remove_memory(int Shmid) --> None | except shm.error"},
    {"remove_semaphore",	PyShm_remove_semaphore,	1,
     "remove_semaphore(int Semid) --> None | except shm.error"},
    {NULL,			NULL}		/* Sentinel */
};


/* Initialize this module */

/* This is for inserting constants in the module's dictionary */

static void
insint(d, name, value)
    PyObject *d;
    char *name;
    int value;
{
	PyObject *v = PyInt_FromLong((long) value);
	if (!v || PyDict_SetItemString(d, name, v))
		Py_FatalError("can't initialize shm module");

	Py_DECREF(v);
}

/* This is to set up the type of shared memory/semaphore object members */

static void
set_member_type(sxm_memberlist, index, typesize)
    struct memberlist *sxm_memberlist;
    int index;		/* index in memberlist */
    int typesize;	/* sizeof(member_type) */
{
    int t;

    if (typesize == sizeof(char))
	t = T_UBYTE;
    else if (typesize == sizeof(short))
	t = T_USHORT;
    else if (typesize == sizeof(int))
	t = T_UINT;
    else if (typesize == sizeof(long))
	t = T_ULONG;
    else
	Py_FatalError("can't initialize shm module");
    sxm_memberlist[index].type = t;
};
  
void
initshm()
{
    PyObject *m, *d;

    m = Py_InitModule("shm", PyShm_methods);
    d = PyModule_GetDict(m);
    PyShm_Error = PyString_FromString("shm.error");
    if (PyShm_Error == NULL ||
	PyDict_SetItemString(d, "error", PyShm_Error) != 0)
	    Py_FatalError("can't define shm.error");
    if (PyDict_SetItemString(d, "__doc__", PyString_FromString
			     ("Interface to System V shared memory IPC")) != 0)
	Py_FatalError("can't define shm.__doc__");
    if ((shm_dict = PyDict_New()) == NULL ||
	(sem_dict = PyDict_New()) == NULL)
	Py_FatalError("can't initialize shm module");

    /* initialize the machine dependent types in memory_memberlist */
    set_member_type(memory_memberlist, 0, sizeof(gid_t));	/* cgid   */
    set_member_type(memory_memberlist, 1, sizeof(pid_t));	/* cpid   */
    set_member_type(memory_memberlist, 2, sizeof(uid_t));	/* cuid   */
    set_member_type(memory_memberlist, 3, sizeof(key_t));	/* key    */
    set_member_type(memory_memberlist, 4, sizeof(pid_t));	/* lpid   */
    set_member_type(memory_memberlist, 5, sizeof(int));		/* shmid  */
    set_member_type(memory_memberlist, 6, sizeof(int));		/* size   */
    set_member_type(memory_memberlist, 7, sizeof(gid_t));	/* gid    */
    set_member_type(memory_memberlist, 8, sizeof(uid_t));	/* uid    */

    /* initialize the machine dependent types in semaphore_memberlist */
    set_member_type(semaphore_memberlist, 0, sizeof(gid_t));	/* cgid   */
    set_member_type(semaphore_memberlist, 1, sizeof(uid_t));	/* cuid   */
    set_member_type(semaphore_memberlist, 2, sizeof(key_t));	/* key    */
    set_member_type(semaphore_memberlist, 3, sizeof(int));	/* semid  */
    set_member_type(semaphore_memberlist, 4, sizeof(gid_t));	/* gid    */
    set_member_type(semaphore_memberlist, 5, sizeof(uid_t));	/* uid    */

    /* relevant constants for this module; the others are useless here */
    insint(d, "IPC_PRIVATE", IPC_PRIVATE);
    insint(d, "SHM_RDONLY", SHM_RDONLY);
    insint(d, "SHM_RND", SHM_RND);
#ifdef SHMLBA
    insint(d, "SHMLBA", SHMLBA);
#endif
#ifdef SEM_A
    insint(d, "SEM_A", SEM_A);
#endif
#ifdef SEM_R
    insint(d, "SEM_R", SEM_R);
#endif
#ifdef SHM_R
    insint(d, "SHM_R", SHM_R);
#endif
#ifdef SHM_W
    insint(d, "SHM_W", SHM_W);
#endif
}


Index: .cvsignore
===================================================================
RCS file: /cvs/free/rpms/compat-python24/devel/.cvsignore,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- .cvsignore	22 Jul 2008 16:48:38 -0000	1.1
+++ .cvsignore	9 Aug 2008 20:39:35 -0000	1.2
@@ -0,0 +1,2 @@
+JapaneseCodecs-1.4.11.tar.gz
+Python-2.4.5.tar.bz2


Index: sources
===================================================================
RCS file: /cvs/free/rpms/compat-python24/devel/sources,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- sources	22 Jul 2008 16:48:38 -0000	1.1
+++ sources	9 Aug 2008 20:39:35 -0000	1.2
@@ -0,0 +1,2 @@
+e4f2ed866f4ce978fb54bb962eab4fdf  JapaneseCodecs-1.4.11.tar.gz
+aade3958cb097cc1c69ae0074297d359  Python-2.4.5.tar.bz2



More information about the rpmfusion-commits mailing list