Subject: bug#5819: 23.1.93; OSX: start-process sometimes returns an unready process

From: YAMAMOTO Mitsuharu <[email-masked]>
Date: Sun, 04 Apr 2010 14:29:44 +0900

>>>>> On Thu, 01 Apr 2010 19:55:11 +0200, Markus Triska <[email-masked]> said:

> Let testprocess.el consist of the following form:
>     (let (p (n 1))
>       (while t
>         (message "iteration %s" n)
>         (setq n (1+ n)
>               p (start-process "bc" nil "bc"))
>         (process-send-string p "test")
>         (delete-process p)))

> On OSX 10.4, when I do "$ emacs -Q --script testprocess.el", I get:

>    $ emacs -Q --script testprocess.el
>    iteration 1
>    iteration 2
>    iteration 3
>    writing to process: Input/output error, bc

> and sometimes, particularly under high system load:

>    $ emacs -Q --script testprocess.el
>    iteration 1
>    iteration 2
>    Process bc not running

> The number of iterations often varies over invocations.

I could reproduce it on Mac OS X 10.3 and 10.4, but not on 10.5 and
10.6.

The following patch, which uses openpty, seems to work for me on 10.4,
but not on 10.3.  I suspect a bug in the kernel.

				     YAMAMOTO Mitsuharu
				[email-masked]

=== modified file 'src/s/darwin.h'
*** src/s/darwin.h	2010-03-30 04:55:59 +0000
--- src/s/darwin.h	2010-04-04 04:50:02 +0000
***************
*** 90,95 ****
--- 90,121 ----
   */
  
  #define HAVE_PTYS
+ /* Run only once.  We need a `for'-loop because the code uses
+    `continue'.  */
+ #define PTY_ITERATION	for (i = 0; i < 1; i++)
+ #define PTY_NAME_SPRINTF	/* none */
+ #define PTY_TTY_NAME_SPRINTF	/* none */
+ #define PTY_OPEN						\
+   do								\
+     {								\
+       int slave, tem;						\
+       if (openpty (&fd, &slave, pty_name, NULL, NULL) == -1)	\
+ 	{							\
+ 	  fd = -1;						\
+ 	  break;						\
+ 	}							\
+       emacs_close (slave);					\
+       tem = fcntl (fd, F_GETFL, 0);				\
+       if (tem >= 0)						\
+ 	tem = fcntl (fd, F_SETFL, tem | O_NONBLOCK);		\
+       if (tem < 0)						\
+ 	{							\
+ 	  emacs_close (fd);					\
+ 	  fd = -1;						\
+ 	  break;						\
+ 	}							\
+     }								\
+   while (0)
  
  /**
   * PTYs only work correctly on Darwin 7 or higher.  So make the