gitweb on Svarog

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