Nowe posty

Autor Wątek: Tworzenie shella  (Przeczytany 3415 razy)

rafalzmarek

  • Gość
Tworzenie shella
« dnia: 2013-01-28, 12:38:23 »
Proszę o pomoc w napisaniu powłoki
1. Wbudowaną obsługę zmiennych środowiskowych, tzn. możliwość ustawiania i wyświetlania
dowolnej zmiennej
środowiskowej.
2. Wbudowane polecenie pwd wyświetlające aktualny katalog roboczy
3. Wbudowane polecenie cd pozwalające na zmianę katalogu roboczego. Polecenie powinno
akceptować nazwy ścieżkowe. Wykonane bez argumentu powinno zmieniać katalog roboczy
na katalog domowy użytkownika.
4.Wbudowane polecenie ls wyświetlające zawartość katalogu roboczego (jeżeli podane bez
argumentów) lub dowolnego podanego jako argument.
5.Wbudowane polecenie ll odpowiadające poleceniu ls l.
Funkcjonalność jak w pkt 4.
6.Możliwość uruchomienia dowolnego programu poprzez podanie jego nazwy (ew. nazwy
ścieżkowej).
Proponowana struktura projektu komponenty



Parser


Analiza polecenia. Wywoływanie funkcji obsługujących poszczególne polecenia. Np.



cmd_env(char* cmdline)

cmd_pwd(char* cmdline)

cmd_cd(char* cmdline)

cmd_ls(char* cmdline)

cmd_exec(char* cmdline)
Każda funkcja obsługuję jedną z funkcji (env – obsługa zmiennych środowiskowych, pwd – obsługa
polecenia pwd, cd – obsługa polecenia cd itd.).
Proponowana lista poleceń rozpoznawanych przez parser:




set zmienna=wartość

unset zmienna

echo zmienna

pwd

cd
ściezka

cd

ls

ls
ścieżka

ll

ll
ścieżka

exec
ścieżka

quit/exit
Algorytm działania parsera:
1.
Wyświetl znak zachęty
2.
Wczytaj linię
3.
Rozpoznaj polecenie
4.
Przekaż sterowanie do wybranej funkcji lub zakończ program (quit/exit)
5.
Wróć do punktu 1
Standardowe funkcje przydatne przy pisaniu parsera: printf, scanf, fgets, strcpy, strncpy, strcmp,
strncmp, strok.


Moduł env – manipulowanie zmiennymi
środowiskowymi


Działanie:


1.
Rozpoznanie polecenia
2.
Wydobycie argumentów (nazwa, ew. wartość zmiennej)
3.
Wywołanie właściwej funkcji bibliotecznej.
Przydatne funkcje standardowe: getenv, putenv, setenv, unsetenv, sscanf, printf, strok.
Moduł pwd – wyświetlenie nazwy katalogu roboczego


Działanie:


1.
Wywołanie odpowiedniej funkcji bibliotecznej
Przydatne funkcje standardowe: getcwd, printf.
Moduł cd – zmiana katalogu roboczego


Działanie:


1.
Sprawdzenie czy podany został argument.

2.
Jeżeli argument jest to wywołanie funkcji bibliotecznej
3.
Jeżeli nie ma argumentu to pobranie zawartości zmiennej
środowiskowej HOME i
wywołanie funkcji bibliotecznej.
Przydatne funkcje standardowe:
chdir, sscanf, strok
Można wykorzystać funkcjonalność modułu env.


Moduł ls – wyświetlenie zawartości katalogu


Działanie:


1.
Określenie typu polecenia (krótki lub długi format)
2.
Sprawdzenie czy podany został argument.
3.
Jeżeli brak argumentu to pobranie wartości zmiennej
środowiskowej PWD
4.
Otwarcie katalogu i kolejne odczytywanie pozycji w katalogu.
5.
Jeżeli długi format to odczytanie atrybutów każdej pozycji.
6.
Wyświetlenie informacji zgodnie z założonym formatem
7.
Zamknięcie katalogu.
Przydatne funkcje standardowe: opendir, readdir, closedir, stat, sscanf, strcmp, strcat, strok, printf.
Moduł exec – uruchomienie programu


Działanie:


1.
Wyodrębnienie nazwy uruchamianego programu z polecenia
2.
Rozwidlenie procesu (fork)
3.
Proces macierzysty czeka na zakończenie potomka, a później kontynuuje działanie.
4.
Proces potomny uruchamia podany program (exec).
Przydatne funkcje standardowe:
sscanf, strok, fork, wait, waitpid, jedna z funkcji z rodziny exec.

rafalzmarek

  • Gość
Tworzenie shella
« Odpowiedź #1 dnia: 2013-01-28, 12:41:25 »
Nie może być używana biblioteka system...

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
Tworzenie shella
« Odpowiedź #2 dnia: 2013-01-28, 20:13:31 »
Jeśli nie może być używana funkcji system() (domyślam się, że o to chodziło), to pozostaje fork(). W Google jest bardzo dużo przykładów i opisów jak to zrobić w kilku[nastu] linijkach. Dopisuj przy wyszukiwaniu zawsze "C++" i/lub "Linux", a na pewno znajdziesz co potrzebujesz.

Co do samej powłoki, musisz wczytywać input od usera i go obrabiać. Trochę zabawy na stronach ale generalnie nic skomplikowanego. Masz to zresztą rozpisane dość dokładnie w poleceniu.
Całość zamknąć w nieskończoną pętlę, zakańczać program przy poleceniu użytkownika "exit".

Do modyfikacji zmiennych środowiskowych służy setenv() [1] z stdlib.h, do usuwania unsetenv() [1]. Pobieranie oczywiście getenv() [2].
Do pobierania katalogu roboczego masz getcwd() [3], do ustawiania chdir() [4].
Poszukaj też na Google jak listować katalog w C++, będzie na pewno dobrze opisane.

[1] http://www.kernel.org/doc/man-pages/online/pages/man3/setenv.3.html
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getenv.3.html
[3] http://www.kernel.org/doc/man-pages/online/pages/man3/getcwd.3.html
[4] http://www.kernel.org/doc/man-pages/online/pages/man2/chdir.2.html

rafalzmarek

  • Gość
Tworzenie shella
« Odpowiedź #3 dnia: 2013-01-29, 09:50:07 »
Dzięki wielkie zabieram się za tworzenie;) Gdyby ktoś miał jeszcze jakieś rady dla początkującego byłbym wdzięczny:)

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
Tworzenie shella
« Odpowiedź #4 dnia: 2013-01-29, 14:30:01 »
Dodam tylko, że warto zacząć od tego pasera poleceń użytkownika. Rozbić input na poszczególne części: polecenie + tablicę parametrów. Najprościej na spacjach, choć fajnie by było dodać także obsługę cudzysłowów pozwalających przekazać łańcuch znaków ze spacjami jako argument.

Potem wystarczy sprawdzić, czy dane polecenie masz obsłużyć wewnętrznie w swoim shellu, a jeśli nie, to przekazać wszystko z marszu do execvp() [1] po forku.

[1] http://www.kernel.org/doc/man-pages/online/pages/man3/exec.3.html