Tak wiem
Mam nadal problem:
[code=ruby]pid = fork{
# child
fork{
# grandchild
pw[1].close
STDIN.reopen(pw[0])
pw[0].close
pr[0].close
STDOUT.reopen(pr[1])
pr[1].close
pe[0].close
STDERR.reopen(pe[1])
pe[1].close
exec(*cmd)
}
exit!
}[/code]
ok to jest standardowa obsługa 3 strumieni - a jak podpiąć kolejne ? 3,4 ?
(zaczynam dochodzić do wniosku, że zrobię to w PHP :/)
@edit:
Oto kod klasy:
Dałem sobie radę z poprzednim problemem. Programik po prostu nie czytał z stdin-a i nic na niego nie należało pisać. Teraz największy problem jest z tym, żeby wysłać coś na strumienie 3,4. Obecny kod:
[code=ruby]class Broker_process
READ = 0 # Consts to explicite mark read
WRITE = 1 # and write pipes
STDLOG = IO.new(3, “w”)
STDPAS = IO.new(4, “w”)
@stdin # Stdin stream
@stdout # Stdout stream
@stderr # Stderr stream
@stdlog # Login stream
@stdpas # Password stream
@login # Login administrator
@password # Password administrator
@pid # Process handler
Set credentials for user
def self.set_credentials(login, password)
@login = login
@password = password
end
Log into broker by set credentials
def self.send_credentials()
@stdlog[WRITE].write @login
@stdlog[WRITE].close
@stdpas[WRITE].write @password
@stdpas[WRITE].close
end
Make pipes to communicate with child.
Each pipe is array of two: read and write pipe.
def self.make_pipes()
@stdin = IO.pipe()
@stdout = IO.pipe()
@stderr = IO.pipe()
@stdlog = IO.pipe()
@stdpas = IO.pipe()
end
Close unused pipes from parent site
def self.close_unused_pipes
@stdin[READ].close
@stdout[WRITE].close
@stderr[WRITE].close
@stdlog[READ].close
@stdpas[READ].close
end
Prepare and run child process
def self.run_child(command)
@stdin[WRITE].close
STDIN.reopen(@stdin[READ])
@stdin[READ].close
@stdout[READ].close
STDOUT.reopen(@stdout[WRITE])
@stdout[WRITE].close
@stderr[READ].close
STDERR.reopen(@stderr[WRITE])
@stderr[WRITE].close
@stdlog[WRITE].close
STDLOG.reopen(@stlog[READ])
@stdlog[READ].close
@stdpas[WRITE].close
STDPAS.reopen(@stdpas[READ])
@stdpas[READ].close
exec(*command) # Replace by command binary code
exit!
end
Run process
def self.run(command, params)
self.make_pipes()
if fork
self.close_unused_pipes()
self.send_credentials()
@stdin[WRITE].write params
@stdin[WRITE].close
Process.wait
out = @stdout[READ].read
@stdout[READ].close
err = @stderr[READ].read
@stderr[READ].close
puts out
else
self.run_child(command)
end
end
end[/code]
Wywala się w tym miejscu:
STDLOG = IO.new(3, "w")
STDPAS = IO.new(4, "w")
[quote]./broker_process.rb:6:in initialize': Bad file descriptor (Errno::EBADF) from ./broker_process.rb:6:in
new’
from ./broker_process.rb:6
from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:4:in `require’
from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:4[/quote]
Być może Ruby nie przewiduje otwierania kolejnych strumieni
Jeżeli tylko stworzę pipy programik testowy napisany w C też tego nie łyka. A oto kod programiku:
[code=C]#include <stdio.h>
#include <unistd.h>
int main() {
char user[101];
char pass[101];
int i;
read(3, user, 101);
read(4, pass, 101);
printf(“Login: %s\nHaslo: %s\n”, user, pass);
return 0;
}[/code]
Proszę bardzo o pomoc !