- Changes donated by Elemental Security to make it work on AIX 5.3
  with IBM's 64-bit compiler (SF patch #1284289).  This also closes SF
  bug #105470: test_pwd fails on 64bit system (Opteron).
diff --git a/Include/import.h b/Include/import.h
index 9f1c2be..572cb8a 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -24,6 +24,7 @@
 PyAPI_FUNC(struct filedescr *) _PyImport_FindModule(
 	const char *, PyObject *, char *, size_t, FILE **, PyObject **);
 PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *);
+PyAPI_FUNC(void) _PyImport_ReInitLock(void);
 
 PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
 PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *);
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index e1c878c..71dc291 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -1070,6 +1070,34 @@
         test_winreg
         test_winsound
         """,
+    'aix5':
+        """
+        test_aepack
+        test_al
+        test_applesingle
+        test_bsddb
+        test_bsddb185
+        test_bsddb3
+        test_bz2
+        test_cd
+        test_cl
+        test_dl
+        test_gdbm
+        test_gl
+        test_gzip
+        test_imgfile
+        test_linuxaudiodev
+        test_macfs
+        test_macostools
+        test_nis
+        test_ossaudiodev
+        test_sunaudiodev
+        test_tcl
+        test_winreg
+        test_winsound
+        test_zipimport
+        test_zlib
+        """,
 }
 _expectations['freebsd5'] = _expectations['freebsd4']
 _expectations['freebsd6'] = _expectations['freebsd4']
diff --git a/Lib/test/test_ioctl.py b/Lib/test/test_ioctl.py
index 959d16e..2b127e2 100644
--- a/Lib/test/test_ioctl.py
+++ b/Lib/test/test_ioctl.py
@@ -1,5 +1,5 @@
 import unittest
-from test_support import TestSkipped, run_unittest
+from test.test_support import TestSkipped, run_unittest
 import os, struct
 try:
     import fcntl, termios
@@ -16,19 +16,23 @@
 
 class IoctlTests(unittest.TestCase):
     def test_ioctl(self):
-        pgrp = os.getpgrp()
+        # If this process has been put into the background, TIOCGPGRP returns
+        # the session ID instead of the process group id.
+        ids = (os.getpgrp(), os.getsid(0))
         tty = open("/dev/tty", "r")
         r = fcntl.ioctl(tty, termios.TIOCGPGRP, "    ")
-        self.assertEquals(pgrp, struct.unpack("i", r)[0])
+        rpgrp = struct.unpack("i", r)[0]
+        self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
 
     def test_ioctl_mutate(self):
         import array
         buf = array.array('i', [0])
-        pgrp = os.getpgrp()
+        ids = (os.getpgrp(), os.getsid(0))
         tty = open("/dev/tty", "r")
         r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
+        rpgrp = buf[0]
         self.assertEquals(r, 0)
-        self.assertEquals(pgrp, buf[0])
+        self.assert_(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
 
 def test_main():
     run_unittest(IoctlTests)
diff --git a/Misc/NEWS b/Misc/NEWS
index 33d6732..e52d251 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,10 @@
 Core and builtins
 -----------------
 
+- Changes donated by Elemental Security to make it work on AIX 5.3
+  with IBM's 64-bit compiler (SF patch #1284289).  This also closes SF
+  bug #105470: test_pwd fails on 64bit system (Opteron).
+
 - Changes donated by Elemental Security to make it work on HP-UX 11 on
   Itanium2 with HP's 64-bit compiler (SF patch #1225212).
 
diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c
index 136dca0..5f33fe9 100644
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -85,9 +85,9 @@
 static PyObject *
 grp_getgrgid(PyObject *self, PyObject *args)
 {
-    int gid;
+    unsigned int gid;
     struct group *p;
-    if (!PyArg_ParseTuple(args, "i:getgrgid", &gid))
+    if (!PyArg_ParseTuple(args, "I:getgrgid", &gid))
         return NULL;
     if ((p = getgrgid(gid)) == NULL) {
 	PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
diff --git a/Modules/makexp_aix b/Modules/makexp_aix
index 9d3bccb..cb349c2 100755
--- a/Modules/makexp_aix
+++ b/Modules/makexp_aix
@@ -70,6 +70,12 @@
 #    left with just the symbol name.
 # 7. Eliminate all entries containing two colons, like Class::method
 #
-/usr/ccs/bin/nm -Bex $inputFiles				\
+
+# Use -X32_64 if it appears to be implemented in this version of 'nm'.
+NM=/usr/ccs/bin/nm
+xopt=-X32_64
+$NM -e $xopt $1 >/dev/null 2>&1 || xopt=""
+
+$NM -Bex $xopt $inputFiles					\
 | sed -e '/ [^BDT] /d' -e '/\./d' -e 's/.* [BDT] //' -e '/::/d'	\
 | sort | uniq >> $expFileName
diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c
index 805d4d9..f418e43 100644
--- a/Modules/pwdmodule.c
+++ b/Modules/pwdmodule.c
@@ -102,9 +102,9 @@
 static PyObject *
 pwd_getpwuid(PyObject *self, PyObject *args)
 {
-	int uid;
+	unsigned int uid;
 	struct passwd *p;
-	if (!PyArg_ParseTuple(args, "i:getpwuid", &uid))
+	if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
 		return NULL;
 	if ((p = getpwuid(uid)) == NULL) {
 		PyErr_Format(PyExc_KeyError,
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index f952e3e..bec2729 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -669,5 +669,6 @@
 	PyEval_ReInitThreads();
 	main_thread = PyThread_get_thread_ident();
 	main_pid = getpid();
+	_PyImport_ReInitLock();
 #endif
 }
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 059153d..4c0a0fc 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1344,7 +1344,7 @@
 static PyObject *
 sock_accept(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	SOCKET_T newfd;
 	socklen_t addrlen;
 	PyObject *sock = NULL;
@@ -1354,7 +1354,7 @@
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 
 #ifdef MS_WINDOWS
 	newfd = INVALID_SOCKET;
@@ -1365,7 +1365,7 @@
 	Py_BEGIN_ALLOW_THREADS
 	timeout = internal_select(s, 0);
 	if (!timeout)
-		newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf,
+		newfd = accept(s->sock_fd, (struct sockaddr *) &addrbuf,
 			       &addrlen);
 	Py_END_ALLOW_THREADS
 
@@ -1392,7 +1392,7 @@
 		SOCKETCLOSE(newfd);
 		goto finally;
 	}
-	addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
+	addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
 			    addrlen, s->sock_proto);
 	if (addr == NULL)
 		goto finally;
@@ -1865,19 +1865,19 @@
 static PyObject *
 sock_getsockname(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	int res;
 	socklen_t addrlen;
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getsockname(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+	res = getsockname(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
 			    s->sock_proto);
 }
 
@@ -1894,19 +1894,19 @@
 static PyObject *
 sock_getpeername(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	int res;
 	socklen_t addrlen;
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getpeername(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+	res = getpeername(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
 			    s->sock_proto);
 }
 
@@ -2115,7 +2115,7 @@
 static PyObject *
 sock_recvfrom(PySocketSockObject *s, PyObject *args)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	PyObject *buf = NULL;
 	PyObject *addr = NULL;
 	PyObject *ret = NULL;
@@ -2132,18 +2132,18 @@
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	timeout = internal_select(s, 0);
 	if (!timeout)
 		n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
 #ifndef MS_WINDOWS
 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
-			     (struct sockaddr *)addrbuf, &addrlen
+			     (struct sockaddr *) &addrbuf, &addrlen
 #else
-			     (void *)addrbuf, &addrlen
+			     (void *) &addrbuf, &addrlen
 #endif
 #else
-			     (struct sockaddr *)addrbuf, &addrlen
+			     (struct sockaddr *) &addrbuf, &addrlen
 #endif
 			);
 	Py_END_ALLOW_THREADS
@@ -2161,7 +2161,7 @@
 	if (n != len && _PyString_Resize(&buf, n) < 0)
 		return NULL;
 
-	if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
+	if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
 				  addrlen, s->sock_proto)))
 		goto finally;
 
@@ -2589,11 +2589,7 @@
 socket_gethostbyname(PyObject *self, PyObject *args)
 {
 	char *name;
-#ifdef ENABLE_IPV6
-	struct sockaddr_storage addrbuf;
-#else
-        struct sockaddr_in addrbuf;
-#endif
+	sock_addr_t addrbuf;
 
 	if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
 		return NULL;
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index 601c282..384d595 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -72,6 +72,26 @@
 #	define SIZEOF_SOCKET_T SIZEOF_INT
 #endif
 
+/* Socket address */
+typedef union sock_addr {
+	struct sockaddr_in in;
+#ifdef AF_UNIX
+	struct sockaddr_un un;
+#endif
+#ifdef ENABLE_IPV6
+	struct sockaddr_in6 in6;
+	struct sockaddr_storage storage;
+#endif
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+	struct sockaddr_l2 bt_l2;
+	struct sockaddr_rc bt_rc;
+	struct sockaddr_sco bt_sco;
+#endif
+#ifdef HAVE_NETPACKET_PACKET_H
+	struct sockaddr_ll ll;
+#endif
+} sock_addr_t;
+
 /* The object holding a socket.  It holds some extra information,
    like the address family, which is used to decode socket address
    arguments properly. */
@@ -82,24 +102,7 @@
 	int sock_family;	/* Address family, e.g., AF_INET */
 	int sock_type;		/* Socket type, e.g., SOCK_STREAM */
 	int sock_proto;		/* Protocol type, usually 0 */
-	union sock_addr {
-		struct sockaddr_in in;
-#ifdef AF_UNIX
-		struct sockaddr_un un;
-#endif
-#ifdef ENABLE_IPV6
-		struct sockaddr_in6 in6;
-		struct sockaddr_storage storage;
-#endif
-#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
-		struct sockaddr_l2 bt_l2;
-		struct sockaddr_rc bt_rc;
-		struct sockaddr_sco bt_sco;
-#endif
-#ifdef HAVE_NETPACKET_PACKET_H
-		struct sockaddr_ll ll;
-#endif
-	} sock_addr;
+	sock_addr_t sock_addr;	/* Socket address */
 	PyObject *(*errorhandler)(void); /* Error handler; checks
 					    errno, returns NULL and
 					    sets a Python exception */
diff --git a/Python/import.c b/Python/import.c
index 7cd5813..9b624a4 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -260,6 +260,18 @@
 	return 1;
 }
 
+/* This function is called from PyOS_AfterFork to ensure that newly
+   created child processes do not share locks with the parent. */
+
+void
+_PyImport_ReInitLock(void)
+{
+#ifdef _AIX
+	if (import_lock != NULL)
+		import_lock = PyThread_allocate_lock();
+#endif
+}
+
 #else
 
 #define lock_import()