; ---------------------------------------------------------- ; Arquivo : salve-pipe.asm ; Reproduz: echo 'Salve, simpatia!' | cat ; Montagem: nasm -f elf64 salve-pipe.asm ; Ligação : ld -o salve-pipe salve-pipe.o ; ---------------------------------------------------------- ; Chamadas de sistema... ; ---------------------------------------------------------- %define SYS_WRITE 1 %define SYS_CLOSE 3 %define SYS_PIPE 22 %define SYS_DUP2 33 %define SYS_FORK 57 %define SYS_EXECVE 59 %define SYS_EXIT 60 %define SYS_WAIT 61 ; ---------------------------------------------------------- ; Parâmetros de SYS_WAIT... ; ---------------------------------------------------------- %define W_CHILD -1 ; filho de qualquer PID %define W_STATUS 0 ; ignorar o estado de término (NULL) %define W_OPTIONS 0 ; sem opções ; ---------------------------------------------------------- ; Descritores de arquivos padrão... ; ---------------------------------------------------------- %define STDIN_FD 0 %define STDOUT_FD 1 ; ---------------------------------------------------------- ; Estados de término... ; ---------------------------------------------------------- %define EXIT_SUCCESS 0 %define EXIT_ERROR 1 ; ---------------------------------------------------------- section .rodata ; ---------------------------------------------------------- ; Mensagem... msg db "Salve, simpatia!", 10 len equ $ - msg ; Argumentos de execve... comm db "/bin/cat", 0 argv dq comm, 0 envp dq 0 ; ---------------------------------------------------------- section .bss ; ---------------------------------------------------------- read_end resd 1 ; Descritor da ponta de leitura do pipe write_end resd 1 ; Descritor da ponta de escrita do pipe ; ---------------------------------------------------------- section .text ; ---------------------------------------------------------- global _start _start: ; pipe(int pipefd[]) ; retorna: pipefd[0] => read_end; pipefd[1] => write_end mov rax, SYS_PIPE mov rdi, read_end ; Retorno vai avançar em write_end syscall .parada1: ; examinar FDs retornados! ; fork() mov rax, SYS_FORK syscall test rax, rax ; rax = 0 -> processo filho jz .filho ; pula a execução do código do pai ; ---------------------------------------------------------- ; Código executado apenas no processo pai... ; ---------------------------------------------------------- .pai: ; ---------------------------------------------------------- ; dup2(write_end, STDOUT) mov rax, SYS_DUP2 mov edi, [write_end] ; FD original: write_end mov rsi, STDOUT_FD ; novo descritor de escrita syscall ; Fechar write_end e read_end... call _close_all .parada2: ;examinar /proc//fd! ; write(STDOUT, msg, len) mov rax, SYS_WRITE mov rdi, STDOUT_FD mov rsi, msg mov rdx, len syscall ; wait4(-1, NULL, 0) mov rax, SYS_WAIT mov rdi, W_CHILD mov rsi, W_STATUS mov rdx, W_OPTIONS ; exit(0) mov rax, SYS_EXIT mov rdi, EXIT_SUCCESS ; sai com sucesso se chegar aqui syscall ; ---------------------------------------------------------- ; Código executado apenas no processo filho... ; ---------------------------------------------------------- .filho: ; ---------------------------------------------------------- ; dup2(read_end, STDIN) mov rax, SYS_DUP2 mov edi, [read_end] ; descritor de leitura no pipe mov rsi, STDIN_FD ; novo descritor de leitura syscall ; Fechar write_end e read_end... call _close_all ; execve("/bin/cat", ["/bin/cat", NULL], [NULL]) mov rax, SYS_EXECVE mov rdi, comm mov rsi, argv mov rdx, envp syscall ; exit(1) mov rax, SYS_EXIT mov rdi, EXIT_ERROR ; sai com erro se execve falhar syscall ; ---------------------------------------------------------- ; Sub de fechamento dos descritores originais do pipe... ; ---------------------------------------------------------- _close_all: ; ---------------------------------------------------------- ; close(read_end) mov rax, SYS_CLOSE mov rdi, [read_end] syscall ; close(write_end) mov rax, SYS_CLOSE mov rdi, [write_end] syscall ret