3

Reading a text file (which happens to be a PDS Member FB 80)

hFile = fopen(filename,"r");

and have reached up to the point in the file where there is only an empty line left.

FilePos = ftell(hFile);

Then read the last line, which only contains a '\n' character.

fseek(hFile, FilePos, SEEK_SET);

fails with:-

errno=(27) EDC5027I The position specified to fseek() was invalid.

The position specified to fseek() was returned by ftell() a few lines earlier. It has the value 841 in the specific error case I have seen. Checking through the debugger, this is also the value returned by ftell a few lines earlier. It has not been corrupted.

The same code works at other positions in the file, and only fails at the point where there is a single empty line left to read when the position is remembered.

My understanding of how ftell/fseek should work is succinctly captured by another answer on SO.

The value returned from ftell on a text stream has no predictable relationship to the number of characters you have read so far. The only thing you can rely on is that you can use it subsequently as the offset argument to fseek or fseeko to move back to the same file position.

It would seem that I cannot rely on the one thing I should be able to rely on.

My questions is, why does fseek fail in this way?

Morag Hughson
  • 7,255
  • 15
  • 44

2 Answers2

0

As z/OS has some file formats that are unique you might find the answer in this Knowledge Center article.

Given that you are processing a PDS member I would suspect that this is record level I/O which is handled differently than stream I/O which is more common in distributed implementations.

Hogstrom
  • 3,581
  • 2
  • 9
  • 25
  • The POSIX file functions support reading from sequential sources (in this case, a PDS member) in streaming mode. – meat Jul 16 '20 at 18:42
  • @Hogstrom - please note, I am not using the `type=record` open mode parameter. so this is not record level I/O. The PDS member is just a small text file, Fixed Block 80, nothing complicated. – Morag Hughson Jul 20 '20 at 01:53
0

I do not know why fseek fails in this way, but if your common usage pattern is to use ftell to get the position and then fseek to go to that position, I strongly suggest using fgetpos and fsetpos instead for data set I/O. Not only will you avoid this problem that you are finding, but it is also better performing for certain data set characteristics.

meat
  • 609
  • 3
  • 8
  • Thank you - this is in fact what I have done in the mean time, but I would like to get to the bottom of the problem too as it certainly does not seem correct to me. – Morag Hughson Jul 18 '20 at 09:57