Existem alguns benefícios para "registros de tamanho fixo". Então, a estrutura histórica para um registro de utmp / wtmp foi
struct utmp {
char ut_line[8]; /* tty name */
char ut_name[8]; /* user id */
char ut_host[16]; /* host name, if remote */
long ut_time; /* time on */
};
(Isso foi de uma máquina SunOS 4; acabei de escolher isso porque é uma entrada fácil de ler).
Isso torna fácil anexar dados a um arquivo e exibi-lo na ordem inversa, simplesmente saltando para trás sizeof(struct utmp)
bytes. Isso facilita o relato de programas como last
na ordem inversa.
A estrutura de dados exata foi alterada ao longo do tempo, mas o registro ainda é fixo em tamanho.
por exemplo, uma máquina atual do FreeBSD tem:
struct utmpx {
short ut_type; /* Type of entry. */
struct timeval ut_tv; /* Time entry was made. */
char ut_id[8]; /* Record identifier. */
pid_t ut_pid; /* Process ID. */
char ut_user[32]; /* User login name. */
char ut_line[16]; /* Device name. */
#if __BSD_VISIBLE
char ut_host[128]; /* Remote hostname. */
#else
char __ut_host[128];
#endif
char __ut_spare[64];
};
Outra vantagem para utmp
e lastlog
é a capacidade de ter arquivos esparsos .
Por exemplo, com lastlog
(que o comando finger
usa para exibir o último horário de login), os dados são armazenados em um deslocamento com base em uid
* sizeof(struct lastlog)
. Assim, você pode rapidamente e facilmente encontrar o último horário de login para o uid 12345678, procurando a posição calculada.
Com arquivos de texto, esses benefícios não existem; cada registro tem largura variável ou tem que ser preenchido. Os resultados são maiores, mais difíceis de lidar, podem exigir análise ( long ut_time
é mais fácil de manipular do que tentar analisar uma string de data ASCII).
ASCII é ótimo para humanos e para dados que humanos podem precisar manipular. O binário é (às vezes) melhor para programas, especialmente para dados brutos que os humanos não precisam necessariamente ver.