Jump to content

Como determinar o tamanho do stdin?


Nicholas F

Recommended Posts

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.

Edited by Nicholas F
Link to comment
Share on other 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 to comment
Share on other 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 to comment
Share on other 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 to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...