%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Rychla reference k systemovym volanim 
%
%  Martin Bruchanov -- bruxy at regnet dot cz
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\pdfoutput=1
\documentclass[a4paper, 10pt, pointednumbers]{scrartcl}
\usepackage{czech}
\usepackage{a4wide}
\usepackage{graphics}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{latexsym}
\usepackage{multicol}

% změna okrajů stránky, které jsou standardně 1 palec = 2.54 cm
\evensidemargin 0mm
\oddsidemargin 0mm
\headsep 0mm
\hoffset -18.4mm
\voffset -17.4mm % vrsek
\topmargin 0in 
\headheight 0cm
\textwidth 197mm
\textheight 28.7cm
\footskip 0mm

\dateczech
\renewcommand{\arraystretch}{0.9}

%\renewcommand{\tt}[#1]{\texttt{#1}}


% Zmena radkovani
\renewcommand{\baselinestretch}{.85}

% Zmena vzdalenosti
%\newcommand{\itemizespace}{-0.5em}
\newcommand{\itemizespace}{0em}


\pagestyle{empty}

\begin{document} 
\section*{Systémová volání UNIXu}
\addtocounter{section}{1}

\begin{multicols}{2}

\subsection{Nebufferované I/O funkce}

\begin{description}
\item[] \verb|#include <sys/types.h>|, \verb|<sys/stat.h>,| \\
\verb|<fcntl.h>|, \verb|<unistd.h>|, \verb|<stdlib.h>|

\item[open] -- otevření souboru

\begin{verbatim}
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, 
         mode_t mode);
\end{verbatim}

Flagy (zadávat s bitovým OR):

\begin{itemize}
% co já vim, tak buď velký písmeno na začátku, čarky na konci každý položky a
% tečka na konci seznamu, nebo všude malý písmena a bez čárek a teček
\item  \texttt{O\_RDONLY} --   otevření pouze pro čtení
\item  \texttt{O\_WRONLY} -- otevření pouze pro zápis   
\item  \texttt{O\_RDWR} --   otevření pro čtení i zápis
\item  \texttt{O\_APPEND} -- připojení na konec souboru
\item  \texttt{O\_CREAT} -- vytvoření nového souboru, vyžaduje nastavit práva
pomocí \texttt{mode} (viz \texttt{creat})
% jednopísmenná (možná jakákoli) předložka nebo spojka by neměla být na konci řádku
\item  \texttt{O\_EXCL} --  otestuje existenci souboru, dohromady s~\texttt{O\_CREAT}
vrací chybu
\item  \texttt{O\_SYNC} -- synchronní I/O operace, každý \texttt{write} čeká na fyzické
ukončení operace
\end{itemize}	   
%ání na skončení vlákla % "skončit" a ne "zkončit" ;-)
\item[creat] -- vytvoření nového souboru, ekvivaletní 
% nahoře jsi používal prototypy bez mezery před arglistem
s~\texttt{open(pathname, O\_WRONLY | O\_CREAT | O\_TRUNC, mode);}

\begin{verbatim}
int creat(const char *pathname, mode_t mode);					 
\end{verbatim}

Nastavení práv:

\begin{itemize}
\item Uživatel: \texttt{S\_IRWXU, S\_IRUSR (S\_IREAD), S\_IWUSR (S\_IWRITE), S\_IXUSR
(S\_IEXEC);}
\item Skupina: \texttt{S\_IRWXG, S\_IRGRP, S\_IWGRP, S\_IXGRP;}
\item Ostatní: \texttt{S\_IRWXO, S\_IROTH, S\_IWOTH, S\_IXOTH.}
\end{itemize}

\item[close] -- zavře otevřený soubor (deskriptor)

\begin{verbatim}
int close(int filedes);
\end{verbatim}

\item[lseek] -- nastavení pozice pro čtení/zápis uvnitř souboru,
pozice (\texttt{offset}) je nezáporný pocet bytů od počátku souboru

\begin{verbatim}
off_t lseek(int filedes, off_t offset, 
            int whence);
\end{verbatim}

Interpretace \texttt{offset} závisi na parametru \texttt{whence}:

\begin{itemize}
\item \texttt{SEEK\_SET} -- offset je vzdálenost od počátku souboru
\item \texttt{SEEK\_CUR} -- offset je relativní vzdálenost od aktualní pozice
\item \texttt{SEEK\_END} -- offset je vzdálenost od konce souboru
\end{itemize}

\item[read] -- čtení dat z~daného deskriptoru, vrací počet
načtených bytů

\begin{verbatim}
ssize_t read(int fd, void *buf, size_t count);
\end{verbatim}

\item[write] -- zapiš do daného souboru, až \texttt{count} bytů z bufferu \texttt{buf} 
do file deskriptoru \texttt{fd}

\begin{verbatim}
ssize_t write(int fd, const void *buf, 
              size_t count);
\end{verbatim}


\item [dup, dup2] -- duplikace existujícího deskriptoru, je sdílena
pozice, flagy. Volání \texttt{dup} vytvoří nejnižší volný deskriptor
ve stejné tabulce jako starý, s \texttt{dup2} specifikujeme
nový hodnotou \texttt{newfd} (musí být předtím otevřen)

\begin{verbatim}
int dup(int oldfd);
int dup2(int oldfd, int newfd);
\end{verbatim}


\item[fnctl] -- změna charakteru otevřeného souboru

\begin{verbatim}
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
\end{verbatim}

Lze použít pro tyto účely (parametr \texttt{cmd}):
\begin{itemize}
\item duplikování existujícího deskriptoru (\texttt{F\_DUPD})
\item zjištění/nastavení příznaku deskriptoru (\texttt{F\_GETFD, F\_SETFD})
\item zjištění/nastavení příznaku souboru (\texttt{F\_GETFL,F\_SETFL})
\item zjištění/nastavení vlastnictví I/O (\texttt{F\_GETOWN, F\_SETOWN})
\item zjištění/nastavení zámku (\texttt{F\_GETLK, F\_SETLK, F\_STELKW})
\end{itemize}

\item[ioctl] -- provádění řídících operací nad I/O zařízením

\begin{verbatim}
int ioctl(int d, int request, ...);
\end{verbatim}
\end{description}


%\subsection{Správa paměti}
%
%\begin{description}
%\item[malloc] --
%
%\begin{verbatim}
%void *malloc (size_t size);
%\end{verbatim}
%
%\item[calloc]
%\begin{verbatim}
%void *calloc (size_t nobj, size_t size);
%\end{verbatim}
%
%\item[realoc]
%\begin{verbatim}
%void *realloc (void *ptr, size_t newsize);
%\end{verbatim}
%
%Vsechny tri vraci: ukazatel kdyz OK, NULL pri chybe
%
%\item[free] -- uvolnění paměti
%
%\begin{verbatim}
%void free(void *ptr);
%\end{verbatim}
%
%\end{description}

\subsection{Procesy}

\begin{description}
\item[exit, \_exit] -- \texttt{exit} normálně ukončí proces,
\texttt{\_exit} okamžitě ukonči právě probíhající proces

\begin{verbatim}
void exit(int status);
void _exit(int status);
\end{verbatim}

\item[atexit] -- registruje funkci, která se má vyvolat při ukončení procesu

\begin{verbatim}
int atexit(void (* function)(void));
\end{verbatim}

\item[getpid, getppid] -- vrací identifikátor procesu, tj. unikátní
nezáporné číslo, \texttt{getpid} vrací ID volajícího, \texttt{getppid} ID
rodiče volajícího

\begin{verbatim}
pid_t getpid(void);
pid_t getppid(void);
\end{verbatim}

% `geteuid' returns the effective user ID of the current process.
Pro zjištění ID uživatelů slouží \texttt{getuid}, \texttt{geteuid} (efektivní),
pro ID skupiny \texttt{getgid}, \texttt{getegid}.

\item[fork] -- vytvoření nového procesu, po zavolání provádí
rodič i potomek stejný kód, programově se dají rozlišit např. pomocí návratové
hodnoty (u potomka vrací 0, u rodiče PID potomka)

\begin{verbatim}
pid_t fork(void);
\end{verbatim}

\item[exec] -- nahradí probíhajcí proces jiným, vrací
se do nadřazeného programu jen při chybě, alternativa
nejdřív \texttt{fork} a v podprocesu \texttt{exec}

\begin{verbatim}
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
\end{verbatim}

% <sys/wait.h>

\item[system] -- alternativa \texttt{exec}, spustí
% tady by to chtělo anglické otevírací a anglické zavírací uvozovky (v UTF-8
% ViMu se to napíše Ctrl-K, ", 6 a Ctrl-K, ", 9) 
daný \textit{příkaz} pomocí \texttt{/bin/sh -c "\textit{příkaz}"}

\begin{verbatim}
int system(const char *string);
\end{verbatim}

% ono je to ve skutečnosti čekání na "změnu stavu" procesu s tím, že pokud jde o
% ukončení potomka, tak při zavolání dojde k uvolnění jeho prostředků; ale že
% bych to neuměl nějak rozumně a krátce zformulovat, tak to radši nechám bejt
% ;-)
\item[wait, waitpid] -- čekání na skončení procesu, čeká
na signál \texttt{SIGCHLD}, \texttt{wait} blokuje volajícího,
\texttt{waitpid} má možnost řízení na koho čekat
 
\begin{verbatim}
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
\end{verbatim}

Parametr \texttt{pid}:
\begin{itemize}
\item $< -1$ -- čeká na dokončení libovolného potomka, % choď do piči ;-)
% to by mě zajímalo, co je absolutní hodnota PID... ale píšou to tam...
\item $-1$ -- čeká na potomka, jehož ID skupiny je shodné s absolutní hodnotou PID,
\item $0$ -- čeká na potomka, jehož ID skupiny je shodné s ID skupiny volajícího,
\item $>0$ -- čeká na dokončení potomka s daným PID.
\end{itemize}
\end{description}

\subsection{Signály}

\begin{description}

\item[Signály] -- softwarová přerušení, po obdržení se spustí obsluha,
kompletní seznam viz \texttt{man 7 signal}, nebo \texttt{kill -l}

{\footnotesize
\begin{tabular}{|l|c|p{4.4cm}|}
\hline
\textbf{Signál} & \textbf{Hodnota} & \textbf{Poznámka}  \\ 
\hline
% často se SIGHUP používá jednoúčelově jako signál pro znovunačtení konfigurace
SIGHUP &       1  &  zavěšení na řidícím TTY nebo ukončení řídícího procesu \\
SIGINT  &      2  &  přerušení z klávesnice \\
SIGQUIT &      3  &  ukončení z klávesnice. \\
SIGABRT &      6  &  ukončení funkcí \texttt{abort} \\
SIGKILL &      9  &  signál pro nepodmíněné ukončení procesu \\
SIGSEGV &     11  &  odkaz na nepřípustnou adresu v paměti \\
SIGPIPE &     13  & pokus o zápis do roury, kterou nikdo nečte. \\
SIGALRM &     14   & signál od časovače, nastaveného funkcí alarm \\
SIGTERM &     15    & signál ukončení \\
SIGUSR1 &  \small{30,10,16} & signál 1 definovaný uživatelem \\
SIGUSR2 &  \small{31,12,17} & signál 2 definovaný uživatelem \\
SIGCHLD &  \small{20,17,18} & zastavení nebo ukončení potomka \\
\hline
\end{tabular}
}

\item[sigaction] -- nastavení obsluhy pro daný signál

\begin{verbatim}
int sigaction(int signum, const struct 
              sigaction *act,
              struct sigaction *oldact);
\end{verbatim}

\begin{verbatim}
struct sigaction {
/* Ukazatel na funkci obsluhy */
/* SIG_DFL - implicitní */
/* SIG_IGN - ignorování */
   void (*sa_handler)(int);
/* Blokované signály při obsluze */
   sigset_t sa_mask;
/* Přiznaky ovlivňující obsluhu */
   int sa_flags; }
\end{verbatim}

Proměná pro záznam signálu v globální obsluze by měla
být typu \texttt{sig\_atomic\_t}.

\item[kill] -- zaslání signálu procesu

\begin{verbatim}
int kill(pid_t pid, int sig);
\end{verbatim}

Parametr \texttt{pid} podobný jako u \texttt{wait}.
\end{description}

\subsection{Meziprocesová komunikace}

\begin{description}
\item[pipe] -- vytvoření datové roury

\begin{verbatim}
int pipe(int filedes[2]);
\end{verbatim}

Pro čtení z roury se použije deskriptor \texttt{filedes[0]},
pro zápis do ní \texttt{filedes[1]}.

\item[popen, pclose] -- vytvoření jednosměrné roury pro I/O operace, \texttt{popen}
otevře nový proces pro vytvoření roury, parametr \texttt{type} je \texttt{r} pro čtění,
\texttt{w} pro zápis.

\begin{verbatim}
FILE *popen(const char *command, 
            const char *type);
int pclose(FILE *stream);
\end{verbatim}

\item[mkfifo] -- vytvoření pojmenované roury (položky v souborovém systému);
normální roury mohou používat
pouze procesy se shodným předchůdcem, FIFO mohou používat i procesy, které
spolu jinak nesouvisí. 

\begin{verbatim}
int mkfifo(const char *pathname, mode_t mode);
\end{verbatim}

\item[Sdílená paměť] -- sdílení adresního prostoru mezi více procesy,
\verb|<sys/ipc.h>|,\verb|<sys/shm.h>|; použití pomocí

\begin{itemize}
\item Alokace
\begin{verbatim}
int   shmget(key_t, size_t, int);
\end{verbatim}

\item Operace
\begin{verbatim}
void *shmat(int shmid, const void *shmaddr, 
            int shmflg);
\end{verbatim}

\item Ovládání
\begin{verbatim}
int shmctl(int shmid, int cmd, 
           struct shmid_ds *buf);
\end{verbatim}

\begin{itemize}
\item \texttt{IPC\_STAT} -- 	 načtení řídící struktury sdílené paměti
\item \texttt{IPC\_SET} -- 	nastaveni některych polí struktury \texttt{shm\_perms}
\item \texttt{IPC\_RMID} -- 	odstranění sdílené paměti ze systému
\item \texttt{SHM\_LOCK}  --	uzamčení sdílené paměti (jen superuživatel)
\item \texttt{SHM\_UNLOCK} -- odemčení sdílené paměti (jen superuživatel)
\end{itemize}


\item Odpojení
\begin{verbatim}
int   shmdt(const void *shmaddr);
\end{verbatim}
\end{itemize}

\item[Semafory] -- slouží k jednoduché synchronizaci procesů, jsou
realizovány polem čítačů, \verb|<sys/sem.h>|

\begin{itemize}
\item Vytvoření identifikátoru, \texttt{nsems} udává počet
semaforů
\begin{verbatim}
int semget(key_t key, int nsems, int semflg);
\end{verbatim}


\item Ovládání
\begin{verbatim}
int semctl(int semid, int semnum, int cmd, ...);
\end{verbatim}

Některé operace, parametr \texttt{cmd}:

\begin{itemize}
\item \texttt{IPC\_STAT} --	 načtení řídící struktury semaforu
\item \texttt{IPC\_SET} --	nastavení některých polí struktury
\item \texttt{semid\_ds}
\item \texttt{IPC\_RMID} -- odstranění semaforu ze systému
\item \texttt{GETVAL} -- zjištění hodnoty semaforu
\item \texttt{SETVAL} -- nastavení hodnoty semaforu
\item \texttt{GETPID} -- zjištění sempid
\end{itemize}

\item Operace nad semaforem

\begin{verbatim}
int   semop(int semid, struct sembuf *sops, 
            unsigned nsops);

struct sembuf {
  unsigned short sem_num; /* číslo semaforu */
  short sem_op;    /* operace nad semaforem */
  short sem_flg;      /* IPC_WAIT, SEM_UNDO */
}
\end{verbatim}

Operace:
\begin{itemize}
\item \texttt{sem\_op} $> 0$ -- hodnota \texttt{sem\_op} se přičte k čítači,
\item \texttt{sem\_op} $< 0$ -- \texttt{sem\_op} se odečte, v případě, že čítač
je záporný volání se pozastaví do doby než bude 0,
\item \texttt{sem\_op} $= 0$ -- čekání dokud se semafor nevynuluje.
\end{itemize}

\end{itemize}
\end{description}

\subsection{Vlákna}

Zahrnout \verb|<pthread.h>|, překládát s \texttt{-lpthread}.

\begin{description}
\item[pthread\_create] -- vytvoření vlákna 

\begin{verbatim}
int pthread_create(pthread_t *restrict threa21d,
          const pthread_attr_t *restrict attr,
          void *(*start_routine)(void*), 
          void *restrict arg);
\end{verbatim}


\item[pthread\_self] -- získání ID volajícího vlákna

\begin{verbatim}
pthread_t pthread_self(void);
\end{verbatim}

\item[pthread\_equal] -- porovnání ID vláken

\begin{verbatim}
int pthread_equal(pthread_t t1, pthread_t t2);
\end{verbatim}

\item[pthread\_join] -- čekání na skončení vlákna

\begin{verbatim}
int pthread_join(pthread_t thread, 
                 void **value_ptr);
\end{verbatim}

\end{description}

\end{multicols}
\end{document}

