Emacs 21 for Mac OS X
Latest News, FAQ, Files, Links, and other Resources.
Latest News

Introduction

Obtaining and Building Emacs

FAQ

Resources


Emacs Home Page

Emacs Project Page on Savannah

Emacs for Mac OS Classic Project Page


My OS X Programming Blog

    This is Emacs 21's Mac OS X maintainer's web page.

The Low-Down on the Pseudo Terminal Bug

Tuesday, October 28, 2003

Judging from recent posts to Emacs related newsgroups, and E-mail messages I've been receiving, I get the impression that more and more less-savvy computer users are trying to use Emacs. Typically, they download a year-old binary, double-click, and post a message that says Emacs is broken in Panther, etc. The fact is, if you checkout or update Emacs from CVS and compile it in Panther, it'll work just fine. Why do I still not make a binary distribution? To that my only answer is: the code is still in CVS! My secret wish is that if you can compile from CVS, you'll write better bug reports and ask more sensible questions. I have already concluded a while ago that this assumption is utterly wrong :-).

Unfortunately the pseudo terminal bug is something I cannot practically fix. I can think of many workarounds but all of them are messy. Perhaps a Darwin developer will read this note and fix the pty implementation. But even then, that won't get into OS X soon. The good news is, if process-connection-type is set to nil in your startup file, everything will work as they should, if you take the right precautions. Let me explain.

The implementation of pty's in Darwin is flawed. If a slave terminates before the master can read all its output, the last part of the output can be lost. A simple program to demonstrate this is as follows (modified from the code in a post in darwin-development).

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) { pid_t pid; int master; char buf[1001]; int n;

pid = forkpty(&master, NULL, NULL, NULL); if(pid < 0) { perror("fork error"); exit(-1); } else if(pid == 0) { int i; for (i = 0; i < 100; i++) printf("### This is the child process, line %d ###n", i); usleep(100000); // Shouldn't be needed... exit(0); } else { while(n = read(master, buf, 1000)) { if(n < 0) { perror("read error"); exit(-1); } buf[n] = 0; // Make a string out of our data. printf("%s", buf); } } exit(0); }

As a result an «interactive» program that uses a pty in Emacs, such as ftp or ssh, will work OK, up until the last command (quit, e.g.) sent to it, which usually doesn't matter. However if pty's are used to start a man, diff, latex, or make process, which don't wait for any input, the last part of the output will be lost. Fortunately «pipes» work and will not lose output, and setting process-connection-type to nil enables them by default. Emacs Lisp packages that do require pty's will set the buffer-local variable process-connection-type to t, and everything should work the way they're intended.

So I think I should leave pty support in Emacs as it is, and find a way to set process-connection-type to nil even when Emacs is running in a terminal on OS X. I'll put a description of this problem in etc/PROBLEM and the FAQ. Of course, as always, any contribution that fixes this problem is welcome.

October 2003
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Sep  Nov


Copyright © 2003 Andrew Choi <akochoi-emacs at shaw.ca> Created with
BlogMax
emacs Made on a Mac