Notes |
(0001635)
joerg (reporter)
2013-06-02 10:40
|
The description in tar.h clearly mentions already:
TMAGIC "ustar" ustar plus null byte.
TMAGLEN 6 Length of the above.
TVERSION "00" 00 without a null byte.
TVERSLEN 2 Length of the above.
Which looks fully correct. |
|
(0001636)
schweikh (reporter)
2013-06-02 13:49
edited on: 2013-06-02 16:20
|
I'd say the wording is not as clear as it could be and has room for improvement.
First, there is no math involved and "plus" should be replaced with "followed by a".
Next, at least in C, there is a distinction between the size and the length of a string. They differ by one.
TMAGLEN is a misnomer for what should be called TMAGSIZ, but it's too late to fix that. Same for TVERSLEN.
TVERSION though isn't a C string, but a two character array. I've often heard of array sizes and can't recall ever hearing array length. So I believe it should be
TMAGIC "ustar" ustar followed by a null byte
TMAGLEN 6 Size of the above
TVERSION "00" 00 without a null byte
TVERSLEN 2 Size of the above
|
|
(0001637)
joerg (reporter)
2013-06-02 14:48
|
*LEN seems to be correct, as it is the string _length_ that is transfered
into the tar header.
BTW: TVERSLEN is not the only string in the tar header that is not nul
terminated. Check e.g. that the path name and the path prefix do not inlcude
a nul byte in case that all space was used in the related field. |
|
(0001638)
tedu (reporter)
2013-06-02 16:22
|
How does one create a symbolic constant that does not include a null byte?
FreeBSD, Linux, OpenBSD, and Solaris all have the following in tar.h:
#define TVERSION "00"
That creates a TVERSION with a null byte, which does not conform to the text above. |
|
(0001639)
schweikh (reporter)
2013-06-02 16:30
|
If a character array is not null terminated, by definition it is not a string (Base Definition: 3.369 String A contiguous sequence of bytes terminated by and including the first null byte.)
TMAGIC is a string. It has a length(5) and a size(6).
TVERSION is not a string. It has no length, but has a size(2). |
|
(0001640)
tedu (reporter)
2013-06-02 16:39
|
What does the following program print on your favorite standards conformant platform?
#include <inttypes.h>
#include <stdio.h>
#include <tar.h>
int main() {
printf("The size of TVERSION is %zu\n", sizeof(TVERSION));
return 0;
} |
|
(0001641)
schweikh (reporter)
2013-06-02 16:40
edited on: 2013-06-02 16:44
|
@tedu C allows to specify array dimensions when initializing a char array with a string. If the initializer has exactly that many characters, the nul is supressed:
#define TVERSION "00"
char a[2] = TVERSION;
initializes a[] with the equivalent of { '0', '0' };
Details in C99, 6.7.8#14
|
|
(0001642)
mdempsky (reporter)
2013-06-02 16:47
|
@schweikh No, you've defined "a" of size 2, but TVERSION is still a size 3 string literal.
Similarly, given
unsigned char x = SIZE_MAX;
surely you won't try to claim that SIZE_MAX == 255 because x == 255?
I really don't understand how this is contentious. Ted's recommended solution is very simple: the actual definitions stay the same (i.e., the same as actual implementations use in practice), and just fix the descriptions to reflect that TMAGLEN includes the trailing NUL byte but TVERSLEN does not, and not try to suggest that a C string literal can be defined without a trailing NUL. |
|
(0001643)
schweikh (reporter)
2013-06-02 17:19
|
@mdempsky Please read C99, 6.7.8#14. The string literal initializer is an explicit special case. Depending on context it is equivalent to
{ '0', '0' } or { '0', '0', '\0' }.
I answered this question "How does one create a symbolic constant that does not include a null byte?" with an example how to initialize an array with it. Maybe that's not exactly an answer to the question, but if you want a literal answer, then {'0', '0'} is it. It doesn't matter, really, since if you need to use the expansion of TVERSION in a context where the null isn't wanted, C provides a way to do just that: initialize a char[2] with it an use it. |
|
(0001644)
joerg (reporter)
2013-06-02 17:20
|
But this is already mentioned in the current text.
BTW: strncpy(to, from, len) will copy without trailing nul byte in
case that len is small enough. |
|
(0001645)
mdempsky (reporter)
2013-06-02 17:34
|
@schweikh Yes, I understand that you can use ``char a[2] = "00";'' to initialize a two-char array. But POSIX's description of TVERSION in tar.h doesn't talk about TVERSION in the context of initializing an array. It says that TVERSION should be defined as "00" without a NUL byte, which is impossible in C99 and not done by any POSIX implementation we've looked at.
POSIX currently says <tar.h> should contain (yes, I know the comments aren't actually required):
#define TMAGIC "ustar" // ustar plus null byte
#define TMAGLEN 6 // Length of the above
#define TVERSION "00" // 00 without a null byte
#define TVERSLEN 2 // Length of the above
Ted is suggesting that instead it should recommend:
#define TMAGIC "ustar" // ustar
#define TMAGLEN 6 // Length of the above, including the null byte
#define TVERSION "00" // 00
#define TVERSLEN 2 // Length of the above, excluding the null byte
In other words, the actual definitions stay exactly the same. We just clarify the descriptions to reflect that TMAGIC and TVERSION are actually normal C string literals, and that TMAGLEN and TVERSLEN are just byte counts that include and exclude the trailing NUL terminators, respectively.
How is this contentious? Can you point to a POSIX system where the #define's don't match above? Can you provide an alternative definition for TVERSION other than ``#define TVERSION "00"'' that you think is POSIX conforming? |
|
(0001652)
geoffclare (manager)
2013-06-13 15:55
edited on: 2013-06-13 16:01
|
Replace lines 13791-13794 with:
TMAGIC "ustar" Used in the magic field in the ustar header
block, including the trailing null byte
TMAGLEN 6 Length in octets of the magic field
TVERSION "00" Used in the version field in the ustar header
block, excluding the trailing null byte
TVERSLEN 2 Length in octets of the version field
Cross-volume change to XCU...
At page 3068 line 102203 section pax add <tar.h> to the XBD part of
the SEE ALSO list.
|
|