gitweb on Svarog

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