Nowe posty

xx Dystrybucja pod HP Omen (6)
Wczoraj o 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
Wczoraj o 21:08:23
lamp Problem z Linux Lite po instalacji (0)
Wczoraj o 19:50:30
xx Ile pingwinów? (1)
Wczoraj o 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: przekazanie deskryptora przez execl ????  (Przeczytany 8185 razy)

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« dnia: 2007-01-02, 01:26:17 »
Chcialbym przekazac deskryptor pipe'a z procesu macierzystego do potomnego z wykorzystaniem execl. Wiem ze generalnie istnieje cos takiego jak duplikowanie deskryptorow z wykorzystaniem funkcji dup(), ale ja nie chce wykorzystac tej metody, a potrzebuje zrobic to poprzez execl.


.....
- pipe(MYpipe_fd);
- wywolanie fork()
-if((execl("procesJeden.o", "procesJeden.o",(char*)MYpipe_fd[0], (char*)pipe1_fd[1])) < 0) printf("nexecl error" ) ;


Proces macierzysty stanowi fizycznie jeden plik, a proces potomny - drugi plik, ktory sie nazywa "procesJeden.o". Z procesu macierzystego wywoluje poprzez execl proces potomny i potrzebuje przekazac do potomnego deskryptor pipe'a. Chyba to udalo mi sie wyjasnic. W ostatniej powyzszej linijce jest blad bo wyrzuca na stdout "execl error". Jak mozna to zribic poprawnie?
----nstn-----

xavery

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #1 dnia: 2007-01-02, 12:34:23 »
OIDP tak to sie nie da nawet w Erze:)
Funkcje rodziny exec kopiują jedynie zestaw standardowych deskryptorów, wiec bez dup (lub dup2) sie nie obejdzie. Deskryptor jako wartość można przekazać lecz co z tego skoro potomny proces po exec'u ma własną tablice deskryptorów i numer deskryptora innego procesu mało go obchodzi.
Jeśli już koniecznie nie chcesz używać funkcji dup to albo użyj popen (z stdio) albo zrób to na wątkach - wątki w obrębie procesu macierzystego posiadają ten sam zestaw deskryptorów.

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #2 dnia: 2007-01-02, 14:11:23 »
2007-01-02 12:34:23 xavery napisał:

 > Funkcje rodziny exec kopiują jedynie zestaw standardowych deskryptorów, wiec bez dup (lub dup2)
 > sie nie obejdzie. Deskryptor jako wartość można przekazać lecz co z tego skoro potomny proces po
 > exec'u ma własną tablice deskryptorów i numer deskryptora innego procesu mało go obchodzi.

Problem jest w tym, ze jak uzywam dup() to przed wywolaniem tej funkcji uzywam close(0), zeby zamknac standardowe wejscie procesu potomnego, a ja potem potrzebuję z klawiatury przekazac cos do procesu potomnego (nr1), a jak uzyję close(0) to potem nie mogę.  
 
 > Jeśli już koniecznie nie chcesz używać funkcji dup to albo użyj popen (z stdio) albo zrób to na
 > wątkach - wątki w obrębie procesu macierzystego posiadają ten sam zestaw deskryptorów.

Na wątkach odpada. Popen do czego mam uzyc, do odpalenia pliku mojego procesu potomnego?

ZipoKing

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #3 dnia: 2007-01-02, 14:24:49 »
A to musi być koniecznie potok???
Możesz przecież użyć gniazd (man 2 socket) - one bardziej nadają się do komunikacji między procesami.

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #4 dnia: 2007-01-02, 15:03:50 »
2007-01-02 14:24:49 ZipoKing napisał:

> A to musi być koniecznie potok???

TAK.



xavery

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #5 dnia: 2007-01-02, 15:16:07 »
 > Problem jest w tym, ze jak uzywam dup() to przed wywolaniem tej funkcji uzywam close(0), zeby
 > zamknac standardowe wejscie procesu potomnego, a ja potem potrzebuję z klawiatury przekazac cos
 > do procesu potomnego (nr1), a jak uzyję close(0) to potem nie mogę.

Powyższe kłoci sie zasadniczo z idea potoków które z założenia przesyłają dane na stdin procesu potomnego. Moze pisz na stdin do procesu macierzystego a potem przesyłaj to do procesu potomnego... Albo zrob to na gniazdach jak pisał przedpiszca lub nazwanych potokach.
 
 > Na wątkach odpada. Popen do czego mam uzyc, do odpalenia pliku mojego procesu potomnego?

Dlaczego wątki odpadają, przecież są dobre (do czasu:) ). Popen to funkcja do całkowicie automatycznego tworzenia potoku ale jeśli potrzebujesz potoku do takiego zastosowania jak napisaleś, to to rozwiązanie odpada.

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #6 dnia: 2007-01-02, 15:45:29 »
W zasadzie uważam ze moj problem polega tylko i wylacznie na tym jak przekazac przez parametr deskryptor potoku do procesu potomnego wykorzystujac execl? Dalbym glowe ze sie da, tylko składniowo cos mi tam nie wychodzi (patrz post 1.)

No bo chodzi tylko o to żeby mozna bylo w procesie potomnym korzystac z pipe'a, ale jednoczesnie rowniez gdzies tam w miedzyczasie pisac z klawiatury do procesu potomnego, czego nie moge zrobic gdy uzywam close(0) i dup().

Ale dodam ze pipe musi byc wykorzystany. Wiem jak zrobic to na kolejkach, ale tu musi byc pipe.

ZipoKing

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #7 dnia: 2007-01-02, 17:04:49 »
>pipe(MYpipe_fd);
>- wywolanie fork()
>-if((execl("procesJeden.o", "procesJeden.o",(char*)MYpipe_fd[0], >(char*)pipe1_fd[1])) < 0) printf("nexecl error" ) ;
Sprawdziłem, i...
1) jeżeli jako polecenia używasz "procesJeden.o" sprawdź, czy katalog, w którym znajduje się ten plik, znajduje się w PATH i czy plik ten ma ustawione prawa wykonania
2) zauważ, że MYpie_fd to tablica o elementach typu int i rzutując takie elementy na char* po prostu tworzysz wskaźnik do nikąd. Spróbuj to zrobić raczej tak:
int fd[2];
char fd_t[3];
...
 pipe(fd);
  fd_t[0] = (char)fd[0];
  fd_t[1] = (char)fd[1];
  fd_t[2] = '0'; /* znak końca tekstu */
  /*  fork  */
  execl("./a.out", "./a.out", fd_t);
  /* ... */
  close(fd[0]);
  close(fd[1]);
- u mnie taki sposób zdziałał - teraz w procesie potomnym możesz mieć dostęp do tych deskryptorów przez argv[1][0] i argv[1][1].

W razie dodatkowych błędów sprawdź wartość zmiennej errno - w man execl masz spis wszystkich zwracanych błędów wraz z opisem powodu ich powstania.

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #8 dnia: 2007-01-02, 17:46:34 »
2007-01-02 17:04:49 ZipoKing napisał:

 > - u mnie taki sposób zdziałał - teraz w procesie potomnym możesz mieć dostęp do tych
 > deskryptorów przez argv[1][0] i argv[1][1].
 
Jaki powinien byc zapis dla main'a by w taki sposob jak napisales wywolac te argumenty?

Moj main ma zapis taki:

int main(int argc, char *argv)

i probuje odwolywac sie do tych argumentow poprzez argv[1], argv[2],

tyle ze to w tym przypadku nie dziala, chociaz przy prostszych programach to dzialalo.




Zeby zastosowac Twoj zapis chyba musze napisac:
int main(int argc, char **argv).

W tym procesie potomnym chce odczytac pipe'a:

read(fd[0], buf, size);

Zatem chcialbym przypisac argv[1][0] do fd[0].
Wystarczy taki zapis:

fd[0] = atoi (&(argv[1][0]));

czy lepiej jakos inaczej to zapisac??

ZipoKing

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #9 dnia: 2007-01-02, 18:23:39 »
2 gwiadki tak i tak musisz dać, ponieważ tak jest main zdefiniowany:
int main(int argc, char **argv) - innego wyjścia nie ma.

atoi() na type char nie musisz robić. wystarczy zwykłe =

A poniżej masz kompletnie działający program (zmień wartość zmiennej prog).

#include
#include
#include

int fd[2];
char fd_t[3];
char prog[64] = "/home/pawel/programowanie/poligon/a.out";
char *args[3];

int main(int argc, char *argv[])
{
  if(argc == 2){
    printf("Potomek: %d %dn", (int)argv[1][0], (int)argv[1][1]);
  } else {
    pipe(fd);
    fd_t[0] = (char)fd[0];
    fd_t[1] = (char)fd[1];
    fd_t[2] = '0';
   
    printf("Rodzic: %d %dn", fd[0], fd[1]);
   
    if(fork() == 0){
      args[0] = prog;
      args[1] = fd_t;
      args[2] = NULL;
      execv(prog, args);
    }
   
 
  close(fd[0]);
  close(fd[1]);
 
  }
 
  return 0;
}

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #10 dnia: 2007-01-02, 19:26:25 »
Dzieki za kod, ale macierzysty mi juz dzialal. Twoj kod wykorzystuje execv, moj execl. W zasadzie na jedno wychodzi. Komilujuja sie te kody bez problemu. Problem jest w odebraniu argumentu w p.potomnym jak napisalem w poprzednim poscie. Niby p.potomny tez sie kompiluje bez problemu, ale odczyt z pipe'a nie dziala. Byc moze wynika to z tego ze u mnie nie ma zamkniecia deskryptorow, ale dodam, ze bez zamknietych deskryptorow wczesniej pipe' dzialal bez problemow, gdy uzywalem dup().

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #11 dnia: 2007-01-02, 19:26:36 »
Dzieki za kod, ale macierzysty mi juz dzialal. Twoj kod wykorzystuje execv, moj execl. W zasadzie na jedno wychodzi. Komilujuja sie te kody bez problemu. Problem jest w odebraniu argumentu w p.potomnym jak napisalem w poprzednim poscie. Niby p.potomny tez sie kompiluje bez problemu, ale odczyt z pipe'a nie dziala. Byc moze wynika to z tego ze u mnie nie ma zamkniecia deskryptorow, ale dodam, ze bez zamknietych deskryptorow wczesniej pipe' dzialal bez problemow, gdy uzywalem dup().

ZipoKing

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #12 dnia: 2007-01-02, 19:40:23 »
Jak już zostało napisane wyżej, nie ma szans, żeby w taki sposób ci czytało potoki, ponieważ nowy proces ma swoje własne tzw. środowisko wykonania i z zasady nie może widzieć środowiska innego procesu (w tym nie może korzystać z potoków innego procesu, ponieważ potok to "prywatna" sprawa każdego procesu). Robiąc fork() tworzy się kopia (klon) tablicy deskryptorów i pomimo tego, że w procesie-rodzicu i procesie-potomku istnieją otwarte deskryptory o takich samych nazwach, są to jednak różne deskryptory. Dlatego też, jak już wcześniej pisałem, jedyna opcja komunikacji proces<->proces to gniazda. A jeżeli koniecznie chcesz korzystać z potoków, będziesz musiał dodatkowo dopisać funkcję interfejs gniazdo<=>potok, lub skorzystać z popen - innego wyjścia nie ma.

nstn2

  • Gość
przekazanie deskryptora przez execl ????
« Odpowiedź #13 dnia: 2007-01-02, 22:37:45 »
ZipoKing, dalbym Ci "Pomogl", ale nie wiem gdzie jest ta opcja na tym forum. Dzieki za pomoc, juz udalo mi sie rozwiazac problem.