Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Jul 1998 03:17:06 -0700
From:      Don Lewis <Don.Lewis@tsc.tdk.com>
To:        Terry Lambert <tlambert@primenet.com>, Don.Lewis@tsc.tdk.com (Don Lewis)
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: Code Logic Question in 2.2 RELENG
Message-ID:  <199807011017.DAA05610@salsa.gv.tsc.tdk.com>
In-Reply-To: Terry Lambert <tlambert@primenet.com> "Re: Code Logic Question in 2.2 RELENG" (Jun  5,  6:41pm)

next in thread | previous in thread | raw e-mail | index | archive | help
On Jun 5,  6:41pm, Terry Lambert wrote:
} Subject: Re: Code Logic Question in 2.2 RELENG
} > } Which reminds me.  Someone needs to fix the "siginterrupt" man page.
} > } 
} > } I would, but I think it is FreeBSD that is broken, not the man page,
} > } and that by default, system calls *should* be restarted after a
} > } signal is caught.  I find it utterly bogus that I have to springle
} > } the bejesus out of my code for while()'s and tests for "EINTR" and
} > } manually restart all of my system calls.  Gruds, if I wanted that,
} > } I load System V on my box instead of BSD.
} > 
} > Why not use the POSIX sigaction() call instead of signal().
} 
} The point is not my choice of interface, it's that the siginterrupt(3)
} man page says:
} 
} 	System call restart has been the default behavior since 4.2BSD,
} 	and is the default behaviour on FreeBSD.
} 
} 
} > It seems
} > to be available except for really old systems that you probably don't
} > want to play with anyway.
} 
} Bad call.  I *like* MicroVAX hardware running Ultrix.  I'm the one
} who always complains about changes that make it so a K&R compiler
} on old hardware can't be used to port FreeBSD to that hardware.
} 
} 
} > It also works the same everywhere, unlike signal().
} 
} Only because System V implemented signals wrong.

The original signal() implementation reset the handler to SIG_DFL before
calling the handler, which generally required you to rearm the handler
from within the handler.  System V kept this behaviour and BSD changed
it to something more sane but incompatible.  Some implementations can
do bad things if you rearm the handler from within the handler.  I think
the problem is if you rearm the SIGCLD/SIGCHLD handler before reaping
any waiting processes, the handler gets re-entered.

} > } In The Good Old Days(tm), it wasn't an option; if you wanted EINTR
} > } type behaviour, you did a setjmp before the call you wanted the
} > } behaviour on, and like a decent, God-fearing BSD'er, you called
} > } longjmp from the signal handler to prevent the call from being
} > } restarted.
} > 
} > Ick!  If you leave out a setjmp(), you'll return to the wrong place.
} 
} And if I call memcpy with arguments in bcopy order, I'll get the
} wrong results, too.
} 
} Bad input == bad output.  I don't see your objection.

I think this makes the code harder to maintain.  If you add a new blocking
syscall and forget the setjmp(), you'll intermittently return to the
wrong place in the code, which will be difficult to debug.  Forgetting
to catch EINTR is easier to track down, especially if you are careful
to check return values and errno.

} > This also prevents you from keeping variables in registers, because
} > they won't be restored when you return.
} 
} What system are you running?  Man setjmp(3) says:
} 
} 	All accessible objects have values as of the time longjmp()
} 	routine was called, except that the values of objects of
} 	automatic storage invocation duration that do not have the
} 	volatile type and have been changed between the setjmp()
} 	invocation and longjmp() call are indeterminate.

This is what I'm referring to.  I just love indeterminate code ...

} 	The setjmp()/longjmp() pairs save and restore the signal
} 	mask while _setjmp()/_longjmp() pairs save and restore only
} 	the register set and the stack.  (See sigprocmask(2).)
} 
} > In some implementations you have to remember to do a sigrelse()
} > after returning from setjmp() if you ever want to catch the signal
} > again.
} 
} ???  Which implementations?  I've worked on UNIXen from UTS to
} Microsoft Xenix on Sun 3 hardware to Heurikon's to whatever, and
} I have *never* seen this.

% uname -rs
HP-UX B.10.20

The fine man page sez:

                Before calling the signal-catching handler, the system
                signal action of sig is set to SIG_HOLD.  During a normal
                return from the signal-catching handler, the system signal
                action is restored to func and any held signal of this type
                is released. If a non-local goto (longjmp(3C)) is taken,
                sigrelse() must be called to restore the system signal
                action to func and release any held signal of this type.
 
though on careful reading this applies to sigset(), while signal() just
sets the action back to SIG_DFL.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807011017.DAA05610>