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 f74696f..a1a4002 100644 (file)
@@ -1,7 +1,7 @@
 % skripta-os2.tex
 % Skripta za predmet Operativni Sistemi 2, DMI, PMF, NS
 % Doni Pracner, Ivan Pribela
-% 2011/12 -- 2013/14
+% 2011/12 -- 2014/15
 
 \documentclass[a4paper,twoside]{article}
 \usepackage[T1]{fontenc}
@@ -13,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}{Februar 2014, Novi Sad}
-\newcommand{\verzija}{ver 14a}
+\newcommand{\datum}{Februar 2015, Novi Sad}
+\newcommand{\verzija}{ver 15a}
 
 \usepackage[serbian]{babel}
 \usepackage{fancyhdr}
@@ -72,7 +72,80 @@ pdfauthor={\autor}%
 %margine
 \usepackage[top=2cm, bottom=2cm, left=2.5cm, right=2cm]{geometry}
 
-\begin{document}
+% 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=1em
+}
+
+\lstdefinestyle{codeblock-indent}{
+  style=codeblock,
+  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{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]{
+    \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]{}
 
 %customize the itemize environments
 
@@ -85,6 +158,8 @@ pdfauthor={\autor}%
   \setlength{\topsep}{-1cm}
 
 }
+ \begin{document}
+
 
 %% ovi redovi daju header i footer
 
@@ -117,77 +192,10 @@ pdfauthor={\autor}%
 %\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
@@ -217,7 +225,7 @@ dobijaju i besplatne ISO, PIM i još neke biblioteke.
 \label{g-prvi-program}
 
 Tradicionalni prvi program ``Hello World'' bi izgledao ovako:
-\begin{codeblock}
+\begin{codeblock-indent}
   MODULE hello;
 
   FROM StrIO IMPORT WriteString, WriteLn;
@@ -226,7 +234,7 @@ 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 se ovde
@@ -272,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
@@ -372,13 +380,6 @@ 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
@@ -492,14 +493,252 @@ BEGIN
 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;
+         mode: INTEGER;
+         nlink: LONGINT;
+         uid: INTEGER;
+         gid: INTEGER;
+         pad1: LONGINT;
+         rdev: INTEGER;
+         size: INTEGER;
+         blksize: INTEGER;
+         blocks: INTEGER;
+         atime: INTEGER;
+         anano: INTEGER;
+         mtime: INTEGER;
+         mnano:INTEGER;
+         ctime:INTEGER;
+         cnano: INTEGER;
+         unused:LONGINT;
+    END;
+  \end{codeblock}
+\end{minipage}
+\begin{minipage}{0.45\textwidth}
+\begin{codeblock}[frame=single,frameround=tttt]
+(* types for 64 bit *)
+  TYPE
+    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}
+    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 stat(path: ARRAY OF CHAR; buf: PStat): [INTEGER];
+  PROCEDURE localtime(time: PInt): PTm;
+
+END LibStat32.
+\end{codeblock}
+
+\begin{codeblock}
+MODULE Zad4;
+
+FROM SYSTEM IMPORT
+  ADR;
+FROM StrIO IMPORT
+  WriteString, WriteLn;
+FROM NumberIO IMPORT
+  WriteInt;
+FROM StrLib IMPORT
+  StrLen, StrConCat;
+FROM Args IMPORT
+  Narg, GetArg;
+FROM LibStat32 IMPORT
+  stat, localtime, Stat, PTm;
+IMPORT LibStat32;
+FROM errno IMPORT
+  geterrno;
+
+TYPE
+  String = ARRAY [0..1023] OF CHAR;
+
+VAR
+  Putanja: String;
+  n, i: INTEGER;
+  ok: BOOLEAN;
+
+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
+  tm: PTm;
+BEGIN
+  tm:= localtime(ADR(time));
+  IF tm # NIL THEN
+    WriteInt(tm^.year + 1900, 0);
+    WriteString("-");
+    IF tm^.mon < 9 THEN
+      WriteString("0");
+    END;
+    WriteInt(tm^.mon + 1, 0);
+    WriteString("-");
+    IF tm^.mday < 10 THEN
+      WriteString("0");
+    END;
+    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
+  n:= Narg();
+  FOR i:= 1 TO n - 1 DO
+    ok:= GetArg(Putanja, i);
+    WriteLn;
+    Listaj(Putanja);
+  END;
+  WriteLn;
+END Zad4.
+\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}
+\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
@@ -509,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
@@ -659,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}
-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"
+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
@@ -692,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
Svarog.pmf.uns.ac.rs/gitweb maintanance Doni Pracner