scs@adam.mit.edu (Steve Summit) (02/14/91)
In article <1991Feb13.032238.11640@athena.mit.edu>, I wrote: > Don't put the > code for catching SIGTSTP inside #ifdef JOBCONTROL; put it inside > #ifdef SIGTSTP. Settable line disciplines? TIOCSETD. In article <17803:Feb1319:45:0991@kramden.acf.nyu.edu>, Dan Bernstein writes: >I have to disagree. There may be occasional cases where the macros >provided by the system exactly match the features you want to use... I was making a suggestion, not stating a rule. Obviously a program's #ifdef strategy depends on a number of factors particular to the environments in question. I don't think the simple cases are occasional. >you'll never lose anything by sticking to #ifdef JOBCONTROL and putting > > #ifdef SIGTSTP > #define JOBCONTROL > #endif > >inside a .h file. This way someone can (1) figure out what you really >meant while reading the code; (2) change the definitions with as little >work as possible in case you messed up. (What, me mess up? :-) ) The biggest problem people tend to have, when porting code with lots of #ifdefs to a system significantly different from the ones the the original author was used to, is figuring out all the #ifdefs in order to get the -D's and #defines right. Chains of #ifdefs can make the problem much worse. I'm not saying that #ifdef SIGTSTP #define JOBCONTROL #endif is unilaterally bad -- if the code has a bunch of stuff specific to job control other than simply catching SIGTSTP, then a JOBCONTROL macro is a good one to introduce. However, if the code is nice and simple (and that's what we all strive for, right? :-) ), containing merely something like #include <signal.h> ... main() { if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, sigcatcher); #ifdef SIGTSTP if(signal(SIGTSTP, SIG_IGN) != SIG_IGN) signal(SIGTSTP, sigcatcher); #endif ... sigcatcher(sig) int sig; { switch(sig) { case SIGINT: ... #ifdef SIGTSTP: case SIGTSTP: /* fix something up */ kill(getpid(), SIGSTOP); /* revert to funny state */ break; #endif then using anything other than #ifdef SIGTSTP is superfluous. Of course, the easiest #ifdefs to handle are the ones that aren't there at all. Many programs go to great lengths to select among several flavors of a system-dependent feature when they would be better off not having anything to do with that feature in the first place. The folks at Berkeley have actually done a fairly good job of introducing new features transparently -- that is, most programs don't need to know about them. In many cases, though, they have turned around and modified far more application programs than strictly necessary, teaching people (by example) that every interactive program has to know about job control, that every program that walks directories has to know about symbolic links, etc. (Don't follow up to tell me that every program that walks directories *does* have to know about symlinks. I know why they have to, or at least why they think they have to. That's one of the problems with symlinks.) Help break the trend: don't make your programs dependent on system-specific features at all, if you can get away with it. Steve Summit scs@adam.mit.edu