[comp.sources.bugs] tcsh for 4.3

jack@cadre.dsl.PITTSBURGH.EDU (Jack Nelson) (10/05/87)

1.  If hit ESC-^D at beginning of command line tcsh will dump core.
	fix: uninitialized pointer "cp" line 127 of tw.init.c
2.  Using "vi" while running tcsh will leave you in strange state when
      you exit or ^Z pause, or with first chars of new command line not being
      echoed, except 'l', and noecho of other commands, even reset
      or RESET, using either RET or LF; get odd error message
      "use 'logout' to logout" as if ^D being hit at beginning of line.
      One can get "exit" in, however, which does get back to login csh
      when terminated with LF.
	This is "pass8" condition of stty(1)!.
	in Rawmode(): add test for T_HasMeta to stay out of lpass8 mode
	in ed.init.c
		if (T_HasMeta)
		    xlb |= (LCRTBS | LCRTERA | LCRTKIL | LPASS8);
		else xlb |= (LCRTBS | LCRTERA | LCRTKIL);
3. Using the ^D, which is delete-forward as well as EOF as well as
    command to complete command, filename, etc: if back over filechars
    then us ^D to delete forward, when hits last char will dump core
    usally; adb shows dump from extract_dir_from_path() called from
    t_search(); also sometimes happens if: "ls -l ed^D" with no
    in-line editing, which may be cleaner instance to work from.
    But extract_dir_from_path() not used in tcsh, in fact.
	FIX: seems to be same bug as #5 below.
4. ls-F with any argment will dump core, i.e. "ls-F ."
    fix: in sh.nfunc.c, call tglob(v) directly, not via rscan()
	which calls tglob() with char argument instead of char ** arg.
	356c356,358
	<     gflag = 0; rscan(v, tglob);
	---
	>     /* gflag = 0; rscan(v, tglob); */
	>     gflag = 0;
	>     tglob(v);
5. ls-F, if interrupted with ^C, will leave tcsh in state in which
	repeat of ls-F will dump core if size of directory large enough.
	Probably has to do with static items not being FREE_ITEM'd
	after the interrupt.  FIX: make items[] and dir_fd not
	be static, so don't need to be freed.  Seems to work, at
	least with my use as non-login shell.
	In ed.init.c
*** ed.h.1	Thu Aug 20 20:12:40 1987
--- ed.h	Thu Oct  1 15:31:18 1987
***************
*** 95,101 ****
  EXTERN struct tchars testtc;
  EXTERN struct ltchars testlc;
  
! #endif OREO
  
  /****************************/
  /* Editor state and buffers */
--- 95,101 ----
  EXTERN struct tchars testtc;
  EXTERN struct ltchars testlc;
  
! #endif SVID
  
  /****************************/
  /* Editor state and buffers */
*** ed.init.c.1	Wed Sep 30 12:03:38 1987
--- ed.init.c	Sat Oct  3 17:31:20 1987
***************
*** 226,234 ****
  	    *ncp = *tcp;
  	    return 1;
  	}
!     } else {
  	return 0;
-     }
  }
  
  int
--- 226,233 ----
  	    *ncp = *tcp;
  	    return 1;
  	}
!     } else
  	return 0;
  }
  
  int
***************
*** 339,345 ****
  	xlb = testnlb;
  
  	xlb &= ~(LPRTERA | LLITOUT);
! 	xlb |= (LCRTBS | LCRTERA | LCRTKIL | LPASS8);
      }
  
      /* get and set the new local chars */
--- 338,346 ----
  	xlb = testnlb;
  
  	xlb &= ~(LPRTERA | LLITOUT);
! 	if (T_HasMeta)
! 	    xlb |= (LCRTBS | LCRTERA | LCRTKIL | LPASS8);
! 	else xlb |= (LCRTBS | LCRTERA | LCRTKIL);
      }
  
      /* get and set the new local chars */
*** tw.init.c.1	Wed Sep 30 13:57:18 1987
--- tw.init.c	Wed Sep 30 18:04:04 1987
***************
*** 124,130 ****
  #ifdef	OUTDEF
      for (bptr = bfunc; cp = bptr->bname; bptr++) {
  #endif
! 	tw_add_comm_name (cp);
      }
  }
  
--- 124,130 ----
  #ifdef	OUTDEF
      for (bptr = bfunc; cp = bptr->bname; bptr++) {
  #endif
! 	tw_add_comm_name (bptr->bname);
      }
  }
  
*** tw.parse.c.1	Wed Sep 30 11:52:41 1987
--- tw.parse.c	Sun Oct  4 16:54:48 1987
***************
*** 1,6 ****
  #define MAKE_TWENEX		/* flag to include definitions */
- #include "tw.h"
  #include "sh.h"
  
  static int maxitems = 0;
  char **command_list = (char **)NULL;  /* the pre-digested list of commands
--- 1,6 ----
  #define MAKE_TWENEX		/* flag to include definitions */
  #include "sh.h"
+ #include "tw.h"
  
  static int maxitems = 0;
  char **command_list = (char **)NULL;  /* the pre-digested list of commands
***************
*** 176,183 ****
  	    looking_for_lognames;	/* True if looking for login names */
      int	    showpathn;			/* True if we want path number */
      struct stat
! 	    dot_statb,			/* Stat buffer for "." */
! 	    curdir_statb;	       /* Stat buffer for current directory */
      int	    dot_scan,			/* True if scanning "." */
  	    dot_got;			/* True if have scanned dot already */
      char    tilded_dir[FILSIZ + 1],	/* dir after ~ expansion */
--- 176,182 ----
  	    looking_for_lognames;	/* True if looking for login names */
      int	    showpathn;			/* True if we want path number */
      struct stat
! 	    dot_statb;			/* Stat buffer for "." */
      int	    dot_scan,			/* True if scanning "." */
  	    dot_got;			/* True if have scanned dot already */
      char    tilded_dir[FILSIZ + 1],	/* dir after ~ expansion */
***************
*** 190,205 ****
  					/* the list of commands */
      int d = 4, nd;	/* distance and new distance to command for SPELL */
  
!     static DIR 
  	    *dir_fd = NULL;
!     static char
             **items = NULL;		/* file names when doing a LIST */
  
-     if (items != NULL)
- 	FREE_ITEMS (items, numitems);
      numitems = 0;
-     if (dir_fd != NULL)
- 	FREE_DIR (dir_fd);
      looking_for_lognames = (*word == '~') && (index (word, '/') == NULL);
      looking_for_command &= (*word != '~') && (index (word, '/') == NULL);
  
--- 189,200 ----
  					/* the list of commands */
      int d = 4, nd;	/* distance and new distance to command for SPELL */
  
!     DIR 
  	    *dir_fd = NULL;
!     char
             **items = NULL;		/* file names when doing a LIST */
  
      numitems = 0;
      looking_for_lognames = (*word == '~') && (index (word, '/') == NULL);
      looking_for_command &= (*word != '~') && (index (word, '/') == NULL);
  
***************
*** 332,338 ****
      if (!looking_for_command) {		
          if (looking_for_lognames)
  	    endpwent ();
!         else
  	    FREE_DIR (dir_fd);
      }
  
--- 327,333 ----
      if (!looking_for_command) {		
          if (looking_for_lognames)
  	    endpwent ();
!         else if (dir_fd != NULL)
  	    FREE_DIR (dir_fd);
      }
  
***************
*** 381,386 ****
--- 376,382 ----
  	catn (word, extended_name, max_word_length);   /* add extended name */
  	return d;
      }
+     else return 0;	/* jpn: shouldn't occur */
  }
  
  
-- 
John P. Nelson, M.D., 3811 O'Hara St, Pittsburgh, PA 15213, t:412-624-1769 Dept. of Psychiatry, U. of Pittsburgh
UUCP: { akgua | allegra | cmcl2 | idis | ihnp4 | mi-cec | pitt | psuvax1 | sun | sunrise | vax135 } ! cadre ! jack
ARPA: jack@cadre.dsl.pittsburgh.edu

jack@cadre.dsl.PITTSBURGH.EDU (Jack Nelson) (10/06/87)

Here is a better fix for tw.parse.c than the one I posted yesterday;
that first fix has the defect the malloc'd memory never gets freed, so
data size grows too fast.  This one merely makes numitems static instead
of register type, so that FREE_ITEMS() at start of t_search() works
correctly.  The ls-F dump core after ^C is still fixed either way.
Apply this patch after applying the DIFFS.2 for 4.3 recently posted.

*** tw.parse.c.1	Wed Sep 30 11:52:41 1987
--- tw.parse.c	Tue Oct  6 16:06:11 1987
***************
*** 1,6 ****
  #define MAKE_TWENEX		/* flag to include definitions */
- #include "tw.h"
  #include "sh.h"
  
  static int maxitems = 0;
  char **command_list = (char **)NULL;  /* the pre-digested list of commands
--- 1,6 ----
  #define MAKE_TWENEX		/* flag to include definitions */
  #include "sh.h"
+ #include "tw.h"			/* jpn: must follow sh.h for sighold define */
  
  static int maxitems = 0;
  char **command_list = (char **)NULL;  /* the pre-digested list of commands
***************
*** 171,178 ****
         *wp;			/* original end-of-word */
  COMMAND command;
  {
!     register numitems,
! 	    name_length,		/* Length of prefix (file name) */
  	    looking_for_lognames;	/* True if looking for login names */
      int	    showpathn;			/* True if we want path number */
      struct stat
--- 171,178 ----
         *wp;			/* original end-of-word */
  COMMAND command;
  {
!     static int numitems;	/* jpn: static for first FREE_ITEMS() */
!     register name_length,		/* Length of prefix (file name) */
  	    looking_for_lognames;	/* True if looking for login names */
      int	    showpathn;			/* True if we want path number */
      struct stat
***************
*** 332,338 ****
      if (!looking_for_command) {		
          if (looking_for_lognames)
  	    endpwent ();
!         else
  	    FREE_DIR (dir_fd);
      }
  
--- 332,338 ----
      if (!looking_for_command) {		
          if (looking_for_lognames)
  	    endpwent ();
!         else if (dir_fd != NULL)
  	    FREE_DIR (dir_fd);
      }
  
***************
*** 381,386 ****
--- 381,387 ----
  	catn (word, extended_name, max_word_length);   /* add extended name */
  	return d;
      }
+     else return 0;	/* jpn: shouldn't occur */
  }
  
  
-- 
John P. Nelson, M.D., 3811 O'Hara St, Pittsburgh, PA 15213, t:412-624-1769 Dept. of Psychiatry, U. of Pittsburgh
UUCP: { akgua | allegra | cmcl2 | idis | ihnp4 | mi-cec | pitt | psuvax1 | sun | sunrise | vax135 } ! cadre ! jack
ARPA: jack@cadre.dsl.pittsburgh.edu