diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index d649874..f175c42 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -26,6 +26,9 @@ jobs: - name: Install pre-requisites for spell check working-directory: master run: ./dev/install-spellcheck.sh + - name: Check labels + working-directory: master + run: ./dev/check-label.sh - name: Run spellcheck working-directory: master run: make spellcheck diff --git a/common.tex b/common.tex index 706f1f1..5e84aad 100644 --- a/common.tex +++ b/common.tex @@ -69,6 +69,10 @@ \renewcommand{\slidelabel}{} \setlength{\textwidth}{0.9\textwidth} +% This command has to be used throught the sources instead of \label +% for hyperref to be able to create valid links. +\newcommand{\hlabel}{\phantomsection\label} + \newcommand{\sltitle}[1]{{\centering\textbf{\Large #1} \vskip 2em plus 0pt minus 2em\par}} % Slide title diff --git a/dev/check-label.sh b/dev/check-label.sh new file mode 100755 index 0000000..e6d0e0a --- /dev/null +++ b/dev/check-label.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if grep '\\label{.*}' *.tex >/tmp/label-err.out; then + echo "Some of the *.tex files contain the \\label command." + echo "This is unwanted as this leads to invalid links in PDFs." + echo "Use \\hlabel instead." + echo "" + cat /tmp/label-err.out + exit 1 +fi diff --git a/file-api.tex b/file-api.tex index b020286..10694d0 100644 --- a/file-api.tex +++ b/file-api.tex @@ -54,7 +54,7 @@ \end{center} \end{slide} -\label{OPENFILETABLES} +\hlabel{OPENFILETABLES} \begin{itemize} \item This is a simplified view of the kernel tables that deal with files. It @@ -113,7 +113,7 @@ \end{itemize} \end{slide} -\label{OPEN} +\hlabel{OPEN} \begin{itemize} \item The first available file descriptor is always used. @@ -145,7 +145,7 @@ reading. \item \texttt{O\_NOCTTY} \dots{} when opening a terminal by a process without a controlling terminal, the terminal being opened does not become one. -\item \label{O_NONBLOCK} \texttt{O\_NONBLOCK} \dots{} if reading or writing +\item \hlabel{O_NONBLOCK} \texttt{O\_NONBLOCK} \dots{} if reading or writing cannot be satisfied right away, calls \texttt{read}/\texttt{write} will fail instead of getting blocked and waiting for the completion. \texttt{errno} is set to \texttt{EAGAIN} in such a case. @@ -187,8 +187,8 @@ \end{itemize} \end{slide} -\label{MKFIFO} -\label{CREAT} +\hlabel{MKFIFO} +\hlabel{CREAT} \begin{itemize} \item The \texttt{open} call allows opening of a regular file, device, or named @@ -230,7 +230,7 @@ \end{itemize} \end{slide} -\label{READCALL} +\hlabel{READCALL} \begin{itemize} \setlength{\itemsep}{0.8\itemsep} @@ -306,7 +306,7 @@ and it is a long living process, a daemon perhaps, depending on the system configuration you may hit memory starvation as the system memory will be filled with an ever growing file descriptor table. -\item \label{SIMPLE_CAT} A very simple \texttt{cat(1)} program: +\item \hlabel{SIMPLE_CAT} A very simple \texttt{cat(1)} program: \example{read/cat.c} \end{itemize} @@ -386,7 +386,7 @@ \end{itemize} \end{slide} -\label{NAMEDPIPE} +\hlabel{NAMEDPIPE} \begin{itemize} \item A named pipe is created using the system call \texttt{mkfifo}, see page @@ -491,7 +491,7 @@ \end{slide} \begin{itemize} -\item \label{LSEEK} The first byte is at position 0. If it makes sense, you may +\item \hlabel{LSEEK} The first byte is at position 0. If it makes sense, you may use a negative number for setting the \emph{offset}. Example: \example{read/lseek.c}. \item It is legal to move beyond the end of the file. If data is written there, @@ -505,7 +505,7 @@ \item You can obviously use the return value of \texttt{lseek} not only for subsequent calls to \texttt{read} and \texttt{write} but also for another call to \texttt{lseek}. -\item \label{BIG_FILE} Beware of files with holes as it may lead to problems +\item \hlabel{BIG_FILE} Beware of files with holes as it may lead to problems with backing up the data. Example: \example{read/big-file.c} demonstrates that moving a sparse file may end up in an actual storage data occupation increase. It greatly depends on the system you run, what archiving utility is used, and @@ -568,7 +568,7 @@ \end{itemize} \end{slide} -\label{DUP_CALL} +\hlabel{DUP_CALL} \begin{itemize} \item We already know that the first available file descriptor is used when @@ -610,7 +610,7 @@ \begin{itemize} \item Note the flag \texttt{O\_APPEND} used to implement a redirection \texttt{>>}. -\item \label{REDIRECT} Another example of \texttt{dup} use will be provided when +\item \hlabel{REDIRECT} Another example of \texttt{dup} use will be provided when we start working with pipes. The first redirection example from the slide (without \texttt{stderr}) is in \example{read/redirect.c}. In that example, the \texttt{execl} call replaces the current process image with the @@ -682,7 +682,7 @@ \end{itemize} \end{slide} -\label{FCNTL} +\hlabel{FCNTL} \begin{itemize} \item Example: close standard error output on program execution (exec call):\\ @@ -790,7 +790,7 @@ last modification of the inode. \item The UNIX norm does not specify the ordering of the \texttt{struct stat} members, nor does it prohibit adding new ones. -\item \label{STAT} Example: \example{stat/stat.c} +\item \hlabel{STAT} Example: \example{stat/stat.c} \item You can call \texttt{fstat} on file descriptors 0, 1, and 2 as well. Unless redirected before, you will get information on the underlying terminal device (e.g. \texttt{/dev/ttys011} on macOS). Example: \example{stat/stat012.c}. @@ -897,7 +897,7 @@ \emph{path2} to file \emph{path1}. Hard links cannot span filesystems (use \funnm{symlink} for that). \end{itemize} -\label{UNLINK} \texttt{ int \funnm{unlink}(const char *\emph{path});} +\hlabel{UNLINK} \texttt{ int \funnm{unlink}(const char *\emph{path});} \begin{itemize} \item deletes a name (i.e. a directory entry) and after deleting the last link to the file and after closing the file by all processes, deletes the file data. @@ -1028,7 +1028,7 @@ mountpoint; this member contains the i-node number of the directory where the filesystem is mounted and not the root of the mounted filesystem as one might expect. -\item \label{D_TYPE} Some system have a \texttt{struct dirent} member +\item \hlabel{D_TYPE} Some system have a \texttt{struct dirent} member \texttt{d\_type}. It can have values of \texttt{DT\_REG}, \texttt{DT\_DIR}, \texttt{DT\_FIFO} etc., see the man page for \texttt{dirent}. It was a BSD specific thing and subsequently copied by other systems, including Linux. @@ -1038,7 +1038,7 @@ to remove all entries before you can delete a directory. You can use \texttt{system("rm -r xxx")} etc. but be careful to sanitize the environment and the directory name to avoid any security implications. -\item \label{REMOVE} The specification also defines \texttt{remove} which +\item \hlabel{REMOVE} The specification also defines \texttt{remove} which behaves like \texttt{unlink} for files and as \texttt{rmdir} for directories. \end{itemize} diff --git a/files.tex b/files.tex index 0141d70..b823361 100644 --- a/files.tex +++ b/files.tex @@ -30,7 +30,7 @@ \end{itemize} \end{slide} -\label{DEVFS} +\hlabel{DEVFS} \begin{itemize} \item Devices, files in \texttt{/proc}, terminals, memory etc. are of one type @@ -433,7 +433,7 @@ %%%%% -\label{VFS} +\hlabel{VFS} \pdfbookmark[1]{Virtual File System}{VFS} \begin{slide} diff --git a/intro.tex b/intro.tex index 7332657..922ee4d 100644 --- a/intro.tex +++ b/intro.tex @@ -169,7 +169,7 @@ \end{itemize} \end{slide} -\label{UNIXSTANDARDS} +\hlabel{UNIXSTANDARDS} \begin{itemize} \item The very basic information is that the area of UNIX standards is very @@ -244,7 +244,7 @@ \end{itemize} \end{slide} -\label{POSIX} +\hlabel{POSIX} \begin{itemize} \item The first document is \emph{IEEE Std POSIX1003.1-1988}, formerly simply @@ -346,7 +346,7 @@ \end{enumerate} \end{slide} -\label{REF_PROGRAMMING} +\hlabel{REF_PROGRAMMING} \begin{enumerate} \item One of the best book on programming in Unix environment. Does not cover @@ -362,7 +362,7 @@ recommended. \item UNIX specifications. \item Detailed descriptions of system calls and functions. -\item \label{POSIX4} A book that did not fit the slide and covers topics outside +\item \hlabel{POSIX4} A book that did not fit the slide and covers topics outside of the scope of this class: Gall\-meis\-ter, B. R.: \emsl{POSIX.4 Programmers Guide: Programming for the Real World}, O'Reilly; \nth{1} edition, 1995. A great book on real-time POSIX extensions with a beautiful cover. See also pages @@ -410,7 +410,7 @@ %%%%% \pdfbookmark[1]{The C Programming Language}{C} -\label{C_LANGUAGE} +\hlabel{C_LANGUAGE} \begin{slide} \sltitle{The C Programming Language} @@ -499,7 +499,7 @@ \end{itemize} \end{slide} -\label{BYTE_ORDERING} +\hlabel{BYTE_ORDERING} \begin{itemize} \item Be careful when using tools like \texttt{hexdump} that by default print @@ -551,7 +551,7 @@ \end{itemize} \end{slide} -\label{NEWLINECHAR} +\hlabel{NEWLINECHAR} \begin{itemize} \item \emsl{LF}, \emph{line feed}, sometimes also referred to as \emph{new @@ -1092,7 +1092,7 @@ \end{minipage} \end{slide} -\label{MAKE}. +\hlabel{MAKE}. \begin{itemize} \item You could compile and link the program via one invocation of a compiler, @@ -1268,7 +1268,7 @@ \end{itemize} \end{slide} -\label{RUNTIMELINKER} +\hlabel{RUNTIMELINKER} \begin{itemize} \item An ELF object format is explained on page \pageref{ELF}. @@ -1365,7 +1365,7 @@ \item You can also edit ELF objects via \texttt{elfedit(1)} on Solaris. You can change \texttt{RUNPATH}, for example. \end{itemize} -\item \label{EVIL_LDLIBPATH} In general, you should not use +\item \hlabel{EVIL_LDLIBPATH} In general, you should not use \texttt{LD\_LIBRARY\_PATH} for anything else than debugging during the development or when moving libraries between directories. You can find lots of articles on ``why is \texttt{LD\_LIBRARY\_PATH} evil?'' etc. For example, @@ -1413,7 +1413,7 @@ \end{itemize} \end{slide} -\label{API_ABI} +\hlabel{API_ABI} \begin{itemize} \item In short -- an API is source code based while an ABI is binary based. @@ -1482,7 +1482,7 @@ -1077941135 \end{verbatim} -\item \label{ABI_MAIN} Example: \example{lib-abi/abi-main.c} (see the block +\item \hlabel{ABI_MAIN} Example: \example{lib-abi/abi-main.c} (see the block comment in the file on how to use other files located in the same directory). \item To change an ABI safely, you need library versioning -- if the library ABI change is not backward compatible, a bumped up version needs to prevent @@ -1867,7 +1867,7 @@ different from an empty string. \item To go through all the command line arguments, you can either use \emph{argc} or test for \texttt{NULL} in \texttt{argv[i]}. -\item \label{SHELL_ARGV0} \texttt{argv[0]} is sometimes a source of additional +\item \hlabel{SHELL_ARGV0} \texttt{argv[0]} is sometimes a source of additional information. For example, commands \texttt{cp}, \texttt{mv}, and \texttt{ln} may be linked to the same executable (Solaris). The value of \texttt{argv[0]} then tells the process what function it is supposed to perform. Another example -- if @@ -1912,7 +1912,7 @@ prog && echo "success" || echo "failure" \end{verbatim} Example: \example{main/return-256.c}. -\item \label{RETURN255} Never use \texttt{return (-1)} in \texttt{main} nor +\item \hlabel{RETURN255} Never use \texttt{return (-1)} in \texttt{main} nor \texttt{exit(-1)}. Based on the information in the previous paragraph, from \texttt{-1} you will get \texttt{255} as the return value you get in the shell in \texttt{\$?}. It just creates confusion. @@ -1927,7 +1927,7 @@ \emsl{without} printing a new line), and calls functions registered via \texttt{atexit()}, and possibly other actions based on a specific system. Example: \example{exit/exit.c} and \example{exit/atexit-abort.c} -\item \label{MAIN_C} Example on printing out command line arguments: +\item \hlabel{MAIN_C} Example on printing out command line arguments: \example{main/print-argv.c} \item If a process is killed by a signal, you can get the signal number from its return value as presented by the shell. See page @@ -2175,7 +2175,7 @@ processing. \item When a undefined option is used, \texttt{getopt} will print an error; this can be suppressed by setting the \texttt{opterr} variable to 0. -\item \label{GETOPT} Example: shell script \example{getopt/getopts.sh} +\item \hlabel{GETOPT} Example: shell script \example{getopt/getopts.sh} rewritten to C language using the \texttt{getopt} function: \example{getopt/getopt.c} \end{itemize} @@ -2499,7 +2499,7 @@ \item Many \texttt{libc} functions and functions from other libraries set \texttt{errno} on failure as well. You always need to consult the relevant documentation. -\item \label{ERRNO} It is common nowadays that \texttt{errno} is in reality +\item \hlabel{ERRNO} It is common nowadays that \texttt{errno} is in reality defined in \texttt{libc} as a dereferenced pointer to an integer returned by a function (returned pointer is specific to a userland thread) and the value is set right after the instruction for the system call. For example, on the i386 @@ -2557,7 +2557,7 @@ %%%%% \begin{itemize} -\label{ERR} +\hlabel{ERR} \item The \funnm{errx}() function behaves as \funnm{err}() but does not use \texttt{errno} to print that extra error message. Similarly, \funnm{warnx}(). \item These functions are very handy especially for smaller programs as they are diff --git a/network.tex b/network.tex index 67a5794..96bc983 100644 --- a/network.tex +++ b/network.tex @@ -11,7 +11,7 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\label{NETWORKING} +\hlabel{NETWORKING} \begin{slide} \sltitle{Network communication} @@ -203,7 +203,7 @@ \end{itemize} \end{slide} -\label{SOCKET} +\hlabel{SOCKET} \begin{itemize} \item Function is declared in \texttt{} as well as other network @@ -341,7 +341,7 @@ \end{verbatim} \end{slide} -\label{BIND_EXAMPLE} +\hlabel{BIND_EXAMPLE} \begin{itemize} \item As already mentioned, such code is for demonstration purposes only. @@ -414,7 +414,7 @@ in a fixed length buffer and after it is filled out, the connection is still active but the TCP window is set to 0 which means the system stopped accepting further data. The buffer size is usually a few tens of kilobytes. -\label{UP_TO_LISTEN_ONLY_C} Example: \example{tcp/up-to-listen-only.c}. +\hlabel{UP_TO_LISTEN_ONLY_C} Example: \example{tcp/up-to-listen-only.c}. \item The example code uses macro \texttt{SOMAXCONN}, required by the UNIX specification to be in \texttt{sys/socket.h}. It specifies the maximum queue length for \funnm{listen}(). As far as we know, Linux, FreeBSD, macOS and @@ -444,7 +444,7 @@ \end{itemize} \end{slide} -\label{ACCEPT} +\hlabel{ACCEPT} \begin{itemize} \item The ``remote end'' is the socket on which a \funnm{connect}() is @@ -466,7 +466,7 @@ structure is guaranteed to fit in \texttt{struct sockaddr\_storage}, i.e. either \texttt{struct sockaddr\_in} or \texttt{struct sockaddr\_in6}. Also see page \pageref{TCPCLNTEXAMPLE}. -\item \label{TCP_SINK_SERVER_C} Example: \example{tcp/tcp-sink-server.c} +\item \hlabel{TCP_SINK_SERVER_C} Example: \example{tcp/tcp-sink-server.c} \end{itemize} \pdfbookmark[1]{connect}{connect} @@ -486,7 +486,7 @@ \end{itemize} \end{slide} -\label{CONNECT} +\hlabel{CONNECT} \begin{itemize} \item As the UNIX specification does not say anything about the socket state @@ -496,8 +496,8 @@ \funnm{read}() and \funnm{write}() calls, or \funnm{send}(), \funnm{recv}, \funnm{sendmsg}(), and \funnm{recvmsg}(). Behavior of the functions is similar as if working with pipes. -\item Example: \label{CONNECT_C} \example{tcp/connect.c} -\item \label{CONNECT_FOR_UDP} For connection-less services (UDP), +\item Example: \hlabel{CONNECT_C} \example{tcp/connect.c} +\item \hlabel{CONNECT_FOR_UDP} For connection-less services (UDP), \funnm{connect}() may be used as well. However, it will only set the remote address so that \funnm{send}() and \funnm{recv}() which do not have a remote address parameter can be used. @@ -645,7 +645,7 @@ \item Like \texttt{sendto}, \texttt{recvfrom} is possible to use for connected service (TCP). That said, getting remote's address for a TCP connection is better via \texttt{getpeername}, see page \pageref{GETPEERNAME}. -\item Example: \label{UDP_SERVER_C} \example{udp/udp-server.c} +\item Example: \hlabel{UDP_SERVER_C} \example{udp/udp-server.c} \end{itemize} %%%%% @@ -691,7 +691,7 @@ \item It is possible to use \texttt{sendto} for stream service, however the address will be ignored. The only reason not to use \texttt{write} would be to use flags. In that case though it would be simpler to use \texttt{send}. -\item Example:\label{UDP_CLIENT_C} \example{udp/udp-client.c}. +\item Example:\hlabel{UDP_CLIENT_C} \example{udp/udp-client.c}. \end{itemize} %%%%% @@ -720,7 +720,7 @@ \end{itemize} \end{slide} -\label{CLOSESOCKET} +\hlabel{CLOSESOCKET} \begin{itemize} \item Once closed, TCP socket can remain in transitory state which is defined in @@ -800,7 +800,7 @@ \end{itemize} \end{slide} -\label{IPv4_IPv6_ADDRESSES} +\hlabel{IPv4_IPv6_ADDRESSES} \begin{itemize} \item The functions are declared in \texttt{arpa/inet.h}. @@ -823,7 +823,7 @@ \texttt{ascii}) were used for IPv4 addresses. Thanks to the functions above these are now legacy. All these calls are usually documented in the \texttt{inet} man page. -\item \label{ADDRESSES} Do realize that by using these functions it is only +\item \hlabel{ADDRESSES} Do realize that by using these functions it is only possible to convert one address family per call, either IPv4 or IPv6. When the input can be either of those, try one and if that fails, fallback to the other one. Example: \example{resolving/addresses.c}. @@ -869,9 +869,9 @@ \end{itemize} \end{slide} -\label{SETSOCKOPT} -\label{GETPEERNAME} -\label{GETSOCKOPT} +\hlabel{SETSOCKOPT} +\hlabel{GETPEERNAME} +\hlabel{GETSOCKOPT} \begin{itemize} \item The \texttt{level} value for \texttt{getsockopt} and \texttt{setsockopt} @@ -932,7 +932,7 @@ \end{itemize} \end{slide} -\label{HTON} +\hlabel{HTON} \begin{itemize} \item If the local system uses the network byte order natively, the functions @@ -987,7 +987,7 @@ the IP packet header, (e.g. TCP, UDP, OSPF, GRE etc., see pages 11 and 14 in RFC~791), not HTTP, SSH, telnet or FTP -- these are \emph{services}, represented by port numbers. -\item \label{GETBYNAME} example: \example{resolving/getbyname.c} +\item \hlabel{GETBYNAME} example: \example{resolving/getbyname.c} \end{itemize} %%%%% @@ -996,7 +996,7 @@ \pdfbookmark[1]{getaddrinfo}{getaddrinfo} ]]]) -\label{GETADDRINF} +\hlabel{GETADDRINF} \begin{slide} \sltitle{Convert hostname to addresses: \texttt{getaddrinfo()}} @@ -1043,7 +1043,7 @@ \item After the results are no longer needed, it is prudent to call \texttt{freeaddrinfo}, that will free the memory allocated by \texttt{getaddrinfo}. -\item \label{GETADDRINFO} example: \example{resolving/getaddrinfo.c} +\item \hlabel{GETADDRINFO} example: \example{resolving/getaddrinfo.c} \item In the past the functions \funnm{gethostbyname} and \funnm{gethostbyaddr} were used. These only work with IPv4 addresses and are therefore considered legacy and not recommended to use. The functions @@ -1111,7 +1111,7 @@ reentrant and is therefore safe to use with threads. \item The man page for \texttt{getnameinfo} contains the list of usable \texttt{NI\_} flags for the \texttt{\emph{flags}} parameter. -\item \label{GETNAMEINFO} example: \example{resolving/getnameinfo.c} +\item \hlabel{GETNAMEINFO} example: \example{resolving/getnameinfo.c} \end{itemize} @@ -1119,7 +1119,7 @@ %%%%% \pdfbookmark[1]{TCP server}{tcpservercode} -\label{TCPSRVEXAMPLE} +\hlabel{TCPSRVEXAMPLE} \begin{slide} \sltitle{Example: TCP server} @@ -1171,7 +1171,7 @@ %%%%% \pdfbookmark[1]{TCP client}{tcpclientcode} -\label{TCPCLNTEXAMPLE} +\hlabel{TCPCLNTEXAMPLE} \begin{slide} \sltitle{Example: TCP client} @@ -1246,7 +1246,7 @@ \end{itemize} \end{slide} -\label{SELECT} +\hlabel{SELECT} \begin{itemize} \item \emsl{Motivation:} to read data from multiple file descriptors, it is @@ -1264,7 +1264,7 @@ iterations of the cycle). Correct solution of this situation is to use e.g. \texttt{select} and then call \texttt{read} only for those descriptors marked as \emph{ready}. -\item \label{BUSY_WAITING_C} Busy waiting example: \example{select/busy-wait.c}. +\item \hlabel{BUSY_WAITING_C} Busy waiting example: \example{select/busy-wait.c}. Notice that newly created socket does not have the \texttt{O\_NONBLOCK} flag, see page \pageref{ACCEPT}, so it is necessary to set it. \item A descriptor marked as \emph{ready} means that \texttt{read} or @@ -1315,12 +1315,12 @@ \item If the time argument is set to 0 (not NULL), then \texttt{select} can be used for so called \emph{polling} -- it will check the current state and return immediately. -\item Example: \label{SELECT_C} \example{select/select.c} +\item Example: \hlabel{SELECT_C} \example{select/select.c} \item \texttt{select} can also be used to determine the state after \texttt{connect} for non-blocking socket. Use \texttt{getsockopt} with \texttt{opt\_name} set to \texttt{SO\_ERROR}, (see page \pageref{GETSOCKOPT}) to see if the connection was successful. -\label{NON_BLOCKING_CONNECT} Example: \example{select/non-blocking-connect.c}. +\hlabel{NON_BLOCKING_CONNECT} Example: \example{select/non-blocking-connect.c}. \end{itemize} @@ -1361,7 +1361,7 @@ communication. Respective read descriptor will be present in the read set for \texttt{select} when the buffer is empty. The write descriptor will be in the write set when the buffer is non-empty. -\item \label{WRITE_SELECT_C} \texttt{select} will put the process to sleep +\item \hlabel{WRITE_SELECT_C} \texttt{select} will put the process to sleep when the data is not read from the remote side if only testing write readiness. This can be simply simulated by a program that merely connects (TCP handshake) however does not read anything. Example: \example{select/write-select.c}. @@ -1395,7 +1395,7 @@ \end{itemize} \end{slide} -\label{POLL} +\hlabel{POLL} \begin{itemize} \item Alternative to \texttt{select}. @@ -1413,7 +1413,7 @@ \item Time set to -1 has the same effect as \texttt{NULL} for \texttt{select}. \item If the number of descriptors is set to 0 (\texttt{fds} should be then \texttt{NULL}), \texttt{poll} can be simply used to sleep with less than one -second granularity. Example: \label{POLL_SLEEP_C} \example{sleep/poll-sleep.c} +second granularity. Example: \hlabel{POLL_SLEEP_C} \example{sleep/poll-sleep.c} That said, this "trick" does not work on macOS. \begin{itemize} \item Another way is to use \texttt{nanosleep}, that is part of POSIX.4 diff --git a/proc.tex b/proc.tex index b1d4dd4..32e90f3 100644 --- a/proc.tex +++ b/proc.tex @@ -74,7 +74,7 @@ \end{center} \end{slide} -\label{SOLARIS_PROC_ADDR_SPACE} +\hlabel{SOLARIS_PROC_ADDR_SPACE} \begin{itemize} \item The following is deductible from the image: @@ -407,7 +407,7 @@ \end{slide} \begin{itemize} -\item \label{FORK} The child process is almost an exact copy of its parent +\item \hlabel{FORK} The child process is almost an exact copy of its parent except for the following: \begin{itemize} \item The child process has a unique process and parent process ID. @@ -426,7 +426,7 @@ \texttt{getpid}. Imagine how the parent would figure out the new child PID, especially if it already spawned multiple children. \item Example: \example{fork/fork.c} -\item \label{VFORK} There is also \texttt{vfork}, used in the past to work +\item \hlabel{VFORK} There is also \texttt{vfork}, used in the past to work around the problem that the child address space was usually rewritten on subsequent \texttt{exec}. This problem was partially solved via already mentioned copy-on-write mechanism. See \example{fork/vfork.c} on how it works. @@ -577,7 +577,7 @@ \end{itemize} \end{slide} -\label{EXEC} +\hlabel{EXEC} \begin{itemize} \item \emph{path} must be an absolute or relative path to the executable file. @@ -698,8 +698,8 @@ calling process, i.e. the \texttt{environ} array. \item For some unknown historical reasons, there is no ``p'' with ``e'' together in the standard. However, GNU provides \funnm{execvpe} as an extension. -\item \label{EXEC_DATE} Example: \example{exec/exec-date.c} -\item \label{EXECL} The following use of \funnm{execl} is incorrect as it is +\item \hlabel{EXEC_DATE} Example: \example{exec/exec-date.c} +\item \hlabel{EXECL} The following use of \funnm{execl} is incorrect as it is missing the mandatory argument for \texttt{argv[0]}: \begin{verbatim} @@ -764,7 +764,7 @@ \end{itemize} \end{slide} -\label{ELF} +\hlabel{ELF} \begin{itemize} \item The UNIX standard does not specify what executable file format systems @@ -913,8 +913,8 @@ right away but carry on with its life and wait for the child later. \item Note that you have to use macros from the previous slide to get the child's return value out of the status information. -\item \label{WAITPID} Example: \example{wait/wait.c} -\item \label{SPAWN} Alternative for the \texttt{fork}/\texttt{exec} combination +\item \hlabel{WAITPID} Example: \example{wait/wait.c} +\item \hlabel{SPAWN} Alternative for the \texttt{fork}/\texttt{exec} combination can be the \texttt{posix\_spawn} function. The new process using this function can be waited on with \texttt{waitpid} etc. just like in the case of \texttt{fork}. Example: \example{exec/spawn.c} @@ -922,7 +922,7 @@ %%%%% -\label{PIPEREADWRITE} +\hlabel{PIPEREADWRITE} \pdfbookmark[1]{pipe}{pipe} @@ -947,7 +947,7 @@ \end{itemize} \end{slide} -\label{PIPE} +\hlabel{PIPE} \begin{itemize} \item \emph{pipe} is an object with 2 endpoints; serves for passing data from @@ -960,7 +960,7 @@ \item If the function \funnm{write} writes at most \texttt{PIPE\_BUF} bytes to the pipe, it is guaranteed that the write will be atomic, i.e. such bytes will not be intermingled with bytes written by other producers. -\item \label{TWO_WAY_PIPES} The SUSv3 standard does not specify whether +\item \hlabel{TWO_WAY_PIPES} The SUSv3 standard does not specify whether \texttt{fildes[0]} is also open for writing and if \texttt{fildes[1]} is also open for reading. FreeBSD and Solaris provide bidirectional pipes while Linux may not. It is best to assume unidirectional pipes. @@ -981,7 +981,7 @@ \end{center} \end{slide} -\label{FDSHARING} +\hlabel{FDSHARING} \begin{itemize} \item Remember, open file descriptors are unaffected by \funnm{exec} aside from @@ -1098,7 +1098,7 @@ \end{itemize} \end{slide} -\label{MMAP} +\hlabel{MMAP} \begin{itemize} \setlength{\itemsep}{0.8\itemsep} @@ -1296,7 +1296,7 @@ \end{itemize} \end{slide} -\label{DLOPEN} +\hlabel{DLOPEN} \begin{itemize} \item For example, you could use these functions to implement a dynamically @@ -1337,7 +1337,7 @@ the same library can be mapped multiple times via \funnm{dlopen} and the symbols in the mapped instances of the same library will not overlap. \end{itemize} -\item \label{RTLD_NEXT} Special handle \texttt{RTLD\_NEXT} searches the symbol +\item \hlabel{RTLD_NEXT} Special handle \texttt{RTLD\_NEXT} searches the symbol only in libraries loaded after the library that called \funnm{dlsym}. Handy for redefining existing functions if we need to call the original function in our redefined one. The library with a modified function is loaded first, possibly diff --git a/signals.tex b/signals.tex index 1866c82..1e844b3 100644 --- a/signals.tex +++ b/signals.tex @@ -26,7 +26,7 @@ \end{itemize} \end{slide} -\label{SIGNALS} +\hlabel{SIGNALS} \begin{itemize} \item Interrupts can be viewed as a mean of communication between the CPU and @@ -129,7 +129,7 @@ \end{itemize} \end{slide} -\label{KILLSYSCALL} +\hlabel{KILLSYSCALL} \begin{itemize} \item Traditionally, process with EUID~==~0 can send a signal to any other @@ -223,7 +223,7 @@ \begin{itemize} \item Those signals are generated on an error in a program. -\item \label{SHELLRETVALUEFORSIGNALS} For the first four signals -- +\item \hlabel{SHELLRETVALUEFORSIGNALS} For the first four signals -- \texttt{SIGBUS}, \texttt{SIGFPE}, \texttt{SIGILL}, and \texttt{SIGSEGV} the standard does not specify what exactly has to be the reason but usually those are errors detected by hardware. Try the following examples, and check the @@ -245,7 +245,7 @@ QUIT \end{verbatim} -\item \label{SPECIALSIGNALS} \emsl{For those four signals, there are some +\item \hlabel{SPECIALSIGNALS} \emsl{For those four signals, there are some special rules as well} (for details, see section \emph{2.4 Signal Concepts} in SUSv4): \begin{itemize} @@ -295,7 +295,7 @@ using the command \texttt{stty} or via a function \funnm{tcsetattr}(). \item In order to generate core files, your system and settings must allow it. Check the \texttt{ulimit} command and associated system call. -\item \label{SIGKILL} As \texttt{SIGKILL} cannot be handled, use it only if you +\item \hlabel{SIGKILL} As \texttt{SIGKILL} cannot be handled, use it only if you know what you are doing. For example, if a running process does not respond to user input nor any other signal. Many applications, mainly daemons, rely on the fact that they are sent \texttt{SIGTERM} on termination, which they often handle @@ -348,7 +348,7 @@ terminal but multiple processes can write to it at the same time. \item Stopping a process group from a terminal, usually via \texttt{Ctrl-Z}, is done with signal \texttt{SIGTSTP}, not \texttt{SIGSTOP}; a program thus can -catch the signal. \label{SIGTSTP} +catch the signal. \hlabel{SIGTSTP} \item the \texttt{SIGCHLD} signal is always received by the parent (no matter if \texttt{wait()} or \texttt{waitpid()} is used) unless explicitly ignored. See \example{signals/sigchld.c} @@ -444,7 +444,7 @@ \example{signals/interrupted-read.c}. \item Beware of deadlocks (will be discussed in the chapter on synchronization). If you set \texttt{SA\_NODEFER}, your handler needs to be reentrant. -\item \label{ASYNCSIGNALSAFE} \emsl{You should only use functions in a safe way +\item \hlabel{ASYNCSIGNALSAFE} \emsl{You should only use functions in a safe way from a handler}. By safe it is meant either use reentrant functions or you need to make sure the signal is not delivered in the wrong time (for example, the signal is delivered within a function and the same function is called from the @@ -471,7 +471,7 @@ different systems, some keep the handler set after delivering the signal, some reset it to \texttt{SIG\_DFL}. Check \example{signals/signal-vs-sigaction.c} if interested. -\item \label{REALTIMEEXTENSIONS} If your system supports a part of POSIX.1b +\item \hlabel{REALTIMEEXTENSIONS} If your system supports a part of POSIX.1b called \emph{Realtime Signals Extension} (RTS), it is possible to use the extension if you use flag \texttt{SA\_SIGINFO}. In that case a \texttt{sa\_sigaction} member of the structure \texttt{sigaction} must be used @@ -482,7 +482,7 @@ \pageref{REF_PROGRAMMING}. More information is also on page \pageref{POSIX} and \pageref{SIGWAITINFO}. Examples: \example{sig\-nals/siginfo.c}, \example{sig\-nals/sigqueue.c}. -\item \label{IGNORE_SIG_CHLD} By ignoring \texttt{SIG\_CHILD} you say you will +\item \hlabel{IGNORE_SIG_CHLD} By ignoring \texttt{SIG\_CHILD} you say you will not wait for child processes and the system will still not accumulate zombies. \end{itemize} @@ -512,7 +512,7 @@ \end{alltt} \end{slide} -\label{SIGALRM} +\hlabel{SIGALRM} \begin{itemize} \item You can also use timers with a finer granularity provided by @@ -569,7 +569,7 @@ \end{itemize} \end{slide} -\label{SIGPROCMASK} +\hlabel{SIGPROCMASK} \begin{itemize} \item The system silently ignores attempts to block \texttt{KILL} and @@ -616,7 +616,7 @@ \end{slide} \begin{itemize} -\item \label{SIGNALBLOCKINGEXAMPLE} The example shows a situation when a child +\item \hlabel{SIGNALBLOCKINGEXAMPLE} The example shows a situation when a child needs to use a different signal handler from its parent. If you just changed the handler in the child without blocking the signals before \funnm{fork}() a potential race would have been created -- a child would have run for a short @@ -629,7 +629,7 @@ %%%%% -\label{SIGWAIT} +\hlabel{SIGWAIT} ifdef([[[NOSPELLCHECK]]], [[[ \pdfbookmark[1]{pause, sigsuspend, sigwait}{sigwait} ]]]) @@ -669,7 +669,7 @@ extensions (threads) and you should use this function when dealing with signals in the multithreaded application. As other POSIX thread functions, it returns an error number directly, and 0 on success. -\item \label{SIGWAITINFO} There are also similar functions \funnm{sigwaitinfo}() +\item \hlabel{SIGWAITINFO} There are also similar functions \funnm{sigwaitinfo}() and \funnm{sigtimedwait}() defined with the POSIX-1003.1\emsl{b} extension (real-time). They work in a similar way but set \texttt{errno} on failure and it is possible to get more information upon signal delivery using a structure diff --git a/spellfilter.sed b/spellfilter.sed index 8f37965..2b17585 100644 --- a/spellfilter.sed +++ b/spellfilter.sed @@ -10,3 +10,4 @@ s/\\emprg\{.*\}//g s/\\verb#[[:alnum:]_\(\)]+#//g s/\\url\{[[:alnum:]_\/:\.]+\}//g s/IPv[46]//g +s/\\hlabel\{[[:alnum:]_]+\}//g diff --git a/synchro.tex b/synchro.tex index 00600ee..26d13bf 100644 --- a/synchro.tex +++ b/synchro.tex @@ -34,7 +34,7 @@ \end{itemize} \end{slide} -\label{SYNCHRONIZATION} +\hlabel{SYNCHRONIZATION} \begin{itemize} \item Operations that can be expressed in C with single statement does not @@ -54,7 +54,7 @@ More on page \pageref{ATOMIC_ADD}. \item In general similar problem happens when multiple processes share a system resource. -\item \label{RACE_C} example \example{race/race.c} +\item \hlabel{RACE_C} example \example{race/race.c} \end{itemize} %%%%% @@ -137,7 +137,7 @@ \end{tabular} \end{slide} -\label{CRITICALSECTION} +\hlabel{CRITICALSECTION} \begin{itemize} \item It is necessary to ensure mutual exclusion also when reading, @@ -210,7 +210,7 @@ the condition and goes asleep. The kernel wakes it up if the condition becomes true. \end{description} -\item \label{BUSYWAITING} active waiting is justifiable only in special +\item \hlabel{BUSYWAITING} active waiting is justifiable only in special situations. \end{itemize} @@ -285,7 +285,7 @@ \end{slide} \begin{itemize} -\item \label{LOCK_UNLOCK} The key is the \texttt{O\_EXCL} flag. +\item \hlabel{LOCK_UNLOCK} The key is the \texttt{O\_EXCL} flag. \item Because the exclusive flag is not accessible in most shells, the shell scripts usually use \texttt{mkdir} or \texttt{ln} (hard link) commands for lock file synchronization. @@ -358,7 +358,7 @@ automatically block the process, i.e. the lock will be applied also on processes that do not explicitly work with the lock. \begin{itemize} - \label{MANDATORY} + \hlabel{MANDATORY} \item not universally recommended, does not always work (e.g. \texttt{lockd} implements just advisory locking) \item for given file they are enabled by setting the SGID bit and @@ -408,8 +408,8 @@ \item If given part is not locked when using \texttt{F\_GETLK}, the \texttt{flock} structure is returned unchanged except for the first member that is set to \texttt{F\_UNLCK}. -\item \label{FCNTL_LOCKING} example: \example{file-locking/fcntl-locking.c} -\item \label{FCNTL_FIXED_RACE_C} example on how to use \texttt{fcntl} (it is +\item \hlabel{FCNTL_LOCKING} example: \example{file-locking/fcntl-locking.c} +\item \hlabel{FCNTL_FIXED_RACE_C} example on how to use \texttt{fcntl} (it is ,,fixed'' version of the previous \example{race/race.c} example from page \pageref{RACE_C}): \example{race/fcntl-fixed-race.c}. \item locking via \texttt{fcntl} and \texttt{lockf} has one important property @@ -465,7 +465,7 @@ closed the write end however it cannot do it because it is blocked. in \texttt{read} syscall: -\label{FIFODEADLOCK} +\hlabel{FIFODEADLOCK} \begin{verbatim} int main(void) { @@ -594,7 +594,7 @@ \pdfbookmark[1]{sem\_open, sem\_wait, sam\_post, sem\_close}{posix-semaphores} ]]]) -\label{NAMED_SEMAPHORES} +\hlabel{NAMED_SEMAPHORES} \begin{slide} \sltitle{POSIX API for semaphores} @@ -694,6 +694,6 @@ service from a userland program. \end{itemize} -\label{SYNCHRONIZATIONEND} +\hlabel{SYNCHRONIZATIONEND} \endinput diff --git a/sys-v-semaphores.tex b/sys-v-semaphores.tex index 1e5d504..8f0f17d 100644 --- a/sys-v-semaphores.tex +++ b/sys-v-semaphores.tex @@ -31,7 +31,7 @@ \end{itemize} \end{slide} -\label{SYSVSEM} +\hlabel{SYSVSEM} \begin{itemize} \item How to get the key for \texttt{semget} is explained on page @@ -150,7 +150,7 @@ \end{itemize} \end{slide} -\label{FTOK} \texttt{ftok()} notes: +\hlabel{FTOK} \texttt{ftok()} notes: \begin{itemize} \item Only the 8 lowest bits are used from the \texttt{id} argument. \item It is left unspecified whether the same key will be returned across file @@ -161,7 +161,7 @@ inode numbers have the same 16 lower bits. \item If unrelated processes need to use the same semaphore, \emsl{the file name used for the key needs to be agreed on beforehand.} -\item \label{SEM_FIXED_RACE_C} Example: \example{race/sem-fixed-race.c} +\item \hlabel{SEM_FIXED_RACE_C} Example: \example{race/sem-fixed-race.c} (this is the \example{race/race.c} example from page \pageref{RACE_C} fixed with semaphores) \end{itemize} diff --git a/threads.tex b/threads.tex index 62b5ecd..99b12a3 100644 --- a/threads.tex +++ b/threads.tex @@ -46,7 +46,7 @@ see page \pageref{REF_PROGRAMMING}. You can also use an online book \emph{Multithreaded Programming Guide} available on \url{http://docs.oracle.com}. -\item \label{PRIVILEGE_SEPARATION} An example situation when you do not want to +\item \hlabel{PRIVILEGE_SEPARATION} An example situation when you do not want to use threads is if you want to change a real and effective UID of processes. Take OpenSSH -- every connection is served by two processes. One, with maximum privileges, usually runs as root, and provides services (allocating a pseudo @@ -98,7 +98,7 @@ However, if the objective is more in better modular programming than real parallelism, usually non-preemptive threads do fine. Switching threads will be done when a process would normally block in system calls. -\item \label{SETJMP} If a system call blocks in a library implemented thread +\item \hlabel{SETJMP} If a system call blocks in a library implemented thread model, the whole process will block as the kernel has no knowledge there are more threads in the process. So the threading library is written the way that non-blocking calls are used, the thread context is saved after that and the @@ -141,7 +141,7 @@ \end{slide} -\label{POSIXTHREADS} +\hlabel{POSIXTHREADS} \begin{itemize} \item General information on POSIX is on page \pageref{POSIX}. @@ -193,7 +193,7 @@ errx(1, "pthread_create: %s", strerror(e)); \end{verbatim} -\item \label{ERRNO_IN_THREADS} Other functions that use \texttt{errno} work the +\item \hlabel{ERRNO_IN_THREADS} Other functions that use \texttt{errno} work the same with POSIX threads as each thread has its own \texttt{errno}. In that case, it is redefined using a function (which can either return the value or an address which is dereferenced). Check \texttt{/usr/include/errno.h} on Linux if @@ -223,7 +223,7 @@ ]]]) \begin{slide} -\label{PTHREAD_T} +\hlabel{PTHREAD_T} \sltitle{Thread creation} ifdef([[[NOSPELLCHECK]]], [[[ \funml{int \funnm{pthread\_create}(\=pthread\_t *\emph{thread}, @@ -258,7 +258,7 @@ It looks like we pass each thread its index. However, before the started thread gets scheduled to run, a next iteration might happen, modifying \texttt{i}. -\item \label{WRONG_USE_OF_ARG} Examples: \example{pthreads/wrong-use-of-arg.c}, +\item \hlabel{WRONG_USE_OF_ARG} Examples: \example{pthreads/wrong-use-of-arg.c}, \example{pthreads/correct-use-of-arg.c}. \item If you need to pass only one value, you could use the following (\textbf{note that it is implementation specific in the C standard so it is not @@ -277,12 +277,12 @@ printf("thread \%d started\bs{}n", (int)arg); \end{alltt} -\label{INT_AS_ARG} Example: \example{pthreads/int-as-arg.c} +\hlabel{INT_AS_ARG} Example: \example{pthreads/int-as-arg.c} \item If we need to pass more bytes than it is the size of the pointer, you must pass a pointer to memory where the passed data is stored, or use global variables. Accessing global variables must be synchronized, of course. More on that on page \pageref{THREADSYNCHRONIZATION}. -\item \label{PTHREAD_CREATE_CYCLE} \texttt{pthread\_t} is a transparent type and +\item \hlabel{PTHREAD_CREATE_CYCLE} \texttt{pthread\_t} is a transparent type and its implementation is not of your concern. Usually it is an integer though used to map to the native threads provided by the system. If you create several threads, you need to pass a different address for a \texttt{pthread\_t} variable @@ -294,7 +294,7 @@ ifdef([[[NOSPELLCHECK]]], [[[ \pdfbookmark[1]{pthread\_self, pthread\_key\_create}{pthreadkey} -\label{THREAD_ATTRS} +\hlabel{THREAD_ATTRS} ]]]) \begin{slide} @@ -399,7 +399,7 @@ \funnm{thr\_join}(). If you needed this functionality with POSIX thread API, it is easy to set threads as \emph{detached} and use a condition variable together with a global variable. More on that on page \pageref{CONDITION_VARIABLES}. -\item \label{PTHREAD_JOIN} Examples: \example{pthreads/pthread-join.c}, +\item \hlabel{PTHREAD_JOIN} Examples: \example{pthreads/pthread-join.c}, \example{pthreads/pthread-detach-join.c} \end{itemize} @@ -491,7 +491,7 @@ \item Functions \funnm{pthread\_setcancelstate}() and \funnm{pthread\_setcanceltype}() provide similar functionality to threads as is manipulating a signal mask to processes. -\item \label{PTHREAD_CANCEL} Example: \example{pthreads/pthread-setcanceltype.c} +\item \hlabel{PTHREAD_CANCEL} Example: \example{pthreads/pthread-setcanceltype.c} \end{itemize} %%%%% @@ -534,7 +534,7 @@ \end{slide} \begin{itemize} -\item \label{THREAD_SPECIFIC_DATA} Global variables and dynamically +\item \hlabel{THREAD_SPECIFIC_DATA} Global variables and dynamically allocated data are common to all threads. Thread specific data provides a way to create a global variable per thread. Note the difference between that and a local variable in the thread function -- as you know, in C, the local variable @@ -586,7 +586,7 @@ \end{itemize} \end{slide} -\label{PTHREAD_CLEANUP} +\hlabel{PTHREAD_CLEANUP} \begin{itemize} \item The cleanup function is called as \texttt{routine(arg)}. @@ -629,13 +629,13 @@ \begin{itemize} \item No cleanup routines or thread specific data destructors are called for threads not propagated to the new process. -\item \label{FORKALL} Note that the way how \funnm{fork}() works also depends on +\item \hlabel{FORKALL} Note that the way how \funnm{fork}() works also depends on the system used. For example, in Solaris before version 10 (i.e. before 2005), \funnm{fork}() in the \texttt{libthread} library (different from \texttt{libpthread}) was the same as \funnm{forkall}(). \item Examples: \example{pthreads/fork.c}, \example{pthreads/fork-not-in-main.c}, and also \example{pthreads/forkall.c} -\item \label{ATFORK} You can use \funnm{pthread\_atfork}() to set handlers that +\item \hlabel{ATFORK} You can use \funnm{pthread\_atfork}() to set handlers that are executed before \funnm{fork}() is called in the parent process, and then after \funnm{fork}() is called both in the parent and its child. The handlers are executed in the context of the thread that calls the \funnm{fork}(). Such @@ -689,7 +689,7 @@ \end{itemize} \end{slide} -\label{PTHREADSIGMASK} +\hlabel{PTHREADSIGMASK} \begin{itemize} \item If the action for a signal is set to process exit, the whole process @@ -706,7 +706,7 @@ \item Do not use \texttt{sigprocmask} (page \pageref{SIGPROCMASK}) in threaded environment, because the behavior of this call is not specified by the standard in such environment. It may work, or not. -\item \label{THREADS_SIGWAIT} Example: \example{pthreads/sigwait.c}. +\item \hlabel{THREADS_SIGWAIT} Example: \example{pthreads/sigwait.c}. \item \emsl{Note} that this way of signal handling should not be used for synchronous signals such as \texttt{SIGSEGV}, \texttt{SIGILL}, etc. These signals are generated directly for a thread, so if blocked the dedicated signal @@ -755,7 +755,7 @@ \end{itemize} \end{slide} -\label{THREADSYNCHRONIZATION} +\hlabel{THREADSYNCHRONIZATION} \begin{itemize} \item Process synchronization is described on pages @@ -804,7 +804,7 @@ ]]]) \end{slide} -\label{MUTEXES} +\hlabel{MUTEXES} \begin{itemize} \item Mutex = \emph{mutual exclusion} @@ -835,7 +835,7 @@ return values of mutex functions can make the code slightly less readable however it can be wrapped in a macro. Alternatively, the checks can be used during development only. Solaris and Linux use \texttt{NORMAL} type by default, -FreeBSD uses \texttt{ERRORCHECK}. \label{NOTMYLOCK} +FreeBSD uses \texttt{ERRORCHECK}. \hlabel{NOTMYLOCK} Example: \example{mutexes/not-my-lock.c}. \item Another type is \texttt{PTHREAD\_MUTEX\_RECURSIVE} that holds a count of lock actions done by given thread. The remaining threads will be granted access @@ -848,7 +848,7 @@ that's fine if these two calls are done by the same thread (another thread will get blocked). That is, assuming \texttt{A:foo()} and \texttt{A:bar()} are aware that the same thread can be already in the critical section. -\item \label{MUTEXTAB} The behavior according to mutex types:\\ +\item \hlabel{MUTEXTAB} The behavior according to mutex types:\\ \\ \raisetab{ \begin{tabular}[t]{r|c|c|c|} @@ -912,7 +912,7 @@ \end{itemize} \end{slide} -\label{MUTEXES2} +\hlabel{MUTEXES2} \begin{itemize} \item If you need to unlock a mutex locked by a different thread, use binary @@ -929,7 +929,7 @@ be spent in the overhead of calling functions implementing the locking. It is therefore desired to search for a compromise. (Or use an algorithm that does not require locks at all). -\item \label{MUTEX_RACE} Examples: \example{mutexes/race.c}, +\item \hlabel{MUTEX_RACE} Examples: \example{mutexes/race.c}, \example{mutexes/race-fixed.c} \item Mutexes can be shared between processes so that their threads will synchronize on them. This is done by using shared memory that will be set as an @@ -955,7 +955,7 @@ \end{itemize} \end{slide} -\label{CONDITION_VARIABLES} +\hlabel{CONDITION_VARIABLES} \begin{itemize} \item In other words -- condition variables are handy in a situation when a @@ -1114,7 +1114,7 @@ %%%%% \begin{slide} -\label{CONDVAR_USE} +\hlabel{CONDVAR_USE} \sltitle{Using condition variables} \begin{alltt} pthread\_cond\_t cond; pthread\_mutex\_t mutex; @@ -1158,7 +1158,7 @@ That said, SUSv3 discourages this (unlocking then signalling / broadcasting), saying it might cause "unpredictable scheduling behavior", possibly in the environment of threads with different scheduling priorities. -\item \label{QUEUESIMULATION} Example: +\item \hlabel{QUEUESIMULATION} Example: \example{cond-variables/queue-simulation.c} \end{itemize} @@ -1198,7 +1198,7 @@ \end{itemize} \end{slide} -\label{RWLOCKS} +\hlabel{RWLOCKS} \begin{itemize} \item You can also use static initialization @@ -1285,7 +1285,7 @@ \end{slide} \begin{itemize} -\item \label{ATOMIC_ADD} Example \example{race/atomic-add.c} demonstrates +\item \hlabel{ATOMIC_ADD} Example \example{race/atomic-add.c} demonstrates the race condition problem when performing addition and its possible solutions. The program spawns two threads, each thread works with the same global variable \emsl{x}, and in a loop, each increments the variable by numbers from a sequence @@ -1352,7 +1352,7 @@ \end{itemize} \end{slide} -\label{BARRIER} +\hlabel{BARRIER} \begin{itemize} \item The barrier API has been defined since SUSv3, @@ -1487,7 +1487,7 @@ \end{itemize} \end{slide} -\label{THREADSAFE} +\hlabel{THREADSAFE} \begin{itemize} \item The consequence of the above is that thread-safe is weaker property diff --git a/user-access.tex b/user-access.tex index 4780bba..d9a4626 100644 --- a/user-access.tex +++ b/user-access.tex @@ -103,7 +103,7 @@ \pdfbookmark[1]{getpwnam, getpwuid, getpwent}{getpw} ]]]) -\label{GETPW_FUNC} +\hlabel{GETPW_FUNC} \begin{slide} \sltitle{Obtain user/group information} \begin{itemize} @@ -167,7 +167,7 @@ \end{itemize} \end{slide} -\label{name_service_switch} +\hlabel{name_service_switch} \begin{itemize} \item Systems using the name service switch typically use the @@ -248,7 +248,7 @@ operation for a file}, the file is deleted automatically once it is no longer referenced from a directory structure and the file is not presently open by any process (see \example{unlink/unlink.c}). -\item \label{FILEDELETE} In order to delete a file, the user has to have write +\item \hlabel{FILEDELETE} In order to delete a file, the user has to have write permission for the \emsl{directory} containing the file, because that is actually the ``file'' being changed. \emsl{The rights of the file to be deleted are not relevant}; the \texttt{rm} command (or shell, if the command is built in) @@ -338,12 +338,12 @@ \end{itemize} \end{slide} -\label{ROOT_SETUID} +\hlabel{ROOT_SETUID} \begin{itemize} \item \emsl{access rights checking always consults the EUID, EGID, and supplementary GIDs} -\item \label{SUID_BIT} The SUID and SGID bits are used for programs that need +\item \hlabel{SUID_BIT} The SUID and SGID bits are used for programs that need bigger privileges than the user who executes them. One example is the \texttt{passwd} program that needs to update files \texttt{/etc/passwd} and \texttt{/etc/shadow}, where the ordinary (i.e. non root) user process cannot