lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) (05/25/89)
Do all vendors still document the return code of signal and
sigvec as being -1 (implicitely an int)? My problem with this is
that if you try to be a "good" programmer and check for an error as
in
if(signal(SIGINT, SIG_IGN) == -1){
perror("signal");
exit(1);
}
say, you will either get a warning or an error, depending on how smart
your compiler is. Why not document the error return as being something
along the lines of SIG_ERR, where SIG_ERR is defined as
#define SIG_ERR ((int(*)())-1)
in <signal.h>?
gwyn@smoke.BRL.MIL (Doug Gwyn) (05/25/89)
In article <8044@batcomputer.tn.cornell.edu> lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) writes: >Why not document the error return as being something >along the lines of SIG_ERR, where SIG_ERR is defined as >#define SIG_ERR ((int(*)())-1) >in <signal.h>? That's exactly what pANSI X3.159 requires (the macro, not the particular value), except you have the type wrong -- it should be ((void(*)())-1). Some older <signal.h>s also use the wrong types; we got AT&T to fix theirs with SVR3, and other vendors will also need to straighten this out for ANSI C and POSIX conformance. Since you can't count on SIG_ERR being defined by non-ANSI <signal.h>, what you should write is #include <signal.h> #ifndef SIG_ERR /* assume the traditional implementation */ #define SIG_ERR ((void(*)())-1) #endif
karl@haddock.ima.isc.com (Karl Heuer) (05/26/89)
In article <10319@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <8044@batcomputer.tn.cornell.edu> lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) writes: >>Why not document the error return as being something [like] >>#define SIG_ERR ((int(*)())-1) > >That's exactly what pANSI X3.159 requires (the macro, not the particular >value), except you have the type wrong -- it should be ((void(*)())-1). Actually, it's ((void (*)(int))-1), but the above is the next best approximation if you don't have prototypes. Interestingly, though, certain implementations that provide the "software signal" package (gsignal/ssignal) now have a problem, because this package really does use int-valued handlers. (The return value is examined by the implementation, to decide whether the condition has been properly handled.) Unfortunately, they also attempt to use the same header file and macro names, so there's a type clash. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
diamond@diamond.csl.sony.junet (Norman Diamond) (05/26/89)
In article <8044@batcomputer.tn.cornell.edu> lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) writes: > Do all vendors still document the return code of signal and >sigvec as being -1 (implicitly an int)? Probably not -- but you do need to know that it is implicitly an int. >My problem with this is >that if you try to be a "good" programmer and check for an error as >in > if(signal(SIGINT, SIG_IGN) == -1){ > perror("signal"); > exit(1); > } >say, you will either get a warning or an error, depending on how smart >your compiler is. In order to do this test properly, maybe it is necessary to cast the result of signal to an (int), and compare to -1. After all, the value of an int does not have to be divisible by 4. Though I still wonder, since signal is returning a pointer to a function, how does signal get a -1 into that address register without aborting (on some machines). >Why not document the error return as being something >along the lines of SIG_ERR, where SIG_ERR is defined as > >#define SIG_ERR ((int(*)())-1) > >in <signal.h>? SIG_IGN has this definition in <signal.h>, last time I looked. And now, besides wondering how signal gets a wierd address into a certain register, I also wonder how the cast does it in the compiled code. Why doesn't the compiled code abort? Why doesn't the compiler notice that an odd address cannot be a function pointer? In short, why does this work? (Also, does ANSI require such nonsense to work, does ANSI require exceptions to be permitted to the usual rules for pointers, or can <signal.h> define values that are at least aligned, even if not guaranteed to be in a legal segment.....) -- Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.co.jp@relay.cs.net) The above opinions are my own. | Why are programmers criticized for If they're also your opinions, | re-implementing the wheel, when car you're infringing my copyright. | manufacturers are praised for it?
gwyn@smoke.BRL.MIL (Doug Gwyn) (05/28/89)
In article <10287@socslgw.csl.sony.JUNET> diamond@csl.sony.junet (Norman Diamond) writes: >In article <8044@batcomputer.tn.cornell.edu> lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) writes: >In order to do this test properly, maybe it is necessary to cast the >result of signal to an (int), and compare to -1. No! The same problem arises on UNIX systems where the result of sbrk() is being tested. These functions return error indications that, when they can be expressed in C at all, have the form ((some_pointer)-1). That is what you should test for; not all implementations permit pointers to be cast to ordinary (int). The real solution is for some system header to define a macro, like SIG_ERR, for use in performing such tests in your application source. On some architectures the value of such a macro may have nothing to do with "-1" in any form. SIG_ERR can always be implemented, e.g.: /* <signal.h>: */ /* ... */ extern void __dummy(int); /* in C run-time library */ #define SIG_ERR __dummy >Why doesn't the compiled code abort? Why doesn't the compiler notice >that an odd address cannot be a function pointer? In short, why does >this work? (Also, does ANSI require such nonsense to work, does ANSI >require exceptions to be permitted to the usual rules for pointers, >or can <signal.h> define values that are at least aligned, ... The C Standard certainly does not require that an arbitrary integer can be successfully cast to a pointer. The rules for when this works and when it doesn't are up to the implementation. Many byte-addressable architecture implementations of C permit casting arbitrary integers to pointers, although an attempt to actually access a function or object via a garbage pointer value may very well fail.
tps@chem.ucsd.edu (Tom Stockfisch) (05/28/89)
In article <8044@batcomputer.tn.cornell.edu> lijewski@batcomputer.tn.cornell.edu (Mike Lijewski) writes: _ Do all vendors still document the return code of signal and _sigvec as being -1 (implicitely an int)? My problem with this is _that if you try to be a "good" programmer and check for an error as _in _ if(signal(SIGINT, SIG_IGN) == -1){ _ perror("signal"); _ exit(1); _ } _say, you will either get a warning or an error, depending on how smart _your compiler is. Why not document the error return as being something _along the lines of SIG_ERR, where SIG_ERR is defined as _#define SIG_ERR ((int(*)())-1) _in <signal.h>? This last cast gets warnings from many compilers (e.g. gcc). Why isn't this implemented without the potentially unportable and kludgey cast of -1? signal.h: int SIG_ERR(), SIG_IGN(), SIG_DFL(); signal.c: int SIG_ERR(){assert(0);} int SIG_IGN(){assert(0);} int SIG_DFL(){assert(0);} -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu