The first step I would try in debugging is using strace or truss to see what arguments are really being passed to the system open function. That should point you in the right direction.
Although this theory has already been debunked, the behavior you're seeing is consistent with O_WRONLY, O_TRUNC, and O_CREAT being undefined or zero. You could try printing the results out before calling sysopen, just to make sure:
print "Flags are ",O_WRONLY|O_TRUNC|O_CREAT,"\n";
On my system, the result is 577.
Also, you've tried the code with changing $self->ascii_error to just die, and with changing $ggg to a fixed value. Why don't you post the exact script you're using with these changes, in a way that any of us can just cut-n-paste to see if we get the same error (instead of making these same changes ourselves, possibly slightly differently than you did)?