Branch merge
diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst
index 30f1726..fd7f453 100644
--- a/Doc/library/cmd.rst
+++ b/Doc/library/cmd.rst
@@ -247,7 +247,7 @@
             right(*parse(arg))
         def do_left(self, arg):
             'Turn turtle left by given number of degrees:  LEFT 90'
-            right(*parse(arg))
+            left(*parse(arg))
         def do_goto(self, arg):
             'Move turtle to an absolute position with changing orientation.  GOTO 100 200'
             goto(*parse(arg))
diff --git a/Lib/test/test_multiprocessing.py b/Lib/test/test_multiprocessing.py
index 6f1c6c4..fd22312 100644
--- a/Lib/test/test_multiprocessing.py
+++ b/Lib/test/test_multiprocessing.py
@@ -267,6 +267,7 @@
         p = self.Process(target=time.sleep, args=(DELTA,))
         self.assertNotIn(p, self.active_children())
 
+        p.daemon = True
         p.start()
         self.assertIn(p, self.active_children())
 
@@ -337,6 +338,7 @@
 
     def test_subclassing(self):
         uppercaser = _UpperCaser()
+        uppercaser.daemon = True
         uppercaser.start()
         self.assertEqual(uppercaser.submit('hello'), 'HELLO')
         self.assertEqual(uppercaser.submit('world'), 'WORLD')
@@ -515,6 +517,7 @@
 
         # fork process
         p = self.Process(target=self._test_fork, args=(queue,))
+        p.daemon = True
         p.start()
 
         # check that all expected items are in the queue
@@ -555,6 +558,7 @@
                    for i in range(4)]
 
         for p in workers:
+            p.daemon = True
             p.start()
 
         for i in range(10):
@@ -825,7 +829,9 @@
 
         #self.assertEqual(event.is_set(), False)
 
-        self.Process(target=self._test_event, args=(event,)).start()
+        p = self.Process(target=self._test_event, args=(event,))
+        p.daemon = True
+        p.start()
         self.assertEqual(wait(), True)
 
 #
@@ -865,6 +871,7 @@
             self.assertEqual(sv.value, cv[1])
 
         proc = self.Process(target=self._test, args=(values,))
+        proc.daemon = True
         proc.start()
         proc.join()
 
@@ -928,6 +935,7 @@
         self.f(seq)
 
         p = self.Process(target=self.f, args=(arr,))
+        p.daemon = True
         p.start()
         p.join()
 
@@ -1332,6 +1340,7 @@
         manager.start()
 
         p = self.Process(target=self._putter, args=(manager.address, authkey))
+        p.daemon = True
         p.start()
 
         manager2 = QueueManager2(
@@ -1373,6 +1382,7 @@
         manager.start()
 
         p = self.Process(target=self._putter, args=(manager.address, authkey))
+        p.daemon = True
         p.start()
         queue = manager.get_queue()
         self.assertEqual(queue.get(), 'hello world')
@@ -1505,6 +1515,7 @@
         conn, child_conn = self.Pipe()
 
         p = self.Process(target=self._echo, args=(child_conn,))
+        p.daemon = True
         p.start()
         child_conn.close()    # this might complete before child initializes
 
@@ -1577,6 +1588,7 @@
         conn, child_conn = self.Pipe(duplex=True)
 
         p = self.Process(target=self._writefd, args=(child_conn, b"foo"))
+        p.daemon = True
         p.start()
         with open(test.support.TESTFN, "wb") as f:
             fd = f.fileno()
@@ -1600,6 +1612,7 @@
         conn, child_conn = self.Pipe(duplex=True)
 
         p = self.Process(target=self._writefd, args=(child_conn, b"bar", True))
+        p.daemon = True
         p.start()
         with open(test.support.TESTFN, "wb") as f:
             fd = f.fileno()
@@ -1688,11 +1701,13 @@
 
         lconn, lconn0 = self.Pipe()
         lp = self.Process(target=self._listener, args=(lconn0, families))
+        lp.daemon = True
         lp.start()
         lconn0.close()
 
         rconn, rconn0 = self.Pipe()
         rp = self.Process(target=self._remote, args=(rconn0,))
+        rp.daemon = True
         rp.start()
         rconn0.close()
 
@@ -1830,6 +1845,7 @@
         string.value = latin('hello')
 
         p = self.Process(target=self._double, args=(x, y, foo, arr, string))
+        p.daemon = True
         p.start()
         p.join()
 
@@ -1902,6 +1918,7 @@
         conn, child_conn = self.Pipe()
 
         p = self.Process(target=self._test_finalize, args=(child_conn,))
+        p.daemon = True
         p.start()
         p.join()
 
@@ -1971,12 +1988,16 @@
         reader, writer = multiprocessing.Pipe(duplex=False)
 
         logger.setLevel(LEVEL1)
-        self.Process(target=self._test_level, args=(writer,)).start()
+        p = self.Process(target=self._test_level, args=(writer,))
+        p.daemon = True
+        p.start()
         self.assertEqual(LEVEL1, reader.recv())
 
         logger.setLevel(logging.NOTSET)
         root_logger.setLevel(LEVEL2)
-        self.Process(target=self._test_level, args=(writer,)).start()
+        p = self.Process(target=self._test_level, args=(writer,))
+        p.daemon = True
+        p.start()
         self.assertEqual(LEVEL2, reader.recv())
 
         root_logger.setLevel(root_level)
@@ -2162,6 +2183,7 @@
 def _TestProcess(q):
     queue = multiprocessing.Queue()
     subProc = multiprocessing.Process(target=_ThisSubProcess, args=(queue,))
+    subProc.daemon = True
     subProc.start()
     subProc.join()
 
diff --git a/Misc/NEWS b/Misc/NEWS
index 12ac26e..d9e8f4b 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -62,6 +62,11 @@
 
 - Issue #12821: Fix test_fcntl failures on OpenBSD 5.
 
+Extension Modules
+-----------------
+ 
+- Issue #12950: Fix passing file descriptors in multiprocessing, under
+  OpenIndiana/Illumos.
 
 What's New in Python 3.2.2?
 ===========================
diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c
index 9de9279..bc635da 100644
--- a/Modules/_multiprocessing/multiprocessing.c
+++ b/Modules/_multiprocessing/multiprocessing.c
@@ -97,31 +97,37 @@
 /* Functions for transferring file descriptors between processes.
    Reimplements some of the functionality of the fdcred
    module at http://www.mca-ltd.com/resources/fdcred_1.tgz. */
+/* Based in http://resin.csoft.net/cgi-bin/man.cgi?section=3&topic=CMSG_DATA */
 
 static PyObject *
 multiprocessing_sendfd(PyObject *self, PyObject *args)
 {
     int conn, fd, res;
-    char dummy_char;
-    char buf[CMSG_SPACE(sizeof(int))];
-    struct msghdr msg = {0};
     struct iovec dummy_iov;
+    char dummy_char;
+    struct msghdr msg;
     struct cmsghdr *cmsg;
+    union {
+        struct cmsghdr hdr;
+        unsigned char buf[CMSG_SPACE(sizeof(int))];
+    } cmsgbuf;
 
     if (!PyArg_ParseTuple(args, "ii", &conn, &fd))
         return NULL;
 
     dummy_iov.iov_base = &dummy_char;
     dummy_iov.iov_len = 1;
-    msg.msg_control = buf;
-    msg.msg_controllen = sizeof(buf);
+
+    memset(&msg, 0, sizeof(msg));
+    msg.msg_control = &cmsgbuf.buf;
+    msg.msg_controllen = sizeof(cmsgbuf.buf);
     msg.msg_iov = &dummy_iov;
     msg.msg_iovlen = 1;
+
     cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     cmsg->cmsg_level = SOL_SOCKET;
     cmsg->cmsg_type = SCM_RIGHTS;
-    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-    msg.msg_controllen = cmsg->cmsg_len;
     * (int *) CMSG_DATA(cmsg) = fd;
 
     Py_BEGIN_ALLOW_THREADS
@@ -138,20 +144,26 @@
 {
     int conn, fd, res;
     char dummy_char;
-    char buf[CMSG_SPACE(sizeof(int))];
-    struct msghdr msg = {0};
     struct iovec dummy_iov;
+    struct msghdr msg = {0};
     struct cmsghdr *cmsg;
+    union {
+        struct cmsghdr hdr;
+        unsigned char buf[CMSG_SPACE(sizeof(int))];
+    } cmsgbuf;
 
     if (!PyArg_ParseTuple(args, "i", &conn))
         return NULL;
 
     dummy_iov.iov_base = &dummy_char;
     dummy_iov.iov_len = 1;
-    msg.msg_control = buf;
-    msg.msg_controllen = sizeof(buf);
+
+    memset(&msg, 0, sizeof(msg));
+    msg.msg_control = &cmsgbuf.buf;
+    msg.msg_controllen = sizeof(cmsgbuf.buf);
     msg.msg_iov = &dummy_iov;
     msg.msg_iovlen = 1;
+
     cmsg = CMSG_FIRSTHDR(&msg);
     cmsg->cmsg_level = SOL_SOCKET;
     cmsg->cmsg_type = SCM_RIGHTS;
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 552f8f0..a0b16a6 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -525,8 +525,8 @@
     return x;
 }
 
-/* Get a C unsigned long int from a long int object.
-   Returns -1 and sets an error condition if overflow occurs. */
+/* Get a C size_t from a long int object. Returns (size_t)-1 and sets
+   an error condition if overflow occurs. */
 
 size_t
 PyLong_AsSize_t(PyObject *vv)
@@ -562,7 +562,7 @@
         if ((x >> PyLong_SHIFT) != prev) {
             PyErr_SetString(PyExc_OverflowError,
                 "Python int too large to convert to C size_t");
-            return (unsigned long) -1;
+            return (size_t) -1;
         }
     }
     return x;