20

20



Komunikacja między procesami w llnixie

łendif    /* DEBOG */

)

main(int argc, char *argv[J) { char    *host;

static char directory[DIR_1]; /* Nazwa katalogu */ if (argc < 2) {

fprintf(stderr, "Składnia %s serwer [katalog]\n", argv[0]); exit(1);

}

host « argv[l];    /* przypis serwer    */

if (argc > 2)

strcpy(directory, argv[2]); else

Strcpy(directory ,

tree_l(host, directory);    /* dalej!    */

Główny trzon programu tree_client. c stanowi kod, który albo jest podobny w swej naturze do poprzednich przykładów, albo jest tak napisany, że nie wymaga komentarza. Jedyna instrukcja, która może wymagać bliższych wyjaśnień, to printf. Służy ona do wyświetlania danych o strukturze katalogów na ekranie. Jak wspomniano, zdalna procedura zwraca wskaźnik na string. Jest to gotowy do wyświetlenia napis zawierający odpowiednie spacjowe wcięcie, nazwę katalogu i na końcu znak nowej linii. Wskaźnik do tego napisu jest zapisany w postaci result->dir_result_u.line_ptr. Jego właściwą składnię uzyskano po odczytaniu zawartości pliku tree.h wygenerowanego programem rpcgen.

Program 9.7. Kod części serwerowej (tree_server.c) programu odczytującego drzewo katalogów

/*

««#»#

łłłłł

******

******

****

******

*****

*

*

******

*****

t

*

f

*

*

#

#

ł

*

*

*

f

t

t

ł

*

*****

*****

****

*****

*

#

»

*

*****

*

*

f

*****

*

*

*

ł

*****

*

#

*

*****

#

*

*

*

*

ł ł

*

f

*

*

ł

*

ł

*

ł

*

*

******

******

****

******

*

*

**

******

*

*

*/

♦include "local.h" łlnclude "tree.h"

static int cur = 0,    /* indeks do tablicy wynikowej */

been_allocated = 0,    /* czy zarezerwowane miejsce na tablicę? *,

depth = 0;    /* poziom wcięcia */

struct stat DIR

struct dirent

char

int

static char


dir_result *

do_dir_l_svc( char **f, struct svc_req static dir result result;


statbuff;

*dp;

*dentry;

♦current;

length;

buffer[DIR_l];


* rqstp) (

/* tablica albo void */

/* na sprawdzanie statusu pozycji */ /* pozycja katalogowa */

/* wskaźnik na bieżąca pozycję */

/* pozycja w tablicy wynikowej */

/* długość bieżącej pozycji */

/* położenie tymczasowe */


* zapisz pozycję w buforze, potem skopiuj bufor do większej tablicy

sprintf(buffer, "%*s %-10s\n", depth, " ", dentry->d_name); length = strlen(buffer) ;

memcpy((char *)result.dir_result_u.line_ptr + cur, buffer, length); cur += length;    /* zmień wskaźnik na nast. poł. */

current = dentry->d_name;    /* nowy katalog */

(dir_result *)do_dir_l_svc(scurrent, rqstp);    /* wywołaj się */

chdir("..");    /* wróć jeden poziom */

deDth -= INDENT:    /* zmień poziom wcięcia */

dentry = -“addir(dp);

)

closedir(dp);

)

return (Sresult);


if (!been allocated)


if ((result.dir_result_u.line_ptr=(line return (Sresult); else{

been_allocated - 1;

) else if ( depth == 0 )    {

memset(result.dir_result_u.line_ptr, cur = 0;

}

if ((dp - opendir(*f)) != NULL) ( chdir(xf);

dentry - readdir(dp); while (dentry != N(JLL) (

if (stat(dentry->d_name, Sstatbuff) != -1)

if ((statbuff.st_mode s S_IFMT) == S_IFDIR SS dentry->d_name[0] !=«.») { depth += INDENT;

/*


/* jeśli nie, zarezerwuj */


)malloc(sizeof(linę))) == NULL)


/*

/*

0,

/* zeruj poziom wcięcia */


rezerwowanie miejsca OK */ zeruj «starą» zawartość */ sizeof(linę));


/* jeśli skutecznie otwarty */

/* przejdź do katalogu */

/* odczytaj pierwsza pozycję */


/* jeśli dostępna */

/* i jest katalogiem */ /* i nie zawiera kropek */ /* zmień wcięcie */


/* odczytaj kolejna pozycję */ /* temu panu już dziękujemy */ /* oddaj wyniki */

W programie tree_server. c występuje kilka statycznych zmiennych typu całkowito-liczbowego. Są one używane w roli liczników i znaczników. Identyfikator cur wskazuje bieżące miejsce (przesunięcie) w tablicy danych wynikowych. Od tego miejsca mogą być zapisywane kolejne odczytane dane. Początkowo przesunięcie to jest równe 0. Identyfikator been_allocated funkcjonuje jako znacznik sygnalizujący, czy bufor wyjściowy został już zarezerwowany. Początkowo znacznik ten jest ustawiany na 0 (FALSE, czyli „nie został zarezerwowany"). Ostatni statyczny identyfikator, depth, zawiera aktualny w każdej chwili numer poziomu zagnieżdżenia. On również początkowo ma wartość 0. Procedura do_dir_l_svc otrzymuje wskaźnik na łańcuch znaków (konkretnie na tablicę znaków) oraz wskaźnik na uchwyt klienta RPC. W procedurze tej rezerwowane jest miejsce na kilka zmiennych lokalnych, które ułatwiają manipulowanie i pozyskiwanie informacji o katalogach. Następnie pojawia się instrukcja if. Ta służy do testowania znacznika been_allocated. Jeżeli bufor wynikowy nie został jeszcze zarezerwowany, wywołana jest funkcja malloc, która go zarezerwuje. Na pozyskiwany obszar pamięci jest rzutowany odpowiedni typ, a wskaźnik do tego obszaru trafia do pola line_ptr struktury dir_result_u. Po zarezerwowaniu miejsca na bufor znacznik been_allocated

283


Wyszukiwarka

Podobne podstrony:
17 p01 #include <stdio.h> #include <conio.c> #include <iostream.h> int main(int ar
Nasz pierwszy program #include <stdio.h> #include <stdlib .h> int main(int argc , char *
098 TIF int main(int argc, char* argv[]){ KlasaNaucz t1; KlasaPrac s1; cout « tl.nldNaucz « endl; co
03 p01 #include <stdio.h> #include <conio.c> #include <iostream.h> int main(i
1.4. Środowisko programistyczne #include "soleng.h" int main(int argc, char *argv[]){ eWor
18 gdb hakingff’ live:/ramdisk/home/haking ) main (int argc, char *argv[]) { fn(argv[ll); print
Podstawy informatyki 2 Wykład nr 2 dr inż. Jarosław Forenc 3/46Argumenty funkcji main int main(int a
Komunikacja między procesami w Unixie int * print_hello_l(void *argp, CLIENT *clnt) { static int
image001 6. Uzupełnić tabelę nazwami mechanizmów komunikacji między procesami w taki sposób, żeby wł
DSC00273 (6) 6. Uzupełnić tabelę nazwami mechanizmów komunikacji między procesami w taki sposób, żeb

więcej podobnych podstron