[net.unix-wizards] Csh under Gosling's emacs

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.