% skripta-os2.tex
% Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
% Doni Pracner, Ivan Pribela
% 2011/12 -- 2013/14

\documentclass[a4paper,twoside]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}%definišemo da je ulaz utf-8 fajl

% osnovne informacije koje ce se prikazati na naslovnoj strani,
% kao i u informacijama u generisanom pdfu
\newcommand{\autor}{Doni Pracner, Ivan Pribela}
\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}{Februar 2014, Novi Sad}
\newcommand{\verzija}{ver 14a}

\usepackage[serbian]{babel}
\usepackage{fancyhdr}
\pagestyle{fancy}

\title{\naslov \ -- \verzija}
\author{\autor \\ \inst}
\date{\datum}

%change the default font
\usepackage{lmodern}
\usepackage{beramono}
\renewcommand{\familydefault}{\sfdefault}

\usepackage{pifont}

%podesavanja outputa za pdf verzije
\usepackage[bookmarks,pdffitwindow=false,unicode=true,%
pdftitle={\naslov \ -- \verzija},%
pdfauthor={\autor}%
]{hyperref}

\usepackage{graphicx}
\usepackage{listings}
\usepackage{amsthm}
\usepackage{amsmath}
\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
\usepackage[top=2cm, bottom=2cm, left=2.5cm, right=2cm]{geometry}

\begin{document}

%customize the itemize environments

\let\olditemize=\itemize
\def\itemize{
\olditemize
  \setlength{\itemsep}{1pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
  \setlength{\topsep}{-1cm}

}

%% ovi redovi daju header i footer

\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
}
\renewcommand{\headheight}{15pt}

%promene u marginama:
%\setlength{\marginparwidth}{32pt}
%\setlength{\textwidth}{620pt}
%\setlength{\textheight}{620pt}


%% specijalni blokovi koji služe kao podsetnici u radu ili napomene
\newcommand{\skica}[1]{
    \noindent \framebox{\parbox[c]{0.9\textwidth}{  {\small** \textit{#1}  }}
    \newline }
}

\newcommand{\skicas}[1]{
    \framebox{* \textit{#1} *}
}

%boldovane skice visokog prioriteta
\newcommand{\skicab}[1]{
  \noindent \framebox{\parbox[c]{0.9\textwidth}{ {\small***
        \textbf{#1} }} \newline } }

\newcommand{\kod}[1]{{\small\texttt{#1}}}

% ako je sledeci red odkomentarisan nista od skica nece biti ispisano
% u finalni dokument

 \renewcommand{\skica}[1]{}


\maketitle

% theorems, definition etc.
%''''''''''''''''''''''''''

\theoremstyle{definition}
\newtheorem{def1}{Definicija}
\theoremstyle{plain}
\newtheorem{theo}{Teorema}
\newtheorem{lema}{Lema}

\lstloadlanguages{Modula-2,C++}

\lstset{
	basicstyle=\ttfamily,
        showstringspaces=false,
	breaklines=true
}

\lstdefinestyle{codeblock}{
%	basicstyle=\footnotesize\ttfamily,
        keywordstyle=\textbf,
        columns=[l]fixed,
        breakatwhitespace=true,
%        prebreak=\P,
%        postbreak=\ding{229}\space,
        language=Modula-2,
        xleftmargin=4em
}

\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{terminal}{\lstset{style=terminal}}{}

% ----------------==================--------------------------------------
%                 Pravi pocetak rada


Programi u ovoj skripti su testirani sa kompajlerom ``GNU Modula 2'' (u
daljem tekstu često skraćeno na \emph{gm2}), pod operativnim
sistemima iz Debian porodice.

\tableofcontents

\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}
  MODULE hello;

  FROM StrIO IMPORT WriteString, WriteLn;

  BEGIN
     WriteString('hello world'); 
     WriteLn
  END hello.
\end{codeblock}

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 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 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:
\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
\end{terminal}

Za dalje opcije kompajlera konsultovati \kod{gm2 -{}-help} i zvaničnu
stranicu kompajlera.
%ovde je trebalo -{}- da razdvoji dva minusa, jer se inače tumače kao jedan.

\subsection{Korišćenje sistemskih poziva}

Mapiranje procedura na sistemske pozive se može izvršiti preko
specijalnog definicionog modula koji u zaglavlju sadrži ključne reči
\kod{FOR "{}C"} u kome se navode imena procedura koja se poklapaju sa
imenima sistemskih poziva i imaju parametre i povratne vrednosti
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
\end{terminal}

odnosno videćemo da je poziv definisan na sledeći način:
\begin{codeblock}
int system(const char *command);
\end{codeblock}
š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
sastoji od svih sledećih znakova u memoriji dokle god se ne naiđe na
0C. Srećom, sve ovo se automatski mapira kreiranjem sledećeg modula:

\begin{codeblock}
DEFINITION MODULE FOR "C" Lib;

  EXPORT UNQUALIFIED system;

  PROCEDURE system(command: ARRAY OF CHAR): INTEGER;

END Lib.
\end{codeblock}

Nije potrebno praviti prazne implementacione module. Iz ovakvog modula
se mogu uvoziti i koristiti procedure kao i iz bilo kakvog
``normalnog'' modula, kao što se može videti u sledećem primeru, koju
od korisnika učitava stringove i pokušava da ih izvrši kao da su uneti
u komandnoj liniji, dokle god korisnik ne unese reč ``kraj'':
\begin{codeblock}
MODULE Zad2;

FROM StrIO IMPORT
  ReadString, WriteString, WriteLn;
FROM StrLib IMPORT
  StrEqual;
FROM Lib IMPORT
  system;

TYPE
  String = ARRAY [0..1023] OF CHAR;

VAR
  Komanda: String;

PROCEDURE Izvrsi(Komanda: ARRAY OF CHAR);
VAR
  c: INTEGER;
BEGIN
  c:= system(Komanda);
END Izvrsi;

BEGIN
  WriteString("?> "); ReadString(Komanda);
  WHILE NOT StrEqual(Komanda, "kraj") DO
    Izvrsi(Komanda);
    WriteString("?> "); ReadString(Komanda);
  END;
END Zad2.
\end{codeblock}

Prilikom mapiranja sistemskih poziva je moguće koristiti ``...'' na
kraju liste argumenata da se označi da je moguće proslediti
proizvoljan broj argumenata nakon navedenih, koji će biti premapirani
na odgovarajuće tipove podataka. Takođe je moguće i označiti da se
povratna vrednost procedure ne mora koristiti. U gornjem primeru je
mogla funkcija da se definiše kao \kod{PROCEDURE system(command: ARRAY
  OF CHAR): [INTEGER];} i tada bi mogla se poziva kao obična procedura
bez korišćenja pomoćne promenljive \kod{c} da se dobije povratna
vrednost. 

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}

Korišćenje sistemskih poziva se može ilustrovati primerom čitanja
sadržaja direktorijuma, komandama \kod{opendir}, \kod{readdir} i
\kod{closedir}. Prva komanda otvara prosledjenu putanju i vraća
pokazivač na otvoreni direktorijum. Komanda \kod{readdir} prima ovakav
pokazivač kao ulazni parametar, a vraća pokazivač na slog koji
predstavlja sledeću stavku u otvorenom direktorijumu ili \kod{NIL} ako
više nema ničega. Poslednja komanda, \kod{closedir}, se izvodi na
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 i 12.04 32bit, a druga je testirana
na Kubuntu 11.10 i 12.10 64bit.

\begin{codeblock}
DEFINITION MODULE FOR "C" Lib32;
  FROM SYSTEM IMPORT 
    ADDRESS, BYTE;
  EXPORT UNQUALIFIED opendir, readdir, closedir, stat, 
    PDir, DirEnt, PDirEnt, Stat, PStat, PInt;
\end{codeblock}
\begin{minipage}{0.5\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;
    END;
    PDirEnt = POINTER TO DirEnt;
    Stat = RECORD
         dev: LONGINT;
         ino: LONGINT;
         mode: INTEGER;
         nlink: LONGINT;
         uid: INTEGER;
         gid: INTEGER;
         pad1: LONGINT;
         rdev: INTEGER;
         size: INTEGER;
         blksize: INTEGER;
         blocks: INTEGER;
         atime: LONGINT;
         mtime: LONGINT;
         ctime: LONGINT;
    END;
  \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;
    Stat = RECORD
         dev: LONGINT;
         ino: LONGINT;
         nlink: LONGINT;
         mode: INTEGER;
         uid: INTEGER;
         gid: INTEGER;
         pad1: INTEGER;
         rdev: LONGINT;
         size: LONGINT;
         blksize: LONGINT;
         blocks: LONGINT;
         atime: LONGINT;
         mtime: LONGINT;
         ctime: LONGINT;
    END;
  \end{codeblock}
\end{minipage}
\begin{codeblock}
    PStat = POINTER TO Stat;
    PInt = POINTER TO INTEGER;

  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.
\end{codeblock}

\begin{codeblock}
MODULE Zad5;

FROM SYSTEM IMPORT
  ADR;
FROM StrIO IMPORT
  WriteString, WriteLn;
FROM NumberIO IMPORT
  WriteInt;
FROM StrLib IMPORT
  StrLen, StrConCat;
FROM Args IMPORT
  Narg, GetArg;
FROM Lib32 IMPORT
  opendir, readdir, closedir, stat, PDir, PDirEnt, Stat;
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;
  info: Stat;
  c: INTEGER;
  Len: CARDINAL;
  Putanja: String;
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);
    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);
    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 Zad5.
\end{codeblock}

\subsection{Stvaranje novih procesa}

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}
PROCEDURE fork(): INTEGER;
\end{codeblock}

Oba procesa se nakon račvanja nastavljaju odvijati u sledećem redu
koda. Jedino po čemu se razlikuju je vrednost koju je vratio
\kod{fork}, ukoliko je u pitanju originalni proces (``roditelj'') tada
je ta vrednost jednaka proces identifikatoru (\emph{pid}-u)
``deteta'', i može se koristiti za komunikaciju sa detetom, a u novom
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}
pid := fork();
IF pid = 0 THEN
   (* "detetove" operacije *)
ELSE
   (* "roditeljske" operacije *)
END;
\end{codeblock}

Komanda \kod{wait} (uvezena kao sistemska) se može pozvati u
originalnom procesu sa efektom da se proces uspava dokle god neki od
procesa dece ne završi sa radom. Veća kontrola nad ovim ponašanjem se
može postići komandom \kod{waitpid} u kojoj možemo precizirati tačno
koji proces čekamo da se završi.

U sledećim sekcijama će biti ilustrovano nekoliko klasičnih primera
organizacije procesa.

\skica{treba nam propratni tekst za ovo sto sledi}

\subsubsection{Lanac procesa}

\begin{minipage}{0.6\textwidth}
\begin{codeblock}
pid := 0;
i := 1;
WHILE (pid = 0) AND (i < n) DO
  pid := fork();
  IF pid # 0 THEN
    (* ... *)
  ELSE
    INC(i);
  END;
END;
\end{codeblock}
\end{minipage}
\begin{minipage}{0.4\textwidth}
\begin{tikzpicture}
[proc/.style={circle,draw}]
\def \n {5}
\foreach \s in {1,...,\n}
{
  \node[proc] (\s) at (\s,-\s/2) {\s};
}
\foreach \s in {2,...,\n} {
  \pgfmathparse{int(\s-1)}
  \draw [<-] (\s) to (\pgfmathresult);
}
\end{tikzpicture}
\end{minipage}

\subsubsection{Roditelj sa puno dece}

\begin{minipage}{0.6\textwidth}
\begin{codeblock}
pid := -1;
j := 0;
WHILE (pid # 0) AND (j < m) DO
  pid := fork();
  IF pid # 0 THEN
    INC(j);
  ELSE
    (* ... *)
  END;
END;
\end{codeblock}
\end{minipage}
\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}
{
  \node[proc] (\s) at (-3.5+\s,-2) {\s};
}
\foreach \s in {2,...,\n} {
  \draw [->] (1) to (\s);
}
\end{tikzpicture}
\end{minipage}

\subsubsection{Stablo procesa}

\begin{minipage}{0.6\textwidth}
\begin{codeblock}
dubina := 1;
brdece := 0;
WHILE (dubina < maxdubina) AND 
      (brdece < potrebnodece) DO
  pid := fork();
  IF pid # 0 THEN
    INC(brdece);
  ELSE
    INC(dubina);
    brdece := 0;
  END;
END;
\end{codeblock}
\end{minipage}
\begin{minipage}{0.4\textwidth}
\begin{tikzpicture}
[proc/.style={circle,draw},
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) {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}


% ----------------------------------------------

\newpage
\pagenumbering{Roman}
\appendix

\section{Instalacija kompajlera GNU Modula 2}
\label{app-instalacija-gm2}

Ova sekcija treba da omogući instalaciju kompajlera GNU Modula 2 na
već postojeći GNU Linux operativni sistem iz Debian porodice, koja
uključuje i sve varijante Ubuntu distribucije, kao i Linux Mint i
mnoge druge. Kompajler je moguće bez većih problema instalirati i na
bilo koji drugi Linux (a i OSX i Windows), kompajliranjem iz izvornog
koda, za šta preporučujemo konsultovanje sa zvaničnom stranicom
\url{http://www.nongnu.org/gm2/obtaining.html}.

Ovo uputstvo neće ulaziti u detalje kako instalirati operativni
sistem. Za one koje koriste Windows i nisu sigurni kako da paralelno
instaliraju drugi operativni sistem, preporučujemo korišćenje
virtuelne mašine (npr besplatni Virtual Box,
\url{http://virtualbox.org}) i instaliranje sistema na nju, ili još
lakše skinuti već instaliranu mašinu sa nekim od Debian sistema, npr
Ubuntu ili Kubuntu, ili eventualno neku manje zahtevnu verziju kao što
je Lubuntu, ako su performanse problematične.

\subsection{Instalacija na Debian platformi}

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}
#
#  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}

Alternativno se mogu koristiti sledeće komande:

\begin{terminal}
sudo add-apt-repository "deb http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
sudo add-apt-repository "deb-src http://floppsie.comp.glam.ac.uk/debian/ squeeze main"
\end{terminal}

Većina sistema omogućava i da se ovo uradi preko nekih grafičkih
alata.

Nakon dodavanja novog izvora za softver potrebno je u konzoli uraditi
sledeće:
\begin{terminal}
sudo apt-get update
sudo apt-get install gm2-doc gm2
\end{terminal}

Po želji se može skinuti i izvorni kod kompajlera sledećom komandom:
\begin{terminal}
sudo apt-get source gm2
\end{terminal}

Videti Glavu~\ref{g-prvi-program} za primer kompajliranja programa.

\subsection{Problem: nedostaje ``ctli.o'' i/ili još neki fajlovi}

Pri pokušaju kompajliranja se na nekim sistemima može desiti da
prijave nedostajuće fajlove \kod{crti.o, crt1.o} i/ili
\kod{crtn.o}. Konkretno je poznato za gcc verziju 4.6 na debianu,
pošto postoji problem u pakovanju kompajlera, ali moguće je da utiče i
na neke druge sisteme.

Greška se ispravlja na sledeći način (korisnik treba da
ima administrativna prava, zato se radi ``sudo'') ukoliko
je u pitanju 64-bitni sistem:
\begin{terminal}
sudo su
cd /usr/lib
ln -sv /usr/lib/x86_64-linux-gnu/crti.o crti.o
ln -sv /usr/lib/x86_64-linux-gnu/crt1.o crt1.o
ln -sv /usr/lib/x86_64-linux-gnu/crtn.o crtn.o
exit
\end{terminal}

Za 32-bitne sisteme važi ista ispravka, jedino što se u komandama
treba zameniti ``x86\_64'' sa ``i386''.

\skica{možda i build from source}

\newpage
\section{Tekst editor Joe}
\label{app-joe}

Ukratko ćemo predstaviti editor ``joe''. Odabran je zbog svoje
rasprostranjenosti, potpune funkcionalnosti u tekstualnom modu rada
(korišćenje iz terminala) te vrlo jasnom sistemu pomoći koji se može
koristiti pri radu.  Na nekim sistemima on dolazi već instaliran, a na
skoro svima se lako može dodati iz repozitorijuma. Na Ubuntu i sličnim
sistemima se ovo može uraditi sa:
\begin{terminal}
sudo apt-get install joe
\end{terminal}
Ili analogno na drugim sistemima za instaliranje softvera.

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}

\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{.} (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.

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
sistemom otvori terminal (konzola, komandna linija) na udaljenom UNIX
serveru. Može se naći online na
\url{http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html}.

Po pokretanju se prikazuje dijalog u kome se može ukucati adresa
udaljenog računara i konfigurisati mnogi parametri. Najčešće je dosta
samo uneti adresu računara i pokrenuti konekciju. Nakon toga (ako je
uspešno povezivanje) biće prikazan ekran za unos korisničkog imena i
lozinke.

\subsection{Problem: terminal ne odgovara na unos, ``smrznuo'' se}
\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
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}
\end{document}
