guy@sun.uucp (Guy Harris) (11/11/85)
> >One can write: > > int size_of_UNIX_file; > >or one can write > > long size_of_UNIX_file; > >The former is incorrect, and the latter is correct. ... > > Actually, if you are trying to write portable code, NEITHER is correct. > This particular problem is exactly why we have the typedef, off_t. > > off_t size_of_UNIX_file; > > is correct for portable code. This would be true *if* the second argument to "lseek", and its return value, were an "off_t"; the "st_size" member of a "stat" structure already is an "off_t". Actually, the second argument to "lseek" and its return value *are* "off_t"s - check out the "struct a" declaration in "seek" in "sys2.c" in non-4.2 systems, "lseek" in "ufs_syscalls.c" in non-NFS 4.2 systems, and "lseek" in "vfs_syscalls.c" in NFS 4.2 systems, and the declaration of "u.u_roff" in "user.h". However, the 4.2 manual says they're "int"s (presumably because, for obscure reasons having to do, I think, with "lint" complaints about mixing "int" and "long", "off_t" is an "int" in 4.xBSD systems) and other UNIX manuals say they're "long"s. The "lint" libraries agree with the manual rather than the kernel code. 4.3's "lint" library agrees with the code (it takes an "off_t" and returns one), as does its manual page. This is what should be done; the trouble is that "off_t" is *still* "typedef"fed to "int", so that int x, y; y = lseek(fd, x, 0); won't cause "lint" errors on a 4.3BSD system, even though it's wrong and will *not* work on a system with "int"s shorter than "long"s. This can be fixed either by having "lint" not treat a "typedef" type as equivalent to the type it's "typedef"fed from (which is probably what it should do, but it'll disrupt some things) or by having "lint" not bitch about truncation of "long" values when casting a "long" to an "int" (after all, if the programmer stuck in a cast, they presumably know that there may be truncation and *want* that truncation to happen) and change "off_t" to a "long". Guy Harris