Hi Tim, Your question is more appropriate for the RPG400-L mailing list, so I'm replying there. I'm CCing you directly, in case you're not subscribed to RPG400-L
I am trying to use the stat() function and getting a RNQ1211 message on my printer file. The code is:
The stat() API has nothing to do with your printer file. However, any time you call a program or procedure improperly with mismatched parameters (no matter what the procedure does!) you can corrupt memory. Corrupting memory has unpredicable results -- and can cause strange things like the RNQ1211 error you describe, if the corrupted memory happens to be part of the internal work variables that the compiler generates when it generates your program.
Let's look at your code for the stat() API:
D stat PR 10I 0 ExtProc('stat') D path * value options(*string) D buf * value D p_statds S * D statds DS BASED(p_statds) D st_mode 10U 0 D MyStat S like(statds)
stat(rootdir + '/00618':%addr(mystat));
The stat() API requires two parameters. The first is a null-terminated string, and it looks like you're passing that one very nicely.
The second parameter is a data structure that has to be 128 bytes long. The API will always set all 128 bytes of this data structure. It doesn't know how long the variable you've passed is (it can't see your source code!) so it always fills in all 128 bytes.
Your MyStat data structure, however, is only 4 bytes long! So the API will overwrite 124 extra bytes of memory that don't belong to the data structure.
Think about it... all you're passing to the API is the ADDRESS of the data structure. If, for example, the DS happens to have an address of 1000, then your MyStat data structure occupies memory from 1000 - 1003, since it's 4 bytes long.
If the API thinks it's 128 long, it'll overwrite locations 1000-1127! So whatever happens to occupy positions 1004-1127 of memory will get changed to a different value by the API -- even if they have nothing to do with the MyStat data structure.
What's stored in those positions? Who knows. It might happen to be unused memory. It might happen to be other variables in your program. It might even be variables in a different program, all of which would get changed by the stat() API.
In this case, I'm guessing that the internal variable that the RPG runtime uses to keep track of whether a file is open happens to be one of the variables in that area of memory. Just your luck :)
Anyway, the fix is to make MyStat be 128 bytes long, as it's supposed to be. Then the API will overwrite those 128 bytes, and nothing else, and all will be well.
Here's my definition of the stat() API and statds: D stat PR 10I 0 ExtProc('stat') D path * value options(*string) D buf likeds(statds) D statds DS qualified D BASED(Template) D st_mode 10U 0 D st_ino 10U 0 D st_nlink 5U 0 D st_reserved2 5U 0 D st_uid 10U 0 D st_gid 10U 0 D st_size 10I 0 D st_atime 10I 0 D st_mtime 10I 0 D st_ctime 10I 0 D st_dev 10U 0 D st_blksize 10U 0 D st_allocsize 10U 0 D st_objtype 11A D st_reserved3 1A D st_codepage 5U 0 D st_ccsid 5U 0 D st_rdev 10U 0 D st_nlink32 10U 0 D st_rdev64 20U 0 D st_dev64 20U 0 D st_reserved1 36A D st_ino_gen_id 10U 0As you can see, I used likeds() instead of a pointer for the data structure in my definition. This'll help protect you against making the same mistake in the future.
I also used to use a pointer for the 2nd parameter, but I changed to this method about 2 years ago, because it just works better. With these definitions, you'll call the API with the following code:
D mystat ds likeds(statds) . . stat(rootdir + '/00618':mystat); Note that %addr() is no longer necessary with the way I prototyped it. Hope that helps
This mailing list archive is Copyright 1997-2014 by MIDRANGE dot COM and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available here. If you have questions about this, please contact