Hi Darryl,
Let's take a look at your code (below):
On 8/3/2010 4:44 PM, Darryl Freinkel wrote:
if (access(%trimr(path) : F_OK)) = 0;
fd = open( %trimr(path)
: O_APPEND + O_TRUNC + O_CCSID + O_TextData + O_WrOnly
: M_RDONLY
: 819
: 0 );
Else;
The access() verifies that the file exists... so this code is only run
for an existing file.
In the absence of the O_TEXT_CREAT flag (which is the case here) the
O_CCSID flag specifies the CCSID of _the_data_in_your_program_. So you
are telling it here that the code in your program is in CCSID 819 (ASCII).
Most likely that's not true. Most likely, your data is actually EBCDIC
-- but the computer doesn't know that! It'll still try to translate it
to the destination CCSID.
As others have already pointed out... combining O_APPEND with O_TRUNC
doesn't make any sense.
O_TRUNC = Truncate the data in the file. (i.e. clear all
data from the file... analogous to CLRPFM)
O_APPEND = Position to the end of the file (rather than the
default of the start of the file.)
Pointless to specify these together. When the file has been cleared,
there's no distinction between the end and start.
M_RDONLY is pointless because you haven't specified O_CREAT, and no file
is being created here.
The final parameter (which you've specified as 0) is pointless as well,
since you haven't specified O_TEXT_CREAT.
Your ELSE then should run when the file doesn't exist:
fd = open( %trimr(path)
: O_TEXT_CREAT + O_TEXTDATA + O_CREAT
+ O_WRONLY + O_APPEND + O_TRUNC + O_CCSID
: M_RDONLY
: 819
: 0 );
ENDIF;
This has O_CREAT and O_TEXT_CREAT which means that the file will be
created if it doesn't exist. (That's what you want.) However, the
O_APPEND once again doesn't make much sense. If the file doesn't exist,
there can't be any data in it. Likewise, O_TRUNC doesn't make sense here.
O_TEXT_CREAT means that the 4th parameter is the CCSID of the file
you're creating, and the 5th parameter is the CCSID of the data in your
program. Which means your program is EBCDIC (0 = take the job CCSID)
and your file is ASCII (819 = iso-8859-1)
So, other than a few superfluous flags, the open() should work properly
if the file does not exist. It'll only be l00py if the file DOES exist.
But I wonder why you're bothering to handle it differently when the file
does/doesn't exist? Your open() in the ELSE statement should work
properly even if the file exists...
So I'm a bit confused as to why you have the IF/ELSE logic.
Thanks for bearing with me through that long boring description :)
To cut to the chase, my suggestion is that you eliminate the "if access"
logic, and simply do this all the time:
fd = open( %trimr(path)
: O_TEXT_CREAT + O_TEXTDATA + O_CREAT
+ O_WRONLY + O_TRUNC + O_CCSID
: M_RDONLY
: 819
: 0 );
So the file is created if it doesn't exist. It it does exist exist, the
O_TRUNC clears it's data. In either case you're translating from EBCDIC
to ASCII when you write to it.
But... if there's more going on than meets the eye, then you might want
to keep that IF/ELSE logic. (I can't think of a reason why you'd want
to... but if you do...)
if (access(%trimr(path) : F_OK)) = 0;
fd = open( %trimr(path)
: O_TRUNC + O_CCSID + O_TEXTDATA + O_WRONLY
: 0: 0 );
Else;
fd = open( %trimr(path)
: O_TEXT_CREAT + O_TEXTDATA + O_CREAT
+ O_WRONLY + O_CCSID + O_EXCL
: M_RDONLY
: 819
: 0 );
ENDIF;
In the first case, since the file exists, no point in specifying the
M_RDONLY since the file isn't going to be created. Instead, I just
put a 0 there as a placeholder. The 4th parameter is also 0 (not 819!)
because that's the CCSID of your RPG program. The 5th parameter is
removed entirely, since you didn't specify O_TEXT_CREAT.
In the second case, I removed O_APPEND and O_TRUNC since we know the
file doesn't exist. I added O_EXCL (this means "return an error if the
file DOES exist") as a safety net, just in case by some weird chance,
someone creates the file in between the call to access() and the call to
open(). Otherwise, I left the options you had.
So if you need the IF ACCESS/ELSE logic, then I'd do it like that.
But I'd eliminate the IF/ELSE logic and use a single open() call, (as
described above) because it's just simpler.
As an Amazon Associate we earn from qualifying purchases.