On Jan 1, 2012, at 16:48, Thomas David Rivers wrote:

>> On Dec 30, 2011, at 12:44, Thomas David Rivers wrote:
>>>
>>> This frequently lulls C developers on MVS into believing the
>>> runtime there checks for dereferencing NULL and does something
>>> "meaningful" with it; or that, for example, strlen(NULL) returns
>>> 0...  but nope - it's just luck.
>>>
>> Actually, not entirely.  It was mentioned on MVS-OE several
>> years ago that many UNIX systems keep a 0 at location 00, and
>> many C programmers have come to depend on this behavior, however
>> incorrectly.  IBM got weary of problem reports, "But it works
>> on systems X, Y, and Z" that many library routines that used
>> to report "Invalid Pointer" were modified to substitute ""
>> for NULL and proceed accordingly.
>>
>> -- gil
>>
>
> Hmm - I can't think of a single UNIX implementation that
> does that by default; although I believe there are link-time
> options on Solaris/AIX and HP-UX and that will enable any number
> of facilities to cover-it-up; several of them requiring shared
> libraries.. but, the reader should check for himself.
>
<snip!>

Your example showed inline code.  The change IBM made was for
function arguments.  During the brief interval when I had
before-and-after IBM CRTL to test with, I tried (IIRC)

   open( NULL, ... );

The older CRTL reported that the argument to open() was an
invalid pointer; the newer one (according to the discussion
on MVS-OE) performed a similar check for pointer validity,
but on detecting that it was NULL, substituted "" and tried
to open that pathname, and returned a less lucid error.

I'm not suggesting that any other implementor adopt the
latter behavior; IMO, the older one was preferable.

A recently re-created test program:

cat ../source/openNULL.c      # ###############################################
#include <stdio.h>
#include <errno.h>

int TryIt( char *fname, char *remark ) {

FILE *fn;

errno = 0;
printf( "\narg is %s\n", remark );
fn = fopen( fname, "r" );
perror( fname );
return( fn==0 ); }


int main() {

TryIt( "", "Empty string" );
TryIt( NULL, "NULL Pointer" );
TryIt( ( char * ) -1, "( char * ) -1" );

return( 0 ); }

Run on Solaris:

./openNULL      # ###############################################

arg is Empty string
No such file or directory

arg is NULL Pointer
Bad address

arg is ( char * ) -1
Segmentation Fault(coredump)

And on z/OS:

./openNULL      # ###############################################

arg is Empty string
EDC5129I No such file or directory. (errno2=0xC00B04B3)

arg is NULL Pointer
EDC5129I No such file or directory. (errno2=0xC00B04B3)

arg is ( char * ) -1
CEE3204S The system detected a protection exception (System Completion 
Code=0C4).
        From entry point TryIt at compile unit offset +0000009E at entry offset 
+0000009E at address 48ACC9F6.
[1] + Done(139) ./openNULL
 50332029       Segmentation violation  ./openNULL

Formerly, z/OS gave results similar to Solaris, which I prefer.

-- gil

Reply via email to