Quasar Posted January 30, 2011 CERT says Thou-Shalt-Not use fseek/ftell to determine file sizes! https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek%28%29+and+ftell%28%29+to+compute+the+size+of+a+file Turns out ISO doesn't require binary streams to support SEEK_END, and of course most people already know fseek is wonky on text streams. So that leaves nowhere that it's both safe AND portable to do this >_> 0 Share this post Link to post
Kaiser Posted January 30, 2011 Apparently this is what may be causing the read/write issues with savegames for Doom64ex. Problem is this may affect other source ports as well such as Chocolate Doom. 0 Share this post Link to post
Quasar Posted January 30, 2011 CERT recommends fstat, which is really slow compared to fseek/ftell where they actually work. 0 Share this post Link to post
Maes Posted January 30, 2011 Well, unless you have to somehow find out the size of several thousands files by opening them first, does this really matter? I guess it also has to do with how a particular OS/library actually populates the fstat object. In some development environments it's easy to get info about a file that you *didn't* open, or even receive a full directory listing without much effort, while in others you have to jump through hoops. Still, it's a method we've all have used :-/ 0 Share this post Link to post
andrewj Posted January 31, 2011 Their compliant solution sucks. You shouldn't have to use the kernel facilities like open() for something as basic as this, the whole point of fopen(), fread() etc is to abstract away those low-level facilities. 0 Share this post Link to post
Graf Zahl Posted January 31, 2011 This is a recommendation I will happily ignore unless someone points me to a system where it really does not work. 0 Share this post Link to post
RjY Posted January 31, 2011 Quasar said:CERT recommends fstat, which is really slow compared to fseek/ftell where they actually work. Really? On my system, at least according to strace, calling fseek calls fstat (as well as precaching a bit of the file.) So fseek must be at least as slow as fstat...$ strace -o trace ./fseek ~/doom/W/epic2/epic2.wad /home/rjy/doom/W/epic2/epic2.wad: 37243712 $ sed -ne '/open.*epic2.wad/,$p' trace open("/home/rjy/doom/W/epic2/epic2.wad", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=37243712, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7755000 fstat64(3, {st_mode=S_IFREG|0644, st_size=37243712, ...}) = 0 _llseek(3, 37240832, [37240832], SEEK_SET) = 0 read(3, " s,\2\0\20\0\0SFLOOR05 \203,\2\0\20\0\0SFLOOR06"..., 2880) = 2880 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7754000 write(1, "/home/rjy/doom/W/epic2/epic2.wad"..., 43) = 43 close(3) = 0 munmap(0xb7755000, 4096) = 0 exit_group(0) = ?fseek.c#include <stdlib.h> #include <stdio.h> int main(int argc, char **argv) { while (++argv, --argc) { char *name = *argv; FILE *F = fopen(name, "rb"); size_t length; fseek(F, 0, SEEK_END); length = ftell(F); printf("%s: %lu\n", name, length); fclose(F); } return EXIT_SUCCESS; } I'm too stupid/lazy to benchmark it properly :-P 0 Share this post Link to post