gitweb on Svarog
projekti pod git sistemom za održavanje verzija -- projects under the git version control system 1 % skripta-os2.tex
2 % Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
3 % Doni Pracner, Ivan Pribela
4 % 2011/12 -- 2012/13
10 % osnovne informacije koje ce se prikazati na naslovnoj strani,
11 % kao i u informacijama u generisanom pdfu
27 %change the default font
35 %podesavanja outputa za pdf verzije
50 %margine
55 %customize the itemize environments
59 \olditemize
65 }
67 %% ovi redovi daju header i footer
71 %\fancyfoot[C]{\thepage}
82 %\renewcommand{\footrulewidth}{0.5pt}
83 %\addtolength{\headheight}{0.5pt} % make space for the rule
89 }
92 %promene u marginama:
93 %\setlength{\marginparwidth}{32pt}
94 %\setlength{\textwidth}{620pt}
95 %\setlength{\textheight}{620pt}
98 %% specijalni blokovi koji služe kao podsetnici u radu ili napomene
102 }
106 }
108 %boldovane skice visokog prioriteta
115 % ako je sledeci red odkomentarisan nista od skica nece biti ispisano
116 % u finalni dokument
121 \maketitle
123 % theorems, definition etc.
124 %''''''''''''''''''''''''''
135 basicstyle=\ttfamily,
136 showstringspaces=false,
137 breaklines=true
138 }
141 % basicstyle=\footnotesize\ttfamily,
142 keywordstyle=\textbf,
144 breakatwhitespace=true,
145 % prebreak=\P,
146 % postbreak=\ding{229}\space,
147 language=Modula-2,
148 xleftmargin=4em
149 }
152 frame=l,
153 % frameround=fftt,
154 xleftmargin=4em
155 }
158 style=codeblock,
159 numbers=left,
160 firstnumber=1,
161 stepnumber=1
162 }
167 % ----------------==================--------------------------------------
168 % Pravi pocetak rada
171 Programi u ovoj skripti su testirani sa kompajlerom ``GNU Modula 2'' (u
173 sistemima iz Debian porodice.
175 \tableofcontents
177 \newpage
179 %\begin{multicols}{2}
186 Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
188 MODULE hello;
190 FROM StrIO IMPORT WriteString, WriteLn;
192 BEGIN
193 WriteString('hello world');
194 WriteLn
195 END hello.
198 Primećuje se razlika u modulu iz koga se uvoze komande u odnosu na
201 brojevima i tako dalje. Za pregled dostupnih biblioteka predlaže se
202 korišćenje zvanične stranice:
205 biblioteke.
207 Predpostavimo da smo da je fajl napravljen u trenutnom direktorijumu,
209 ``joe'' koji se koristi na vežbama). Kreirani fajl se tada može
210 prevesti u izvršnu verziju sledećom komandom:
212 gm2 hello.mod
215 Ako je kod ispravan (kao onaj gore) u istom direktorijumu će se
218 ./a.out
221 direktorijuma (koji se označava tačkom). Ako je potrebno da
222 izvršni fajl ima neki drugi naziv može se koristiti poziv sledećeg
223 tipa:
225 gm2 -o imeIzlaznogFajla ulaznifajl
229 stranicu kompajlera.
230 %ovde je trebalo -{}- da razdvoji dva minusa, jer se inače tumače kao jedan.
234 Mapiranje procedura na sistemske pozive se može izvršiti preko
235 specijalnog definicionog modula koji u zaglavlju sadrži ključne reči
237 imenima sistemskih poziva i imaju parametre i povratne vrednosti
240 komande možemo videti sa
242 man system
245 odnosno videćemo da je poziv definisan na sledeći način:
247 int system(const char *command);
249 što znači da vraća ceo broj, a prima jedan argument koji je pokazivač
250 (što se označava *) na znak. Ovo je zapravo ceo string, pošto se u C
251 jeziku oni predstavljaju kao pokazivač na prvi znak, a string se onda
252 sastoji od svih sledećih znakova u memoriji dokle god se ne naiđe na
253 0C. Srećom, sve ovo se automatski mapira kreiranjem sledećeg modula:
256 DEFINITION MODULE FOR "C" Lib;
258 EXPORT UNQUALIFIED system;
260 PROCEDURE system(command: ARRAY OF CHAR): INTEGER;
262 END Lib.
265 Nije potrebno praviti prazne implementacione module. Iz ovakvog modula
266 se mogu uvoziti i koristiti procedure kao i iz bilo kakvog
267 ``normalnog'' modula, kao što se može videti u sledećem primeru, koju
268 od korisnika učitava stringove i pokušava da ih izvrši kao da su uneti
269 u komandnoj liniji, dokle god korisnik ne unese reč ``kraj'':
271 MODULE Zad2;
273 FROM StrIO IMPORT
274 ReadString, WriteString, WriteLn;
275 FROM StrLib IMPORT
276 StrEqual;
277 FROM Lib IMPORT
278 system;
280 TYPE
283 VAR
284 Komanda: String;
286 PROCEDURE Izvrsi(Komanda: ARRAY OF CHAR);
287 VAR
288 c: INTEGER;
289 BEGIN
290 c:= system(Komanda);
291 END Izvrsi;
293 BEGIN
294 WriteString("?> "); ReadString(Komanda);
295 WHILE NOT StrEqual(Komanda, "kraj") DO
296 Izvrsi(Komanda);
297 WriteString("?> "); ReadString(Komanda);
298 END;
299 END Zad2.
302 Prilikom mapiranja sistemskih poziva je moguće koristiti ``...'' na
303 kraju liste argumenata da se označi da je moguće proslediti
304 proizvoljan broj argumenata nakon navedenih, koji će biti premapirani
305 na odgovarajuće tipove podataka. Takođe je moguće i označiti da se
306 povratna vrednost procedure ne mora koristiti. U gornjem primeru je
310 vrednost.
312 Tabela pretvaranja tipova se može videti na
317 Korišćenje sistemskih poziva se može ilustrovati primerom čitanja
321 pokazivač kao ulazni parametar, a vraća pokazivač na slog koji
324 kraju i zatvara otvoreni direktorijum. Bitno je zatvarati otvorene
325 resurse jer je moguće da sistem odbije da otvori novi ako ih
326 proces već ima previše otvorenih.
328 Kada imamo imena stavki iz direktorijuma o njima možemo dobiti više
330 putanja do fajla, a drugi je pokazivač na strukturu u koju će komanda
331 upisati podatke. Obratiti pažnju da zbog ovoga struktura već mora
332 postojati u memoriji, ili kao lokalna promenljiva odgovarajućeg
333 slogovnog tipa, ili dinamički alocirana korišćenjem pokazivača na nju.
335 Budući da su u pitanju sistemski pozivi niskog nivoa, veličine tipova
336 su nažalost promenljive i mogu zavisiti od konkretnog operativnog
338 sistem. Zbog ovoga su date dve varijante bibilioteke sa tipovima.
339 Prva je testirana na Lubuntu 11.10 32bit, a druga je testirana na
340 Kubuntu 11.10 64bit.
343 DEFINITION MODULE FOR "C" Lib32;
344 FROM SYSTEM IMPORT
345 ADDRESS, BYTE;
346 EXPORT UNQUALIFIED opendir, readdir, closedir, stat,
347 PDir, DirEnt, PDirEnt, Stat, PStat, PInt;
351 (* types for 32 bit *)
352 TYPE
353 PDir = ADDRESS;
354 DirEnt = RECORD
355 ino: INTEGER;
356 off: INTEGER;
357 reclen: SHORTCARD;
358 type: BYTE;
360 END;
361 PDirEnt = POINTER TO DirEnt;
362 Stat = RECORD
363 dev: LONGINT;
364 ino: LONGINT;
365 mode: INTEGER;
366 nlink: LONGINT;
367 uid: INTEGER;
368 gid: INTEGER;
369 pad1: LONGINT;
370 rdev: INTEGER;
371 size: INTEGER;
372 blksize: INTEGER;
373 blocks: INTEGER;
374 atime: LONGINT;
375 mtime: LONGINT;
376 ctime: LONGINT;
377 END;
382 (* types for 64 bit *)
383 TYPE
384 PDir = ADDRESS;
385 DirEnt = RECORD
386 ino: LONGINT;
387 off: LONGINT;
388 reclen: SHORTCARD;
389 type: BYTE;
391 END;
392 PDirEnt = POINTER TO DirEnt;
393 Stat = RECORD
394 dev: LONGINT;
395 ino: LONGINT;
396 nlink: LONGINT;
397 mode: INTEGER;
398 uid: INTEGER;
399 gid: INTEGER;
400 pad1: INTEGER;
401 rdev: LONGINT;
402 size: LONGINT;
403 blksize: LONGINT;
404 blocks: LONGINT;
405 atime: LONGINT;
406 mtime: LONGINT;
407 ctime: LONGINT;
408 END;
412 PStat = POINTER TO Stat;
413 PInt = POINTER TO INTEGER;
415 PROCEDURE opendir(name: ARRAY OF CHAR): PDir;
416 PROCEDURE readdir(dirp: PDir): PDirEnt;
419 END Lib32.
423 MODULE Zad5;
425 FROM SYSTEM IMPORT
426 ADR;
427 FROM StrIO IMPORT
428 WriteString, WriteLn;
429 FROM NumberIO IMPORT
430 WriteInt;
431 FROM StrLib IMPORT
432 StrLen, StrConCat;
433 FROM Args IMPORT
434 Narg, GetArg;
435 FROM Lib32 IMPORT
436 opendir, readdir, closedir, stat, PDir, PDirEnt, Stat;
437 FROM errno IMPORT
438 geterrno;
440 TYPE
443 VAR
444 Putanja: String;
445 n, i: INTEGER;
446 ok: BOOLEAN;
448 PROCEDURE Listaj(Ime: ARRAY OF CHAR);
449 VAR
450 dir: PDir;
451 entry: PDirEnt;
452 info: Stat;
453 c: INTEGER;
454 Len: CARDINAL;
455 Putanja: String;
456 BEGIN
457 dir:= opendir(Ime);
458 IF dir = NIL THEN
459 WriteString("Folder "); WriteString(Ime); WriteLn;
460 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
461 WriteString(" Ne mogu da otvorim direktorijum."); WriteLn();
462 ELSE
463 Len:= StrLen(Ime);
465 StrConCat(Ime, "/", Ime);
466 END;
467 WriteString("Folder "); WriteString(Ime); WriteLn;
468 entry:= readdir(dir);
469 WHILE entry # NIL DO
471 StrConCat(Ime, entry^.name, Putanja);
472 c:= stat(Putanja, ADR(info));
473 WriteString(" ");
474 IF c = -1 THEN
475 WriteString("? ? KB");
476 ELSE
477 WriteInt(info.nlink, 3);
479 END;
480 WriteString(" "); WriteString(entry^.name); WriteLn;
481 END;
482 entry:= readdir(dir);
483 END;
484 c:= closedir(dir);
485 IF c = -1 THEN
486 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
487 WriteString(" Ne mogu da zatvorim direktorijum."); WriteLn();
488 END;
489 END;
490 END Listaj;
492 BEGIN
493 n:= Narg();
495 ok:= GetArg(Putanja, i);
496 WriteLn;
497 Listaj(Putanja);
498 END;
499 WriteLn;
500 END Zad5.
506 (``račva''). Novi proces je identičan sa originalnim, osim u svom
507 identifikacionom broj. Komanda ne prima parametre i vraća jedan integer, pa se može mapirati na sledeći način:
509 PROCEDURE fork(): INTEGER;
512 Oba procesa se nakon račvanja nastavljaju odvijati u sledećem redu
513 koda. Jedino po čemu se razlikuju je vrednost koju je vratio
516 ``deteta'', i može se koristiti za komunikaciju sa detetom, a u novom
517 procesu je ova vrednost jednaka nuli. Budući da je najčešće potrebno
518 da dete i roditelj rade različite stvari, to se obično rešava kodom
519 sledećeg oblika:
521 pid := fork();
522 IF pid = 0 THEN
523 (* "detetove" operacije *)
524 ELSE
525 (* "roditeljske" operacije *)
526 END;
530 originalnom procesu sa efektom da se proces uspava dokle god neki od
531 procesa dece ne završi sa radom. Veća kontrola nad ovim ponašanjem se
533 koji proces čekamo da se završi.
535 U sledećim sekcijama će biti ilustrovano nekoliko klasičnih primera
536 organizacije procesa.
544 pid := 0;
545 i := 1;
546 WHILE (pid = 0) AND (i < n) DO
547 pid := fork();
548 IF pid # 0 THEN
549 (* ... *)
550 ELSE
551 INC(i);
552 END;
553 END;
561 {
563 }
567 }
575 pid := -1;
576 j := 0;
577 WHILE (pid # 0) AND (j < m) DO
578 pid := fork();
579 IF pid # 0 THEN
580 INC(j);
581 ELSE
582 (* ... *)
583 END;
584 END;
593 {
595 }
598 }
606 i := 1;
607 j := 0;
608 WHILE (i < n) AND (j < m) DO
609 pid := fork();
610 IF pid # 0 THEN
611 INC(j);
612 ELSE
613 INC(i);
614 j:=0;
615 END;
616 END;
624 ]
628 }};
634 % ----------------------------------------------
636 \newpage
638 \appendix
643 Ova sekcija treba da omogući instalaciju kompajlera GNU Modula 2 na
644 već postojeći GNU Linux operativni sistem iz Debian porodice, koja
645 uključuje i sve varijante Ubuntu distribucije, kao i Linux Mint i
646 mnoge druge. Kompajler je moguće bez većih problema instalirati i na
647 bilo koji drugi Linux (a i OSX i Windows), kompajliranjem iz izvornog
648 koda, za šta preporučujemo konsultovanje sa zvaničnom stranicom
651 Ovo uputstvo neće ulaziti u detalje kako instalirati operativni
652 sistem. Za one koje koriste Windows i nisu sigurni kako da paralelno
653 instaliraju drugi operativni sistem, preporučujemo korišćenje
654 virtuelne mašine (npr besplatni Virtual Box,
656 lakše skinuti već instaliranu mašinu sa nekim od Debian sistema, npr
657 Ubuntu ili Kubuntu, ili eventualno neku manje zahtevnu verziju kao što
658 je Lubuntu, ako su performanse problematične.
662 Prvi korak za instalaciju dodatnog kompajlera GNU Modula 2 je
663 dodavanje repozitorijuma softvera u sistem. Ovo se može uraditi ručnim
666 #
667 # GNU Modula-2 repo
668 #
670 deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main
671 deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main
674 Alternativno se mogu koristiti sledeće komande:
677 sudo add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
678 sudo add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
681 Većina sistema omogućava i da se ovo uradi preko nekih grafičkih
682 alata.
684 Nakon dodavanja novog izvora za softver potrebno je u konzoli uraditi
685 sledeće:
687 sudo apt-get update
688 sudo apt-get install gm2-doc gm2
691 Po želji se može skinuti i izvorni kod kompajlera sledećom komandom:
693 sudo apt-get source gm2
700 Pri pokušaju kompajliranja se na nekim sistemima može desiti da
703 pošto postoji problem u pakovanju kompajlera, ali moguće je da utiče i
704 na neke druge sisteme.
706 Greška se ispravlja na sledeći način (korisnik treba da
707 ima administrativna prava, zato se radi ``sudo'') ukoliko
708 je u pitanju 64-bitni sistem:
710 sudo su
711 cd /usr/lib
712 ln -sv /usr/lib/x86_64-linux-gnu/crti.o crti.o
713 ln -sv /usr/lib/x86_64-linux-gnu/crt1.o crt1.o
714 ln -sv /usr/lib/x86_64-linux-gnu/crtn.o crtn.o
715 exit
718 Za 32-bitne sisteme važi ista ispravka, jedino što se u komandama
719 treba zameniti ``x86\_64'' sa ``i386''.
726 Ukratko ćemo predstaviti editor ``joe''. Odabran je zbog svoje
727 rasprostranjenosti, potpune funkcionalnosti u tekstualnom modu rada
728 (korišćenje iz terminala) te vrlo jasnom sistemu pomoći koji se može
729 koristiti pri radu. Na nekim sistemima on dolazi već instaliran, a na
730 skoro svima se lako može dodati iz repozitorijuma. Na Ubuntu i sličnim
731 sistemima se ovo može uraditi sa:
733 sudo apt-get install joe
735 Ili analogno na drugim sistemima za instaliranje softvera.
737 Otvoranje postojećeg fajla ``hello.mod'' za uređivanje,
738 odnosno otvaranje novog praznog fajla u koji ćemo unositi
739 odgovarajući kod ili tekst se može postići sledećom komandom:
741 joe hello.mod
744 Snimanje sa izlaskom iz programa se može uraditi sa \Ctrl
748 slučaja joe pita za ime fajla koji snimamo, pri čemu kao podrazumevanu
749 vrednost ponudi trenutno ime. Brz izlaz iz editora je moguć i sa
751 trenutnog procesa u terminalu), pri čemu će joe pitati da li želimo da
752 izađemo ako postoje promene koje nisu snimljene.
754 Za pomoć pri korišćenju ediora ``joe'' preporučujemo pritiskanje
756 komandi u gornjem delu editora. Postoji nekoliko stranica ove pomoći
759 U okviru pomoći stoje i komande za označavanje blokova teksta i
760 njihovo nakndadno premeštanje, kopiranje ili brisanje. Pritiskom na
764 može odabrati više opcija za rad, kao što su margine, automatsko
766 sintaksno bojenje itd.
773 sistemom otvori terminal (konzola, komandna linija) na udaljenom UNIX
774 serveru. Može se naći online na
777 Po pokretanju se prikazuje dijalog u kome se može ukucati adresa
778 udaljenog računara i konfigurisati mnogi parametri. Najčešće je dosta
779 samo uneti adresu računara i pokrenuti konekciju. Nakon toga (ako je
780 uspešno povezivanje) biće prikazan ekran za unos korisničkog imena i
781 lozinke.
785 Putty se može dovesti u stanje da ne prikazuje ispis unosa na ekranu,
787 poklapa sa standardnom prečicom za snimanje u većini grafičkih
788 aplikacija). Iz ovog režima rada se može izaći prečicom
790 Ukratko:
792 Do not press
793 Ctrl S
794 If you do
795 Ctrl Q
800 %\end{multicols}