From:	SMTP%"Mark.Martinec@ijs.si"  6-JUN-1994 12:33:34.21
To:	EVERHART
CC:	
Subj:	Re: Interactive users gets into CPU loop after disconnecting              (patch)

Message-Id: <9406020345.AA20362@uu7.psi.com>
Date:         Wed, 1 Jun 1994 19:41:21 GMT
Reply-To: Mark Martinec <Mark.Martinec@ijs.si>
Sender: ANU-NEWS Discussion <ANU-NEWS@VM1.NoDak.EDU>
From: Mark Martinec <Mark.Martinec@ijs.si>
Organization: J. Stefan Institute, Lj, Slovenia
Subject:      Re: Interactive users gets into CPU loop after disconnecting
              (patch)
To: Multiple recipients of list ANU-NEWS <ANU-NEWS@VM1.NoDak.EDU>

> In article <1994May27.211327.3973@vms.huji.ac.il>, yehavi@vms.huji.ac.il write
s:
>> Since I've installed 6.1b9 I find from time to time an interactive process
>> of a user running NEWS in disconnected state in a CPU loop.
>> Might it be that some terminal read function does not check the return
>> status and enters a loop when tyhe user disconnects the line?

The following patch should fix two problems reported recently:

 - Prevents one (most probable) cause of loop when SMG is hit
   by an unexpected i/o error (like when connection to a terminal is broken)

 - Partialy fix the cursor repositioning problem after displaying
   broadcast message (ok now with just a prompt on the line, no better
   than before after user starts typing a command).


The fix prevented looping after the simulated terminal i/o problems here,
but I am not sure that the course of events after the real circuit
breakdown is the same as with the simulated fault.

Please let me know if the looping problems still occur
after applying this fix (the processes running ANU-News spinning
in a loop and having a broken/hung connection to the terminal
(LAT or SET HOST) ).


$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_UNPACK_VERIFY"))'
$!
$! This archive created:
$!  Name : 0
$!  By   : mark@cathy.ijs.si
$!  Date :  1-JUN-1994 19:16:29.45
$!  Using: VMS_SHARE 8.4, (C) 1993 Andy Harper, Kings College London UK
$!
$! Credit is due to these people for their original ideas:
$!    James Gray, Michael Bednarek
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. 940601_NEWS.PATCH;1
$!
$ set="set"
$ set symbol/scope=(nolocal,noglobal)
$ f=f$parse("SHARE_UNPACK_TEMP","SYS$SCRATCH:."+f$getjpi("","PID"))
$ e="write sys$error  ""%UNPACK"", "
$ w="write sys$output ""%UNPACK"", "
$ if .not. f$trnlnm("SHARE_UNPACK_LOG") then $ w = "!"
$ if f$getsyi("CPU") .gt. 127 then $ goto start
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto start
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$unpack: subroutine ! P1=filename, P2=checksum, P3=attributes,P4=size
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'"
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn' File skipped"
$ delete 'f'*
$ exit
$dirok:
$ x=f$search(P1)
$ if x .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped"
$ delete 'f'*
$ exit
$file_absent:
$ w "-I-UNPACK, Unpacking ", P5, " of ", P6, " - ", P1, " - ", P4, " Blocks"
$ n=P1
$ if P3 .nes. "" then $ n=f
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT/NOJOURNAL 'f'/OUT='n'
PROCEDURE GetHex(s,p)LOCAL x1,x2;x1:=INDEX(t,SUBSTR(s,p,1))-1;x2:=INDEX(t,
SUBSTR(s,p+1,1))-1;RETURN 16*x1+x2;ENDPROCEDURE;PROCEDURE SkipPartsep LOCAL m;
LOOP m:=MARK(NONE);EXITIF m=END_OF(b);DELETE(m);EXITIF INDEX(ERASE_LINE,
"-+-+-+-+-+-+-+-+")=1;ENDLOOP;ENDPROCEDURE;PROCEDURE ProcessLine LOCAL c,s,l,b,
n,p;c := ERASE_CHARACTER(1);s := ERASE_LINE;EDIT(s,"TRIM");IF c =
 "X" THEN SPLIT_LINE; ENDIF;MOVE_HORIZONTAL(-1);l := LENGTH(s);p := 1;
LOOP EXITIF p > l;c := SUBSTR(s,p,1);p := p+1;CASE c FROM ' ' TO '`' ['`']
: COPY_TEXT(ASCII(GetHex(s,p))); p:=p+2;[INRANGE,OUTRANGE]: COPY_TEXT(c);
ENDCASE;ENDLOOP;ENDPROCEDURE;PROCEDURE Decode LOCAL m;POSITION(BEGINNING_OF(b))
;LOOP m:=MARK(NONE);EXITIF m=END_OF(b);DELETE(m);IF INDEX(CURRENT_LINE,
"+-+-+-+-+-+-+-+-")=1 THEN SkipPartSep;ELSE ProcessLine;MOVE_HORIZONTAL(1);
ENDIF;ENDLOOP;ENDPROCEDURE;SET(FACILITY_NAME,"UNPACK");SET(SUCCESS,OFF);SET(
INFORMATIONAL,OFF);t:="0123456789ABCDEF";f:=GET_INFO(COMMAND_LINE,"file_name");
b:=CREATE_BUFFER(f,f);Decode;WRITE_FILE(b,GET_INFO(COMMAND_LINE,"output_file"))
;QUIT;
$ if p3 .eqs. "" then $ goto dl
$ open/write fdl &f
$ write fdl "RECORD"
$ write fdl P3
$ close fdl
$ w "-I-CONVRFM, Converting record format to ", P3
$ convert/fdl=&f &f-1 &P1
$dl: delete 'f'*
$ checksum 'P1'
$ if checksum$checksum .nes. P2 then $ -
  e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ exit
$ endsubroutine
$start:
$!
$ create 'f'
XANU News Patch
XPatch ID: 940601_news.c!mark.martinec@ijs.si
XDate: 1-Jun-1994
XAuthor: Mark Martinec  mark.martinec@ijs.si
XNews Version: 6.1beta9
XNews Files: News.C,NewsFiles.C,NewsUtility.C
XDescription:
X  - Prevents one (most probable) cause of loop when SMG is hit
X    by an unexpected error (like broken connection to a terminal);
X  - Partialy fix the cursor repositioning problem after displaying
X    broadcast message.
X*** orig_dev:`5Banu-news.news_src`5Dnews.c;1
X--- news.c
X**************
X*** 47,52
X  **`09V6.1b8`0918-Jan-1994`09Charles Bailey  bailey@genetics.upenn.edu
X  **`09  - fixed bug introduced by 14-Jan-1994 patch which causes remote
X  **`09    session to occur even though News_Root is defined
X  **--
X  **/
X  `0C
X--- 47,56 -----
X  **`09V6.1b8`0918-Jan-1994`09Charles Bailey  bailey@genetics.upenn.edu
X  **`09  - fixed bug introduced by 14-Jan-1994 patch which causes remote
X  **`09    session to occur even though News_Root is defined
X+ **`09V6.1b9`09 1-Jun-1994`09mark.martinec@ijs.si
X+ **`09  - test for status==0 returned from get_input_general()
X+ **`09    which happens when UNWIND takes place during terminal I/O;
X+ **`09    this prevents looping in case of SMG I/O errors.
X  **--
X  **/
X  `0C
X**************
X*** 527,532
X        for (;;) `7B
X          status = get_input_general(`26cmd_dsc,c$dsc("NEWS> "),`26cmd_len,
X                                     0,0,1,line_editing);
X  `09if ((cmd_len >= 4) `26`26 (toupper(cmd`5B0`5D) == 'M' ) `26`26 (toupper(c
Vmd`5B1`5D) == 'E') `26`26 (toupper(cmd`5B2`5D) == 'N' ) `26`26(toupper(cmd`5B3
V`5D) == 'U') ) `7B
X  `09  strcpy (cmd,get_menu_input());
X  `09  cmd_len = strlen( cmd );
X--- 531,537 -----
X        for (;;) `7B
X          status = get_input_general(`26cmd_dsc,c$dsc("NEWS> "),`26cmd_len,
X                                     0,0,1,line_editing);
X+         if (! (status`261) ) break;
X  `09if ((cmd_len >= 4) `26`26 (toupper(cmd`5B0`5D) == 'M' ) `26`26 (toupper(c
Vmd`5B1`5D) == 'E') `26`26 (toupper(cmd`5B2`5D) == 'N' ) `26`26(toupper(cmd`5B3
V`5D) == 'U') ) `7B
X  `09  strcpy (cmd,get_menu_input());
X  `09  cmd_len = strlen( cmd );
X**************
X*** 542,547
X          exit(1);
X          `7D
X        if ((status == SMG$_EOF) `7C`7C (status == RMS$_EOF)) break;
X        `7D
X `20
X      brdcst_line = 0;
X--- 547,555 -----
X          exit(1);
X          `7D
X        if ((status == SMG$_EOF) `7C`7C (status == RMS$_EOF)) break;
X+       if (status == 0) break;  /* break the main loop in case of UNWIND
X+                                   from within get_input_general()
X+                                   ( condition handler returns 0 in %r0 ) */
V
X        `7D
X `20
X      brdcst_line = 0;
X*** orig_dev:`5Banu-news.news_src`5Dnewsfiles.c;1
X--- newsfiles.c
X**************
X*** 46,51
X  **`09V6.1b8  12-Apr-1994  mark.martinec@ijs.si
X  **`09   - rms_open() and rms_create receive an extra argument
X  **`09     to disable some (more common) cases of signalling errors
X  **--
X  */
X  `0C
X--- 46,59 -----
X  **`09V6.1b8  12-Apr-1994  mark.martinec@ijs.si
X  **`09   - rms_open() and rms_create receive an extra argument
X  **`09     to disable some (more common) cases of signalling errors
X+ **`09V6.1b9   1-Jun-1994  mark.martinec@ijs.si
X+ **`09   - set variable brdcst_col in get_input_general() (which knows
X+ **`09     the actual size of the prompt) as a temporary remedy for
X+ **`09     cursor repositioning problems after displaying broadcast messages.
V
X+ **`09     The true solution would be to move the call to display_brdcst()
X+ **`09     out of the AST routine.  The problem remains as the code stands no
Vw
X+ **`09     because during data entry in smg$read_composed_line()
X+ **`09     the exact cursor position is not known outside SMG.
X  **--
X  */
X  `0C
X**************
X*** 1156,1161
X      tmp_init_dsc.dsc$w_length = tmp_init_str_l;
X      tmp_prompt_dsc.dsc$w_length = tmp_prompt_str_l;
X      tmp_get_dsc.dsc$w_length = min(get_dsc->dsc$w_length,tmp_get_str_size-1)
V;
X      stat = smg$read_composed_line(`26kid,`26keytab,
X               (use_tmp_init ? `26tmp_get_dsc : get_dsc),
X               (use_tmp_prompt ? `26tmp_prompt_dsc : prompt_dsc),
X--- 1164,1174 -----
X      tmp_init_dsc.dsc$w_length = tmp_init_str_l;
X      tmp_prompt_dsc.dsc$w_length = tmp_prompt_str_l;
X      tmp_get_dsc.dsc$w_length = min(get_dsc->dsc$w_length,tmp_get_str_size-1)
V;
X+`20
X+     brdcst_col = 1;
X+     if (use_tmp_prompt) brdcst_col += tmp_prompt_dsc.dsc$w_length;
X+     else brdcst_col += (!prompt_dsc ? 0 : prompt_dsc->dsc$w_length);
X+`20
X      stat = smg$read_composed_line(`26kid,`26keytab,
X               (use_tmp_init ? `26tmp_get_dsc : get_dsc),
X               (use_tmp_prompt ? `26tmp_prompt_dsc : prompt_dsc),
X*** orig_dev:`5Banu-news.news_src`5Dnewsutility.c;1
X--- newsutility.c
X**************
X*** 2237,2243
X    int bell_cnt, dst, j, at_the_beginning;
X `20
X    if (((sts = smg$get_broadcast_message(`26pid,`26bm_dsc,`26bm_len,0)) `26 1
V)
X!       `26`26 (sts != SMG$_NO_MORMSG)) `7B
X      bm`5Bbm_len`5D = '`5C0';
X `20
X      /* remove and count <BEL> chars and remove <CR> before line terminators
V */
X--- 2237,2243 -----
X    int bell_cnt, dst, j, at_the_beginning;
X `20
X    if (((sts = smg$get_broadcast_message(`26pid,`26bm_dsc,`26bm_len,0)) `26 1
V)
X!       `26`26 (sts != SMG$_NO_MORMSG) `26`26 (sts != SMG$_NONBRDMSG)) `7B
X      bm`5Bbm_len`5D = '`5C0';
X `20
X      /* remove and count <BEL> chars and remove <CR> before line terminators
V */
X**************
X*** 2251,2257
X      bm`5Bdst`5D = '`5C0';  bm_len = dst;
X `20
X      if (bell_cnt > 3) bell_cnt = 3;
X!     _c$cks(smg$ring_bell(`26trailer_vd,`26bell_cnt));
X `20
X      _c$cks(smg$erase_line(`26trailer_vd,`26line,c$ac(1)));
X      smg_put_chars(trailer_vd,bm,line,1,1,SMG$M_BOLD);
X--- 2251,2257 -----
X      bm`5Bdst`5D = '`5C0';  bm_len = dst;
X `20
X      if (bell_cnt > 3) bell_cnt = 3;
X!     if (bell_cnt > 0) _c$cks(smg$ring_bell(`26trailer_vd,`26bell_cnt));
X `20
X      _c$cks(smg$erase_line(`26trailer_vd,`26line,c$ac(1)));
X      smg_put_chars(trailer_vd,bm,line,1,1,SMG$M_BOLD);
$ call unpack 940601_NEWS.PATCH;1 -
 302712249 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 12 1 1
$ v=f$verify(v)
$ exit

--
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  !!  Mark Martinec (system manager)   tel +386 61 1259-199  !!
  !!  J. Stefan Institute, Jamova 39   fax +386 61  219-385  !!
  !!  61000 Ljubljana, Slovenia        mark.martinec@ijs.si  !!
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! http://www.ijs.si/ !!!!!
