From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6407 invoked by alias); 16 Dec 2013 16:33:20 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 32129 Received: (qmail 22520 invoked from network); 16 Dec 2013 16:33:04 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-Biglobe-Sender: From: "Jun T." Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Subject: accessing zpty after child has finished (Mac OS X) Message-Id: Date: Tue, 17 Dec 2013 01:33:00 +0900 To: zsh-workers@zsh.org Mime-Version: 1.0 (Mac OS X Mail 7.0 \(1822\)) X-Mailer: Apple Mail (2.1822) On Mac OS X, 'make check' succeeds normally, but zpty still has some problems: mac$ zpty x date (date finishes immediately) mac$ zpty -r x # (1): no output mac$ zpty (20359) x: date # should be (finished) mac$ zpty -w x foo (2): zsh goes into an infinite loop (100% cpu usage). Suppose the child on the slave side of the pty has already finished, and we try to read from the master by 'ret = read(master, buf, 1)'. On Linux, what we get is either the data written to the slave but not yet read from the master, or ret = -1 (with errno set to EIO) if no such data remains. On Mac OS X, the data not yet read by the master is lost, and read() always returns 0 (not -1). The infinite loop (2) is in ptywritestr(); the for loop starting at line 676 of zpty.c never breaks and loops forever, because checkptycmd() (called at line 689) doesn't set cmd->fin. The following patch solves this problem, and I hope it does no harm on other OS. I feel the data loss (1) is OK at least for now. The only way I can think of to avoid the data loss is to open the slave in the parent and keep the file descriptor open in the parent. But I believe it causes trouble on other OS. diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c index fca0cc1..b0c339b 100644 --- a/Src/Modules/zpty.c +++ b/Src/Modules/zpty.c @@ -510,7 +510,7 @@ checkptycmd(Ptycmd cmd) if (cmd->read != -1 || cmd->fin) return; - if ((r = read(cmd->fd, &c, 1)) < 0) { + if ((r = read(cmd->fd, &c, 1)) <= 0) { if (kill(cmd->pid, 0) < 0) { cmd->fin = 1; zclose(cmd->fd);