Não é armazenada no arquivo. Ele é armazenado no sistema de arquivos e todos os parâmetros são copiados manualmente, um por um (embora alguns não possam ser copiados).
Ou seja, a maioria dos sistemas operacionais não possui realmente uma chamada "copiar arquivo com metadados". O programa de cópia de arquivo apenas cria um novo arquivo chamado foobar.py
, copia todos os 0 bytes de dados e usa utime () ou SetFileTime () para fazer com que o tempo de modificação pareça o mesmo do original. Da mesma forma, as permissões de arquivo seriam "copiadas", definindo-as novamente usando chmod () ou copiando o atributo POSIX ACL.
Alguns metadados não são copiados. A configuração da propriedade requer privilégios de root; portanto, cópias dos arquivos de outra pessoa pertencem a você e ocupam sua cota de disco. É impossível definir o ctime (hora de mudança de atributo) manualmente nos Unixes; btime (hora de nascimento / criação) também não é copiado.
Compare cp -a foo bar
(que copia metadados) e cp foo bar
(que não):
$ strace -v cp foo bar
...
open ("foo", O_RDONLY) = 3
aberto ("barra", O_WRONLY | O_TRUNC) = 4
read (3, "teste \ n", 131072) = 5
write (4, "teste \ n", 5) = 5
read (3, "", 131072) = 0
fechar (4) = 0
fechar (3) = 0
...
$ strace -v cp -a foo bar
...
- os metadados originais são recuperados
lstat ("foo", {st_dev = makedev (254, 0), st_ino = 60569468, st_mode = S_IFREG | 0644,
st_nlink = 1, st_uid = 1000, st_gid = 1000, st_blksize = 4096, st_blocks = 8,
st_size = 5, st_atime = 2016-12-28T09: 16: 59 + 0200.879714332,
st_mtime = 2016-12-28T09: 16: 55 + 0200.816363098,
st_ctime = 28-12-2016T09: 16: 55 + 0200.816363098}) = 0
- os dados são copiados
open ("foo", O_RDONLY | O_NOFOLLOW) = 3
aberto ("barra", O_WRONLY | O_TRUNC) = 4
read (3, "teste \ n", 131072) = 5
write (4, "teste \ n", 5) = 5
read (3, "", 131072) = 0
- tempo de modificação é copiado
utimensat (4, NULL, [{tv_sec = 1482909419, tv_nsec = 879714332},
{tv_sec = 1482909415, tv_nsec = 816363098}], 0) = 0
- a propriedade é copiada (apenas com 'sudo [strace] cp')
fchown (4, 1000, 1000) = 0
- atributos estendidos são copiados (xdg.origin.url é definido pelos navegadores, wget)
flistxattr (3, NULL, 0) = 0
flistxattr (3, "user.xdg.origin.url \ 0", 20) = 20
fgetxattr (3, "user.xdg.origin.url", "https://superuser.com/", 22) = 22
fsetxattr (4, "user.xdg.origin.url", "https://superuser.com/", 22, 0) = 0
- ACLs POSIX não estão presentes, portanto, uma ACL básica é criada a partir de st_mode
- (neste caso, um simples fchmod () também funcionaria)
fgetxattr (3, "system.posix_acl_access", 0x7ffc87a50be0, 132) = -1 ENODATA (dados não disponíveis)
fsetxattr (4, "system.posix_acl_access", "\ 2 \ 0 \ 0 \ 0 \ 1 \ 0 \ 6 \ 0 \ 377 \ 377 \ 377 \ 377 \ 4 \ 0 \ 4 \ 0 \ 377 \ 377 \ 377 \ 377 \ 0 \ 4 \ 0 \ 377 \ 377 \ 377 \ 377 ", 28, 0) = 0
fechar (4) = 0
fechar (3) = 0
...