KARNEY%PPC.MFENET@NMFECC.ARPA (10/03/87)
Below is an update to the BOSS program I posted in August. It contains a new BOSS.HLP and BOSS.DIF which using $ EDIT/SUM BOSS.C/UPDATE=BOSS.DIF will take you from BOSS 1.0 to BOSS 1.2. Changes are: (1) A process can initiate a switch to another process by defining BOSS$SWITCH. It can also stuff text into the input via of the new process via BOSS$STUFF. (2) A bug wherein PHY_IO was inherited by the subprocesses is fixed. Charles Karney Plasma Physics Laboratory Phone: 609/683-2607 Princeton University MFENet: Karney@PPC.MFENET PO Box 451 ARPANet: Karney%PPC.MFENET@NMFECC.ARPA Princeton, NJ 08544-0451 Bitnet: Karney%PPC.MFENET@ANLVMS.BITNET ....................... Cut between dotted lines and save ...................... $!.............................................................................. $! VAX/VMS archive file created by VMS_SHAR V-5.01 01-Oct-1987 $! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au) $! To unpack, simply save and execute (@) this file. $! $! This archive was created by KARNEY $! on Friday 2-OCT-1987 17:06:11.28 $! $! It contains the following 2 files: $! BOSS.HLP BOSS.DIF $!============================================================================== $ Set Symbol/Scope=(NoLocal,NoGlobal) $ Version=F$GetSYI("VERSION") ! See what VMS version we have here: $ If Version.ges."V4.4" then goto Version_OK $ Write SYS$Output "Sorry, you are running VMS ",Version, - ", but this procedure requires V4.4 or higher." $ Exit 44 $Version_OK: CR[0,8]=13 $ Pass_or_Failed="failed!,passed." $ Goto Start $Convert_File: $ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd $No_Error1: Define/User_Mode SYS$Output NL: $ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' - VMS_SHAR_DUMMY.DUMMY f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f); o:=Get_Info(Command_Line,"Output_File");Set(Output_File,b,o); Position(Beginning_of(b));Loop x:=Erase_Character(1);Loop ExitIf x<>"V"; Move_Vertical(1);x:=Erase_Character(1);Append_Line; Move_Horizontal(-Current_Offset);EndLoop;Move_Vertical(1); ExitIf Mark(None)=End_of(b) EndLoop;Position(Beginning_of(b));Loop x:=Search("`",Forward,Exact);ExitIf x=0;Position(x);Erase_Character(1); If Current_Character='`' then Move_Horizontal(1);else Copy_Text(ASCII(INT(Erase_Character(3))));EndIf;EndLoop;Exit; $ Delete VMS_SHAR_DUMMY.DUMMY;* $ Checksum 'File_is $ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR $ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd $No_Error2: Return $Start: $ File_is="BOSS.HLP" $ Check_Sum_is=1047802103 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X1 BOSS XBOSS is an interactive job controller. It lets you run several interactive Xjobs simultaneously. Before running BOSS put X X $ boss :== $usr:[utility]boss X Xinto your login.com file. In order to run BOSS type X X $ boss X XBOSS was written by Charles Karney based on the PHOTO program written by Asbed XBedrossian of USC. It utilizes the Pseudo TTY package of Kevin Carosso of XHughes Aircraft Co. X XBugs, questions, etc. to Charles Karney (Karney@PPC). X2 Description XBOSS lets you create up to 8 processes each of which is identified by a Xsingle letter (A thru Z). This letter is used in the process name and in Xthe DCL prompt. At most one of these processes is ``current'. This means Xthat what you type is sent to that process, and output from that process is Xsent to your terminal. A process which is not current can run but cannot do Xoutput. (Output is saved until you make that process current.) You usually Xswitch between processes by typing control-\ followed by the identifying Xletter. It is also possible to have have of your processes initiate the Xswitch. X XYou can run any program under BOSS. For example, you might X run Emacs or EVE in process E X SET HOST to the EPX in process H X run NETTY to the B machine in process B X do a FORTRAN compilation in process F X execute DCL commands in process D X talk to your colleague using PHONE in process P Xand so on. X XOf course, you would normally not need to run so many processes. (Indeed Xyour subprocess quota may only let you run 5 processes.) When you are Xthrough with a process, you should log out of it (with ``logout') and switch Xback to some other process. X XBOSS makes no attempt to keep track of what is on your screen. Usually when Xswitching to a process which manages the screen in an advanced manner, you Xshould issue a command to the program to get it to re-draw the screen. X(This is control-w for EVE, PHONE, SPELL; control-l for Emacs.) X XBOSS uses the VT100 escape sequences for clearing the screen, etc. However Xit should still be useable on non-VT100-compatible terminals. X2 Commands XUsually, all commands to BOSS begin with the C-\ (control-\). The exception Xis when there is no current process (i.e., initially and immediately after Xlogging out of a process). In that case the C-\ is optional. X XThe commands are: X X C-h (or BS) Print command summary X C-z Quit (asking confirmation if there are processes) X a thru z Switch to a particular process (starting it if necessary) X A thru Z the same except clear the screen first X ? List processes (* means current, + means waiting for output) X C-\ Send a real C-\ to the current process X DEL Do nothing X other Sound the bell on the terminal X2 Communicating XBOSS and the processes under it can communicate via logical names. The Xfollowing are recognized: X XBOSS$ID (in process table); BOSS defines this as the identifying letter of Xthe process. This can be used in tailoring the DCL prompt etc.; e.g., X $ set prompt "boss-''f$trnlnm("boss$id")'>" XIt can also be used to indicate to a program that it is running under BOSS. X XBOSS$SWITCH (in job table); whenever BOSS is writes output to the real Xterminal, it checks whether BOSS$SWITCH is defined. If it's defined as a Xsingle letter, BOSS will switch to that process and delete the logical name. XThus a DCL procedure can initiate a switch to process G with X $ define/job boss$switch g X $ write sys$error ""`009! do some output to make BOSS wake up X XBOSS$STUFF (in job table); whenever a BOSS makes a process initiated Xswitch. It stuffs the definition of BOSS$STUFF into the input stream of Xthe process being switched to. After being used, BOSS$STUFF is deleted. X3 Examples XThe following command procedure will do a SHO DEF and leave SHO DEF in the Xrecall buffer: X $ cr[0,8] = 13 X $ define/job boss$stuff "sho def''cr'" X $ define/job boss$switch 'f$trnlnm("boss$id")' X XHere's how to switch to process F and have the present job continue Xrunning: X $ define/job boss$switch f X $ char[0,8] = 22`009`009`009! control-V X $ gosub out_char X $ return X $! X $out_char:`009`009! Spit out the character X $ read/prompt='char'/end=40$/error=40$/time_out=0 sys$command dummy X $40$: return X XIf you want the present process to wait, then repeat the gosub out_char 3 Xtimes. X XReturn paths may be implemented via additional logical names. E.g., the Xprocedure that runs Emacs under BOSS does the following. X XIf Emacs isn't running (boss$emacs undefined) do X $ define/job boss$emacs 'f$trnlnm("boss$id")' Xand start Emacs. X XIf Emacs is running (boss$emacs defined) do X $ define/job boss$return_switch 'f$trnlnm("boss$id")' X $ define/job boss$switch 'f$trnlnm("boss$emacs","lnm$job")' X $ gosub out_char X $ gosub out_char X $ gosub out_char X XThe suspend-emacs function in Emacs is redefined to do the equivalent of X $ define/job boss$switch 'f$trnlnm("boss$return_switch","lnm$job")' X $ deassign/job boss$return_switch X ... X XSimilarly boss$return_stuff may be used as the string to stuff into the Xprocess on return. The edit procedure that is called on a TeX error may Xset this to the current TeX command line so that on exiting from the Xeditor the user has the input buffer prepared with the command to re-run XTeX. The user then has the option either of accepting the command (by Xtyping return) or cancelling it (with C-u). X2 Bugs XBOSS does single character input. This is rather slow. Don't expect it to Xbe able to keep up with lots of data coming from the terminal. X XThe output on a Visual 550 at 9600 baud occasionally has glitches in it. XThis is because the Visual 550 needs flow control enabled to operate at 9600 Xbaud, but BOSS doesn't react quickly enough to the control-s sent by the Xterminal. The solution is to run at 4800 baud or slower. X XBOSS sometimes hangs when it runs out of BYTLM. I believe this is caused by XLIB$SPAWN never returning (instead of returning with an error code). Make Xsure your BYTLM is high enough. (It appears that 8000 is too low. 40000 is Xadequate.) X XOutput gets garbled when using BOSS via SET HOST (i.e., SET HOST followed by XBOSS). This happens when you type while output is coming to your terminal. XThe symptom is that the lines come out in the wrong order. It's OK to use XSET HOST while in BOSS (i.e., BOSS followed by SET HOST). X XPC file transfer (e.g., using MACX, XMODEM) probably doesn't work through XBOSS. (Actually I have got downloads to work with MACX. That presumably is Xan accident of the Mac not sending a C-\ as part of the handshaking. XUploads seem to stall.) X XAttempting to attach to the process running BOSS from one of its Xsubprocesses causes a hangage. X2 Unfeatures XThe following features are not implemented but are possible future Xenhancements. X X* Log files. X* Largish output buffer for non-current processes (have to worry about X controlling the output though). Sending a C-s won't work. X* Ability to kill particular processes. X* Ability to ATTACH to non-BOSS processes. I haven't managed to make this X work yet. X* Configurable for other terminals. X* Allow default directory to propagate to other processes. $ GoSub Convert_File $ File_is="BOSS.DIF" $ Check_Sum_is=456414080 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X- 3 XVersion 1.1. August 27, 1987 X Add BOSS$ID, BOSS$SWITCH, BOSS$STUFF. XVersion 1.2. September 30, 1987 X Stop PHY_IO being inherited by subprocesses. X- 39 X#include LNMDEF X#include PRVDEF X- 72, 72 X pid[nproc], st, cur, count[nproc], procno[nalph], priv[2], no_phy_io; X- 81, 81 X pending = 0, quit_pending = 0, oboss_id = 0; X- 85 Xstatic short trnlnm_string_len; Xstatic char trnlnm_string[81]; X Xstruct ITEM_LST { X unsigned short len, code; unsigned long addr, retlen; X } trnlnm_item = {80, LNM$_STRING, &trnlnm_string, &trnlnm_string_len}; X X- 88 X char id[2]; X X $DESCRIPTOR(d_boss_id,"BOSS$ID"); X $DESCRIPTOR(d_id, id); X if (oboss_id != 0) {`009`009/* Restore BOSS$ID */ X id[0] = oboss_id; X j = LIB$SET_LOGICAL(&d_boss_id,&d_id,0,0,0); X } X- 122, 122 X char proc[20],prompt[4],id[2]; X- 125 X $DESCRIPTOR(d_boss_id,"BOSS$ID"); X $DESCRIPTOR(d_id, id); /* The id */ X- 141, 142 X id[0] = name; X check(LIB$SET_LOGICAL(&d_boss_id,&d_id,0,0,0)); X st = LIB$SPAWN(0,&d_pty_io,&d_pty_io,&flg,&d_proc,pid,0,0, X &comp_srv,n,&d_prompt,0); X check(LIB$DELETE_LOGICAL(&d_boss_id,0)); X- 158, 160 X int j; X char nname; X $DESCRIPTOR(d_boss_switch,"BOSS$SWITCH"); X $DESCRIPTOR(d_boss_stuff,"BOSS$STUFF"); X $DESCRIPTOR(d_lnm_job,"LNM$JOB"); X check(SYS$QIO(1,tt_chn,IO$_WRITEVBLK,&tiosb,0,0, X &tpline[n],count[n],0,0,0,0)); X j = SYS$TRNLNM(0,&d_lnm_job,&d_boss_switch,0,&trnlnm_item); X check(SYS$WAITFR(1)); /* for some reason QIOW does not work */ X if (!bad(j) && trnlnm_string_len == 1) { X j = LIB$DELETE_LOGICAL(&d_boss_switch,&d_lnm_job); X nname = toupper(trnlnm_string[0]); X j = SYS$TRNLNM(0,&d_lnm_job,&d_boss_stuff,0,&trnlnm_item); X if (!bad(j)) { X j = LIB$DELETE_LOGICAL(&d_boss_stuff,&d_lnm_job); X trnlnm_string[trnlnm_string_len] = '\0'; X } else { X trnlnm_string[0] = '\0'; X } X if (nname >= 'A' && nname <= 'Z') X mov_to(nname, 0, trnlnm_string); X } X- 212, 212 X int j, item; X short len; X- 218, 223 X if (bad(j)) strcpy(image,"<UNKNOWN>"); X else { X image[len]='\0'; X if (len == 0) { X item = JPI$_CLINAME; X j = LIB$GETJPI(&item,&pid,0,0,&d_image,&len); X if (bad(j)) strcpy(image,"<UNKNOWN>"); X else image[len]='\0'; X } X else { X if ((ptr = strrchr(image,']'))) ptr++; X else ptr = ℑ X if (ptra = strchr(ptr,'.')) *ptra = '\0'; X } X- 228, 231 Xmov_to(nname, clear, string)`009/* Switch to process */ Xchar nname, *string; Xint clear; X{ X int ncur,len; X char *prefix; X prefix = clear ? clr : bos; X len = strlen(string); X if ((cur >= 0) && (name[cur] == nname)) { /* Redundant move */ X if (len == 0) { X sprintf(buf,"%s[Already in process %c, %s]%s", X`009 prefix,nname,get_image(pid[cur]),ceoln); X term_msg(buf); X } X } X else if ((ncur = procno[nname-'A']) >= 0) { /* Existing proc */ X cur = ncur; X sprintf(buf,"%s[Switch to process %c, %s]%s", X`009 prefix,name[cur],get_image(pid[cur]),ceoln); X term_msg(buf); X if (blocked[cur]) term_out(cur); X } X else if ((ncur = next_slot()) < 0) { X if (cur >= 0) X sprintf(buf,"%s[No process slots left--still in %c]%s", X`009 bos,name[cur],ceoln); X else sprintf(buf,"%s[No process slots left]%s",bos,ceoln); X term_msg(buf); X len = 0; X } X else { X sprintf(buf,"%s[Starting process %c...%s",prefix,nname,ceol); X term_msg(buf); X if (bad(fire_up(ncur,nname))) { X if (cur >= 0) X`009sprintf(buf,"failed!!\007--still in %c]%s",name[cur],ceoln); X else X`009sprintf(buf,"failed!!\007]%s",ceoln); X term_msg(buf); X len = 0; X } else { X sprintf(buf,"done; now in process %c, %s]%s\r", X`009 nname,get_image(pid[ncur]),ceol); X term_msg(buf); X cur = ncur; X if (blocked[cur]) term_out(cur); X } X } X if (len > 0) { X check(SYS$QIOW(0,py_chn[cur],IO$_WRITEVBLK,&tiosb,0,0, X string,len,0,0,0,0)); X check(tiosb.stats); X } X} X Xtt_srv() /* AST: Read on real terminal */ X{ X int i; X char post, nname; X- 283, 320 X`009mov_to(nname,input_char < 'a',""); /* Clear if upper case */ X- 374 X if (no_phy_io) check(SYS$SETPRV(1,&priv,0,0)); X- 378 X if (no_phy_io) check(SYS$SETPRV(0,&priv,0,0)); X- 421, 421 X int j,item; X $DESCRIPTOR(d_boss_id,"BOSS$ID"); X $DESCRIPTOR(d_lnm_process,"LNM$PROCESS"); X X- 426 X`009`009`009`009/* Save old value of BOSS$ID */ X j = SYS$TRNLNM(0,&d_lnm_process,&d_boss_id,0,&trnlnm_item); X if (!bad(j) && trnlnm_string_len == 1) { X oboss_id = trnlnm_string[0]; X j = LIB$DELETE_LOGICAL(&d_boss_id,0); X } X X item = JPI$_PROCPRIV;`009`009/* Check whether have PHY_IO */ X check(LIB$GETJPI(&item,0,0,&priv,0,0)); X no_phy_io = !(priv[0] & PRV$M_PHY_IO); X priv[0] = PRV$M_PHY_IO; priv[1] = 0; X if (no_phy_io) check(SYS$SETPRV(0,&priv,0,0)); X X- 436, 436 X printf("Begin BOSS 1.2\nType control-\\ control-h for information\n\n"); X/ $ GoSub Convert_File $ Exit