Funkcja rexec wymaga sześciu argumentów. Pierwszym jest wskaźnik na nazwę zdalnego hosta. Wskaźnik jest przekazywany do rexec za pośrednictwem funkcji gethostbyna-me (więcej informacji na temat tej funkcji znajduje się w rozdziale 10). Drugi argument, inport, jest liczbą całkowitą oznaczającą port, który zostanie użyty podczas połączenia. W rexec najczęściej używa się portu numer 512 (jest to pracujący według TCP port skojarzony z wykonywaniem zdalnych procedur). W dalszej kolejności występują dwa argumenty w postaci ciągów znaków, w których należy przekazać nazwę użytkownika i jego hasło. Jeżeli zostaną one ustalone na NULL, system sprawdzi zawartość pliku .netrc, znajdującego się w katalogu domowym użytkownika, szukając nazwy hosta, użytkownika i hasła. Jeżeli plik .netrc nie istnieje albo jeśli zawiera tylko częściowe informacje, użytkpwnik zostanie poproszony o uzupełnienie danych. Szóstym argumentem rexec jest wskaźnik na liczbę całkowitą. Jeśli ta wartość jest inna niż 0, rexec założy, że jest to wskaźnik do prawidłowego deskryptora pliku i spróbuje przypisać na czas wykonywania zdalnej procedury standardowe wyjście błędów do pliku wskazanego deskryptorem. Funkcja rexec zakończona powodzeniem zwraca deskryptor poprawnego pliku gniazda strumieniowego, który jest przypisywany do standardowego wejścia i wyjścia lokalnego hosta. W przypadku błędów funkcja zwraca -1.
A oto przykładowa aplikacja funkcji rexec:
/*
* Korzystanie ż rexec
* /
łinclude <stdio.h>
łinclude <sys/types.h>
łinclude <unistd.h>
łinclude <stdlib.h>
łinclude <netinet/in.h>
łinclude <netdb.h>
main(int argc, char *argv[]) (
int fd, count ;
char buffer[BUFSIZ], *command, *host;
if(argc!=3) {
fprintf (stderr, 'Składnia: %s host polecenie\n", argv[0]); exit(1);
)
host =argv[l];
comraand = argv[2);
if ((fd = rexec(Shost, htons(S12), 0, 0, command, 0)) == -1) fprintf (stderr, "niepowodzenie rexec\n"); exit(2);
)
while{(count - read(fd, buffer, BUFSIZ)) > 0) fwrite(buffer, count, 1, stdout);
W programie 9.1. pierwszym argumentem linii poleceń jest host, w którym zostanie wykonana zdalna procedura. Drugim argumentem jest polecenie przekazywane zdalnemu hostowi. W drugim argumencie wywołania funkcji rexec użyto wywołania sieciowego htons, które ma zagwarantować właściwą kolejność bajtów w numerze portu. Prototyp htons można odszukać w pliku <netinet/in. h>. Argumenty określające nazwę i hasło użytkownika ustawiono na 0. Nakaże to funkcji iexec najpierw sprawdzić plik .netrc w katalogu domowym właściciela pod kątem danych z nazwą i hasłem użytkownika, a dopiero w przypadku nieistnienia tego pliku pobrać te dane wprost od użytkownika. Jeżeli rexec zakończy się bez błędu, zostaną odczytane i wyświetlone (na standardowym wyjściu) rezultaty działania polecenia w zdalnym hoście. Na ilustracji 9.4 pokazano przebieg kompilowania i uruchamiania programu 9.1 (warto zwrócić uwagę na włączenia bibliotek).
morpheus% p91 stimpty who
Name (stimpty:gray): gray
Password (stimpytgray):
bjeroszk console Apr 14 15:20
bjeroszk pts/1 Apr 14 15:21
Na podstawie otrzymanych wyników można powiedzieć, że plik .netrc użytkownika nie zawierał wpisów dla hosta stimpy. Hasło użytkownika nie odbiło się echem na konsoli. Funkcja rexec komunikuje się z rexecd (demon zdalnego wykonywania) z systemu hosta. Choć funkcja rexec jest godna uwagi i zapewnia bezproblemowy sposób wykonywania poleceń w zdalnych hostach, często zachodzi potrzeba generowania własnych par klient-serwer spełniających bardziej specyficzne wymagania.
Zgłębianie zagadnień związanych z oprogramowywaniem systemu RPC zaczniemy od przekształcenia prostego programu C z jedną lokalną funkcją do postaci pary klient-serwer z jedną wywołaną zdalnie procedurą. Raz wygenerowany program oparty na systemie RPC będzie można uruchamiać w środowisku rozproszonym, w którym pro-ces-klient, zawierający funkcję przeznaczoną do wykonania, jest ulokowany w innym hoście niż proces-serwer. Program, który przekształcimy (program 9.2) został napisani' w C. Jego działanie sprowadza się do wywołania jednej lokalnej funkcji, print_hello, wyświetlającej komunikat Cześć, ludzie! Funkcja po wyprowadzeniu tego tekstu kończy działanie i zwraca do main wartość otrzymaną z printf. Określa ona, czy funkcja printf wykonała zaleconą operację bezbłędnie.'
1 Wielu programistów nie zdaje sobie sprawy z tego, że printf zwraca jakąś wartość. Jednak przepuszczenie dowolnego programu zawierającego wywołanie tej funkcji przez narzędzie lint spowoduje zazwyczaj wygenerowanie komunikatu informującego, że wartość zwracana przez printf jest niewykorzystywana.
25;