gitweb on Svarog
projekti pod git sistemom za održavanje verzija -- projects under the git version control system19a392b131afa485647740e6a253bc23f408f04b
1 % skripta-os2.tex
2 % Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
3 % Doni Pracner, Ivan Pribela
4 % 2011/12 -- 2013/14
10 % osnovne informacije koje ce se prikazati na naslovnoj strani,
11 % kao i u informacijama u generisanom pdfu
27 %change the default font
34 %podesavanja outputa za pdf verzije
47 %\usepackage{keystroke}
48 % ispod je dodata alternativa za ovaj paket
56 draw,
57 fill=white,
59 rectangle,
60 rounded corners=2pt,
61 inner sep=1pt,
62 line width=0.5pt,
63 font=\small\sffamily
65 ;
66 }
72 %margine
77 %customize the itemize environments
81 \olditemize
87 }
89 %% ovi redovi daju header i footer
93 %\fancyfoot[C]{\thepage}
104 %\renewcommand{\footrulewidth}{0.5pt}
105 %\addtolength{\headheight}{0.5pt} % make space for the rule
111 }
114 %promene u marginama:
115 %\setlength{\marginparwidth}{32pt}
116 %\setlength{\textwidth}{620pt}
117 %\setlength{\textheight}{620pt}
120 %% specijalni blokovi koji služe kao podsetnici u radu ili napomene
124 }
128 }
130 %boldovane skice visokog prioriteta
137 % ako je sledeci red odkomentarisan nista od skica nece biti ispisano
138 % u finalni dokument
143 \maketitle
145 % theorems, definition etc.
146 %''''''''''''''''''''''''''
157 basicstyle=\ttfamily,
158 showstringspaces=false,
159 breaklines=true
160 }
163 % basicstyle=\footnotesize\ttfamily,
164 keywordstyle=\textbf,
166 breakatwhitespace=true,
167 % prebreak=\P,
168 % postbreak=\ding{229}\space,
169 language=Modula-2,
170 xleftmargin=4em
171 }
174 frame=l,
175 % frameround=fftt,
176 xleftmargin=4em
177 }
180 style=codeblock,
181 numbers=left,
182 firstnumber=1,
183 stepnumber=1
184 }
189 % ----------------==================--------------------------------------
190 % Pravi pocetak rada
193 Programi u ovoj skripti su testirani sa kompajlerom ``GNU Modula 2'' (u
195 sistemima iz Debian porodice.
197 \tableofcontents
199 \newpage
201 %\begin{multicols}{2}
207 (GCC). Podržava nekoliko dijalekata jezika ``Modula 2'' --
208 najznačajniji su ISO standard i nekoliko varijacija koje je originalni
211 dobijaju i besplatne ISO, PIM i još neke biblioteke.
216 Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
218 MODULE hello;
220 FROM StrIO IMPORT WriteString, WriteLn;
222 BEGIN
223 WriteString('hello world');
224 WriteLn
225 END hello.
228 Primećuje se razlika u modulu iz koga se uvoze komande u odnosu na
231 brojevima i tako dalje. Za pregled dostupnih biblioteka predlaže se
232 korišćenje zvanične stranice:
235 biblioteke.
237 Predpostavimo da smo da je fajl napravljen u trenutnom direktorijumu,
239 ``joe'' koji se koristi na vežbama). Kreirani fajl se tada može
240 prevesti u izvršnu verziju sledećom komandom:
242 gm2 hello.mod
245 Ako je kod ispravan (kao onaj gore) u istom direktorijumu će se
248 ./a.out
251 direktorijuma (koji se označava tačkom). Ako je potrebno da
252 izvršni fajl ima neki drugi naziv može se koristiti poziv sledećeg
253 tipa:
255 gm2 -o imeIzlaznogFajla ulaznifajl
259 stranicu kompajlera.
260 %ovde je trebalo -{}- da razdvoji dva minusa, jer se inače tumače kao jedan.
264 Mapiranje procedura na sistemske pozive se može izvršiti preko
265 specijalnog definicionog modula koji u zaglavlju sadrži ključne reči
267 imenima sistemskih poziva i imaju parametre i povratne vrednosti
270 komande možemo videti sa
272 man system
275 odnosno videćemo da je poziv definisan na sledeći način:
277 int system(const char *command);
279 što znači da vraća ceo broj, a prima jedan argument koji je pokazivač
280 (što se označava *) na znak. Ovo je zapravo ceo string, pošto se u C
281 jeziku oni predstavljaju kao pokazivač na prvi znak, a string se onda
282 sastoji od svih sledećih znakova u memoriji dokle god se ne naiđe na
283 0C. Srećom, sve ovo se automatski mapira kreiranjem sledećeg modula:
286 DEFINITION MODULE FOR "C" Lib;
288 EXPORT UNQUALIFIED system;
290 PROCEDURE system(command: ARRAY OF CHAR): INTEGER;
292 END Lib.
295 Nije potrebno praviti prazne implementacione module. Iz ovakvog modula
296 se mogu uvoziti i koristiti procedure kao i iz bilo kakvog
297 ``normalnog'' modula, kao što se može videti u sledećem primeru, koju
298 od korisnika učitava stringove i pokušava da ih izvrši kao da su uneti
299 u komandnoj liniji, dokle god korisnik ne unese reč ``kraj'':
301 MODULE Zad2;
303 FROM StrIO IMPORT
304 ReadString, WriteString, WriteLn;
305 FROM StrLib IMPORT
306 StrEqual;
307 FROM Lib IMPORT
308 system;
310 TYPE
313 VAR
314 Komanda: String;
316 PROCEDURE Izvrsi(Komanda: ARRAY OF CHAR);
317 VAR
318 c: INTEGER;
319 BEGIN
320 c:= system(Komanda);
321 END Izvrsi;
323 BEGIN
324 WriteString("?> "); ReadString(Komanda);
325 WHILE NOT StrEqual(Komanda, "kraj") DO
326 Izvrsi(Komanda);
327 WriteString("?> "); ReadString(Komanda);
328 END;
329 END Zad2.
332 Prilikom mapiranja sistemskih poziva je moguće koristiti ``...'' na
333 kraju liste argumenata da se označi da je moguće proslediti
334 proizvoljan broj argumenata nakon navedenih, koji će biti premapirani
335 na odgovarajuće tipove podataka. Takođe je moguće i označiti da se
336 povratna vrednost procedure ne mora koristiti. U gornjem primeru je
340 vrednost.
342 Neki primeri pretvaranja tipova su dati u Tabeli~\ref{t-pretvaranje-tipova}, preuzetoj sa \url{http://www.nongnu.org/gm2/interface_to_c.html}.
347 Stvarni parametar & Konverzija & Tip vrednosti koji će biti prosleđen\\
348 \hline
349 123 & - & long long int\\
350 "hello world" & - & const char *\\
351 a: ARRAY OF CHAR & ADR(a) & char *\\
353 3.14 & - & long double
361 Korišćenje sistemskih poziva se može ilustrovati primerom čitanja
365 pokazivač kao ulazni parametar, a vraća pokazivač na slog koji
368 kraju i zatvara otvoreni direktorijum. Bitno je zatvarati otvorene
369 resurse jer je moguće da sistem odbije da otvori novi ako ih
370 proces već ima previše otvorenih.
372 Kada imamo imena stavki iz direktorijuma o njima možemo dobiti više
374 putanja do fajla, a drugi je pokazivač na strukturu u koju će komanda
375 upisati podatke. Obratiti pažnju da zbog ovoga struktura već mora
376 postojati u memoriji, ili kao lokalna promenljiva odgovarajućeg
377 slogovnog tipa, ili dinamički alocirana korišćenjem pokazivača na nju.
379 Budući da su u pitanju sistemski pozivi niskog nivoa, veličine tipova
380 su nažalost promenljive i mogu zavisiti od konkretnog operativnog
382 sistem. Zbog ovoga su date dve varijante bibilioteke sa tipovima.
383 Prva je testirana na Lubuntu 11.10 32bit, a druga je testirana na
384 Kubuntu 11.10 64bit.
387 DEFINITION MODULE FOR "C" Lib32;
388 FROM SYSTEM IMPORT
389 ADDRESS, BYTE;
390 EXPORT UNQUALIFIED opendir, readdir, closedir, stat,
391 PDir, DirEnt, PDirEnt, Stat, PStat, PInt;
395 (* types for 32 bit *)
396 TYPE
397 PDir = ADDRESS;
398 DirEnt = RECORD
399 ino: INTEGER;
400 off: INTEGER;
401 reclen: SHORTCARD;
402 type: BYTE;
404 END;
405 PDirEnt = POINTER TO DirEnt;
406 Stat = RECORD
407 dev: LONGINT;
408 ino: LONGINT;
409 mode: INTEGER;
410 nlink: LONGINT;
411 uid: INTEGER;
412 gid: INTEGER;
413 pad1: LONGINT;
414 rdev: INTEGER;
415 size: INTEGER;
416 blksize: INTEGER;
417 blocks: INTEGER;
418 atime: LONGINT;
419 mtime: LONGINT;
420 ctime: LONGINT;
421 END;
426 (* types for 64 bit *)
427 TYPE
428 PDir = ADDRESS;
429 DirEnt = RECORD
430 ino: LONGINT;
431 off: LONGINT;
432 reclen: SHORTCARD;
433 type: BYTE;
435 END;
436 PDirEnt = POINTER TO DirEnt;
437 Stat = RECORD
438 dev: LONGINT;
439 ino: LONGINT;
440 nlink: LONGINT;
441 mode: INTEGER;
442 uid: INTEGER;
443 gid: INTEGER;
444 pad1: INTEGER;
445 rdev: LONGINT;
446 size: LONGINT;
447 blksize: LONGINT;
448 blocks: LONGINT;
449 atime: LONGINT;
450 mtime: LONGINT;
451 ctime: LONGINT;
452 END;
456 PStat = POINTER TO Stat;
457 PInt = POINTER TO INTEGER;
459 PROCEDURE opendir(name: ARRAY OF CHAR): PDir;
460 PROCEDURE readdir(dirp: PDir): PDirEnt;
463 END Lib32.
467 MODULE Zad5;
469 FROM SYSTEM IMPORT
470 ADR;
471 FROM StrIO IMPORT
472 WriteString, WriteLn;
473 FROM NumberIO IMPORT
474 WriteInt;
475 FROM StrLib IMPORT
476 StrLen, StrConCat;
477 FROM Args IMPORT
478 Narg, GetArg;
479 FROM Lib32 IMPORT
480 opendir, readdir, closedir, stat, PDir, PDirEnt, Stat;
481 FROM errno IMPORT
482 geterrno;
484 TYPE
487 VAR
488 Putanja: String;
489 n, i: INTEGER;
490 ok: BOOLEAN;
492 PROCEDURE Listaj(Ime: ARRAY OF CHAR);
493 VAR
494 dir: PDir;
495 entry: PDirEnt;
496 info: Stat;
497 c: INTEGER;
498 Len: CARDINAL;
499 Putanja: String;
500 BEGIN
501 dir:= opendir(Ime);
502 IF dir = NIL THEN
503 WriteString("Folder "); WriteString(Ime); WriteLn;
504 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
505 WriteString(" Ne mogu da otvorim direktorijum."); WriteLn();
506 ELSE
507 Len:= StrLen(Ime);
509 StrConCat(Ime, "/", Ime);
510 END;
511 WriteString("Folder "); WriteString(Ime); WriteLn;
512 entry:= readdir(dir);
513 WHILE entry # NIL DO
515 StrConCat(Ime, entry^.name, Putanja);
516 c:= stat(Putanja, ADR(info));
517 WriteString(" ");
518 IF c = -1 THEN
519 WriteString("? ? KB");
520 ELSE
521 WriteInt(info.nlink, 3);
523 END;
524 WriteString(" "); WriteString(entry^.name); WriteLn;
525 END;
526 entry:= readdir(dir);
527 END;
528 c:= closedir(dir);
529 IF c = -1 THEN
530 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
531 WriteString(" Ne mogu da zatvorim direktorijum."); WriteLn();
532 END;
533 END;
534 END Listaj;
536 BEGIN
537 n:= Narg();
539 ok:= GetArg(Putanja, i);
540 WriteLn;
541 Listaj(Putanja);
542 END;
543 WriteLn;
544 END Zad5.
550 (``račva''). Novi proces je identičan sa originalnim, osim u svom
551 identifikacionom broj. Komanda ne prima parametre i vraća jedan integer, pa se može mapirati na sledeći način:
553 PROCEDURE fork(): INTEGER;
556 Oba procesa se nakon račvanja nastavljaju odvijati u sledećem redu
557 koda. Jedino po čemu se razlikuju je vrednost koju je vratio
560 ``deteta'', i može se koristiti za komunikaciju sa detetom, a u novom
561 procesu je ova vrednost jednaka nuli. Budući da je najčešće potrebno
562 da dete i roditelj rade različite stvari, to se obično rešava kodom
563 sledećeg oblika:
565 pid := fork();
566 IF pid = 0 THEN
567 (* "detetove" operacije *)
568 ELSE
569 (* "roditeljske" operacije *)
570 END;
574 originalnom procesu sa efektom da se proces uspava dokle god neki od
575 procesa dece ne završi sa radom. Veća kontrola nad ovim ponašanjem se
577 koji proces čekamo da se završi.
579 U sledećim sekcijama će biti ilustrovano nekoliko klasičnih primera
580 organizacije procesa.
588 pid := 0;
589 i := 1;
590 WHILE (pid = 0) AND (i < n) DO
591 pid := fork();
592 IF pid # 0 THEN
593 (* ... *)
594 ELSE
595 INC(i);
596 END;
597 END;
605 {
607 }
611 }
619 pid := -1;
620 j := 0;
621 WHILE (pid # 0) AND (j < m) DO
622 pid := fork();
623 IF pid # 0 THEN
624 INC(j);
625 ELSE
626 (* ... *)
627 END;
628 END;
637 {
639 }
642 }
650 i := 1;
651 j := 0;
652 WHILE (i < n) AND (j < m) DO
653 pid := fork();
654 IF pid # 0 THEN
655 INC(j);
656 ELSE
657 INC(i);
658 j:=0;
659 END;
660 END;
668 ]
672 }};
678 % ----------------------------------------------
680 \newpage
682 \appendix
687 Ova sekcija treba da omogući instalaciju kompajlera GNU Modula 2 na
688 već postojeći GNU Linux operativni sistem iz Debian porodice, koja
689 uključuje i sve varijante Ubuntu distribucije, kao i Linux Mint i
690 mnoge druge. Kompajler je moguće bez većih problema instalirati i na
691 bilo koji drugi Linux (a i OSX i Windows), kompajliranjem iz izvornog
692 koda, za šta preporučujemo konsultovanje sa zvaničnom stranicom
695 Ovo uputstvo neće ulaziti u detalje kako instalirati operativni
696 sistem. Za one koje koriste Windows i nisu sigurni kako da paralelno
697 instaliraju drugi operativni sistem, preporučujemo korišćenje
698 virtuelne mašine (npr besplatni Virtual Box,
700 lakše skinuti već instaliranu mašinu sa nekim od Debian sistema, npr
701 Ubuntu ili Kubuntu, ili eventualno neku manje zahtevnu verziju kao što
702 je Lubuntu, ako su performanse problematične.
706 Prvi korak za instalaciju dodatnog kompajlera GNU Modula 2 je
707 dodavanje repozitorijuma softvera u sistem. Ovo se može uraditi ručnim
710 #
711 # GNU Modula-2 repo
712 #
714 deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main
715 deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main
718 Alternativno se mogu koristiti sledeće komande:
721 sudo add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
722 sudo add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
725 Većina sistema omogućava i da se ovo uradi preko nekih grafičkih
726 alata.
728 Nakon dodavanja novog izvora za softver potrebno je u konzoli uraditi
729 sledeće:
731 sudo apt-get update
732 sudo apt-get install gm2-doc gm2
735 Po želji se može skinuti i izvorni kod kompajlera sledećom komandom:
737 sudo apt-get source gm2
744 Pri pokušaju kompajliranja se na nekim sistemima može desiti da
747 pošto postoji problem u pakovanju kompajlera, ali moguće je da utiče i
748 na neke druge sisteme.
750 Greška se ispravlja na sledeći način (korisnik treba da
751 ima administrativna prava, zato se radi ``sudo'') ukoliko
752 je u pitanju 64-bitni sistem:
754 sudo su
755 cd /usr/lib
756 ln -sv /usr/lib/x86_64-linux-gnu/crti.o crti.o
757 ln -sv /usr/lib/x86_64-linux-gnu/crt1.o crt1.o
758 ln -sv /usr/lib/x86_64-linux-gnu/crtn.o crtn.o
759 exit
762 Za 32-bitne sisteme važi ista ispravka, jedino što se u komandama
763 treba zameniti ``x86\_64'' sa ``i386''.
767 \newpage
771 Ukratko ćemo predstaviti editor ``joe''. Odabran je zbog svoje
772 rasprostranjenosti, potpune funkcionalnosti u tekstualnom modu rada
773 (korišćenje iz terminala) te vrlo jasnom sistemu pomoći koji se može
774 koristiti pri radu. Na nekim sistemima on dolazi već instaliran, a na
775 skoro svima se lako može dodati iz repozitorijuma. Na Ubuntu i sličnim
776 sistemima se ovo može uraditi sa:
778 sudo apt-get install joe
780 Ili analogno na drugim sistemima za instaliranje softvera.
782 Otvaranje postojećeg fajla ``hello.mod'' za uređivanje, odnosno
783 otvaranje novog praznog fajla u koji ćemo unositi odgovarajući kod ili
784 tekst se može postići sledećom komandom:
786 joe hello.mod
791 Za pomoć pri korišćenju ediora ``joe'' preporučujemo pritiskanje
793 komandi u gornjem delu editora. Postoji nekoliko stranica ove pomoći
797 U okviru pomoći postoje maltene sve komande koje editor pruža, a na
798 kraju su čak uključene i ASCII tabele znakova. Preporučuje se makar
799 ovlašno upoznavanje sa stranicama pomoći i mogućnostima editora.
803 Snimanje sa izlaskom iz programa se može uraditi sa \Ctrl
807 slučaja ``joe'' pita za ime fajla koji snimamo, pri čemu kao podrazumevanu
808 vrednost ponudi trenutno ime.
810 Joe može raditi sa više fajlova odjednom. Novi fajl se može otvoriti
812 polje za kucanje imena fajla koje dozvoljava i da se putanja
813 automatski dopunjava mogućnostima pritiskom na taster \Tab (Tab), baš
814 kao i u komandnoj liniji.
816 Prelazak na sledeći, odnosno prethodni, otvoreni fajl se dobija pritiskom
820 standardna komanda za ``ubijanje'' trenutnog procesa u terminalu), pri
821 čemu će ``joe'' pitati da li želimo da izađemo ako postoje promene
822 koje nisu snimljene. Ako je u pitanju bio jedini otvoren fajl, tada će
823 se i sam editor zatvoriti.
829 Premeštanje i kopiranje delova teksta je malo drugačije nego u
830 klasičnim grafičkim programima. Prvo je potrebno označiti željeni
832 početak bloka na trenutnu poziciju kursora, a \Ctrl
834 selekcija biti i vizuelno označena. Sada je moguće na proizvoljnom
835 mestu u istom ili drugom dokumentu pritisnuti \Ctrl
843 može odabrati više opcija za rad, kao što su margine, automatsko
845 sintaksno bojenje itd.
849 ``Joe'' ima mogućnosti i da podeli radnu površinu na nekoliko prozora
850 koji omogućavaju da se vidi više dokumenata, ili čak da se vide
851 različiti delovi istog dokumenta. Prozor se deli na dva komandom \Ctrl
855 sledeći, odnosno prethodni prozor se dobija pristikom na \Ctrl
858 omogućuje da se naizmenično vide svi prozori, ili samo jedan.
861 kao da se zaledio verovatno je problem što je stisnuta ``klasična''
863 ovom programu, a nažalost izaziva prekid osvežavanja ekrana. Efekat
869 \newpage
873 sistemom otvori terminal (konzola, komandna linija) na udaljenom UNIX
874 serveru. Može se naći online na
877 Po pokretanju se prikazuje dijalog u kome se može ukucati adresa
878 udaljenog računara i konfigurisati mnogi parametri. Najčešće je dosta
879 samo uneti adresu računara i pokrenuti konekciju. Nakon toga (ako je
880 uspešno povezivanje) biće prikazan ekran za unos korisničkog imena i
881 lozinke.
886 Putty (kao i većina standardnih linux terminala koji koriste
888 može dovesti u stanje da ne prikazuje ispis unosa na ekranu, pritiskom
890 standardnom prečicom za snimanje u većini grafičkih aplikacija, pa se
891 može nehotično aktivirati. Iz ovog režima rada se može izaći prečicom
894 Do not press
895 Ctrl S
896 If you do
897 Ctrl Q
900 Smisao postojanja ovakve opcije je dobrim delom istorijski, iz vremena
901 kad su brzine protoka bile veoma male, i kada se štedelo time što bi
902 se privrmeno isključio protok kada nisu neophodne povratne
903 informacije, na primer kod komandi koje se dugo izvršavaju. Naravno
904 ovo ima svoje primene i danas kod slabijih veza, ili kod mobilnih veza
905 koje se plaćaju po protoku, a nekad se može i dobiti na brzini
906 izvršavanja programa, ako se ne gubi vreme na osvežavanje ekrana.
910 %\end{multicols}