<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.4.4" />
<title>Техническое задание на утилиту <em>cat(1)</em></title>
<style type="text/css">
/* ---------------------------------------------------------------------------
   Bare AsciiDoc styles
   Ryan Tomayko <r@tomayko.com>
--------------------------------------------------------------------------- */

body {
        font-family:verdana,helvetica,arial,sans-serif;
        font-size:81.25%;   /* 13px */
        line-height:1.538;  /* 20px */
        margin:40px 50px;
        max-width:53.8461538462em; /* 790px */
        color:#333;
        text-align:justify;
}

em {
        font-style:italic;
}

strong {
        font-weight:bold;
        color:#000;
}

tt {
        font-family:consolas, 'lucida console', 'bitstream vera sans mono',
                   'courier new', monospace;
        color:#000;
}

p, ul, ol, dl {
        margin:10px 0
}

dl {
        margin-left:40px
}

dt {
        font-weight:normal;
        color:#000;
}

h1, h2, h3, h4, h5 {
        font-family:'lucida grande',georgia,verdana,helvetica,arial,sans-serif;
        font-weight:normal;
        color:#000;
}

h1 {
        font-size:30px;
        line-height:1.428;
        margin:20px 0;
}

h2 {
        font-size:23px;
        line-height:1.36363636; /* repeating, of course */
        margin:20px 0;
}

h2 + .sectionbody {}

h3 {
        font-size:18px;
        line-height:1.1;
        margin:30px 0 10px 0;
}

h4 {
        font-size:13px;
        font-weight:bold;
        line-height:1.538;
}

h5 {
        font-size:13px;
        font-style:italic;
        line-height:1.538;
}

pre {
        font-size:larger;
}

#header {
        text-align:center;
        margin-bottom:30px;
}

#header h1 { margin-bottom:0 }


.title, .sidebar-title {
        font-weight:normal;
        color:#000;
        margin-bottom:0;
}

.admonitionblock .title {
        font-weight:bold;
}

.admonitionblock {
        margin:30px 0px;
        color:#555;
}

.admonitionblock td.icon {
        width:30px;
        padding-right:20px;
        padding-left:20px;
        text-transform:uppercase;
        font-weight:bold;
        color:#888;
}

.listingblock .content {
        border:1px solid silver;
        background:#eee;
        padding:5px;
}

.listingblock .content pre {
        margin:0;
}

.literalblock .content {
        margin-left:40px;
}

.verseblock .content {
        white-space:pre
}

.sidebarblock .sidebar-content {
        border:1px solid silver;
        background:#FFFFEE;
        padding:0 10px;
        color:#222;
        font-size:smaller;
        line-height:1.5;
}

.sidebar-title {
        margin:10px 0;
        font-weight:bold;
        color:#442;
}

.quoteblock-content {
        font-style:italic;
        color:#444;
        margin-left:40px;
}

.quoteblock-content .attribution {
        font-style:normal;
        text-align:right;
        color:#000;
}

.exampleblock-content *:first-child { margin-top:0 }
.exampleblock-content {
        border-left:2px solid silver;
        padding-left:8px;
}

#footer {
        font-size:11px;
        margin-top:40px;
        border-top:1px solid silver;
        color:#555;
}

#author {
        color:#000;
        text-transform:uppercase
}

/* vim: set ft=css ts=4 sw=4 noexpandtab: */
</style>
</head>
<body>
<div id="header">
<h1>Техническое задание на утилиту <em>cat(1)</em></h1>
<span id="author">Grigoriy A. Sitkarev,</span><br />
<span id="email"><tt>&lt;<a href="mailto:sitkarev@unixkomi.ru">sitkarev@unixkomi.ru</a>&gt;</tt></span><br />
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>Technical requirements specification for <em>cat(1)</em> utility.</p></div>
</div>
</div>
<h2 id="_">Назначение</h2>
<div class="sectionbody">
<div class="paragraph"><p>Утилита <em>cat(1)</em> предназначена для вывода одного или
нескольких файлов на стандартный вывод. Файлы могут быть
как текстовыми так и бинарными. В последнем случае может
оказаться что не все символы могут отображаться на
терминале и требуется их специальная обработка.</p></div>
</div>
<h2 id="__2">Поддерживаемые опции</h2>
<div class="sectionbody">
<div class="paragraph"><p>Классическая утилита <em>cat(1)</em> имеет как минимум следующие
опции, передаваемые с командой строки:</p></div>
<div class="ulist"><ul>
<li>
<p>
-n, нумеровать линии при выводе.
</p>
</li>
<li>
<p>
-b, нумеровать только непустые линии при выводе.
</p>
</li>
<li>
<p>
-u, осуществлять вывод без задержек.
</p>
</li>
<li>
<p>
-v, отображать непечатные управляющие символы и
  восьмибитные символы.
</p>
</li>
</ul></div>
</div>
<h2 id="__3">Задержка вывода</h2>
<div class="sectionbody">
<div class="paragraph"><p>Функции буферизованного ввода/вывода, предоставляемые
стандартной библиотекой Си, имеют три режима буферизации:</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
нет буферизации,
</p>
</li>
<li>
<p>
буферизация по блокам (block buffered),
</p>
</li>
<li>
<p>
буферизация по линиям (line buffered).
</p>
</li>
</ol></div>
<div class="paragraph"><p>Подробнее см. <em>setvbuf(3)</em>. При включённой буферизации
вывод в файл осуществляется не сразу после записи в него,
а по возможности блоками большего размера. По умолчанию
для <tt>stdin</tt> и <tt>stdout</tt> включена буферизация по линиям,
поэтому фактическая запись в файл, представленный <tt>stdout</tt>,
происходит только после того как в байтах вывода был
обнаружен символ конца строки (<strong>LF</strong>, <tt><em>\n</em></tt>).</p></div>
<div class="paragraph"><p>Если была установлена опция <em>-u</em>, то буферизацию нужно
отключить, и вывод в файл осуществлять без задержек, как
только были прочитаны байты входного файла.</p></div>
<div class="paragraph"><p>Функции низкоуровневого ввода/вывода (системные вызовы)
работают без буферизации.</p></div>
</div>
<h2 id="__4">Отображение непечатных символов</h2>
<div class="sectionbody">
<div class="paragraph"><p>ASCII стандарт определяет символы состоящие только из 7-ми
бит. Часть из них является управляющими кодами, такими как
перенос каретки и горизонтальная табуляция. Символы, имеющие
включенный восьмой бит могут отображаться на различных
терминалах по-разному и не стандартизованы ASCII. Их
назначение как правило специфично для национальных
кодировок. Для вывода бинарных файлов и файлов, содержащих
управляющие последовательности и восьмибитные символы
<em>cat(1)</em> использует специальные методы:</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
кареточную нотацию, для управляющих символов из набора
   ASCII,
</p>
</li>
<li>
<p>
метанотацию, для символов, использующих восьмой бит.
</p>
</li>
</ol></div>
<div class="paragraph"><p>В первом случае, все управляющие символы, за исключением
символа горизонтальной табуляции (<strong>HT</strong>, 0x09) и
символа конца строки (<strong>LF</strong>, 0x0A), выводятся в кареточной
нотации. Например, символ, соответствующий коду <tt>0x00</tt>,
выводится как <tt>^\@</tt>, символ с кодом <tt>0x01</tt> выводится как <tt>^A</tt>
и т.д. Код символа, выводимого после префикса <tt>^</tt>, вычисляется
как значение кода исходного символа плюс <tt>0x40</tt>. Подробнее о
кареточной нотации смотреть:</p></div>
<div class="ulist"><ul>
<li>
<p>
<a href="http://en.wikipedia.org/wiki/C0_and_C1_control_codes">Управляющие коды ASCII</a>
</p>
</li>
<li>
<p>
<a href="http://en.wikipedia.org/wiki/ASCII">Краткое описание ASCII</a>
</p>
</li>
</ul></div>
<div class="paragraph"><p>Во втором случае, все восьмибитные символы выводятся в так
называемой метанотации, с добавлением префикса <tt>M-</tt> к коду,
полученному из исходного отбрасыванием старшего бита. Таким
образом если например имеется символ с кодом <tt>0x80</tt> , он
будет выводиться как <tt>M-^@</tt>, символ с кодом <tt>0xC1</tt> будет
выводиться как <tt>M-A</tt>. Код символа, выводимого после префикса
<tt>M-</tt> вычисляется как значение исходного символа с
отброшенным старшим битом (например, через побитовое ИЛИ с
маской <tt>0x80</tt>) а затем выводиться точно так же как и в первом
случае.</p></div>
</div>
<h2 id="__5">Список файлов и стандартный ввод</h2>
<div class="sectionbody">
<div class="paragraph"><p>Утилита должна иметь возможность вывода произвольного
количества файлов, переданных с командной строки как
аргументы.</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>$ cat /etc/passwd /etc/group /etc/rc.local</tt></pre>
</div></div>
<div class="paragraph"><p>Также она должна интерпретировать файл со специальным
именем &#8220;-&#8221; как файл стандартного ввода.</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>$ cat - &gt; /home/user/console-out.txt</tt></pre>
</div></div>
</div>
<h2 id="__6">Проверки на корректность</h2>
<div class="sectionbody">
<div class="paragraph"><p>Утилита должна проверять зацикливание вывода на ввод -
файл источника и файлы назначения  должны быть обязательно
разными файлами.</p></div>
</div>
<h2 id="__7">Ссылки</h2>
<div class="sectionbody">
<div class="olist arabic"><ol class="arabic">
<li>
<p>
<a href="http://www.opengroup.org/onlinepubs/007908799/xcu/cat.html">Спецификация Opengroup cat(1)</a>
</p>
</li>
<li>
<p>
<a href="http://www.gnu.org/software/libc/manual/html_node/I_002fO-Overview.html#I_002fO-Overview">Обзор ввода/вывода в GNU Libc</a>
</p>
</li>
<li>
<p>
<a href="http://docstore.mik.ua/orelly/unix3/upt/ch12_04.htm">"Unix Power Tools, 3rd Edition", 12.4. Showing Nonprinting Characters with cat -v or od -c</a>
</p>
</li>
</ol></div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2010-12-13 00:07:58 MSD
</div>
</div>
</body>
</html>