I am sending file from client to server using TCP. To mark the end of the file I like to send file size before the actual data. So I use stat
system call to find the size of the file. This is of type off_t
. I like to know how many bytes it occupies so that I can read it properly on the server side. It is defined in the <sys/types.h>
. But I do not understand the definition. It just defines __off_t or _off64_t
to be off_t
. Where to look for __off_t
? Also is it convention that __
is prefixed for most of the things in header files and scares me when I read header files to understand better. How to read a header file better?
#ifndef __off_t_defined
# ifndef __USE_FILE_OFFSET64
typedef __off_t off_t;
# else
typedef __off64_t off_t;
# endif
# define __off_t_defined
#endif
If you are having trouble tracing the definitions, you can use the preprocessed output of the compiler which will tell you all you need to know. E.g.
If you look at the complete output you can even see the exact header file location and line number where it was defined:
...
Since this answer still gets voted up, I want to point out that you should almost never need to look in the header files. If you want to write reliable code, you're much better served by looking in the standard. A better question than "how is
off_t
defined on my machine" is "how isoff_t
defined by the standard?". Following the standard means that your code will work today and tomorrow, on any machine.In this case,
off_t
isn't defined by the C standard. It's part of the POSIX standard, which you can browse here.Unfortunately,
off_t
isn't very rigorously defined. All I could find to define it is on the page onsys/types.h
:This means that you can't be sure how big it is. If you're using GNU C, you can use the instructions in the answer below to ensure that it's 64 bits. Or better, you can convert to a standards defined size before putting it on the wire. This is how projects like Google's Protocol Buffers work (although that is a C++ project).
So, I think "where do I find the definition in my header files" isn't the best question. But, for completeness here's the answer:
You'll find the definition in
bits/types.h
(as a comment says at the top, never directly include this file), but it's obscured a bit in a bunch of macros. An alternative to trying to unravel them is to look at the preprocessor output:And then:
However, if you want to know the size of something, you can always use the
sizeof()
operator.Edit: Just saw the part of your question about the
__
. This answer has a good discussion. The key point is that names starting with__
are reserved for the implementation (so you shouldn't start your own definitions with__
).As the "GNU C Library Reference Manual" says
and
Thus if you want reliable way of representing file size between client and server, you can:
off64_t
type andstat64()
function accordingly (as it fills structurestat64
, which containsoff64_t
type itself). Typeoff64_t
guaranties the same size on 32 and 64 bit machines.-D_FILE_OFFSET_BITS == 64
and use usualoff_t
andstat()
.Convert
off_t
to typeint64_t
with fixed size (C99 standard). Note: (my book 'C in a Nutshell' says that it is C99 standard, but optional in implementation). The newest C11 standard says:And about implementation:
Thus, in general, C standard can't guarantee types with fixed sizes. But most compilers (including gcc) support this feature.
If you are writing portable code, the answer is "you can't tell", the good news is that you don't need to. Your protocol should involve writing the size as (eg) "8 octets, big-endian format" (Ideally with a check that the actual size fits in 8 octets.)