🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.ruby
5 messages
5 total messages Started by Jan Koprowski Mon, 03 Dec 2007 06:29
Próba pisania do procesu na strumień 3,4
#728
Author: Jan Koprowski
Date: Mon, 03 Dec 2007 06:29
105 lines
3771 bytes
Cześć !

   Próbuję przeportować moją aplikację na Rubego. Wcześniej pisana
była w PHP. Problem podstawowy z jakim się zmagam to otworzyć strumien
3,4 i napisać na nich coś do procesu. Kod który mam wygląda mniej
więcej tak:

class Broker_process

  READ = 0  # Consts to explicite mark read
  WRITE = 1 # and write pipes

  @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
    @stdpas[WRITE].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
    else
      self.run_child(command)
    end
  end

end

Jednak podczas wywołania metody run dostaję błąd:

./broker_process.rb:78:in `write': Broken pipe (Errno::EPIPE)
        from ./broker_process.rb:78:in `run'
        from /home/johny/NetBeansProjects/zhradmin/lib/main.rb:6

co jest nie tak ? i czy to w ogóle ma szanse powodzenia ? Pozdrawiam !
Re: Próba pisania do procesu na strumień 3,4
#729
Author: Jan Koprowski
Date: Mon, 03 Dec 2007 07:12
127 lines
4158 bytes
Dałem sobie radę z poprzednim probleme. 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:

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

Wywala się w tym miejscu:

  STDLOG = IO.new(3, "w")
  STDPAS = IO.new(4, "w")

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:

#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;
}

Proszę bardzo o pomoc !
Re: Próba pisania do procesu na strumień 3,4
#730
Author: Paweł Kondzior
Date: Mon, 03 Dec 2007 16:46
135 lines
4578 bytes
Nie mozesz otworzyc IO na File Descriptor 3 i 4 poniewaz takie nie 
istnieja (patrz http://en.wikipedia.org/wiki/File_descriptor)

Mysle ze masz bledne zalorzenia co do sposobu wymiany tych danych. Co 
dokladnie probujesz osiagnac w taki sposob ?


Dnia 12/3/07 8:12 AM, Jan Koprowski napisał(a):
> Dałem sobie radę z poprzednim probleme. 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:
> 
> 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
> 
> Wywala się w tym miejscu:
> 
>   STDLOG = IO.new(3, "w")
>   STDPAS = IO.new(4, "w")
> 
> 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:
> 
> #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;
> }
> 
> Proszę bardzo o pomoc !
Re: Próba pisania do procesu na strumień 3,4
#731
Author: Jan Koprowski
Date: Mon, 03 Dec 2007 17:45
15 lines
1865 bytes
Dostosować się do programu, który muszę obsłużyć.

Program działa tak:
Przyjmuje login na 3
Przyjumuje hasło na 4
przyjmuje polecenie i parametry na stdin
wypluwa stdout
wypluwa stderr
i kończy działanie.

Program to binarka napisana w C, która wykonuje pewne określone
działania z poziomu systemu po uwierzytelnieniu się w niej loginem i
hasłem.

Muszę napisać kod, który będzie wywoływał tą binarkę :)
Re: Próba pisania do procesu na strumień 3,4
#732
Author: edek
Date: Thu, 21 Feb 2008 09:33
14 lines
1565 bytes
> Program to binarka napisana w C, która wykonuje pewne określone
> działania z poziomu systemu po uwierzytelnieniu się w niej loginem i
> hasłem.
> 
> Muszę napisać kod, który będzie wywoływał tą binarkę :)

Z tego co mi wiadomo, to nr deskryptora jest przydzielany przez system 
(za wyjątkiem standardowych 0, 1, 2) i pisanie na 3, 4 jest tym samym 
bez sensu.

Coś sknociłeś jeśli chodzi o samą koncepcję, jak te dane mają być 
przesyłane.

m.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads