gitweb on Svarog

projekti pod git sistemom za održavanje verzija -- projects under the git version control system
napomena o upgradeu i izvorima softvera
[os2skripta.git] / skripta-os2.tex
1 % skripta-os2.tex
2 % Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
3 % Doni Pracner, Ivan Pribela
4 % 2011/12 -- 2013/14
6 \documentclass[a4paper,twoside]{article}
7 \usepackage[T1]{fontenc}
8 \usepackage[utf8]{inputenc}%definišemo da je ulaz utf-8 fajl
10 % osnovne informacije koje ce se prikazati na naslovnoj strani,
11 % kao i u informacijama u generisanom pdfu
12 \newcommand{\autor}{Doni Pracner, Ivan Pribela}
13 \newcommand{\inst}{Departman za matematiku i informatiku, PMF, UNS}
14 \newcommand{\autorinst}{\autor \\ \inst}
15 \newcommand{\naslov}{Skripta za vežbe iz predmeta operativni sistemi 2}
16 \newcommand{\datum}{Februar 2014, Novi Sad}
17 \newcommand{\verzija}{ver 14a}
19 \usepackage[serbian]{babel}
20 \usepackage{fancyhdr}
21 \pagestyle{fancy}
23 \title{\naslov \ -- \verzija}
24 \author{\autor \\ \inst}
25 \date{\datum}
27 %change the default font
28 \usepackage{lmodern}
29 \usepackage{beramono}
30 \renewcommand{\familydefault}{\sfdefault}
32 \usepackage{pifont}
34 %podesavanja outputa za pdf verzije
35 \usepackage[bookmarks,pdffitwindow=false,unicode=true,%
36 pdftitle={\naslov \ -- \verzija},%
37 pdfauthor={\autor}%
38 ]{hyperref}
40 \usepackage{graphicx}
41 \usepackage{listings}
42 \usepackage{amsthm}
43 \usepackage{amsmath}
44 \usepackage{latexsym}
45 \usepackage{multicol}
47 %\usepackage{keystroke}
48 % ispod je dodata alternativa za ovaj paket
50 \usepackage{tikz}
51 \usetikzlibrary{shadows}
53 \newcommand*\keystroke[1]{%
54 \tikz[baseline=(key.base)]
55 \node[%
56 draw,
57 fill=white,
58 drop shadow={shadow xshift=0.2ex,shadow yshift=-0.2ex,fill=black,opacity=0.75},
59 rectangle,
60 rounded corners=2pt,
61 inner sep=1pt,
62 line width=0.5pt,
63 font=\small\sffamily
64 ](key) {#1\strut}
65 ;
66 }
68 \newcommand*\Ctrl{\keystroke{Ctrl}}
69 \newcommand*\Tab{\keystroke{Tab}}
70 \newcommand*\Esc{\keystroke{Esc}}
72 %margine
73 \usepackage[top=2cm, bottom=2cm, left=2.5cm, right=2cm]{geometry}
75 \begin{document}
77 %customize the itemize environments
79 \let\olditemize=\itemize
80 \def\itemize{
81 \olditemize
82 \setlength{\itemsep}{1pt}
83 \setlength{\parskip}{0pt}
84 \setlength{\parsep}{0pt}
85 \setlength{\topsep}{-1cm}
87 }
89 %% ovi redovi daju header i footer
91 \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
92 \fancyhf{} % delete current setting for header and footer
93 %\fancyfoot[C]{\thepage}
95 \fancyhead[LO]{\bfseries\rightmark}
96 \fancyhead[RO]{\thepage}
98 \fancyhead[RE]{Operativni sistemi 2 -- skripta}
99 \fancyhead[LE]{\thepage}
101 \renewcommand{\headrulewidth}{0.5pt}
102 \renewcommand{\headwidth}{\textwidth}
104 %\renewcommand{\footrulewidth}{0.5pt}
105 %\addtolength{\headheight}{0.5pt} % make space for the rule
106 \fancypagestyle{plain}{%
107 \fancyhead{} % get rid of headers on plain pages
108 \fancyfoot{}
109 \renewcommand{\headrulewidth}{0pt} % and the line
110 \renewcommand{\footrulewidth}{0pt} % and the line
112 \renewcommand{\headheight}{15pt}
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
121 \newcommand{\skica}[1]{
122 \noindent \framebox{\parbox[c]{0.9\textwidth}{ {\small** \textit{#1} }}
123 \newline }
126 \newcommand{\skicas}[1]{
127 \framebox{* \textit{#1} *}
130 %boldovane skice visokog prioriteta
131 \newcommand{\skicab}[1]{
132 \noindent \framebox{\parbox[c]{0.9\textwidth}{ {\small***
133 \textbf{#1} }} \newline } }
135 \newcommand{\kod}[1]{{\small\texttt{#1}}}
137 % ako je sledeci red odkomentarisan nista od skica nece biti ispisano
138 % u finalni dokument
140 \renewcommand{\skica}[1]{}
143 \maketitle
145 % theorems, definition etc.
146 %''''''''''''''''''''''''''
148 \theoremstyle{definition}
149 \newtheorem{def1}{Definicija}
150 \theoremstyle{plain}
151 \newtheorem{theo}{Teorema}
152 \newtheorem{lema}{Lema}
154 \lstloadlanguages{Modula-2,C++}
156 \lstset{
157 basicstyle=\ttfamily,
158 showstringspaces=false,
159 breaklines=true
162 \lstdefinestyle{codeblock}{
163 % basicstyle=\footnotesize\ttfamily,
164 keywordstyle=\textbf,
165 columns=[l]fixed,
166 breakatwhitespace=true,
167 % prebreak=\P,
168 % postbreak=\ding{229}\space,
169 language=Modula-2,
170 xleftmargin=4em
173 \lstdefinestyle{terminal}{
174 frame=lt,
175 % frameround=fftt,
176 backgroundcolor=\color[gray]{.95},
177 % prebreak=\P,
178 postbreak=\ding{229}\space,
179 xleftmargin=2em
182 \lstdefinestyle{numcodeblock}{
183 style=codeblock,
184 numbers=left,
185 firstnumber=1,
186 stepnumber=1
189 \lstnewenvironment{codeblock}[1][]{\lstset{style=codeblock,#1}}{}
190 \lstnewenvironment{terminal}{\lstset{style=terminal}}{}
192 % ----------------==================--------------------------------------
193 % Pravi pocetak rada
196 Programi u ovoj skripti su testirani sa kompajlerom ``GNU Modula 2'' (u
197 daljem tekstu često skraćeno na \emph{gm2}), pod operativnim
198 sistemima iz Debian porodice.
200 \tableofcontents
202 \newpage
204 %\begin{multicols}{2}
206 \section{GNU Modula 2}
208 \emph{GNU Modula 2} (u daljem tekstu često skraćeno na \emph{gm2}) je
209 pred procesor (\emph{front end}) za GNU kolekciju kompajlera
210 (GCC). Podržava nekoliko dijalekata jezika ``Modula 2'' --
211 najznačajniji su ISO standard i nekoliko varijacija koje je originalni
212 autor Niklaus Virt (\emph{Niklaus Wirth}) opisao u različitima
213 verzijama knjige \emph{Programming in Modula 2 (PIM)}. Uz kompajler se
214 dobijaju i besplatne ISO, PIM i još neke biblioteke.
216 \subsection{Prvi program u gm2 }
217 \label{g-prvi-program}
219 Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
220 \begin{codeblock}
221 MODULE hello;
223 FROM StrIO IMPORT WriteString, WriteLn;
225 BEGIN
226 WriteString('hello world');
227 WriteLn
228 END hello.
229 \end{codeblock}
231 Primećuje se razlika u modulu iz koga se uvoze komande u odnosu na
232 XDS/TopSpeed verzije M2, tamo je sve bilo u \kod{InOut}, dok se ovde
233 koristi \kod{StrIO} za rad sa stringovima, \kod{NumberIO} za rad sa
234 brojevima i tako dalje. Za pregled dostupnih biblioteka predlaže se
235 korišćenje zvanične stranice:
236 \url{http://nongnu.org/gm2/libraries.html}, odnosno
237 \url{http://nongnu.org/gm2/base_libraries.html} za samo osnovne
238 biblioteke.
240 Predpostavimo da je fajl napravljen u trenutnom direktorijumu,
241 koristeći neki tesktualni editor (u dodatku~\ref{app-joe} je opisan
242 ``joe'' koji se koristi na vežbama). Kreirani fajl se tada može
243 prevesti u izvršnu verziju sledećom komandom:
244 \begin{terminal}
245 gm2 hello.mod
246 \end{terminal}
248 Ako je kod ispravan (kao onaj gore) u istom direktorijumu će se
249 napraviti fajl \kod{a.out}, koji se može pokrenuti sa:
250 \begin{terminal}
251 ./a.out
252 \end{terminal}
253 pri čemu \kod{./} naglašava da hoćemo da pokrenemo program iz trenutnog
254 direktorijuma (koji se označava tačkom). Ako je potrebno da
255 izvršni fajl ima neki drugi naziv može se koristiti poziv sledećeg
256 tipa:
257 \begin{terminal}
258 gm2 -o imeIzlaznogFajla ulaznifajl
259 \end{terminal}
261 Za dalje opcije kompajlera konsultovati \kod{gm2 -{}-help} i zvaničnu
262 stranicu kompajlera.
263 %ovde je trebalo -{}- da razdvoji dva minusa, jer se inače tumače kao jedan.
265 \subsection{Korišćenje sistemskih poziva}
267 Mapiranje procedura na sistemske pozive se može izvršiti preko
268 specijalnog definicionog modula koji u zaglavlju sadrži ključne reči
269 \kod{FOR "{}C"} u kome se navode imena procedura koja se poklapaju sa
270 imenima sistemskih poziva i imaju parametre i povratne vrednosti
271 odgovarajućih tipova. Na primer, mapirajmo poziv \kod{system}, koji
272 izvršava prosleđenu komandu u novom \emph{shell}-u. Specifikaciju
273 komande možemo videti sa
274 \begin{terminal}
275 man system
276 \end{terminal}
278 odnosno videćemo da je poziv definisan na sledeći način:
279 \begin{codeblock}
280 int system(const char *command);
281 \end{codeblock}
282 što znači da vraća ceo broj, a prima jedan argument koji je pokazivač
283 (što se označava *) na znak. Ovo je zapravo ceo string, pošto se u C
284 jeziku oni predstavljaju kao pokazivač na prvi znak, a string se onda
285 sastoji od svih sledećih znakova u memoriji dokle god se ne naiđe na
286 0C. Srećom, sve ovo se automatski mapira kreiranjem sledećeg modula:
288 \begin{codeblock}
289 DEFINITION MODULE FOR "C" Lib;
291 EXPORT UNQUALIFIED system;
293 PROCEDURE system(command: ARRAY OF CHAR): INTEGER;
295 END Lib.
296 \end{codeblock}
298 Nije potrebno praviti prazne implementacione module. Iz ovakvog modula
299 se mogu uvoziti i koristiti procedure kao i iz bilo kakvog
300 ``normalnog'' modula, kao što se može videti u sledećem primeru, koju
301 od korisnika učitava stringove i pokušava da ih izvrši kao da su uneti
302 u komandnoj liniji, dokle god korisnik ne unese reč ``kraj'':
303 \begin{codeblock}
304 MODULE Zad2;
306 FROM StrIO IMPORT
307 ReadString, WriteString, WriteLn;
308 FROM StrLib IMPORT
309 StrEqual;
310 FROM Lib IMPORT
311 system;
313 TYPE
314 String = ARRAY [0..1023] OF CHAR;
316 VAR
317 Komanda: String;
319 PROCEDURE Izvrsi(Komanda: ARRAY OF CHAR);
320 VAR
321 c: INTEGER;
322 BEGIN
323 c:= system(Komanda);
324 END Izvrsi;
326 BEGIN
327 WriteString("?> "); ReadString(Komanda);
328 WHILE NOT StrEqual(Komanda, "kraj") DO
329 Izvrsi(Komanda);
330 WriteString("?> "); ReadString(Komanda);
331 END;
332 END Zad2.
333 \end{codeblock}
335 Prilikom mapiranja sistemskih poziva je moguće koristiti ``...'' na
336 kraju liste argumenata da se označi da je moguće proslediti
337 proizvoljan broj argumenata nakon navedenih, koji će biti premapirani
338 na odgovarajuće tipove podataka. Takođe je moguće i označiti da se
339 povratna vrednost procedure ne mora koristiti. U gornjem primeru je
340 mogla funkcija da se definiše kao \kod{PROCEDURE system(command: ARRAY
341 OF CHAR): [INTEGER];} i tada bi mogla se poziva kao obična procedura
342 bez korišćenja pomoćne promenljive \kod{c} da se dobije povratna
343 vrednost.
345 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 \begin{table}[htp]
348 \begin{center}
349 \begin{tabular}{lll}
350 Stvarni parametar & Konverzija & Tip vrednosti koji će biti prosleđen\\
351 \hline
352 123 & - & long long int\\
353 "hello world" & - & const char *\\
354 a: ARRAY OF CHAR & ADR(a) & char *\\
355 a: ARRAY [0..5] OF CHAR& ADR(a) & char *\\
356 3.14 & - & long double
357 \end{tabular}
358 \end{center}
359 \caption{Tabela pretvaranja tipova\label{t-pretvaranje-tipova}}
360 \end{table}
362 \subsubsection{Primer: Izlistavanje sadržaja direktorijuma}
364 Korišćenje sistemskih poziva se može ilustrovati primerom čitanja
365 sadržaja direktorijuma, komandama \kod{opendir}, \kod{readdir} i
366 \kod{closedir}. Prva komanda otvara prosledjenu putanju i vraća
367 pokazivač na otvoreni direktorijum. Komanda \kod{readdir} prima ovakav
368 pokazivač kao ulazni parametar, a vraća pokazivač na slog koji
369 predstavlja sledeću stavku u otvorenom direktorijumu ili \kod{NIL} ako
370 više nema ničega. Poslednja komanda, \kod{closedir}, se izvodi na
371 kraju i zatvara otvoreni direktorijum. Bitno je zatvarati otvorene
372 resurse jer je moguće da sistem odbije da otvori novi ako ih
373 proces već ima previše otvorenih.
375 Budući da su u pitanju sistemski pozivi niskog nivoa, veličine tipova
376 su nažalost promenljive i mogu zavisiti od konkretnog operativnog
377 sistema, a naročito utiče da li je u pitanju~32--bitni, ili~64--bitni
378 sistem. Zbog ovoga su date dve varijante bibilioteke sa tipovima.
379 Prva je testirana na Lubuntu 11.10 i 12.04 32bit, a druga je testirana
380 na Kubuntu 11.10 i 12.10 64bit.
382 \begin{codeblock}
383 DEFINITION MODULE FOR "C" libdir;
385 FROM SYSTEM IMPORT
386 ADDRESS, BYTE;
388 EXPORT UNQUALIFIED opendir, readdir, closedir, PDir, DirEnt, PDirEnt;
389 \end{codeblock}
390 \begin{minipage}{0.45\textwidth}
391 \begin{codeblock}
392 (* types for 32 bit *)
393 TYPE
394 PDir = ADDRESS;
395 DirEnt = RECORD
396 ino: INTEGER;
397 off: INTEGER;
398 reclen: SHORTCARD;
399 type: BYTE;
400 name: ARRAY [0..255] OF CHAR;
401 END;
402 PDirEnt = POINTER TO DirEnt;
403 \end{codeblock}
404 \end{minipage}
405 \begin{minipage}{0.45\textwidth}
406 \begin{codeblock}[frame=single,frameround=tttt]
407 (* types for 64 bit *)
408 TYPE
409 PDir = ADDRESS;
410 DirEnt = RECORD
411 ino: LONGINT;
412 off: LONGINT;
413 reclen: SHORTCARD;
414 type: BYTE;
415 name: ARRAY [0..255] OF CHAR;
416 END;
417 PDirEnt = POINTER TO DirEnt;
418 \end{codeblock}
419 \end{minipage}
420 \begin{codeblock}
421 PROCEDURE opendir(name: ARRAY OF CHAR): PDir;
422 PROCEDURE readdir(dirp: PDir): PDirEnt;
423 PROCEDURE closedir(dirp: PDir): [INTEGER];
425 END libdir.
426 \end{codeblock}
428 \begin{codeblock}
429 MODULE Zad3;
431 FROM StrIO IMPORT
432 WriteString, WriteLn;
433 FROM NumberIO IMPORT
434 WriteInt;
435 FROM Args IMPORT
436 Narg, GetArg;
437 FROM libdir IMPORT
438 opendir, readdir, closedir, PDir, PDirEnt;
439 FROM errno IMPORT
440 geterrno;
442 TYPE
443 String = ARRAY [0..1023] OF CHAR;
445 VAR
446 Putanja: String;
447 n, i: INTEGER;
448 ok: BOOLEAN;
450 PROCEDURE Listaj(Ime: ARRAY OF CHAR);
451 VAR
452 dir: PDir;
453 entry: PDirEnt;
454 c: INTEGER;
455 BEGIN
456 WriteString("Folder "); WriteString(Ime); WriteLn;
457 dir:= opendir(Ime);
458 IF dir = NIL THEN
459 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
460 WriteString(" Ne mogu da otvorim direktorijum."); WriteLn();
461 ELSE
462 entry:= readdir(dir);
463 WHILE entry # NIL DO
464 IF entry^.name[0] # "." THEN
465 WriteString(" "); WriteString(entry^.name); WriteLn;
466 END;
467 entry:= readdir(dir);
468 END;
469 c:= closedir(dir);
470 IF c = -1 THEN
471 WriteString(" Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
472 WriteString(" Ne mogu da zatvorim direktorijum."); WriteLn();
473 END;
474 END;
475 END Listaj;
477 BEGIN
478 n:= Narg();
479 FOR i:= 1 TO n - 1 DO
480 ok:= GetArg(Putanja, i);
481 WriteLn;
482 Listaj(Putanja);
483 END;
484 WriteLn;
485 END Zad3.
486 \end{codeblock}
488 Kada imamo imena stavki iz direktorijuma o njima možemo dobiti više
489 informacija koristeći sistemski poziv \kod{stat}. On prima dva
490 argumenta, prvi je \emph{puna} putanja do fajla, a drugi je pokazivač
491 na strukturu u koju će komanda upisati podatke. Obratiti pažnju da
492 zbog ovoga struktura već mora postojati u memoriji, ili kao lokalna
493 promenljiva odgovarajućeg slogovnog tipa, ili dinamički alocirana
494 korišćenjem pokazivača na nju.
496 Linux i mnogi drugi srodni sistemi za internu prezentaciju vremena
497 koriste broj sekundi od početka ``epohe'', odnosno od prvog januara
498 1970 godine. Za konverziju u klasičnije mere vremena se može koristiti
499 poziv \kod{localtime}.
501 \begin{codeblock}
502 DEFINITION MODULE FOR "C" LibStat32;
503 FROM SYSTEM IMPORT
504 ADDRESS, BYTE;
505 EXPORT UNQUALIFIED stat, localtime,
506 Stat, PStat, Tm, PTm, PInt,
507 fifo, character, directory, block, regular, network, link, socket;
509 CONST
510 fifo = 1;
511 character = 2;
512 directory = 4;
513 block = 6;
514 regular = 8;
515 network = 9;
516 link = 10;
517 socket = 12;
518 \end{codeblock}
519 \begin{minipage}{0.45\textwidth}
520 \begin{codeblock}
521 (* types for 32 bit *)
522 TYPE
523 Stat = RECORD
524 dev: LONGINT;
525 ino: LONGINT;
526 mode: INTEGER;
527 nlink: LONGINT;
528 uid: INTEGER;
529 gid: INTEGER;
530 pad1: LONGINT;
531 rdev: INTEGER;
532 size: INTEGER;
533 blksize: INTEGER;
534 blocks: INTEGER;
535 atime: LONGINT;
536 mtime: LONGINT;
537 ctime: LONGINT;
538 END;
539 \end{codeblock}
540 \end{minipage}
541 \begin{minipage}{0.45\textwidth}
542 \begin{codeblock}[frame=single,frameround=tttt]
543 (* types for 64 bit *)
544 TYPE
545 Stat = RECORD
546 dev: LONGINT;
547 ino: LONGINT;
548 nlink: LONGINT;
549 mode: INTEGER;
550 uid: INTEGER;
551 gid: INTEGER;
552 pad1: INTEGER;
553 rdev: LONGINT;
554 size: LONGINT;
555 blksize: LONGINT;
556 blocks: LONGINT;
557 atime: LONGINT;
558 mtime: LONGINT;
559 ctime: LONGINT;
560 END;
561 \end{codeblock}
562 \end{minipage}
563 \begin{codeblock}
564 Tm = RECORD
565 sec, min, hour,
566 mday, mon, year,
567 wday, yday, isdst: INTEGER;
568 END;
569 PTm = POINTER TO Tm;
570 PInt = POINTER TO INTEGER;
572 PROCEDURE stat(path: ARRAY OF CHAR; buf: PStat): [INTEGER];
573 PROCEDURE localtime(time: PInt): PTm;
575 END LibStat32.
576 \end{codeblock}
578 \begin{codeblock}
579 MODULE Zad4;
581 FROM SYSTEM IMPORT
582 ADR;
583 FROM StrIO IMPORT
584 WriteString, WriteLn;
585 FROM NumberIO IMPORT
586 WriteInt;
587 FROM StrLib IMPORT
588 StrLen, StrConCat;
589 FROM Args IMPORT
590 Narg, GetArg;
591 FROM LibStat32 IMPORT
592 stat, localtime, Stat, PTm;
593 IMPORT LibStat32;
594 FROM errno IMPORT
595 geterrno;
597 TYPE
598 String = ARRAY [0..1023] OF CHAR;
600 VAR
601 Putanja: String;
602 n, i: INTEGER;
603 ok: BOOLEAN;
605 PROCEDURE WriteMode(mode: INTEGER);
607 PROCEDURE WriteType(type: INTEGER);
608 BEGIN
609 IF type = lib32.fifo THEN
610 WriteString("f");
611 ELSIF type = lib32.character THEN
612 WriteString("c");
613 ELSIF type = lib32.directory THEN
614 WriteString("d");
615 ELSIF type = lib32.block THEN
616 WriteString("b");
617 ELSIF type = lib32.regular THEN
618 WriteString("-");
619 ELSIF type = lib32.network THEN
620 WriteString("n");
621 ELSIF type = lib32.link THEN
622 WriteString("l");
623 ELSIF type = lib32.socket THEN
624 WriteString("s");
625 ELSE
626 WriteString("?");
627 END;
628 END WriteType;
630 PROCEDURE WriteRWX(triplet: INTEGER);
631 BEGIN
632 IF ((triplet DIV 4) MOD 2) # 0 THEN
633 WriteString("r");
634 ELSE
635 WriteString("-");
636 END;
637 IF ((triplet DIV 2) MOD 2) # 0 THEN
638 WriteString("w");
639 ELSE
640 WriteString("-");
641 END;
642 IF (triplet MOD 2) # 0 THEN
643 WriteString("x");
644 ELSE
645 WriteString("-");
646 END;
647 END WriteRWX;
649 BEGIN
650 WriteType((mode DIV 4096) MOD 16);
651 WriteRWX(mode DIV 64);
652 WriteRWX(mode DIV 8);
653 WriteRWX(mode);
654 END WriteMode;
656 PROCEDURE WriteTime(time: LONGINT);
657 VAR
658 tm: PTm;
659 BEGIN
660 tm:= localtime(ADR(time));
661 IF tm # NIL THEN
662 WriteInt(tm^.year + 1900, 0);
663 WriteString("-");
664 IF tm^.mon < 9 THEN
665 WriteString("0");
666 END;
667 WriteInt(tm^.mon + 1, 0);
668 WriteString("-");
669 IF tm^.mday < 10 THEN
670 WriteString("0");
671 END;
672 WriteInt(tm^.mday, 0);
673 WriteString(" ");
674 IF tm^.hour < 10 THEN
675 WriteString("0");
676 END;
677 WriteInt(tm^.hour, 0);
678 WriteString(":");
679 IF tm^.hour < 10 THEN
680 WriteString("0");
681 END;
682 WriteInt(tm^.min, 0);
683 ELSE
684 WriteString("??:??");
685 END;
686 END WriteTime;
688 PROCEDURE Listaj(Putanja: ARRAY OF CHAR);
689 VAR
690 info: Stat;
691 c: INTEGER;
692 BEGIN
693 c:= stat(Putanja, ADR(info));
694 IF c = -1 THEN
695 WriteString("?????????? ? ? KB ????-??-?? ??:??");
696 ELSE
697 WriteMode(info.mode);
698 WriteInt(info.nlink, 3);
699 WriteInt((info.size + 512) DIV 1024, 5); WriteString(" KB ");
700 WriteTime(info.atime);
701 END;
702 WriteString(" "); WriteString(Putanja); WriteLn;
703 END Listaj;
705 BEGIN
706 n:= Narg();
707 FOR i:= 1 TO n - 1 DO
708 ok:= GetArg(Putanja, i);
709 WriteLn;
710 Listaj(Putanja);
711 END;
712 WriteLn;
713 END Zad4.
714 \end{codeblock}
716 \subsection{Stvaranje novih procesa}
718 Korišćenjem sistemske komande \kod{fork} trenutni proces se duplira
719 (``račva''). Novi proces je identičan sa originalnim, osim u svom
720 identifikacionom broj. Komanda ne prima parametre i vraća jedan integer, pa se može mapirati na sledeći način:
721 \begin{codeblock}
722 PROCEDURE fork(): INTEGER;
723 \end{codeblock}
725 Oba procesa se nakon račvanja nastavljaju odvijati u sledećem redu
726 koda. Jedino po čemu se razlikuju je vrednost koju je vratio
727 \kod{fork}, ukoliko je u pitanju originalni proces (``roditelj'') tada
728 je ta vrednost jednaka proces identifikatoru (\emph{pid}-u)
729 ``deteta'', i može se koristiti za komunikaciju sa detetom, a u novom
730 procesu je ova vrednost jednaka nuli. Budući da je najčešće potrebno
731 da dete i roditelj rade različite stvari, to se obično rešava kodom
732 sledećeg oblika:
733 \begin{codeblock}
734 pid := fork();
735 IF pid = 0 THEN
736 (* "detetove" operacije *)
737 ELSE
738 (* "roditeljske" operacije *)
739 END;
740 \end{codeblock}
742 Komanda \kod{wait} (uvezena kao sistemska) se može pozvati u
743 originalnom procesu sa efektom da se proces uspava dokle god neki od
744 procesa dece ne završi sa radom. Veća kontrola nad ovim ponašanjem se
745 može postići komandom \kod{waitpid} u kojoj možemo precizirati tačno
746 koji proces čekamo da se završi.
748 U sledećim sekcijama će biti ilustrovano nekoliko klasičnih primera
749 organizacije procesa.
751 \skica{treba nam propratni tekst za ovo sto sledi}
753 \subsubsection{Lanac procesa}
755 \begin{minipage}{0.6\textwidth}
756 \begin{codeblock}
757 pid := 0;
758 i := 1;
759 WHILE (pid = 0) AND (i < n) DO
760 pid := fork();
761 IF pid # 0 THEN
762 (* ... *)
763 ELSE
764 INC(i);
765 END;
766 END;
767 \end{codeblock}
768 \end{minipage}
769 \begin{minipage}{0.4\textwidth}
770 \begin{tikzpicture}
771 [proc/.style={circle,draw}]
772 \def \n {5}
773 \foreach \s in {1,...,\n}
775 \node[proc] (\s) at (\s,-\s/2) {\s};
777 \foreach \s in {2,...,\n} {
778 \pgfmathparse{int(\s-1)}
779 \draw [<-] (\s) to (\pgfmathresult);
781 \end{tikzpicture}
782 \end{minipage}
784 \subsubsection{Roditelj sa puno dece}
786 \begin{minipage}{0.6\textwidth}
787 \begin{codeblock}
788 pid := -1;
789 j := 0;
790 WHILE (pid # 0) AND (j < m) DO
791 pid := fork();
792 IF pid # 0 THEN
793 INC(j);
794 ELSE
795 (* ... *)
796 END;
797 END;
798 \end{codeblock}
799 \end{minipage}
800 \begin{minipage}{0.4\textwidth}
801 \begin{tikzpicture}
802 [proc/.style={circle,draw}]
803 \def \n {3}
804 \node[proc] (top) at (0,0) {0..4};
805 \foreach \s in {0,...,\n}
807 \node[proc] (\s) at (-1.5+\s,-2) {\s};
809 \foreach \s in {0,...,\n} {
810 \draw [->] (top) to (\s);
812 \end{tikzpicture}
813 \end{minipage}
815 \subsubsection{Stablo procesa}
817 \begin{minipage}{0.6\textwidth}
818 \begin{codeblock}
819 dubina := 1;
820 brdece := 0;
821 WHILE (dubina < maxdubina) AND
822 (brdece < potrebnodece) DO
823 pid := fork();
824 IF pid # 0 THEN
825 INC(brdece);
826 ELSE
827 INC(dubina);
828 brdece := 0;
829 END;
830 END;
831 \end{codeblock}
832 \end{minipage}
833 \begin{minipage}{0.4\textwidth}
834 \begin{tikzpicture}
835 [proc/.style={circle,draw},
836 level 1/.style={sibling distance=28mm,level distance=10mm},
837 level 2/.style={sibling distance=14mm,font=\scriptsize},
838 level 3/.style={sibling distance=6mm,font=\tiny}
840 \node[proc] (root) {1-0}
841 child[->] foreach \x in {0,1} {node[proc] {1-\x}
842 child foreach \y in {0,1} {node[proc] {2-\y}
843 child foreach \z in {0,1} {node[proc] {3-\z}
844 }}};
846 \node[text width=0.9\textwidth] (desc) at (0,-4) {maxdubina=4, potrebnodece=2,
847 čvorovi prikazuju vrednosti pri kreiranju};
848 \end{tikzpicture}
849 \end{minipage}
852 % ----------------------------------------------
854 \newpage
855 \pagenumbering{Roman}
856 \appendix
858 \section{Instalacija kompajlera GNU Modula 2}
859 \label{app-instalacija-gm2}
861 Ova sekcija treba da omogući instalaciju kompajlera GNU Modula 2 na
862 već postojeći GNU Linux operativni sistem iz Debian porodice, koja
863 uključuje i sve varijante Ubuntu distribucije, kao i Linux Mint i
864 mnoge druge. Kompajler je moguće bez većih problema instalirati i na
865 bilo koji drugi Linux (a i OSX i Windows), kompajliranjem iz izvornog
866 koda, za šta preporučujemo konsultovanje sa zvaničnom stranicom
867 \url{http://www.nongnu.org/gm2/obtaining.html}.
869 Ovo uputstvo neće ulaziti u detalje kako instalirati operativni
870 sistem. Za one koje koriste Windows i nisu sigurni kako da paralelno
871 instaliraju drugi operativni sistem, preporučujemo korišćenje
872 virtuelne mašine (npr besplatni Virtual Box,
873 \url{http://virtualbox.org}) i instaliranje sistema na nju, ili još
874 lakše skinuti već instaliranu mašinu sa nekim od Debian sistema, npr
875 Ubuntu ili Kubuntu, ili eventualno neku manje zahtevnu verziju kao što
876 je Lubuntu, ako su performanse problematične.
878 \subsection{Instalacija na Debian platformi}
880 Prvi korak za instalaciju dodatnog kompajlera GNU Modula 2 je
881 dodavanje repozitorijuma softvera u sistem. Ovo se može uraditi ručnim
882 menjanjem fajla \kod{/etc/apt/sources.list} i dodavanjem
883 \begin{codeblock}
885 # GNU Modula-2 repo
888 deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main
889 deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main
890 \end{codeblock}
892 Alternativno se mogu koristiti sledeće komande:
894 \begin{terminal}
895 sudo add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
896 sudo add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
897 \end{terminal}
899 Većina sistema omogućava i da se ovo uradi preko nekih grafičkih
900 alata.
902 Nakon dodavanja novog izvora za softver potrebno je u konzoli uraditi
903 sledeće:
904 \begin{terminal}
905 sudo apt-get update
906 sudo apt-get install gm2-doc gm2
907 \end{terminal}
909 Po želji se može skinuti i izvorni kod kompajlera sledećom komandom:
910 \begin{terminal}
911 sudo apt-get source gm2
912 \end{terminal}
914 Videti Glavu~\ref{g-prvi-program} za primer kompajliranja programa.
916 \paragraph{Napomena:} Prilikom unapredjivanja Linux distribucije na
917 sledeću verziju (npr. 13.10 na 14.04) se standardno onemogućavaju
918 dodati izvori softvera i potrebno ih je ručno ponovo upaliti. Ovo se
919 može uraditi otvoranjem \kod{/etc/apt/sources.list} i uklonjanjem
920 ``\#'' sa početka redova koje želimo da koristimo ponovo ili
921 korišćenjem adekvatnih vizuelnih alata.
923 \subsection{Problem: nedostaje ``ctli.o'' i/ili još neki fajlovi}
925 Pri pokušaju kompajliranja se na nekim sistemima može desiti da
926 prijave nedostajuće fajlove \kod{crti.o, crt1.o} i/ili
927 \kod{crtn.o}. Konkretno je poznato za gcc verziju 4.6 na debianu,
928 pošto postoji problem u pakovanju kompajlera, ali moguće je da utiče i
929 na neke druge sisteme.
931 Greška se ispravlja na sledeći način (korisnik treba da
932 ima administrativna prava, zato se radi ``sudo'') ukoliko
933 je u pitanju 64-bitni sistem:
934 \begin{terminal}
935 sudo su
936 cd /usr/lib
937 ln -sv /usr/lib/x86_64-linux-gnu/crti.o crti.o
938 ln -sv /usr/lib/x86_64-linux-gnu/crt1.o crt1.o
939 ln -sv /usr/lib/x86_64-linux-gnu/crtn.o crtn.o
940 exit
941 \end{terminal}
943 Za 32-bitne sisteme važi ista ispravka, jedino što se u komandama
944 treba zameniti ``x86\_64'' sa ``i386''.
946 \skica{možda i build from source}
948 \newpage
949 \section{Tekst editor Joe}
950 \label{app-joe}
952 Ukratko ćemo predstaviti editor ``joe''. Odabran je zbog svoje
953 rasprostranjenosti, potpune funkcionalnosti u tekstualnom modu rada
954 (korišćenje iz terminala) te vrlo jasnom sistemu pomoći koji se može
955 koristiti pri radu. Na nekim sistemima on dolazi već instaliran, a na
956 skoro svima se lako može dodati iz repozitorijuma. Na Ubuntu i sličnim
957 sistemima se ovo može uraditi sa:
958 \begin{terminal}
959 sudo apt-get install joe
960 \end{terminal}
961 Ili analogno na drugim sistemima za instaliranje softvera.
963 Otvaranje postojećeg fajla ``hello.mod'' za uređivanje, odnosno
964 otvaranje novog praznog fajla u koji ćemo unositi odgovarajući kod ili
965 tekst se može postići sledećom komandom:
966 \begin{terminal}
967 joe hello.mod
968 \end{terminal}
970 \subsection{Tumačenje prečica na tastaturi}
972 Joe je po svojoj prirodi bogat prečicama na tastaturi. U daljem tekstu
973 će biti navedene mnoge od njih. Kod svih se navodi redosled
974 pritiskanja tastera individualno, a ako su negde tasteri spojeni sa
975 ``+'' (alternativno sa ``-'') onda ih je potrebno pritisnuti
976 odjednom. Neki primeri:
978 \begin{itemize}
979 \item \Ctrl +\keystroke{\_} (poništavanje poslednje promene) pristsak
980 na taster \emph{CTRL} i \emph{\_ (podvlaka)} odjednom.
981 \item \Ctrl +\keystroke{K}\keystroke{H} (otvaranje sistema pomoći)
982 pritisak na \emph{CTRL} i \emph{K} odjednom, odpustiti sve, pa onda
983 pritisak na \emph{H}.
984 \item \Esc \keystroke{,} (prelazak na sledeću stranu pomoći)
985 pritisak na taster \emph{Escape}, a nakon toga pritisak na taster
986 \emph{, (zarez)}.
987 \end{itemize}
989 U okviru sistema pomoći koji je ugrađen u sam editor uglavnom se
990 pojavljuju skraćeni oblici:
991 \begin{itemize}
992 \item \^{}D isto što i ``Ctrl-D''
993 \item \^{}KH isto što i ``Ctrl-K H''
994 \item \^{}[. isto što i ``Esc .''
995 \end{itemize}
998 \subsection{Sistem pomoći}
1000 Za pomoć pri korišćenju ediora ``joe'' preporučujemo pritiskanje
1001 kombinacije \Ctrl +\keystroke{K}\keystroke{H}, koja daje spisak
1002 komandi u gornjem delu editora. Postoji nekoliko stranica ove pomoći
1003 kroz koje se može kretati sa \Esc \keystroke{.} (tačka) i \Esc
1004 \keystroke{,} (zarez).
1006 U okviru pomoći postoje maltene sve komande koje editor pruža, a na
1007 kraju su čak uključene i ASCII tabele znakova. Preporučuje se makar
1008 ovlašno upoznavanje sa stranicama pomoći i mogućnostima editora.
1010 \subsection{Rad sa fajlovima}
1012 Snimanje sa izlaskom iz programa se može uraditi sa \Ctrl
1013 +\keystroke{K}\keystroke{X}, dok se
1014 samo snimanje izvršava sa \Ctrl +\keystroke{K}\keystroke{D}. U oba
1015 slučaja ``joe'' pita za ime fajla koji snimamo, pri čemu kao podrazumevanu
1016 vrednost ponudi trenutno ime.
1018 Joe može raditi sa više fajlova odjednom. Novi fajl se može otvoriti
1019 sa \Ctrl +\keystroke{K}\keystroke{E}. Na dnu editora će se pojaviti
1020 polje za kucanje imena fajla koje dozvoljava i da se putanja
1021 automatski dopunjava mogućnostima pritiskom na taster \Tab (Tab), baš
1022 kao i u komandnoj liniji.
1024 Prelazak na sledeći, odnosno prethodni, otvoreni fajl se dobija pritiskom
1025 na \Esc \keystroke{V}, odnosno \Esc \keystroke{U}.
1027 Zatvaranje fajla je moguće sa \Ctrl+\keystroke{C} (što je i
1028 standardna komanda za ``ubijanje'' trenutnog procesa u terminalu), pri
1029 čemu će ``joe'' pitati da li želimo da izađemo ako postoje promene
1030 koje nisu snimljene. Ako je u pitanju bio jedini otvoren fajl, tada će
1031 se i sam editor zatvoriti.
1033 \subsection{Rad sa tekstom}
1035 Pritiskom na \Ctrl+\keystroke{\_} se poništava poslednja promena (undo).
1037 Premeštanje i kopiranje delova teksta je malo drugačije nego u
1038 klasičnim grafičkim programima. Prvo je potrebno označiti željeni
1039 tekst u dva koraka: \Ctrl +\keystroke{K}\keystroke{B} postavlja
1040 početak bloka na trenutnu poziciju kursora, a \Ctrl
1041 +\keystroke{K}\keystroke{K} postavlja kraj bloka, nakon čega će
1042 selekcija biti i vizuelno označena. Sada je moguće na proizvoljnom
1043 mestu u istom ili drugom dokumentu pritisnuti \Ctrl
1044 +\keystroke{K}\keystroke{C} da bi se iskopirao označeni blok, odnosno
1045 \Ctrl +\keystroke{K}\keystroke{M} da bi se on premestio.
1046 Komanda \Ctrl +\keystroke{K}\keystroke{Y} briše odabrani blok.
1048 Pretraga dokumenta se započinje sa \Ctrl +\keystroke{K}\keystroke{F}.
1050 Pritiskom na \Ctrl +\keystroke{T} se dobija meni sa opcijama u kome se
1051 može odabrati više opcija za rad, kao što su margine, automatsko
1052 prelamanje redova, očuvanje uvlačenja redova (\emph{auto-indent}),
1053 sintaksno bojenje itd.
1055 \subsection{Rad sa prozorima}
1057 ``Joe'' ima mogućnosti i da podeli radnu površinu na nekoliko prozora
1058 koji omogućavaju da se vidi više dokumenata, ili čak da se vide
1059 različiti delovi istog dokumenta. Prozor se deli na dva komandom \Ctrl
1060 +\keystroke{K}\keystroke{O}. Veličina trenutnog prozora se potom može
1061 povećavati (\Ctrl +\keystroke{K}\keystroke{G}) ili smanjivati (\Ctrl
1062 +\keystroke{K}\keystroke{T}) na uštrb drugih prozora. Prelazak na
1063 sledeći, odnosno prethodni prozor se dobija pristikom na \Ctrl
1064 +\keystroke{K}\keystroke{N}, odnosno na \Ctrl
1065 +\keystroke{K}\keystroke{P}. Komanda \Ctrl +\keystroke{K}\keystroke{I}
1066 omogućuje da se naizmenično vide svi prozori, ili samo jedan.
1068 \subsection{Problem: ``zamrzavanje'' pri snimanju} ako editor izgleda
1069 kao da se zaledio verovatno je problem što je stisnuta ``klasična''
1070 kombinacija za snimanje \Ctrl + \keystroke{S} koja ne radi u
1071 ovom programu, a nažalost izaziva prekid osvežavanja ekrana. Efekat
1072 se poništava pritiskom na \Ctrl + \keystroke{Q}. Za više detalja
1073 pogledati Glavu~\ref{g-smrzavanje}.
1075 \skica{joe i sintaksno bojenje za m2}
1077 \newpage
1078 \section{Putty}
1080 \emph{Putty} je program koji služi da se pod Windows operativnim
1081 sistemom otvori terminal (konzola, komandna linija) na udaljenom UNIX
1082 serveru. Može se naći online na
1083 \url{http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html}.
1085 Po pokretanju se prikazuje dijalog u kome se može ukucati adresa
1086 udaljenog računara i konfigurisati mnogi parametri. Najčešće je dosta
1087 samo uneti adresu računara i pokrenuti konekciju. Nakon toga (ako je
1088 uspešno povezivanje) biće prikazan ekran za unos korisničkog imena i
1089 lozinke.
1091 \subsection{Problem: terminal ne odgovara na unos, ``smrznuo'' se}
1092 \label{g-smrzavanje}
1094 Putty (kao i većina standardnih linux terminala koji koriste
1095 softversku kontrolu toka podataka \emph{software flow control}) se
1096 može dovesti u stanje da ne prikazuje ispis unosa na ekranu, pritiskom
1097 na \Ctrl+\keystroke{S}. Ovo je često velik problem jer se poklapa sa
1098 standardnom prečicom za snimanje u većini grafičkih aplikacija, pa se
1099 može nehotično aktivirati. Iz ovog režima rada se može izaći prečicom
1100 \Ctrl+\keystroke{Q}. Ukratko:
1101 \begin{lstlisting}[xleftmargin=10em]
1102 Do not press
1103 Ctrl S
1104 If you do
1105 Ctrl Q
1106 \end{lstlisting}
1108 Smisao postojanja ovakve opcije je dobrim delom istorijski, iz vremena
1109 kad su brzine protoka bile veoma male, i kada se štedelo time što bi
1110 se privrmeno isključio protok kada nisu neophodne povratne
1111 informacije, na primer kod komandi koje se dugo izvršavaju. Naravno
1112 ovo ima svoje primene i danas kod slabijih veza, ili kod mobilnih veza
1113 koje se plaćaju po protoku, a nekad se može i dobiti na brzini
1114 izvršavanja programa, ako se ne gubi vreme na osvežavanje ekrana.
1116 \skica{literatura i linkovi izdovjeni na kraju dokumenta}
1118 %\end{multicols}
1119 \end{document}
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner