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
index 0e1509a..a1a4002 100644 (file)
@@ -1,6 +1,7 @@
 % skripta-os2.tex
 % Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
-% 2011/2012
+% Doni Pracner, Ivan Pribela
+% 2011/12 -- 2014/15
 
 \documentclass[a4paper,twoside]{article}
 \usepackage[T1]{fontenc}
@@ -12,8 +13,8 @@
 \newcommand{\inst}{Departman za matematiku i informatiku, PMF, UNS}
 \newcommand{\autorinst}{\autor \\ \inst}
 \newcommand{\naslov}{Skripta za vežbe iz predmeta operativni sistemi 2} 
-\newcommand{\datum}{April 2012, Novi Sad}
-\newcommand{\verzija}{ver 12d}
+\newcommand{\datum}{Februar 2015, Novi Sad}
+\newcommand{\verzija}{ver 15a}
 
 \usepackage[serbian]{babel}
 \usepackage{fancyhdr}
 
 %change the default font
 \usepackage{lmodern}
+\usepackage{beramono}
 \renewcommand{\familydefault}{\sfdefault}
 
 \usepackage{pifont}
-\usepackage{keystroke}
 
 %podesavanja outputa za pdf verzije
 \usepackage[bookmarks,pdffitwindow=false,unicode=true,%
@@ -43,54 +44,86 @@ pdfauthor={\autor}%
 \usepackage{latexsym}
 \usepackage{multicol}
 
+%\usepackage{keystroke}
+% ispod je dodata alternativa za ovaj paket
+
 \usepackage{tikz}
+\usetikzlibrary{shadows}
+
+\newcommand*\keystroke[1]{%
+  \tikz[baseline=(key.base)]
+    \node[%
+      draw,
+      fill=white,
+      drop shadow={shadow xshift=0.2ex,shadow yshift=-0.2ex,fill=black,opacity=0.75},
+      rectangle,
+      rounded corners=2pt,
+      inner sep=1pt,
+      line width=0.5pt,
+      font=\small\sffamily
+    ](key) {#1\strut}
+  ;
+}
+
+\newcommand*\Ctrl{\keystroke{Ctrl}} 
+\newcommand*\Tab{\keystroke{Tab}}
+\newcommand*\Esc{\keystroke{Esc}}
 
 %margine
-%experiment 
-%\usepackage[top=2.5cm, bottom=1.5cm, left=2cm, right=1cm]{geometry}
-%staro: 
-\usepackage[top=1.5cm, bottom=1cm, left=2cm, right=1cm]{geometry}
+\usepackage[top=2cm, bottom=2cm, left=2.5cm, right=2cm]{geometry}
 
-\begin{document}
+% theorems, definition etc.
+%''''''''''''''''''''''''''
 
-%customize the itemize environments
+\theoremstyle{definition}
+\newtheorem{def1}{Definicija}
+\theoremstyle{plain}
+\newtheorem{theo}{Teorema}
+\newtheorem{lema}{Lema}
 
-\let\olditemize=\itemize
-\def\itemize{
-\olditemize
-  \setlength{\itemsep}{1pt}
-  \setlength{\parskip}{0pt}
-  \setlength{\parsep}{0pt}
-  \setlength{\topsep}{-1cm}
+\lstloadlanguages{Modula-2,C++}
 
+\lstset{
+       basicstyle=\ttfamily,
+        showstringspaces=false,
+       breaklines=true
 }
 
-%% ovi redovi daju header i footer
+\lstdefinestyle{codeblock}{
+%      basicstyle=\footnotesize\ttfamily,
+        keywordstyle=\textbf,
+        columns=[l]fixed,
+        breakatwhitespace=true,
+%        prebreak=\P,
+%        postbreak=\ding{229}\space,
+        language=Modula-2,
+        xleftmargin=1em
+}
 
-\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
-\fancyhf{} % delete current setting for header and footer
-%\fancyfoot[C]{\thepage}
-\fancyhead[LO]{\bfseries\rightmark}
-\fancyhead[RO]{\thepage}
-\fancyhead[RE]{Operativni sistemi 2 -- skripta}
-\fancyhead[LE]{\thepage}
-\renewcommand{\headrulewidth}{0.5pt}
-\renewcommand{\headwidth}{\textwidth}
-%\renewcommand{\footrulewidth}{0.5pt}
-%\addtolength{\headheight}{0.5pt} % make space for the rule
-\fancypagestyle{plain}{%
-\fancyhead{} % get rid of headers on plain pages
-\fancyfoot{}
-\renewcommand{\headrulewidth}{0pt} % and the line
-\renewcommand{\footrulewidth}{0pt} % and the line
+\lstdefinestyle{codeblock-indent}{
+  style=codeblock,
+  xleftmargin=4em
 }
-\renewcommand{\headheight}{15pt}
 
-%promene u marginama:
-%\setlength{\marginparwidth}{32pt}
-%\setlength{\textwidth}{620pt}
-%\setlength{\textheight}{620pt}
+\lstdefinestyle{terminal}{
+  frame=lt,
+%  frameround=fftt,
+  backgroundcolor=\color[gray]{.95},
+% prebreak=\P,
+  postbreak=\ding{229}\space,
+  xleftmargin=2em
+}
 
+\lstdefinestyle{numcodeblock}{
+  style=codeblock,
+  numbers=left,
+  firstnumber=1,
+  stepnumber=1
+}
+
+\lstnewenvironment{codeblock}[1][]{\lstset{style=codeblock,#1}}{}
+\lstnewenvironment{codeblock-indent}[1][]{\lstset{style=codeblock-indent,#1}}{}
+\lstnewenvironment{terminal}{\lstset{style=terminal}}{}
 
 %% specijalni blokovi koji služe kao podsetnici u radu ili napomene
 \newcommand{\skica}[1]{
@@ -114,52 +147,55 @@ pdfauthor={\autor}%
 
  \renewcommand{\skica}[1]{}
 
+%customize the itemize environments
 
-\maketitle
+\let\olditemize=\itemize
+\def\itemize{
+\olditemize
+  \setlength{\itemsep}{1pt}
+  \setlength{\parskip}{0pt}
+  \setlength{\parsep}{0pt}
+  \setlength{\topsep}{-1cm}
 
-% theorems, definition etc.
-%''''''''''''''''''''''''''
+}
+ \begin{document}
 
-\theoremstyle{definition}
-\newtheorem{def1}{Definicija}
-\theoremstyle{plain}
-\newtheorem{theo}{Teorema}
-\newtheorem{lema}{Lema}
 
-\lstloadlanguages{Modula-2,C++}
+%% ovi redovi daju header i footer
 
-\lstset{
-       basicstyle=\footnotesize\ttfamily,
-        showstringspaces=false,
-       breaklines=true
-}
+\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
+\fancyhf{} % delete current setting for header and footer
+%\fancyfoot[C]{\thepage}
 
-\lstdefinestyle{codeblock}{
-       basicstyle=\footnotesize,
-        keywordstyle=\textbf,
-        columns=[l]fixed,
-        breakatwhitespace=true,
-%        prebreak=\P,
-%        postbreak=\ding{229}\space,
-        language=Modula-2,
-        xleftmargin=4em
-}
+\fancyhead[LO]{\bfseries\rightmark}
+\fancyhead[RO]{\thepage}
 
-\lstdefinestyle{terminal}{
-  frame=l,
-%  frameround=fftt,
-  xleftmargin=4em
-}
+\fancyhead[RE]{Operativni sistemi 2 -- skripta}
+\fancyhead[LE]{\thepage}
 
-\lstdefinestyle{numcodeblock}{
-  style=codeblock,
-  numbers=left,
-  firstnumber=1,
-  stepnumber=1
+\renewcommand{\headrulewidth}{0.5pt}
+\renewcommand{\headwidth}{\textwidth}
+
+%\renewcommand{\footrulewidth}{0.5pt}
+%\addtolength{\headheight}{0.5pt} % make space for the rule
+\fancypagestyle{plain}{%
+  \fancyhead{} % get rid of headers on plain pages
+  \fancyfoot{}
+  \renewcommand{\headrulewidth}{0pt} % and the line
+  \renewcommand{\footrulewidth}{0pt} % and the line
 }
+\renewcommand{\headheight}{15pt}
+
+%promene u marginama:
+%\setlength{\marginparwidth}{32pt}
+%\setlength{\textwidth}{620pt}
+%\setlength{\textheight}{620pt}
+
+
+
+
+\maketitle
 
-\lstnewenvironment{codeblock}[1][]{\lstset{style=codeblock,#1}}{}
-\lstnewenvironment{terminal}{\lstset{style=terminal}}{}
 
 % ----------------==================--------------------------------------
 %                 Pravi pocetak rada
@@ -171,17 +207,25 @@ sistemima iz Debian porodice.
 
 \tableofcontents
 
-%\newpage %necemo jos da prelamamo ovde
+\newpage
 
 %\begin{multicols}{2}
 
 \section{GNU Modula 2}
 
+\emph{GNU Modula 2} (u daljem tekstu često skraćeno na \emph{gm2}) je
+pred procesor (\emph{front end}) za GNU kolekciju kompajlera
+(GCC). Podržava nekoliko dijalekata jezika ``Modula 2'' --
+najznačajniji su ISO standard i nekoliko varijacija koje je originalni
+autor Niklaus Virt (\emph{Niklaus Wirth}) opisao u različitima
+verzijama knjige \emph{Programming in Modula 2 (PIM)}. Uz kompajler se
+dobijaju i besplatne ISO, PIM i još neke biblioteke.
+
 \subsection{Prvi program u gm2 }
 \label{g-prvi-program}
 
 Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
-\begin{codeblock}
+\begin{codeblock-indent}
   MODULE hello;
 
   FROM StrIO IMPORT WriteString, WriteLn;
@@ -190,30 +234,33 @@ Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
      WriteString('hello world'); 
      WriteLn
   END hello.
-\end{codeblock}
+\end{codeblock-indent}
 
 Primećuje se razlika u modulu iz koga se uvoze komande u odnosu na
-XDS/TopSpeed verzije M2, tamo je sve bilo u \kod{InOut}, dok ovde
-koristimo \kod{StrIO} za rad sa stringovima, \kod{NumberIO}, za rad sa
+XDS/TopSpeed verzije M2, tamo je sve bilo u \kod{InOut}, dok se ovde
+koristi \kod{StrIO} za rad sa stringovima, \kod{NumberIO} za rad sa
 brojevima i tako dalje. Za pregled dostupnih biblioteka predlaže se
 korišćenje zvanične stranice:
 \url{http://nongnu.org/gm2/libraries.html}, odnosno
 \url{http://nongnu.org/gm2/base_libraries.html} za samo osnovne
 biblioteke.
 
-Predpostavimo da smo ga napravili u trenutnom direktorijumu, koristeći
-neki tesktualni editor (u dodatku~\ref{app-joe} je opisan ``joe'' koji
-koristimo na vežbama).  Kreirani fajl se može prevesti u izvršnu
-verziju sledećom komandom:
+Predpostavimo da je fajl napravljen u trenutnom direktorijumu,
+koristeći neki tesktualni editor (u dodatku~\ref{app-joe} je opisan
+``joe'' koji se koristi na vežbama).  Kreirani fajl se tada može
+prevesti u izvršnu verziju sledećom komandom:
 \begin{terminal}
   gm2 hello.mod
 \end{terminal}
 
 Ako je kod ispravan (kao onaj gore) u istom direktorijumu će se
-napraviti fajl \kod{a.out}, koji se može pokrenuti sa \kod{./a.out},
-pri čemu naglašavamo da hoćemo da pokrenemo program iz trenutnog
-direktorijuma koji se označava tačkom. Ako želimo da napravimo
-izvršni fajl pod nekim drugim nazivom možemo koristiti poziv sledećeg
+napraviti fajl \kod{a.out}, koji se može pokrenuti sa:
+\begin{terminal}
+  ./a.out
+\end{terminal}
+pri čemu \kod{./} naglašava da hoćemo da pokrenemo program iz trenutnog
+direktorijuma (koji se označava tačkom). Ako je potrebno da
+izvršni fajl ima neki drugi naziv može se koristiti poziv sledećeg
 tipa:
 \begin{terminal}
   gm2 -o imeIzlaznogFajla ulaznifajl
@@ -233,13 +280,13 @@ odgovarajućih tipova.  Na primer, mapirajmo poziv \kod{system}, koji
 izvršava prosleđenu komandu u novom \emph{shell}-u. Specifikaciju
 komande možemo videti sa
 \begin{terminal}
-man system
+  man system
 \end{terminal}
 
 odnosno videćemo da je poziv definisan na sledeći način:
-\begin{codeblock}
+\begin{codeblock-indent}
 int system(const char *command);
-\end{codeblock}
+\end{codeblock-indent}
 što znači da vraća ceo broj, a prima jedan argument koji je pokazivač
 (što se označava *) na znak. Ovo je zapravo ceo string, pošto se u C
 jeziku oni predstavljaju kao pokazivač na prvi znak, a string se onda
@@ -303,8 +350,22 @@ mogla funkcija da se definiše kao \kod{PROCEDURE system(command: ARRAY
 bez korišćenja pomoćne promenljive \kod{c} da se dobije povratna
 vrednost. 
 
-Tabela pretvaranja tipova se može videti na
-\url{http://www.nongnu.org/gm2/interface_to_c.html}
+Neki primeri pretvaranja tipova su dati u Tabeli~\ref{t-pretvaranje-tipova}, preuzetoj sa \url{http://www.nongnu.org/gm2/interface_to_c.html}.
+
+\begin{table}[htp]
+\begin{center}
+\begin{tabular}{lll}
+Stvarni parametar      &  Konverzija  &   Tip vrednosti koji će biti prosleđen\\
+\hline
+123                    &  -                &   long long int\\
+"hello world"          &  -                &   const char *\\
+a: ARRAY OF CHAR       &  ADR(a)           &   char *\\
+a: ARRAY [0..5] OF CHAR&  ADR(a)           &   char *\\
+3.14                   &  -                &   long double
+\end{tabular}
+\end{center}
+\caption{Tabela pretvaranja tipova\label{t-pretvaranje-tipova}}
+\end{table}
 
 \subsubsection{Primer: Izlistavanje sadržaja direktorijuma}
 
@@ -319,40 +380,159 @@ kraju i zatvara otvoreni direktorijum. Bitno je zatvarati otvorene
 resurse jer je moguće da sistem odbije da otvori novi ako ih
 proces već ima previše otvorenih.
 
-Kada imamo imena stavki iz direktorijuma o njima možemo dobiti više
-informacija \kod{stat}. Ona prima dva argumenta, prvi je \emph{puna}
-putanja do fajla, a drugi je pokazivač na strukturu u koju će komanda
-upisati podatke. Obratiti pažnju da zbog ovoga struktura već mora
-postojati u memoriji, ili kao lokalna promenljiva odgovarajućeg
-slogovnog tipa, ili dinamički alocirana korišćenjem pokazivača na nju.
-
 Budući da su u pitanju sistemski pozivi niskog nivoa, veličine tipova
 su nažalost promenljive i mogu zavisiti od konkretnog operativnog
 sistema, a naročito utiče da li je u pitanju~32--bitni, ili~64--bitni
 sistem. Zbog ovoga su date dve varijante bibilioteke sa tipovima.
-Prva je testirana na Lubuntu 11.10 32bit, a druga je testirana na
-Kubuntu 11.10 64bit.
+Prva je testirana na Lubuntu 11.10 i 12.04 32bit, a druga je testirana
+na Kubuntu 11.10 i 12.10 64bit.
 
 \begin{codeblock}
-DEFINITION MODULE FOR "C" Lib32;
+DEFINITION MODULE FOR "C" libdir;
+
   FROM SYSTEM IMPORT 
     ADDRESS, BYTE;
-  EXPORT UNQUALIFIED opendir, readdir, closedir, stat, 
-    PDir, DirEnt, PDirEnt, Stat, PStat, PInt;
+
+  EXPORT UNQUALIFIED opendir, readdir, closedir, PDir, DirEnt, PDirEnt;
 \end{codeblock}
-\begin{minipage}{0.5\textwidth}
+\begin{minipage}{0.45\textwidth}
 \begin{codeblock}
 (* types for 32 bit *)
   TYPE
     PDir = ADDRESS;
     DirEnt = RECORD
-         ino: INTEGER;
-         off: INTEGER;
-         reclen: SHORTCARD;
-         type: BYTE;
-         name: ARRAY [0..255] OF CHAR;
+       ino: INTEGER;
+       off: INTEGER;
+       reclen: SHORTCARD;
+       type: BYTE;
+       name: ARRAY [0..255] OF CHAR;
+    END;
+    PDirEnt = POINTER TO DirEnt;
+ \end{codeblock}
+\end{minipage}
+\begin{minipage}{0.45\textwidth}
+\begin{codeblock}[frame=single,frameround=tttt]
+(* types for 64 bit *)
+  TYPE
+    PDir = ADDRESS;
+    DirEnt = RECORD
+       ino: LONGINT;
+       off: LONGINT;
+       reclen: SHORTCARD;
+       type: BYTE;
+       name: ARRAY [0..255] OF CHAR;
     END;
     PDirEnt = POINTER TO DirEnt;
+\end{codeblock}
+\end{minipage}
+\begin{codeblock}
+  PROCEDURE opendir(name: ARRAY OF CHAR): PDir;
+  PROCEDURE readdir(dirp: PDir): PDirEnt;
+  PROCEDURE closedir(dirp: PDir): [INTEGER];
+
+END libdir.
+\end{codeblock}
+
+\begin{codeblock}
+MODULE Zad3;
+
+FROM StrIO IMPORT
+  WriteString, WriteLn;
+FROM NumberIO IMPORT
+  WriteInt;
+FROM Args IMPORT
+  Narg, GetArg;
+  FROM libdir IMPORT
+  opendir, readdir, closedir, PDir, PDirEnt;
+FROM errno IMPORT
+  geterrno;
+
+TYPE
+  String = ARRAY [0..1023] OF CHAR;
+
+VAR
+  Putanja: String;
+  n, i: INTEGER;
+  ok: BOOLEAN;
+
+PROCEDURE Listaj(Ime: ARRAY OF CHAR);
+VAR
+  dir: PDir;
+  entry: PDirEnt;
+  c: INTEGER;
+BEGIN
+  WriteString("Folder "); WriteString(Ime); WriteLn;
+  dir:= opendir(Ime);
+  IF dir = NIL THEN
+    WriteString("  Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
+    WriteString("  Ne mogu da otvorim direktorijum."); WriteLn();
+  ELSE
+    entry:= readdir(dir);
+    WHILE entry # NIL DO
+      IF entry^.name[0] # "." THEN
+        WriteString("  "); WriteString(entry^.name); WriteLn;
+      END;
+      entry:= readdir(dir);
+    END;
+    c:= closedir(dir);
+    IF c = -1 THEN
+      WriteString("  Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
+      WriteString("  Ne mogu da zatvorim direktorijum."); WriteLn();
+    END;
+  END;
+END Listaj;
+
+BEGIN
+  n:= Narg();
+  FOR i:= 1 TO n - 1 DO
+    ok:= GetArg(Putanja, i);
+    WriteLn;
+    Listaj(Putanja);
+  END;
+  WriteLn;
+END Zad3.
+\end{codeblock}
+
+\subsubsection{Primer: Ispis osobina pojedinih fajlova}
+
+O pojedinim fajlovima možemo dobiti više informacija koristeći
+sistemski poziv \kod{stat}. On prima dva argumenta, prvi je
+\emph{puna} putanja do fajla, a drugi je pokazivač na strukturu u koju
+će komanda upisati podatke. Obratiti pažnju da zbog ovoga struktura
+već mora postojati u memoriji, ili kao lokalna promenljiva
+odgovarajućeg slogovnog tipa, ili dinamički alocirana korišćenjem
+pokazivača na nju.
+
+Linux i mnogi drugi srodni sistemi za internu prezentaciju vremena
+koriste broj sekundi od početka ``epohe'', odnosno od prvog januara
+1970 godine. Za konverziju u klasičnije mere vremena se može koristiti
+poziv \kod{localtime}.
+
+Kao i u prethodnom primeru date su dve verzije definicija nekih
+tipova.
+
+\begin{codeblock}
+DEFINITION MODULE FOR "C" LibStat32;
+  FROM SYSTEM IMPORT 
+    ADDRESS, BYTE;
+  EXPORT UNQUALIFIED stat, localtime,
+    Stat, PStat, Tm, PTm, PInt,
+    fifo, character, directory, block, regular, network, link, socket;
+
+  CONST
+    fifo      =  1;
+    character =  2;
+    directory =  4;
+    block     =  6;
+    regular   =  8;
+    network   =  9;
+    link      = 10;
+    socket    = 12;
+\end{codeblock}
+\begin{minipage}{0.45\textwidth}
+\begin{codeblock}
+(* types for 32 bit *)
+  TYPE
     Stat = RECORD
          dev: LONGINT;
          ino: LONGINT;
@@ -365,9 +545,13 @@ DEFINITION MODULE FOR "C" Lib32;
          size: INTEGER;
          blksize: INTEGER;
          blocks: INTEGER;
-         atime: LONGINT;
-         mtime: LONGINT;
-         ctime: LONGINT;
+         atime: INTEGER;
+         anano: INTEGER;
+         mtime: INTEGER;
+         mnano:INTEGER;
+         ctime:INTEGER;
+         cnano: INTEGER;
+         unused:LONGINT;
     END;
   \end{codeblock}
 \end{minipage}
@@ -375,15 +559,6 @@ DEFINITION MODULE FOR "C" Lib32;
 \begin{codeblock}[frame=single,frameround=tttt]
 (* types for 64 bit *)
   TYPE
-    PDir = ADDRESS;
-    DirEnt = RECORD
-         ino: LONGINT;
-         off: LONGINT;
-         reclen: SHORTCARD;
-         type: BYTE;
-         name: ARRAY [0..255] OF CHAR;
-    END;
-    PDirEnt = POINTER TO DirEnt;
     Stat = RECORD
          dev: LONGINT;
          ino: LONGINT;
@@ -403,18 +578,23 @@ DEFINITION MODULE FOR "C" Lib32;
   \end{codeblock}
 \end{minipage}
 \begin{codeblock}
-    PStat = POINTER TO Stat;
+    Tm = RECORD
+             sec, min, hour,
+             mday, mon, year,
+             wday, yday, isdst: INTEGER;
+         END;
+    PTm = POINTER TO Tm;
     PInt = POINTER TO INTEGER;
+    PStat = POINTER TO Stat;
 
-  PROCEDURE opendir(name: ARRAY OF CHAR): PDir;
-  PROCEDURE readdir(dirp: PDir): PDirEnt;
-  PROCEDURE closedir(dirp: PDir): [INTEGER];
   PROCEDURE stat(path: ARRAY OF CHAR; buf: PStat): [INTEGER];
-END Lib32.
+  PROCEDURE localtime(time: PInt): PTm;
+
+END LibStat32.
 \end{codeblock}
 
 \begin{codeblock}
-MODULE Zad5;
+MODULE Zad4;
 
 FROM SYSTEM IMPORT
   ADR;
@@ -426,8 +606,9 @@ FROM StrLib IMPORT
   StrLen, StrConCat;
 FROM Args IMPORT
   Narg, GetArg;
-FROM Lib32 IMPORT
-  opendir, readdir, closedir, stat, PDir, PDirEnt, Stat;
+FROM LibStat32 IMPORT
+  stat, localtime, Stat, PTm;
+IMPORT LibStat32;
 FROM errno IMPORT
   geterrno;
 
@@ -439,48 +620,104 @@ VAR
   n, i: INTEGER;
   ok: BOOLEAN;
 
-PROCEDURE Listaj(Ime: ARRAY OF CHAR);
+PROCEDURE WriteMode(mode: INTEGER);
+
+  PROCEDURE WriteType(type: INTEGER);
+  BEGIN
+    IF type = lib32.fifo THEN
+      WriteString("f");
+    ELSIF type = lib32.character THEN
+      WriteString("c");
+    ELSIF type = lib32.directory THEN
+      WriteString("d");
+    ELSIF type = lib32.block THEN
+      WriteString("b");
+    ELSIF type = lib32.regular THEN
+      WriteString("-");
+    ELSIF type = lib32.network THEN
+      WriteString("n");
+    ELSIF type = lib32.link THEN
+      WriteString("l");
+    ELSIF type = lib32.socket THEN
+      WriteString("s");
+    ELSE
+      WriteString("?");
+    END;
+  END WriteType;
+
+  PROCEDURE WriteRWX(triplet: INTEGER);
+  BEGIN
+    IF ((triplet DIV 4) MOD 2) # 0 THEN
+      WriteString("r");
+    ELSE
+      WriteString("-");
+    END;
+    IF ((triplet DIV 2) MOD 2) # 0 THEN
+      WriteString("w");
+    ELSE
+      WriteString("-");
+    END;
+    IF (triplet MOD 2) # 0 THEN
+      WriteString("x");
+    ELSE
+      WriteString("-");
+    END;
+  END WriteRWX;
+
+BEGIN
+  WriteType((mode DIV 4096) MOD 16);
+  WriteRWX(mode DIV 64);
+  WriteRWX(mode DIV 8);
+  WriteRWX(mode);
+END WriteMode;
+
+PROCEDURE WriteTime(time: LONGINT);
 VAR
-  dir: PDir;
-  entry: PDirEnt;
-  info: Stat;
-  c: INTEGER;
-  Len: CARDINAL;
-  Putanja: String;
+  tm: PTm;
 BEGIN
-  dir:= opendir(Ime);
-  IF dir = NIL THEN
-    WriteString("Folder "); WriteString(Ime); WriteLn;
-    WriteString("  Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
-    WriteString("  Ne mogu da otvorim direktorijum."); WriteLn();
-  ELSE
-    Len:= StrLen(Ime);
-    IF Ime[Len - 1] # "/" THEN
-      StrConCat(Ime, "/", Ime);
+  tm:= localtime(ADR(time));
+  IF tm # NIL THEN
+    WriteInt(tm^.year + 1900, 0);
+    WriteString("-");
+    IF tm^.mon < 9 THEN
+      WriteString("0");
     END;
-    WriteString("Folder "); WriteString(Ime); WriteLn;
-    entry:= readdir(dir);
-    WHILE entry # NIL DO
-      IF entry^.name[0] # "." THEN
-        StrConCat(Ime, entry^.name, Putanja);
-        c:= stat(Putanja, ADR(info));
-        WriteString("  ");
-        IF c = -1 THEN
-          WriteString("?    ? KB");
-        ELSE
-          WriteInt(info.nlink, 3);
-          WriteInt((info.size + 512) DIV 1024, 5); WriteString(" KB ");
-        END;
-        WriteString(" "); WriteString(entry^.name); WriteLn;
-      END;
-      entry:= readdir(dir);
+    WriteInt(tm^.mon + 1, 0);
+    WriteString("-");
+    IF tm^.mday < 10 THEN
+      WriteString("0");
     END;
-    c:= closedir(dir);
-    IF c = -1 THEN
-      WriteString("  Greska broj "); WriteInt(geterrno(), 0); WriteString("."); WriteLn();
-      WriteString("  Ne mogu da zatvorim direktorijum."); WriteLn();
+    WriteInt(tm^.mday, 0);
+    WriteString(" ");
+    IF tm^.hour < 10 THEN
+      WriteString("0");
+    END;
+    WriteInt(tm^.hour, 0);
+    WriteString(":");
+    IF tm^.hour < 10 THEN
+      WriteString("0");
     END;
+    WriteInt(tm^.min, 0);
+  ELSE
+    WriteString("??:??");
+  END;
+END WriteTime;
+
+PROCEDURE Listaj(Putanja: ARRAY OF CHAR);
+VAR
+  info: Stat;
+  c: INTEGER;
+BEGIN
+  c:= stat(Putanja, ADR(info));
+  IF c = -1 THEN
+    WriteString("??????????  ?    ? KB ????-??-?? ??:??");
+  ELSE
+    WriteMode(info.mode);
+    WriteInt(info.nlink, 3);
+    WriteInt((info.size + 512) DIV 1024, 5); WriteString(" KB ");
+    WriteTime(info.atime);
   END;
+  WriteString(" "); WriteString(Putanja); WriteLn;
 END Listaj;
 
 BEGIN
@@ -491,7 +728,7 @@ BEGIN
     Listaj(Putanja);
   END;
   WriteLn;
-END Zad5.
+END Zad4.
 \end{codeblock}
 
 \subsection{Stvaranje novih procesa}
@@ -499,9 +736,9 @@ END Zad5.
 Korišćenjem sistemske komande \kod{fork} trenutni proces se duplira
 (``račva''). Novi proces je identičan sa originalnim, osim u svom
 identifikacionom broj. Komanda ne prima parametre i vraća jedan integer, pa se može mapirati na sledeći način:
-\begin{codeblock}
+\begin{codeblock-indent}
 PROCEDURE fork(): INTEGER;
-\end{codeblock}
+\end{codeblock-indent}
 
 Oba procesa se nakon račvanja nastavljaju odvijati u sledećem redu
 koda. Jedino po čemu se razlikuju je vrednost koju je vratio
@@ -511,14 +748,14 @@ je ta vrednost jednaka proces identifikatoru (\emph{pid}-u)
 procesu je ova vrednost jednaka nuli. Budući da je najčešće potrebno
 da dete i roditelj rade različite stvari, to se obično rešava kodom
 sledećeg oblika:
-\begin{codeblock}
+\begin{codeblock-indent}
 pid := fork();
 IF pid = 0 THEN
    (* "detetove" operacije *)
 ELSE
    (* "roditeljske" operacije *)
 END;
-\end{codeblock}
+\end{codeblock-indent}
 
 Komanda \kod{wait} (uvezena kao sistemska) se može pozvati u
 originalnom procesu sa efektom da se proces uspava dokle god neki od
@@ -581,14 +818,14 @@ END;
 \begin{minipage}{0.4\textwidth}
 \begin{tikzpicture}
 [proc/.style={circle,draw}]
-\def \n {5}
-\node[proc] (1) at (0,0) {1};
-\foreach \s in {2,...,\n}
+\def \n {3}
+\node[proc] (top) at (0,0) {0..4};
+\foreach \s in {0,...,\n}
 {
-  \node[proc] (\s) at (-3.5+\s,-2) {\s};
+  \node[proc] (\s) at (-1.5+\s,-2) {\s};
 }
-\foreach \s in {2,...,\n} {
-  \draw [->] (1) to (\s);
+\foreach \s in {0,...,\n} {
+  \draw [->] (top) to (\s);
 }
 \end{tikzpicture}
 \end{minipage}
@@ -597,15 +834,16 @@ END;
 
 \begin{minipage}{0.6\textwidth}
 \begin{codeblock}
-i := 1;
-j := 0;
-WHILE (i < n) AND (j < m) DO
+dubina := 1;
+brdece := 0;
+WHILE (dubina < maxdubina) AND 
+      (brdece < potrebnodece) DO
   pid := fork();
   IF pid # 0 THEN
-    INC(j);
+    INC(brdece);
   ELSE
-    INC(i);
-    j:=0;
+    INC(dubina);
+    brdece := 0;
   END;
 END;
 \end{codeblock}
@@ -613,14 +851,18 @@ END;
 \begin{minipage}{0.4\textwidth}
 \begin{tikzpicture}
 [proc/.style={circle,draw},
-level 1/.style={sibling distance=20mm,level distance=10mm},
-level 2/.style={sibling distance=10mm,font=\scriptsize}
+level 1/.style={sibling distance=28mm,level distance=10mm},
+level 2/.style={sibling distance=14mm,font=\scriptsize},
+level 3/.style={sibling distance=6mm,font=\tiny}
 ]
-\node[proc] (root) {0}
-child[->] foreach \x in {1,2} {node[proc] {\x}
-  child foreach \y in {1,2} {node[proc] {\x-\y}
-    }};
-
+\node[proc] (root) {1-0}
+child[->] foreach \x in {0,1} {node[proc] {1-\x}
+  child foreach \y in {0,1} {node[proc] {2-\y}
+    child foreach \z in {0,1} {node[proc] {3-\z}
+    }}};
+
+\node[text width=0.9\textwidth] (desc) at (0,-4) {maxdubina=4, potrebnodece=2, 
+čvorovi prikazuju vrednosti pri kreiranju};
 \end{tikzpicture}
 \end{minipage}
 
@@ -656,20 +898,20 @@ je Lubuntu, ako su performanse problematične.
 Prvi korak za instalaciju dodatnog kompajlera GNU Modula 2 je
 dodavanje repozitorijuma softvera u sistem. Ovo se može uraditi ručnim
 menjanjem fajla \kod{/etc/apt/sources.list} i dodavanjem
-\begin{codeblock}
+\begin{codeblock-indent}
 #
 #  GNU Modula-2 repo
 #
 
-deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main 
-deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main
-\end{codeblock}
+deb http://floppsie.comp.glam.ac.uk/debian/ wheezy main 
+deb-src http://floppsie.comp.glam.ac.uk/debian/ wheezy main
+\end{codeblock-indent}
 
 Alternativno se mogu koristiti sledeće komande:
 
 \begin{terminal}
-add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
-add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
+sudo add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ wheezy main"
+sudo add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ wheezy main"
 \end{terminal}
 
 Većina sistema omogućava i da se ovo uradi preko nekih grafičkih
@@ -689,6 +931,13 @@ sudo apt-get source gm2
 
 Videti Glavu~\ref{g-prvi-program} za primer kompajliranja programa.
 
+\paragraph{Napomena:} Prilikom unapredjivanja Linux distribucije na
+sledeću verziju (npr. 13.10 na 14.04) se standardno onemogućavaju
+dodati izvori softvera i potrebno ih je ručno ponovo upaliti.  Ovo se
+može uraditi otvoranjem \kod{/etc/apt/sources.list} i uklonjanjem
+``\#'' sa početka redova koje želimo da koristimo ponovo ili
+korišćenjem adekvatnih vizuelnih alata.
+
 \subsection{Problem: nedostaje ``ctli.o'' i/ili još neki fajlovi}
 
 Pri pokušaju kompajliranja se na nekim sistemima može desiti da
@@ -714,6 +963,7 @@ treba zameniti ``x86\_64'' sa ``i386''.
 
 \skica{možda i build from source}
 
+\newpage
 \section{Tekst editor Joe}
 \label{app-joe}
 
@@ -728,39 +978,121 @@ sudo apt-get install joe
 \end{terminal}
 Ili analogno na drugim sistemima za instaliranje softvera.
 
-Otvoranje postojećeg fajla ``hello.mod'' za uređivanje,
-odnosno otvaranje novog praznog fajla u koji ćemo unositi
-odgovarajući kod ili tekst se može postići sledećom komandom:
+Otvaranje postojećeg fajla ``hello.mod'' za uređivanje, odnosno
+otvaranje novog praznog fajla u koji ćemo unositi odgovarajući kod ili
+tekst se može postići sledećom komandom:
 \begin{terminal}
 joe hello.mod
 \end{terminal}
 
-Snimanje sa izlaskom iz programa se može uraditi sa \Ctrl
-+\keystroke{K}\keystroke{X} (\emph{ctrl} i \emph{K} odjednom, pa onda
-\emph{X}, ova šema pritiskanja tastera važi za sve prečice), dok se
-samo snimanje izvršava sa \Ctrl +\keystroke{K}\keystroke{D}. U oba
-slučaja joe pita za ime fajla koji snimamo, pri čemu kao podrazumevanu
-vrednost ponudi trenutno ime. Brz izlaz iz editora je moguć i sa
-\Ctrl+\keystroke{C} (što je i standardna komanda za ``ubijanje''
-trenutnog procesa u terminalu), pri čemu će joe pitati da li želimo da
-izađemo ako postoje promene koje nisu snimljene.
+\subsection{Tumačenje prečica na tastaturi}
+
+Joe je po svojoj prirodi bogat prečicama na tastaturi. U daljem tekstu
+će biti navedene mnoge od njih. Kod svih se navodi redosled
+pritiskanja tastera individualno, a ako su negde tasteri spojeni sa
+``+'' (alternativno sa ``-'') onda ih je potrebno pritisnuti
+odjednom. Neki primeri:
+
+\begin{itemize}
+\item \Ctrl +\keystroke{\_} (poništavanje poslednje promene) pristsak
+  na taster \emph{CTRL} i \emph{\_ (podvlaka)} odjednom.
+\item \Ctrl +\keystroke{K}\keystroke{H} (otvaranje sistema pomoći) 
+  pritisak na \emph{CTRL} i \emph{K} odjednom, odpustiti sve, pa onda
+  pritisak na \emph{H}.
+\item \Esc \keystroke{,} (prelazak na sledeću stranu pomoći)
+  pritisak na taster \emph{Escape}, a nakon toga pritisak na taster
+  \emph{, (zarez)}.
+\end{itemize}
+
+U okviru sistema pomoći koji je ugrađen u sam editor uglavnom se
+pojavljuju skraćeni oblici:
+\begin{itemize}
+\item \^{}D isto što i ``Ctrl-D''
+\item \^{}KH isto što i ``Ctrl-K H''
+\item \^{}[. isto što i ``Esc .''
+\end{itemize}
+
+
+\subsection{Sistem pomoći}
 
 Za pomoć pri korišćenju ediora ``joe'' preporučujemo pritiskanje
 kombinacije \Ctrl +\keystroke{K}\keystroke{H}, koja daje spisak
 komandi u gornjem delu editora.  Postoji nekoliko stranica ove pomoći
-kroz koje se može kretati sa \Esc \keystroke{.} i \Esc \keystroke{,}.
+kroz koje se može kretati sa \Esc \keystroke{.} (tačka) i \Esc
+\keystroke{,} (zarez).
+
+U okviru pomoći postoje maltene sve komande koje editor pruža, a na
+kraju su čak uključene i ASCII tabele znakova. Preporučuje se makar
+ovlašno upoznavanje sa stranicama pomoći i mogućnostima editora.
+
+\subsection{Rad sa fajlovima}
+
+Snimanje sa izlaskom iz programa se može uraditi sa \Ctrl
++\keystroke{K}\keystroke{X}, dok se
+samo snimanje izvršava sa \Ctrl +\keystroke{K}\keystroke{D}. U oba
+slučaja ``joe'' pita za ime fajla koji snimamo, pri čemu kao podrazumevanu
+vrednost ponudi trenutno ime. 
+
+Joe može raditi sa više fajlova odjednom. Novi fajl se može otvoriti
+sa \Ctrl +\keystroke{K}\keystroke{E}.  Na dnu editora će se pojaviti
+polje za kucanje imena fajla koje dozvoljava i da se putanja
+automatski dopunjava mogućnostima pritiskom na taster \Tab (Tab), baš
+kao i u komandnoj liniji.
 
-U okviru pomoći stoje i komande za označavanje blokova teksta i
-njihovo nakndadno premeštanje, kopiranje ili brisanje. Pritiskom na
-\Ctrl+\keystroke{\_} se vraća poslednja promena (undo).
+Prelazak na sledeći, odnosno prethodni, otvoreni fajl se dobija pritiskom
+na \Esc \keystroke{V}, odnosno \Esc \keystroke{U}. 
+
+Zatvaranje fajla je moguće sa \Ctrl+\keystroke{C} (što je i
+standardna komanda za ``ubijanje'' trenutnog procesa u terminalu), pri
+čemu će ``joe'' pitati da li želimo da izađemo ako postoje promene
+koje nisu snimljene. Ako je u pitanju bio jedini otvoren fajl, tada će
+se i sam editor zatvoriti.
+
+\subsection{Rad sa tekstom}
+
+Pritiskom na \Ctrl+\keystroke{\_} se poništava poslednja promena (undo).
+
+Premeštanje i kopiranje delova teksta je malo drugačije nego u
+klasičnim grafičkim programima. Prvo je potrebno označiti željeni
+tekst u dva koraka: \Ctrl +\keystroke{K}\keystroke{B} postavlja
+početak bloka na trenutnu poziciju kursora, a \Ctrl
++\keystroke{K}\keystroke{K} postavlja kraj bloka, nakon čega će
+selekcija biti i vizuelno označena. Sada je moguće na proizvoljnom
+mestu u istom ili drugom dokumentu pritisnuti \Ctrl
++\keystroke{K}\keystroke{C} da bi se iskopirao označeni blok, odnosno
+\Ctrl +\keystroke{K}\keystroke{M} da bi se on premestio.
+Komanda \Ctrl +\keystroke{K}\keystroke{Y} briše odabrani blok.
+
+Pretraga dokumenta se započinje sa \Ctrl +\keystroke{K}\keystroke{F}.
 
 Pritiskom na \Ctrl +\keystroke{T} se dobija meni sa opcijama u kome se
 može odabrati više opcija za rad, kao što su margine, automatsko
 prelamanje redova, očuvanje uvlačenja redova (\emph{auto-indent}),
 sintaksno bojenje itd.
 
+\subsection{Rad sa prozorima}
+
+``Joe'' ima mogućnosti i da podeli radnu površinu na nekoliko prozora
+koji omogućavaju da se vidi više dokumenata, ili čak da se vide
+različiti delovi istog dokumenta. Prozor se deli na dva komandom \Ctrl
++\keystroke{K}\keystroke{O}. Veličina trenutnog prozora se potom može
+povećavati (\Ctrl +\keystroke{K}\keystroke{G}) ili smanjivati (\Ctrl
++\keystroke{K}\keystroke{T}) na uštrb drugih prozora. Prelazak na
+sledeći, odnosno prethodni prozor se dobija pristikom na \Ctrl
++\keystroke{K}\keystroke{N}, odnosno na \Ctrl
++\keystroke{K}\keystroke{P}. Komanda \Ctrl +\keystroke{K}\keystroke{I}
+omogućuje da se naizmenično vide svi prozori, ili samo jedan.
+
+\subsection{Problem: ``zamrzavanje'' pri snimanju} ako editor izgleda
+kao da se zaledio verovatno je problem što je stisnuta ``klasična''
+kombinacija za snimanje \Ctrl + \keystroke{S} koja ne radi u
+ovom programu, a nažalost izaziva prekid osvežavanja ekrana. Efekat
+se poništava pritiskom na \Ctrl + \keystroke{Q}. Za više detalja
+pogledati Glavu~\ref{g-smrzavanje}.
+
 \skica{joe i sintaksno bojenje za m2}
 
+\newpage
 \section{Putty}
 
 \emph{Putty} je program koji služi da se pod Windows operativnim
@@ -775,13 +1107,15 @@ uspešno povezivanje) biće prikazan ekran za unos korisničkog imena i
 lozinke.
 
 \subsection{Problem: terminal ne odgovara na unos, ``smrznuo'' se}
-
-Putty se može dovesti u stanje da ne prikazuje ispis unosa na ekranu,
-pritiskom na \Ctrl+\keystroke{S} (što je često velik problem jer se
-poklapa sa standardnom prečicom za snimanje u većini grafičkih
-aplikacija). Iz ovog režima rada se može izaći prečicom
-\Ctrl+\keystroke{Q}.
-Ukratko:
+\label{g-smrzavanje}
+
+Putty (kao i većina standardnih linux terminala koji koriste
+softversku kontrolu toka podataka \emph{software flow control}) se
+može dovesti u stanje da ne prikazuje ispis unosa na ekranu, pritiskom
+na \Ctrl+\keystroke{S}. Ovo je često velik problem jer se poklapa sa
+standardnom prečicom za snimanje u većini grafičkih aplikacija, pa se
+može nehotično aktivirati. Iz ovog režima rada se može izaći prečicom
+\Ctrl+\keystroke{Q}.  Ukratko:
 \begin{lstlisting}[xleftmargin=10em]
 Do not press
   Ctrl S
@@ -789,6 +1123,14 @@ If you do
   Ctrl Q
 \end{lstlisting}
 
+Smisao postojanja ovakve opcije je dobrim delom istorijski, iz vremena
+kad su brzine protoka bile veoma male, i kada se štedelo time što bi
+se privrmeno isključio protok kada nisu neophodne povratne
+informacije, na primer kod komandi koje se dugo izvršavaju. Naravno
+ovo ima svoje primene i danas kod slabijih veza, ili kod mobilnih veza
+koje se plaćaju po protoku, a nekad se može i dobiti na brzini
+izvršavanja programa, ako se ne gubi vreme na osvežavanje ekrana.
+
 \skica{literatura i linkovi izdovjeni na kraju dokumenta}
 
 %\end{multicols}
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner