question on lseek

I was surprised when I read the documentation for lseek. I've been searching for examples on the std library to learn if the lseek behavior is similar to that of the seekp or seekg functions. With the seekp function, if you specify seekp(20, ios_base::end) does that increase the size of the file by 20 bytes? I always thought that would seek from the end towards the beginning of the existing file. I didn't know that you could increase the size of the file using lseek. The documentation for lseek states that when SEEK_END is specified, the position is moved to the EOF + offset. Is this also how the std library seek functions work? I've never really tried to do anything like that and I didn't see any examples on this website that uses seek in that way.
It's undefined. In my experience, a seekp call will eventually result in a call to lseek on Unix (through filebuf::seekoff), but there is no guarantee that it must be. The filebuf could be implemented in terms of memory mapped IO rather than file IO, and may not do lseek at all.
I don't understand. When specifying ios_base::end during the seekp, what is the behavior supposed to be? seekp has to work the same way on every system regardless of whether it uses lseek under the covers or not.
If you use Linux, try this program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <fstream>
#include <cstring>
#include <cerrno>

int main()
{
    std::ofstream myCerr("/dev/fd/2");
    
    myCerr.exceptions(std::ios::failbit | std::ios::badbit);
    
    try
    {
        myCerr.seekp(20, std::ios_base::end);
        myCerr << "output" << std::endl;
    }
    catch (std::ios::failure& ex)
    {
        std::cout << strerror(errno) << std::endl;
    }

    return 0;
}


There is no guarantee the the file you open is seekable to begin with. On Linux, the seekp() call actually succeeds. It's the write that trips it up.
I don't really use linux. To be honest, I am writing code for a real-time OS that happens to provide posix interfaces and the documentation was confusing me. I still don't know what this line is supposed to do, according to the c++ standard. It should work the same on all platforms that correctly implement the c++ std. My point was that the lseek documentation is more explicit about the SEEK_END request where the documentation that I have found on the seekp has been vague on the subject. My reading on the subject of lseek led me to question what I understood about seekp. I'll have to try writing some code on my own and experimenting with it. I was hoping for a quicker answer as well as some more definitive documentation about how seekp works.
myCerr.seekp(20, std::ios_base::end);
You can only rely on the seekp documentation. There are no guarantees about what may or may not happen when calling seekp past the end of file.

It should work the same on all platforms that correctly implement the c++ std.


If only it were so. But, no, the standard does not define this behavior. Anything can happen. This is one of the pitfalls of writing portable code. You have to know where the standards leave you in uncharted territory.

If you need to extend a file, the POSIX-ly portable way to do it is with truncate/ftruncate.
Topic archived. No new replies allowed.