at least one uses spaces for delimiters
Incorreto.
Se você olhar o final do pseudo-arquivo no FreeBSD / TrueOS, onde você pode encontrar exatamente o mesmo comportamento com o Chromium, você encontrará um ␀
. Este é terminado em.. É um único argumento .
O Chromium está sobrescrevendo seus argumentos após um fork()
, para dar a você algo interessante para ver na saída de ps
. Está usando a função de biblioteca setproctitle()
. Isso faz parte das bibliotecas BSD C. Não faz parte da biblioteca GNU C. Nas plataformas GNU C, o Chromium usa um setproctitle()
de sua própria que sobrescreve os dados argv
diretamente.
setproctitle()
não é de fato a ferramenta certa para este trabalho, porque não permite configurar mais de uma cadeia de argumento. Ele define o "título" formatado como o 0º argumento e define a contagem de argumentos como 1. Tudo é organizado através da função de biblioteca como um único argumento.
Este não é o único problema com setproctitle()
. A versão da biblioteca FreeBSD / OpenBSD / NetBSD C também tem uma limitação arbitrária de 2KiB, herdada diretamente do antigo programa sendmail
do BSD (do qual a função biblioteca foi originalmente levantada no caso do FreeBSD), que é muito curta para o que o Chromium define linhas de comando para. E tanto o próprio Chromium quanto a versão da biblioteca FreeBSD / OpenBSD / NetBSD C tem funcionalidade extra, sendo que a string de formato é um ponteiro nulo, que o Chromium não usa (mas, ironicamente, tem que lidar com sua própria implementação de setproctitle()
) .
Pode-se fazer muito melhor com menos código. A chamada de sistema subjacente no FreeBSD / TrueOS que a função de biblioteca chama para fazer o trabalho, uma vez que tenha construído os dados do argumento, é a função sysctl()
, levando CTL_KERN
, KERN_PROC
, KERN_PROC_ARGS
e um ID de processo como o endereço. Este pode aceitar várias sequências terminadas em ␀. Eu escrevi uma função setprocargv()
razoavelmente simples para meus conjuntos de ferramentas que usam isso.
extern void setprocargv ( size_t argc, const char * argv[] ) { #if defined(__FreeBSD__) || defined(__DragonFly__) std::string s; for (size_t c(0); c < argc; ++c) { if (!argv[c]) break; s += argv[c]; s += '% /package/admin/nosh/command/exec foreground pause \; true & [1] 30318 % hexdump -C /proc/30318/cmdline 00000000 66 6f 72 65 67 72 6f 75 6e 64 00 70 61 75 73 65 |foreground.pause| 00000010 00 3b 00 74 72 75 65 00 |.;.true.| 00000018 % hexdump -C /proc/30319/cmdline 00000000 70 61 75 73 65 00 |pause.| 00000006 %'; } const int oid[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() }; sysctl(oid, sizeof oid/sizeof *oid, 0, 0, s.data(), s.length()); #elif defined(__OpenBSD__) …
(o OpenBSD / NetBSD faz as coisas da maneira antiga que o FreeBSD / TrueOS costumava fazer, com uma estrutura ps_strings
na memória do aplicativo, mas ainda é sysctl()
que é a chamada de sistema subjacente usada para encontrar a localização desse estrutura.)
for (size_t i = 1; i < command_line->argv().size(); ++i) { if (!title.empty()) title += " "; title += command_line->argv()[i]; } // Disable prepending argv[0] with '-' if we prepended it ourselves above. setproctitle(have_argv0 ? "-%s" : "%s", title.c_str());
Como setproctitle()
é a ferramenta errada para o trabalho, Cromo está pegando os novos membros argv
e construindo uma única string longa delimitada por ␠ deles , para ser passada como um único argumento para setproctitle()
.
extern void setprocargv ( size_t argc, const char * argv[] ) { #if defined(__FreeBSD__) || defined(__DragonFly__) std::string s; for (size_t c(0); c < argc; ++c) { if (!argv[c]) break; s += argv[c]; s += '% /package/admin/nosh/command/exec foreground pause \; true & [1] 30318 % hexdump -C /proc/30318/cmdline 00000000 66 6f 72 65 67 72 6f 75 6e 64 00 70 61 75 73 65 |foreground.pause| 00000010 00 3b 00 74 72 75 65 00 |.;.true.| 00000018 % hexdump -C /proc/30319/cmdline 00000000 70 61 75 73 65 00 |pause.| 00000006 %'; } const int oid[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, getpid() }; sysctl(oid, sizeof oid/sizeof *oid, 0, 0, s.data(), s.length()); #elif defined(__OpenBSD__) …
Como você pode ver, o próprio Chromium já possui o novo vetor argumento como uma série de strings terminadas em ␀. Ele está passando por uma camada de biblioteca intermediária que precisa de todos eles agrupados em uma cadeia, onde o nível de chamada real do sistema, no entanto, opera em termos de um vetor de argumento de sequências terminadas em.
Daí o comportamento que você está testemunhando, onde o Chromium está apresentando seus vetores de argumentos alterados para o sistema como um único argumento .
Talvez você possa persuadir os redatores do Chromium a adotar algo como setprocargv()
. ☺
Leitura adicional
- Peter Wemm (1995-12-16).
setproctitle
. Manual de Funções da Biblioteca do FreeBSD . FreeBSD.