Ir para conteúdo

Como determinar o tamanho do stdin?


Nicholas F

Posts Recomendados

Fala, galera. Estou aprendendo assembly com nasm x64 e estou fazendo um programa que eu quero que receba uma entrada via stdin (como em echo palavra | ./programa) e armazene em um buffer para ser processado posteriormente por outras funções.

Eu não posso ler byte a byte até o fim do arquivo e ir aplicando a função a cada byte do stdin (ou a cada chunk de bytes), eu preciso guardá-lo primeiro para depois aplicar a função na string inteira. O problema é que de quase todas as maneiras que pensei em fazer isso, eu preciso saber o tamanho do stdin, e não sei como determinar isso, já que é algo variávei.

Tentei usar fstat() no fd do stdin (0) e a função até chegou a retornar, mas não encontrei o tamanho dele lá.

Tentei ler chunks de bytes e usar mmap para cada chunk até que o arquivo termine, e isso até funcionou, mas o problema é que os chunks alocados não estão imediatamente uns após os outros, então no final das contas a string acaba ficando separada.

Eu até consigo usar read() para ler chunks de bytes do stdin até o fim, mas o problema é que eu não sei como criar um buffer onde esses bytes lidos sejam armazenados sem correr o risco de dar problema se o len(stdin) for maior que o buffer.

Cheguei a falar com uns gringos e me recomendaram usar mmap e/ou sbrk, mas não soube exatamente como fazer isso.

A única solução que pensei e que acho que deve funcionar é ler o stdin byte a byte até o fim, ir contando os bytes, usar mmap para alocar o tamanho correto e depois ler novamente, mas acabaria tendo que usar duas vezes o read() e algo me faz pensar que há uma solução melhor para isso.

Se alguém puder dar uma luz do que pode ser feito, ajudaria bastante. Estou há uns bons dias preso nisso e já passei por umas três ou quatro páginas do Google inteiras, hehe. Valeu.

Editado por Nicholas F
Link para o comentário
Compartilhar em outros sites

Oi Nicholas. Acho que seu único equívoco é achar que precisa saber o tamanho do de stdin antes. ?

A real é que como você não sabe quantos bytes receberá de entrada, vai precisar alocar memória dinamicamente. Uma abordagem possível é:

  1. Alocar um buffer qualquer.
  2. Realocá-lo em 256 bytes (aumentá-lo nessa quantidade).
  3. Ler 256 bytes para este buffer.
  4. Equanto o número de bytes lidos for positivo, ir para 2.

No final você terá um buffer com todo o conteúdo de stdin.

Não sei se esta é a melhor opção, no entanto.

Abraço!

Link para o comentário
Compartilhar em outros sites

11 hours ago, Fernando Mercês said:

Oi Nicholas. Acho que seu único equívoco é achar que precisa saber o tamanho do de stdin antes. ?

A real é que como você não sabe quantos bytes receberá de entrada, vai precisar alocar memória dinamicamente. Uma abordagem possível é:

  1. Alocar um buffer qualquer.
  2. Realocá-lo em 256 bytes (aumentá-lo nessa quantidade).
  3. Ler 256 bytes para este buffer.
  4. Equanto o número de bytes lidos for positivo, ir para 2.

No final você terá um buffer com todo o conteúdo de stdin.

Não sei se esta é a melhor opção, no entanto.

Abraço!

Valeu pela resposta, Fernando!

Eu havia tentado realocar o buffer que eu criei com o mmap mas não encontrei como fazer isso. Dei uma procurada por alocação dinâmica de memória e encontrei pessoas falando sobre o malloc. Tô tentando fazer tudo com syscalls, então não queria usar o malloc.

O caminho seria com o brk mesmo? Encontrei alguns exemplos em C, mas não ficou muito claro. Ou há alguma maneira de realocar um buffer que tenha sido criado com o mmap, por exemplo?

Abraço!

Link para o comentário
Compartilhar em outros sites

8 horas atrás, Nicholas F disse:

Valeu pela resposta, Fernando!

Eu havia tentado realocar o buffer que eu criei com o mmap mas não encontrei como fazer isso. Dei uma procurada por alocação dinâmica de memória e encontrei pessoas falando sobre o malloc. Tô tentando fazer tudo com syscalls, então não queria usar o malloc.

O caminho seria com o brk mesmo? Encontrei alguns exemplos em C, mas não ficou muito claro. Ou há alguma maneira de realocar um buffer que tenha sido criado com o mmap, por exemplo?

Abraço!


Veja sobre a syscall mremap.

https://man7.org/linux/man-pages/man2/mremap.2.html

Link para o comentário
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...