[comp.sources.bugs] Patch #2 to Pcomm v1.1

hood@osiris.cso.uiuc.edu (09/16/88)

Here we go again...  This is patch #2 to Pcomm v1.1

This patch will fix the problem that some people are having with 
seqmentation faults (although I'm not convinced the problem isn't
in their compiler).  Also, the problem of the "add line feed after
carriage return" function being set accidently has been fixed.

Emmet P. Gray				US Army, HQ III Corps & Fort Hood
..!uunet!uiucuxc!fthood!egray		Attn: AFZF-DE-ENV
					DEH, Environmental Management Office
					Fort Hood, TX 76544-5057

------------------------------------------------------------------------------
*** old/info.c	Thu Sep 15 12:43:27 1988
--- info.c	Thu Sep 15 12:44:56 1988
***************
*** 5,9
  
  #define VERSION "1.1"
! #define DATE	"13 Sep 88"
  
  #include <stdio.h>

--- 5,9 -----
  
  #define VERSION "1.1"
! #define DATE	"15 Sep 88"
  
  #include <stdio.h>
*** old/main.c	Thu Sep 15 12:43:27 1988
--- main.c	Thu Sep 15 12:44:44 1988
***************
*** 18,21
   *	Release v1.1	21 Aug 88
   *	  patch #1	13 Sep 88
   */
  

--- 18,22 -----
   *	Release v1.1	21 Aug 88
   *	  patch #1	13 Sep 88
+  *	  patch #2	15 Sep 88
   */
  
*** old/port.c	Thu Sep 15 12:44:07 1988
--- port.c	Thu Sep 15 12:41:14 1988
***************
*** 214,218
  	}
  					/* remove the lock */
! 	if (*lock_path != NULL && lock_path != NULL) {
  		if (unlink(lock_path)) {
  			sprintf(buf, "\"%s\"", lock_path);

--- 214,218 -----
  	}
  					/* remove the lock */
! 	if (lock_path != NULL && *lock_path != NULL) {
  		if (unlink(lock_path)) {
  			sprintf(buf, "\"%s\"", lock_path);
*** old/terminal.c	Thu Sep 15 12:44:20 1988
--- terminal.c	Thu Sep 15 12:26:14 1988
***************
*** 40,43
  	resetterm();
  	term_mode();
  
  	if (input_status)

--- 40,44 -----
  	resetterm();
  	term_mode();
+ 	cr_lf = !strcmp(param->cr_out, "CR/LF");
  
  	if (input_status)

ok@quintus.uucp (Richard A. O'Keefe) (09/16/88)

In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
>This patch will fix the problem that some people are having with 
>seqmentation faults (although I'm not convinced the problem isn't
>in their compiler).

It isn't.  It's the famous *NULL bug.

>! 	if (*lock_path != NULL && lock_path != NULL) {

This only tests whether lock_path is legal *after* trying to use it!

paula@bcsaic.UUCP (Paul Allen) (09/21/88)

In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
>>This patch will fix the problem that some people are having with 
>>seqmentation faults (although I'm not convinced the problem isn't
>>in their compiler).
>
>It isn't.  It's the famous *NULL bug.
>
>>! 	if (*lock_path != NULL && lock_path != NULL) {
>
>This only tests whether lock_path is legal *after* trying to use it!

I've now seen a couple postings about this bug, but nobody has got it
right yet!  What has been missed is that C makes no guarantee about the
order of expression evaluation.  The only safe way to perform this test
is using two nested if statements.

I'll be quiet now.
Paul

-- 
------------------------------------------------------------------------
Paul L. Allen                       | paula@boeing.com
Boeing Advanced Technology Center   | ...!uw-beaver!ssc-vax!bcsaic!paula

mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
>>
>>>! 	if (*lock_path != NULL && lock_path != NULL) {
>>
>>This only tests whether lock_path is legal *after* trying to use it!
> 
> I've now seen a couple postings about this bug, but nobody has got it
> right yet!  What has been missed is that C makes no guarantee about the <--
> order of expression evaluation.  The only safe way to perform this test <--
> is using two nested if statements.					  <--

from page 19 of K&R (1978 ed.)

	Expressions connected by && or || are evaluated
	left to right
	^^^^^^^^^^^^^
furthermore, "!=" has higher precedence than "&&" so

	if (lock_path != NULL && *lock_path != NULL)

is correct.

Mike Khaw
-- 
internet: mkhaw@teknowledge.arpa
uucp:	  {uunet|sun|ucbvax|decwrl|uw-beaver}!mkhaw%teknowledge.arpa
hardcopy: Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

news@amdcad.AMD.COM (Network News) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
| In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
| >In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
| >>This patch will fix the problem that some people are having with 
| >>seqmentation faults (although I'm not convinced the problem isn't
| >>in their compiler).
| >
| >It isn't.  It's the famous *NULL bug.
| >
| >>! 	if (*lock_path != NULL && lock_path != NULL) {
| >
| >This only tests whether lock_path is legal *after* trying to use it!
| 
| I've now seen a couple postings about this bug, but nobody has got it
| right yet!  What has been missed is that C makes no guarantee about the
| order of expression evaluation.  The only safe way to perform this test
| is using two nested if statements.

No.  Check your reference again: the operators '&&' '||' ',' all
guarantee left-to-right evaluation of the operands.  This type of
expression is the main reason why && and || are short-circuit
evaluators.  The fix is correctly written:

	if (lock_path != NULL && *lock_path != NULL)

or, if you prefer:

	if (lock_path && *lock_path)


	-- Tim Olson
	Advanced Micro Devices
	(tim@crackle.amd.com)

jlo@elan.UUCP (Jeff Lo) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
>In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>>In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
>>>! 	if (*lock_path != NULL && lock_path != NULL) {
>>
>>This only tests whether lock_path is legal *after* trying to use it!
>
>I've now seen a couple postings about this bug, but nobody has got it
>right yet!  What has been missed is that C makes no guarantee about the
>order of expression evaluation.  The only safe way to perform this test
>is using two nested if statements.

In most cases the order of evaluation is undefined. The exceptions
are &&, ||, ?:< and ','. So here you would want to reverse the order
of the original expression to make it correct; i.e.:

 	if (lock_path != NULL && *lock_path != NULL) {

In this case, if lock_path is equal to NULL, the second part of the
expression would never be evaluated, and you would never indirect
through the NULL pointer. You don't need to use nested if's. See the
section of K&R that deals with precedence, and the Reference Manual
section of K&R that discusses each of the operators for which the
order of evaluation is guaranteed.
-- 
Jeff Lo
..!{ames,hplabs,uunet}!elan!jlo
Elan Computer Group, Inc.
(415) 322-2450

kjk@pbhyf.PacBell.COM (Ken Keirnan) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
>In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
>>In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
[ stuff deleted ]
>>
>>>! 	if (*lock_path != NULL && lock_path != NULL) {
>>
>>This only tests whether lock_path is legal *after* trying to use it!
>
>I've now seen a couple postings about this bug, but nobody has got it
>right yet!  What has been missed is that C makes no guarantee about the
>order of expression evaluation.  The only safe way to perform this test
>is using two nested if statements.
>
>I'll be quiet now.
>Paul

Paul, I quote from the UNIX System V Programmers Guide section on the
"C" Language:

    The "&&" operator groups left to right.  It returns 1 if both
    its operands evaluate to nonzero, 0 otherwise.  Unlike the "&",
    "&&" guarantees left to right evaluation; moreover, the second
    operand is not evaluated if the first operand evaluates to 0.

    The operands need not have the same type, but each must have one
    of the fundamental types or be a pointer.  The result is always
    "int".

I hope this clears up some confusion.  If your compiler produces code
that doesn't correctly evaluate the above expression, its broke.

Ken Keirnan
-- 

Ken Keirnan - Pacific Bell - {att,bellcore,sun,ames,pyramid}!pacbell!pbhyf!kjk
  San Ramon, California	                    kjk@pbhyf.PacBell.COM

paula@bcsaic.UUCP (Paul Allen) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
>>
>>>! 	if (*lock_path != NULL && lock_path != NULL) {
>>
>>This only tests whether lock_path is legal *after* trying to use it!
>
>I've now seen a couple postings about this bug, but nobody has got it
>right yet!  What has been missed is that C makes no guarantee about the
>order of expression evaluation.  The only safe way to perform this test
>is using two nested if statements.
>
>I'll be quiet now.
>Paul

I should have kept my mouth shut!  I just found messages in my inbox from
Rich $alz and Bob Wilber (thanks, guys!) pointing out my error.  What I
remembered reading is on page 49 of K&R:

	"C, like most languages, does not specify in what order the
	operands of an operator are evaluated."

However, in Appendix A we find:

	"Unlike &, && guarantees left-to-right evaluation; moreover the
	second operand is not evaluated if the first operand is 0."

Geez, just think of all the keystrokes I've wasted on coding nested if's
to test for NULL pointers!  :-)

And now, as evening settles in and I prepare to wend my way home, 
countless messages of gentle correction are journeying through the
night, passing swiftly from machine to machine, unswervingly intent
upon filling my mailbox with joy!  Ain't the net wonderful?

Paul
-- 
------------------------------------------------------------------------
Paul L. Allen                       | paula@boeing.com
Boeing Advanced Technology Center   | ...!uw-beaver!ssc-vax!bcsaic!paula

tnphhbu@dutrun.UUCP (Hans Buurman) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
>I've now seen a couple postings about this bug, but nobody has got it
>right yet!  What has been missed is that C makes no guarantee about the
>order of expression evaluation.  The only safe way to perform this test
>is using two nested if statements.

In <The C Programming Language (2nd edition), p. 21>, Kernighan &
Ritchie write:
>Expressions connected by && or || are evaluated left to right, and it is
>guaranteed that evaluation will stop as soon as the truth or falsehood
>is known.
This is repeated on page 49, and on 207-208.

Hans Buurman
hans@duttnph.uucp or mcvax!dutrun!duttnph!hans
Disclaimer: any opinions expressed above are those of Allen, Kernighan &
Ritchie. (aren't they ?)

danny@itm.UUCP (Danny) (09/22/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
~In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
~>
~>It isn't.  It's the famous *NULL bug.
~>
~>>! 	if (*lock_path != NULL && lock_path != NULL) {
~>
~>This only tests whether lock_path is legal *after* trying to use it!
~
~I've now seen a couple postings about this bug, but nobody has got it
~right yet!  What has been missed is that C makes no guarantee about the
~order of expression evaluation.  The only safe way to perform this test
~is using two nested if statements.

    Sorry, wrong.  See page 190, section 7.11: "Logical AND operator"
in K&R.  "Unlike &, && guarantees left-to-right evaluation; moreover
the second operand is not evaluated if the first operand is 0."

    The above line should read:
     	if (lock_path != NULL && *lock_path != NULL) {
            -or-
      if (lock_path && *lock_path) {
    
    Left to right evaluation of logical connectives and short-circuiting
is one of the nicest aspects of C!  If your compiler doesn't do it, it's
not a C compiler.  Complain loudly to your vendor.

                                    Danny
-- 
				Daniel S. Cox
				(seismo!gatech!itm!danny)

mcneill@eplrx7.UUCP (Keith McNeill) (09/22/88)

In article <7782@bcsaic.UUCP>, paula@bcsaic.UUCP (Paul Allen) writes:
> In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
> >In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
> >
> >>!   if (*lock_path != NULL && lock_path != NULL) {
> >
> >This only tests whether lock_path is legal *after* trying to use it!
>
> I've now seen a couple postings about this bug, but nobody has got it
> right yet!  What has been missed is that C makes no guarantee about the
> order of expression evaluation.  The only safe way to perform this test
> is using two nested if statements.
>
> I'll be quiet now.
> Paul

WRONG WRONG WRONG...

"Expressions connnected by && or || are evaluated left to right, and evaluation
stops as soon as the truth or falsehood of the result is known." (K&R PG 38)

You seem to have been confused by the fact that "C, like most languages, does
not specify in what order the operands of an operator evaluated." (K&R PG 49)

(FLA..FLA..FLA.....FLAME ON)
Would hate to see your code with all those nested if-statements....
If only you had read the words of the prophets Brian & Dennis.
(FLAME OFF) 

We'll be quiet now.

Keith & Thom

			
-- 
    Keith D. McNeill              |    E.I. du Pont de Nemours & Co.
    uunet!eplrx7!mcneill          |    Experimental Station
    (302) 695-7395                |    P.O. Box 80357
                                  |    Wilmington, Delaware 19880-0357

kent@happym.UUCP (Kent Forschmiedt) (09/23/88)

In article <7782@bcsaic.UUCP> paula@bcsaic.UUCP (Paul Allen) writes:
[ argument about whether:
 	if (*lock_path != NULL && lock_path != NULL) {
 is correct... ]

>I've now seen a couple postings about this bug, but nobody has got it
>right yet!  What has been missed is that C makes no guarantee about the
>order of expression evaluation.  The only safe way to perform this test
>is using two nested if statements.
>
>I'll be quiet now.

Please do.

It doesn't bother me that most  people do not know C, but I am dismayed 
that so many people seem so bent on displaying their ignorance.  I am 
not just picking on you, Paul - lots of people have blown this one. 

I wish that anyone, before offering information as fact, would be sure 
that said information is factual.  Compilers are not democratic; they do 
not care for the opinions of the unwashed masses. 


Appendix A, 7.11:
"The && operator groups left-to-right.  It returns 1 if both its operands are 
non-zero, 0 otherwise.  Unlike &, && guarantees left-to-right evaluation; 
moreover the second operand is not evaluated if the first operand is 0. 
 The operands need not have the same type, but each must have one of the 
fundamental types or be a pointer.  The result is always int." 

 -- Reproduced without permission from "The C Programming Language",
 Kernighan and Ritchie, 1978

-- 
  kent@happym.UUCP, tikal!camco!happym!kent, Happy Man Corp. USA 206-282-9598

felix@netmbx.UUCP (Felix Gaehtgens) (09/26/88)

In article <3957@pbhyf.PacBell.COM> kjk@pbhyf.PacBell.COM (Ken Keirnan) writes:
hi!

well, i guess everyone has managed to patch port.c by now ;-)
the bug that distracts me most, though is that i am not getting anything
back from the modem, it doesn't appear on the screen. i checked curses.c
already and #defined WGETCH_BROKE but that doesn't seem to be the solution...

has anyone got it to work on uport sysv/286 yet?

so long,
		felix

davidsen@steinmetz.ge.com (William E. Davidsen Jr) (09/28/88)

In article <25069@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:

| from page 19 of K&R (1978 ed.)
| 
| 	Expressions connected by && or || are evaluated
| 	left to right
| 	^^^^^^^^^^^^^
| furthermore, "!=" has higher precedence than "&&" so
| 
| 	if (lock_path != NULL && *lock_path != NULL)
| 
| is correct.

  Bear in mind that NULL is not always zero, but rather that zero cast
to a pointer type is always NULL. Comparing NULL with data types other
than pointers may (a) produce slow code or (b) produce code which
doesn't work correctly. I would suggest that:

 	if (lock_path != NULL && *lock_path != '\0')

is easier to read and will avoid having the char->int->pointer
conversion done at runtime.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

allbery@ncoast.UUCP (Brandon S. Allbery) (09/30/88)

As quoted from <7782@bcsaic.UUCP> by paula@bcsaic.UUCP (Paul Allen):
+---------------
| In article <416@quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
| >In article <13900004@osiris.cso.uiuc.edu> hood@osiris.cso.uiuc.edu writes:
| >>This patch will fix the problem that some people are having with 
| >>seqmentation faults (although I'm not convinced the problem isn't
| >>in their compiler).
| >
| >It isn't.  It's the famous *NULL bug.
| >
| >>! 	if (*lock_path != NULL && lock_path != NULL) {
| 
| I've now seen a couple postings about this bug, but nobody has got it
| right yet!  What has been missed is that C makes no guarantee about the
| order of expression evaluation.  The only safe way to perform this test
| is using two nested if statements.
+---------------

C makes no guarantee about the order of expression evaluation IN GENERAL.
However, it DOES guarantee the evaluation order of && and ||, as they are
intended not to evaluate the expression on the right of the expression on
the left is sufficient to determine the value of the compound expression
(i.e. for "&&" the LHS is zero, for "||" the LHS is non-zero).  Check out
K&R, Appendix A, sections 7.11 (&&) and 7.12 (||).

++Brandon
-- 
Brandon S. Allbery, uunet!marque!ncoast!allbery			DELPHI: ALLBERY
	  For comp.sources.misc send mail to <backbone>!sources-misc
comp.sources.misc is moving off ncoast -- please do NOT send submissions direct
ncoast's days are numbered -- please send mail to ncoast!system if you can help