From: cross@spitfire.i.gajendra.net   
      
   In article <10470be$dalk$1@dont-email.me>,   
   Craig A. Berry wrote:   
   >   
   >On 7/3/25 3:07 PM, Dan Cross wrote:   
   >> In article <1046hc5$62th$2@dont-email.me>,   
   >> Arne Vajhøj wrote:   
   >>> On 7/3/2025 1:40 PM, Dan Cross wrote:   
   >   
   >>>> You refer to `_PATH_DEVNULL` but do not `#include `, as   
   >>>> required by POSIX.   
   >>>   
   >>> This must support non *nix systems (as an example   
   >>> VMS !!) - config.h is expected to provide that with the rest.   
   >>   
   >> If copyright dates are anything to judge by, `` has   
   >> been a thing since 1989, but I was wrong in that it is not   
   >> actually in POSIX: it is a BSD extension, though common.   
   >>   
   >> In general, it is good practice and good hygiene in C programs   
   >> to `#include` the header files that are documented to define the   
   >> symbols and types that you use in your program, instead of   
   >> relying on transitive includes to populate things ambiantly via   
   >> e.g. `config.h`.   
   >>   
   >> Regardless, in that case, you shouldn't use `_PATH_DEVNULL`.   
   >> Note the leading `_`: that signifies a reserved identifier,   
   >> which is not something you should be defining yourself. If you   
   >> want to punt this to e.g. config.h, better would be to define a   
   >> new name (say, `TDS_PATH_DEVNULL`) and use that.   
   >   
   >The code ya'll are talking about replacing:   
   >   
   >https://github.com/FreeTDS/freetds/blob/Branch-1_5/src/replacem   
   nts/vasprintf.c   
   >   
   >does the following:   
   >   
   >#if HAVE_PATHS_H   
   >#include    
   >#endif /* HAVE_PATHS_H */   
   >. . .   
   >#ifndef _PATH_DEVNULL   
   >#define _PATH_DEVNULL "/dev/null"   
   >#endif   
   >   
   >FreeTDS is relying on autoconf to sort out whether paths.h is available   
   >and will only include it if HAVE_PATHS_H is defined in config.h, and   
   >thus only defines _PATH_DEVNULL if it's known not to exist. Obviously   
   >one should avoid making up one's own reserved identifiers and clobbering   
   >documented and well-known names, but that's not really the same thing as   
   >providing an implementation for one that's known to be missing. This   
   >fallback approach could of course be added to Arne's implementation if   
   >desired; to me it seems a lot cleaner than defining yet another macro,   
   >which would need to be defined in terms of _PATH_DEVNULL when it exists   
   >but otherwise not.   
   >   
   >The problem for VMS is that the workaround doesn't work. Or at least it   
   >didn't when I was first porting FreeTDS 20+ years ago because the CRTL   
   >at the time did not recognize '/dev/null' as a valid path. I believe   
   >recentish CRTLs (maybe VMS 8.x and later?) do have special case code   
   >that translates it to the native null device. But that wasn't   
   >available, so I added the following line to the template from which   
   >config.h is generated on VMS:   
   >   
   >#define _PATH_DEVNULL "_NLA0:"   
   >   
   >The main advantage of this approach is that it worked, and it did so   
   >with a one-line change to a file I was already maintaining. I didn't   
   >have to sprinkle '#ifdef __VMS' in files that already existed and were   
   >already working on other platforms. I didn't have to create a lot of new   
   >files, the presence of which in the repository I couldn't test without   
   >autoconf/automake, which I didn't have access to at the time. All of   
   >which meant upstream maintainers were far more likely to accept my changes.   
   >   
   >I'm sure I'll get a lecture about everything I did wrong, but at least   
   >now the context is out there for why it was reasonable for Arne to   
   >depend on prior art, i.e., the presence of _PATH_DEVNULL in config.h.   
      
   Meh. If it works and it's not new code, then that's fine. But   
   I don't see how having a "compat.h" header with something like:   
      
   #ifndef TDS_PATH_DEVNULL   
   #if defined(HAVE_PATHS_H)   
   #include    
   #define TDS_PATH_DEVNULL _PATH_DEVNULL   
   #elif defined(VMS)   
   #define TDS_PATH_DEVNULL "_NLA0:"   
   #else   
   #define TDS_PATH_DEVNULL "/dev/null"   
   #endif   
   #endif   
      
   ...in it is either appreciably different or much cleaner.   
      
   The point isn't to sprinkle VMS-isms all over, but rather, to   
   centralize platform-specifics and provide an application   
   specific portability layer. Given that `_PATH_DEVNULL` is not   
   standard, but _is_ provided by system headers on a lot of   
   systems, using it directly is already injecting a kind of system   
   dependency. By isolating its use as above, you instead decouple   
   that from the rest of the system   
      
   Anyway, not meant to be a lecture, just an observation.   
      
    - Dan C.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|