leanid.chaika
leanid.chaika

Reputation: 2442

Why POSIX allows seeking beyond the existing end of file (fseek) for read only mode

Why seek over end of file can be usefull? Why POSIX let to seek like in example in file opened for read only?

c++: http://en.cppreference.com/w/c/io/fseek posix: https://www.unix.com/man-page/posix/3P/fseek/

Next code I test on MinGW-64w

#include <cassert>
#include <cstdio>
#include <cstring>

int main() {
  std::FILE* f = std::fopen("tmp_file.txt", "wb");
  auto result = std::fwrite("1", 1, 1, f);
  assert(result == 1);
  result = std::fclose(f);
  assert(result == 0);

  f = std::fopen("tmp_file.txt", "rb");  // READ ONLY binary mode
  result = std::fseek(f, 100500, SEEK_SET);
  assert(result == 0);  // WHY I can seek to not existing position in file?
                        // opended in READ_ONLY mode?
  char buff[100500] = {0};
  result = std::fread(&buff, sizeof(buff), 1, f);
  printf("result = %zu, errno: %s ferror(f): %d feof(f): %d", result,
         std::strerror(errno), std::ferror(f), std::feof(f) != 0);

  return result;
}

Upvotes: 3

Views: 1648

Answers (2)

Steve Summit
Steve Summit

Reputation: 47952

As you know, seeking beyond the end of a writable file, and then writing, extends the file. I presume your question is that you wouldn't want to extend a file that's merely open for reading, since extending is a modification.

But just seeking beyond the end of a writable file doesn't extend it -- it's seeking and then writing. Seeking just sets the read/write point.

So seeking beyond the end of a file while reading sets the read point, which is just a number in a data structure, so I guess no one was worried about checking it for validity. If you seek beyond the end of a readable file and then try to write, you get an error ("file not open for writing"), and if you seek beyond the end of a readable file and then read, you simply get EOF. In neither case do you extend or otherwise alter the file.

(You might also wonder, what happens if you seek beyond the end of a readable file that some other process is writing, and then that other process writes some more to "fill in" up to the point you seeked to, and then you try to read? That's an interesting question. I suspect it would work, but I haven't tried it.)

Upvotes: 6

John Bollinger
John Bollinger

Reputation: 180266

Why seek over end of file can be usefull?

Whether it is useful or not in general depends on implementation. C and C++ do not specify that such an action must succeed, though POSIX does, as you seem to be aware. Even in non-POSIX C, however,

If a read or write error occurs [within fseek], the error indicator for the stream is set and fseek fails

(C2011 7.21.9.2/2), and

a successful call to the fseek function undoes any effects of the ungetc function on the stream, clears the end-of-file indicator for the stream

(C2011 7.21.9.2/5). These side effects are potentially desirable even if the fseek leaves the file in an odd (but valid) state. That notwithstanding, your question

Why POSIX let to seek like in example in file opened for read only?

suggests that you think perhaps fseek ought to fail if it otherwise would position the (read only) file at a point where no data can be read. But why make a special case for that? A file open for both reading and writing can (according to POSIX) be positioned past its end, and reading it then is not particularly different from reading a similarly-positioned read-only file.

Making fseek's behavior consistent across all seekable files is of more worth than you seem to appreciate.

Upvotes: 7

Related Questions