thomas (10/22/82)
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
jdd (10/25/82)
Still better than returning -1 for TIOCGPGRP ioctl's, you can keep track of the "correct" proces group (by tracking TIOCSPGRP's), thereby allowing job control under the csh. I found myself in a similar situation a while ago and it took me quite a while to guess what baroque stuff csh was doing. Cheers, John DeTreville Bell Labs, Murray Hill
chris.umcp-cs@UDel-Relay@sri-unix (10/28/82)
From: Chris Torek <chris.umcp-cs@UDel-Relay> Date: 25 Oct 82 21:15:32 EDT (Mon) We've had this working for a long time now, and what's more I've recently fixed the mchan.c code so that the csh doesn't even say "Warning; no access to tty, thus no job control in this shell". Instead we get nearly complete job control. [The reason we don't get complete job control is because of brain damage in the multiplexor code. I may try to fix this later.] If anyone is interested I can send our current mchan.c code.