Path: utzoo!dciem!nrcaer!scs!spl1!laidbak!att!osu-cis!tut.cis.ohio-state.edu!mailrus!rutgers!paul.rutgers.edu!aramis.rutgers.edu!athos.rutgers.edu From: hedrick@athos.rutgers.edu (Charles Hedrick) Newsgroups: comp.unix.microport Subject: diffs for ksh for Emacs editing, BSD-style job control Message-ID: Date: 4 Jun 88 03:49:26 GMT Article-I.D.: athos.Jun.3.23.49.25.1988.3346 Organization: Rutgers Univ., New Brunswick, N.J. Lines: 349 Having gotten tired of waiting for a ksh binary with emacs enabled to show up on the Uport BBS, I decided to build one myself. Unfortunately, licensing considerations prevent me from posting the whole thing. But I have some advice to others who are trying to do the same thing. (Hopefully the kind folks at Microport will follow these instructions and generate an emacs version of ksh for the BBS.) These instructions also tell you how to get BSD-style job control to work. The capability is there is the ksh source, but a couple of fixes and some instructions are needed to make it work. These instructions apply to what is called "ksh-i", from the Toolchest. There are no version numbers that I can find, but files seem to be created on Oct 27, 1987. This applies to SV/AT. Presumably ksh and the job control stuff also works on the 386 version, but I have no way to test it. In order to build a ksh with emacs editing and job control, you have to be in the src directory, and do make OPTIONS="+v +s" This turns off vi and the ability to do suid scripts, to save space in the core image. (This would be unnecessary on the 386 version. I haven't had a chance to try building a large-model version on SV/AT.) vi and emacs do not fit at once. (That's why the uport copy doesn't include emacs: you have to choose, and the default choice is vi.) If you want job control, you will then want to go into the jsh subdirectory and do make install Note that you have to be root to do this install, as jsh has to be installed setuid root (in order to be able to change ownership of the sxt devices). You will have to be running a kernel that has the sxt devices in it. By default uport kernels do not, but I believe the "large" kernel does, and you can build one for yourself using the linkkit. /usr/bin/jsh is a jacket for ksh. It sets things up to use the appropriate set of sxt devices, and then calls /bin/sh (actually it calls whatever shell is pointed to by the environment variable SHELL, but I've only been able to make it work with the default configuration where the Korn shell is installed as /bin/sh). The changes below do the following: - make file name completion work right. In the original ksh, ESC ESC causes a partly-typed file name to be replaced by *all* file names that match it. That is not what any other system means by filename recognition. If there are several files beginning with what you typed, you want to complete the part that is the same for all of them and beep, rather than putting them all in your command line. I've made ESC ESC do this, and left ESC * doing the old version. - ESC ? is an alternative to ESC = for listing all files that match what has been typed. I found ESC = impossible to remember. - ESC u uppercases the next word. They took ESC l, but for some reason not ESC u. (They called it ESC c, which at least on my version of Emacs capitalizes the next word, i.e. changes the first letter only to upper-case.) - fixed ^W to work if you have changed the erase character. - fixed the make file to enable the sxt code. (You should just be able to remove the comments from 3 lines that are there already. For reasons I didn't take time to look at, this didn't work for me, so I had to do what you see below.) - fixed the code for job control so that it works with pipelines. Previously if you typed "diff a b | more", the job would hang. It is very clear that nobody has used job control seriously on System V. Almost no implementations of the sxt code work correctly, so probably Korn was unable to test his code very much. (Interestingly, SV/AT seems to have a solid implementation of sxt's.) The code to implement job control using sxt's is by default disabled in ksh. However I haven't run into any serious problems other than the fact that pipelines hang, which is fixed below. I *really* like getting job control back. I almost feel like this is real Unix now! (My primary editor, jove, has code in it to allow ^Z to suspend it. This was part of the diffs I posted a couple of weeks ago. Probably similar code should be put into "more" and any other programs that use the raw terminal.) The way I use job control is as follows: in my .profile, the last line is exec /usr/bin/jsh This causes the login shell to be replaced by jsh, which then replaces itself by ksh again (actually /bin/sh in my case, but that is ksh on my system), but in a mode that allows it to do job control. This gives job control at the top level. If you find yourself in a recursively-spawned shell later (e.g. emacs spawns a shell), I don't know of any way to get jsh to provide job control at that level. I tried setting SHELL to /usr/bin/jsh so that jsh is used by any program that starts a shell, but that didn't work. However having it even at the top level is a welcome relief. Now and then I find that something resets my tty modes to something odd, so I have a script "reset" that puts back the appropriate characters. In case you find that suddenly job control has stopped working, take a look at "stty". If SWTCH is suddenly ^`, you will need to do "stty swtch '^z'" to get it back to ^Z. (This is part of my reset script, which is probably a better approach.) *** edit.c.ORIG Fri Jun 3 20:34:18 1988 --- edit.c Fri Jun 3 04:43:37 1988 *************** *** 628,634 * file name generation for edit modes * non-zero exit for error, <0 ring bell * don't search back past character of the buffer ! * mode is '*' for inline expansion, otherwise files are listed in select format */ q_expand(outbuff,cur,eol,start,mode) --- 628,636 ----- * file name generation for edit modes * non-zero exit for error, <0 ring bell * don't search back past character of the buffer ! * mode is '*' for inline expansion, ! * '?' for listing all files in select format ! * otherwise unique completion */ q_expand(outbuff,cur,eol,start,mode) *************** *** 716,722 endstak(ptr); last = ptr-1; } ! if(mode!='*') on_option(MARKDIR); { register char **com; --- 718,724 ----- endstak(ptr); last = ptr-1; } ! if(mode=='?') on_option(MARKDIR); { register char **com; *************** *** 736,742 goto done; } } ! if(mode!='*') { if (strip) { --- 738,744 ----- goto done; } } ! if(mode=='?') { if (strip) { *************** *** 751,756 p_flush(); goto done; } /* see if there is enough room */ size = *eol - (out-begin); size += narg; --- 753,777 ----- p_flush(); goto done; } + /* if normal completion, and not unique, beep and make it unique */ + if(mode!='*' && narg > 1) { + char **nextcom = com+1; + char *firstcom; + char *thiscom; + + e_ringbell(); + while (*nextcom) { + thiscom = *nextcom; + firstcom = *com; + while (*thiscom++ == *firstcom) + firstcom++; + *firstcom = 0; + nextcom++; + } + narg = 1; + com[1] = 0; + } + /* see if there is enough room */ size = *eol - (out-begin); size += narg; *** emacs.c.ORIG Fri Jun 3 20:32:06 1988 --- emacs.c Fri Jun 3 05:19:54 1988 *************** *** 360,366 continue; } adjust = i - mark; ! ungetchar('\b'); continue; case cntl(D) : mark = i; --- 360,366 ----- continue; } adjust = i - mark; ! ungetchar(usrerase); continue; case cntl(D) : mark = i; *************** *** 626,631 case 'l': /* M-l == lower-case */ case 'd': case 'c': case 'f': { --- 626,632 ----- case 'l': /* M-l == lower-case */ case 'd': + case 'u': case 'c': case 'f': { *************** *** 664,670 draw(UPDATE); return(-1); } ! else if(ch=='c') { ungetchar(cntl(C)); return(i-cur); --- 665,671 ----- draw(UPDATE); return(-1); } ! else if(ch=='c' || ch=='u') { ungetchar(cntl(C)); return(i-cur); *************** *** 751,760 } /* file name expansion */ ! case cntl([) : /* easier to type */ ! i = '*'; ! case '*': ! case '=': /* escape = - list all matching file names */ mark = cur; if(q_expand(out,&cur,&eol,plen,i) < 0) beep(); --- 752,762 ----- } /* file name expansion */ ! case '=': i = '?'; /* ? and = are list */ ! case '?': ! case cntl([) : /* unique completion */ ! case '*': /* complete all */ ! mark = cur; if(q_expand(out,&cur,&eol,plen,i) < 0) beep(); *************** *** 758,764 mark = cur; if(q_expand(out,&cur,&eol,plen,i) < 0) beep(); ! else if(i=='*') draw(UPDATE); else draw(REFRESH); --- 760,766 ----- mark = cur; if(q_expand(out,&cur,&eol,plen,i) < 0) beep(); ! else if(i!='?') draw(UPDATE); else draw(REFRESH); *** makesh.ORIG Fri Jun 3 22:38:30 1988 --- makesh Fri Jun 3 13:37:52 1988 *************** *** 79,87 if test -d /dev/fd # new research UNIX feature then Options="$Options DEVFD=-DDEVFD" fi ! #if test -d /dev/sxt # sxt driver available ! #then Options="$Options SXT=-DSXT" ! #fi if test -f /vmunix -o "$SYSTYPE" = bsd4.1 -o "$SYSTYPE" = bsd4.2 # true for BSD unix then JOBLIB=-ljobs Options="$Options DBSD=-DBSD" JOBS=jobs.o LFLAGS=-z if test -f /etc/networks #BSD 4.2 --- 79,88 ----- if test -d /dev/fd # new research UNIX feature then Options="$Options DEVFD=-DDEVFD" fi #if test -d /dev/sxt # sxt driver available #then Options="$Options SXT=-DSXT" #fi ! Options="$Options SXT=-DSXT" if test -f /vmunix -o "$SYSTYPE" = bsd4.1 -o "$SYSTYPE" = bsd4.2 # true for BSD unix then JOBLIB=-ljobs Options="$Options DBSD=-DBSD" JOBS=jobs.o LFLAGS=-z if test -f /etc/networks #BSD 4.2 *** xec.c.ORIG Fri Jun 3 22:15:12 1988 --- xec.c Fri Jun 3 22:15:13 1988 *************** *** 256,261 int no_fork; sync_io(); #ifdef SXT /* find job number and create synchronization pipe */ if((jobstat.cur_job = next_job()) < jobstat.maxjob) if(pipe(jobstat.pipe)<0) --- 256,262 ----- int no_fork; sync_io(); #ifdef SXT + if(jobstat.j_flag==0) { /* find job number and create synchronization pipe */ if((jobstat.cur_job = next_job()) < jobstat.maxjob) if(pipe(jobstat.pipe)<0) *************** *** 260,265 if((jobstat.cur_job = next_job()) < jobstat.maxjob) if(pipe(jobstat.pipe)<0) jobstat.maxjob = 0; #endif /* SXT */ no_fork = (execflg&1) && (type&(FAMP|FPOU))==0; if(no_fork) --- 261,267 ----- if((jobstat.cur_job = next_job()) < jobstat.maxjob) if(pipe(jobstat.pipe)<0) jobstat.maxjob = 0; + } #endif /* SXT */ no_fork = (execflg&1) && (type&(FAMP|FPOU))==0; if(no_fork) Brought to you by Super Global Mega Corp .com