[net.bugs.usg] "tabs" and "tput" assume TERM is set

guy@sun.uucp (Guy Harris) (07/24/85)

Both of them assume, at some point, that getenv("TERM") will never return a
NULL.  Regardless of whether the S5 Interface Definition says it'll always
be set or not, it's really dumb to assume it'll never happen...  (Also,
"tput" didn't declare "getenv".)

*** tabs.c.BAK	Thu May  2 10:22:04 1985
--- tabs.c	Tue Jul 23 17:15:30 1985
***************
*** 126,133
  		else
  			tabspec = scan;		/* save tab specification */
  	}
! 	if (*terminal == '\0')
! 		terminal = getenv("TERM");
  #ifdef pdp11
  	if(*terminal == '\0') err = -1;	/*setupterm (libcurses/terminfo) problem on pdp11*/
  	else		/*doesn't detect error if terminal is null*/

--- 126,137 -----
  		else
  			tabspec = scan;		/* save tab specification */
  	}
! 	if (*terminal == '\0') {
! 		if ((terminal = getenv("TERM")) == NULL) {
! 			fprintf(stderr, "tabs: No terminal type variable TERM in the environment\n");
! 			exit(1);
! 		}
! 	}
  #ifdef pdp11
  	if(*terminal == '\0') err = -1;	/*setupterm (libcurses/terminfo) problem on pdp11*/
  	else		/*doesn't detect error if terminal is null*/

*** tput.c.BAK	Wed Jan 30 20:04:51 1985
--- tput.c	Tue Jul 23 18:36:19 1985
***************
*** 22,27
  	int err;
  	int xcode;
  	char cap[40];
  	
  	if (!((argc == 2 && argv[1][0] != '-') ||
  	 (argc == 3 && strncmp(argv[1],"-T",2) == 0 && strlen(argv[1]) > 2))) {

--- 22,29 -----
  	int err;
  	int xcode;
  	char cap[40];
+ 	register char *termp;
+ 	extern char *getenv();
  	
  	if (!((argc == 2 && argv[1][0] != '-') ||
  	 (argc == 3 && strncmp(argv[1],"-T",2) == 0 && strlen(argv[1]) > 2))) {
***************
*** 30,36
  	}
  	if (argc == 3) {
  		strcpy(cap,argv[2]);
! 		setupterm(&argv[1][2],1,&err);
  	}
  	else {
  		strcpy(cap,argv[1]);

--- 32,38 -----
  	}
  	if (argc == 3) {
  		strcpy(cap,argv[2]);
! 		termtype = &argv[1][2];
  	}
  	else {
  		strcpy(cap,argv[1]);
***************
*** 34,40
  	}
  	else {
  		strcpy(cap,argv[1]);
! 		setupterm(0,1,&err);
  	}
  	if (err <= 0)
  	{

--- 36,45 -----
  	}
  	else {
  		strcpy(cap,argv[1]);
! 		if ((termtype = getenv("TERM")) == 0) {
! 			fprintf(stderr, "tput: No terminal type variable TERM in the environment\n");
! 			exit(-2);
! 		}
  	}
  	setupterm(termtype,1,&err);
  	if (err <= 0)
***************
*** 36,41
  		strcpy(cap,argv[1]);
  		setupterm(0,1,&err);
  	}
  	if (err <= 0)
  	{
  	    if (argc == 3) {

--- 41,47 -----
  			exit(-2);
  		}
  	}
+ 	setupterm(termtype,1,&err);
  	if (err <= 0)
  	{
  	    fprintf(stderr,"tput: unknown terminal \"%s\"\n",termtype);
***************
*** 38,51
  	}
  	if (err <= 0)
  	{
! 	    if (argc == 3) {
! 		fprintf(stderr,"tput: unknown terminal \"%s\"\n",&argv[1][2]);
! 		exit(-2);
! 	    }
! 	    else {
! 		fprintf(stderr,"tput: unknown terminal \"%s\"\n",getenv("TERM"));
! 		exit(-2);
! 	    }
  	}
  	xcode = capindex(cap);
  	resetterm();

--- 44,51 -----
  	setupterm(termtype,1,&err);
  	if (err <= 0)
  	{
! 	    fprintf(stderr,"tput: unknown terminal \"%s\"\n",termtype);
! 	    exit(-2);
  	}
  	xcode = capindex(cap);
  	resetterm();

hansen@pegasus.UUCP (Tony L. Hansen) (07/27/85)

In article <2484@sun.uucp> guy@sun.uucp (Guy Harris) writes:
>Both of them assume, at some point, that getenv("TERM") will never return a
>NULL.  Regardless of whether the S5 Interface Definition says it'll always
>be set or not, it's really dumb to assume it'll never happen...  (Also,
>"tput" didn't declare "getenv".)
>

Actually, both of these programs pass that work on to setupterm() to notice
that getenv() may have returned a NULL. Setupterm() then handles it
gracefully.

Agreed that getenv() should have been declared.

You did not note that the setupterm(0,...) should really have been
setupterm((char*)0,...); probably because your changes got rid of the line.

Nor did you note that tabs copies the information from the terminfo
structure into its own local buffers which are much too small for some
terminal entries. It should either declare the buffers larger, just use the
terminfo entries where appropriate, or use char pointers instead of strcpy()
into the buffer.


					Tony Hansen
					pegasus!hansen

guy@sun.uucp (Guy Harris) (07/31/85)

> In article <2484@sun.uucp> guy@sun.uucp (Guy Harris) writes:
> >Both of them assume, at some point, that getenv("TERM") will never return a
> >NULL.  Regardless of whether the S5 Interface Definition says it'll always
> >be set or not, it's really dumb to assume it'll never happen...  (Also,
> >"tput" didn't declare "getenv".)
> 
> Actually, both of these programs pass that work on to setupterm() to notice
> that getenv() may have returned a NULL. Setupterm() then handles it
> gracefully.

By handing an error code back to "tput", instead of printing a message.
"Tput" then proceeds to print an error message using "getenv" *WITHOUT*
checking for "getenv" being null.  It should do this check if for no other
reason than to give a meaningful error message:

	No such terminal: unknown

(as "setupterm" would print if no error return were specified) or

	tput: unknown terminal "unknown"

just won't do;

	TERM not specified in environment

or some translation of that into a human language is required (so the user
knows *why* the program is complaining and can correct the problem
immediately, instead of having to call in a guru and engaging in a 5-minute
dialogue the result of which is that the guru, rather annoyed by getting
dragged in on a trivial matter like this, finally figures out that the guy
didn't set TERM - or that the system can't do it for them).  Since it has to
call "getenv" anyway (unless a "-T" flag was specified), it might as well
pass the result on to "setupterm" and save it the trouble.

	Guy Harris