CPIO 生成的文件中填充了额外的字节
Extra bytes are padding in the generated file from CPIO
我有一个目录中的文件列表,我想创建一个存档格式文件。我使用 CPIO 将文件创建为
ls | cpio -ov -H crc > demo.cpio
我有这样的 cpio 结构
struct cpio_newc_header {
char c_magic[6];
char c_ino[8];
char c_mode[8];
char c_uid[8];
char c_gid[8];
char c_nlink[8];
char c_mtime[8];
char c_filesize[8];
char c_devmajor[8];
char c_devminor[8];
char c_rdevmajor[8];
char c_rdevminor[8];
char c_namesize[8];
char c_check[8];
};
我可以使用c_filesize获取header中的元数据、路径名、文件数据,c_namesize.I可以根据c_filesize获取文件数据,但是在获取文件数据之后,填充了一些额外的位,即在文件数据之后和下一个 header.
之前
00000230: 6e63 6965 7322 3a5b 5d0d 0a7d 0d0a 0000 ncies":[]..}....
00000240: 3037 3037 3032 3030 3636 4246 3838 3030 0707020066BF8800
在这里我们可以观察到在'}'之后填充了一些额外的字节。我用四的倍数教它四舍五入,但我观察到一些其他数据不是四的倍数
00000450: 2066 6f72 2063 7279 7074 6f20 7665 7269 for datapo veri
00000460: 6669 6361 7469 6f6e 0a00 0000 3037 3037 fication....0707
为什么我们在执行 CPIO 时会避免 padding.Can 额外的字节?
来自 cpio 的联机帮助页(新 ASCII 格式部分):
The pathname is followed by NUL bytes so that the total size of the fixed header plus pathname is a multiple of four. Likewise, the file data is padded to a multiple of four bytes. Note that this format supports only 4 gigabyte files (unlike the older ASCII format, which supports 8 gigabyte files).
另见 man 5 cpio
在你的第二个例子中,它也被填充为 4-bytes-aligned:
00000460: 6669 6361 7469 6f6e 0a00 0000 3037 3037 fication....0707
你看,数据结束于 0x468
并且添加了三个额外的零字节用于填充,因此下一个块可以从 0x46c
开始。
执行此填充可能是为了避免在将 header 字段读入内存后对其进行未对齐访问。它是规范的一部分,因此无法避免。
但计算起来很容易。如果偏移量 x
是文件结束后的下一个字节,那么下一个 header 从偏移量
开始
int nextheader = (x+3)&~3;
我有一个目录中的文件列表,我想创建一个存档格式文件。我使用 CPIO 将文件创建为
ls | cpio -ov -H crc > demo.cpio
我有这样的 cpio 结构
struct cpio_newc_header {
char c_magic[6];
char c_ino[8];
char c_mode[8];
char c_uid[8];
char c_gid[8];
char c_nlink[8];
char c_mtime[8];
char c_filesize[8];
char c_devmajor[8];
char c_devminor[8];
char c_rdevmajor[8];
char c_rdevminor[8];
char c_namesize[8];
char c_check[8];
};
我可以使用c_filesize获取header中的元数据、路径名、文件数据,c_namesize.I可以根据c_filesize获取文件数据,但是在获取文件数据之后,填充了一些额外的位,即在文件数据之后和下一个 header.
之前00000230: 6e63 6965 7322 3a5b 5d0d 0a7d 0d0a 0000 ncies":[]..}....
00000240: 3037 3037 3032 3030 3636 4246 3838 3030 0707020066BF8800
在这里我们可以观察到在'}'之后填充了一些额外的字节。我用四的倍数教它四舍五入,但我观察到一些其他数据不是四的倍数
00000450: 2066 6f72 2063 7279 7074 6f20 7665 7269 for datapo veri
00000460: 6669 6361 7469 6f6e 0a00 0000 3037 3037 fication....0707
为什么我们在执行 CPIO 时会避免 padding.Can 额外的字节?
来自 cpio 的联机帮助页(新 ASCII 格式部分):
The pathname is followed by NUL bytes so that the total size of the fixed header plus pathname is a multiple of four. Likewise, the file data is padded to a multiple of four bytes. Note that this format supports only 4 gigabyte files (unlike the older ASCII format, which supports 8 gigabyte files).
另见 man 5 cpio
在你的第二个例子中,它也被填充为 4-bytes-aligned:
00000460: 6669 6361 7469 6f6e 0a00 0000 3037 3037 fication....0707
你看,数据结束于 0x468
并且添加了三个额外的零字节用于填充,因此下一个块可以从 0x46c
开始。
执行此填充可能是为了避免在将 header 字段读入内存后对其进行未对齐访问。它是规范的一部分,因此无法避免。
但计算起来很容易。如果偏移量 x
是文件结束后的下一个字节,那么下一个 header 从偏移量
int nextheader = (x+3)&~3;