From: utzoo!decvax!harpo!utah-cs!utah-gr!thomas Newsgroups: net.unix-wizards Title: Csh under Gosling's emacs Article-I.D.: utah-gr.592 Posted: Thu Oct 21 20:41:42 1982 Received: Fri Oct 22 02:47:27 1982 We've been running csh under Gosling's emacs for some time now here. There was a bug, and I finally tracked it down. Here is the fix: I've finally figured out why csh won't run under emacs. It has to do with the brokeness of the mpx driver w/ respect to ioctl calls, but can be fairly easily fixed with a minor change to your emacs. When the csh tries to establish a process group, it first reads the tty pgrp. If this is -1, it assumes the tty isn't really, otherwise it compares t_pgrp to its own pgrp. If they aren't the same, it sleeps forever (essentially). If you follow this action through the mpx driver, you find that emacs is returning the sgtty struct in response to the TIOCGPGRP ioctl, the first four bytes of this struct certainly aren't -1, neither are they equal to the csh pgrp, so csh sleeps. The fix is easy - in response to the TIOCGPGRP call, return a struct with the first 4 bytes (taken as an integer) of -1. In particular, in mchan.c, make the following changes: ---------------------------------------------------------------- Near the beginning of the file, find the declaration of ioans_rec and ioans, and change it to /* ioans_rec is a structure used to return the IOANS message to a sender process. The structure is initialized in InitMpx() by gtty on the terminal. */ struct w_msg { short code; struct sgttyb ioctl_ans; } ioans_rec, iopg_rec, ioany_rec; struct wh ioans; /* The record actually used to send IOANS_REC */ struct wh iopg; /* The record actually used to send IOPG_REC */ struct wh ioany; ---------------------------------------------------------------- in Take_msg, change if (msg -> mpx_arg == TIOCGETP) { ioans.index = index; if (write (mpx_fd, &ioans, sizeof (ioans)) != sizeof (ioans)) error ("Unable to reply to process IOCTL"); } else { /* in response to a stty, we will simple give back the default tty record */ ioans.index = index; if (write (mpx_fd, &ioans, sizeof (ioans)) != sizeof (ioans)) error ("Unable to reply to process IOCTL"); } to if (msg -> mpx_arg == TIOCGETP) { ioans.index = index; if (write (mpx_fd, &ioans, sizeof (ioans)) != sizeof (ioans)) error ("Unable to reply to process IOCTL"); } else if (msg -> mpx_arg == TIOCGPGRP) { /* In response to TIOCGPGRP return an "error" * record. This is so csh will get the "right" * answer to its TIOCGPGRP. */ iopg.index = index; if (write (mpx_fd, &iopg, sizeof (iopg)) != sizeof (iopg)) error ("Unable to reply to process IOCTL"); } else { /* In response to anything else, reflect the same data * back. */ ioany.index = index; ioany_rec.ioctl_ans = msg -> mpx_ioctl; if (write (mpx_fd, &ioany, sizeof (ioany)) != sizeof (ioany)) error ("Unable to reply to process IOCTL"); } ---------------------------------------------------------------- and add the following lines to InitMpx: /* Answer TIOCGPGRP with a record containing a -1. This is so csh will work. */ iopg_rec.code = M_IOANS; *(int *)(&iopg_rec.ioctl_ans) = -1; /* gross! */ iopg.ccount = sizeof iopg_rec; iopg.data = (char *) & iopg_rec; /* Finally, any other ioctls get reflected. */ ioany_rec.code = M_IOANS; ioany.ccount = sizeof ioany_rec; ioany.data = (char *) & ioany_rec; ---------------------------------------------------------------- After doing this, you can run csh in your emacs window, it should say Warning: no access to tty; thus no job control in this shell... when you start it up. =Spencer