X-Git-Url: http://svarog.pmf.uns.ac.rs/gitweb/?p=os2skripta.git;a=blobdiff_plain;f=skripta-os2.tex;h=a1a400225fa9804a0190ab3c736b62afe03a221d;hp=f74696f9390bcbf7937a8081425f0fb779cff4c4;hb=HEAD;hpb=e148eb56fab9e6c7cb759a8fdc686202382f199f diff --git a/skripta-os2.tex b/skripta-os2.tex index f74696f..a1a4002 100644 --- a/skripta-os2.tex +++ b/skripta-os2.tex @@ -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