#$FreeBSD$
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2021-01-09 10:58-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
msgctxt "_"
msgid "translator-credits"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:32
msgid "FreeBSD Developers' Handbook"
msgstr ""

#. (itstool) path: info/author
#: book.translate.xml:35
msgid "<orgname>The FreeBSD Documentation Project</orgname>"
msgstr ""

#. (itstool) path: info/pubdate
#. (itstool) path: info/releaseinfo
#: book.translate.xml:37 book.translate.xml:148
msgid "$FreeBSD$"
msgstr ""

#. (itstool) path: info/copyright
#: book.translate.xml:39
msgid ""
"<year>2000</year> <year>2001</year> <year>2002</year> <year>2003</year> "
"<year>2004</year> <year>2005</year> <year>2006</year> <year>2007</year> "
"<year>2008</year> <year>2009</year> <year>2010</year> <year>2011</year> "
"<year>2012</year> <year>2013</year> <year>2014</year> <year>2015</year> "
"<year>2016</year> <year>2017</year> <year>2018</year> <year>2019</year> "
"<year>2020</year> <holder>The FreeBSD Documentation Project</holder>"
msgstr ""

#. (itstool) path: legalnotice/title
#: book.translate.xml:66
msgid "Copyright"
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:68
msgid ""
"Redistribution and use in source (XML DocBook) and 'compiled' forms (XML, "
"HTML, PDF, PostScript, RTF and so forth) with or without modification, are "
"permitted provided that the following conditions are met:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:75
msgid ""
"Redistributions of source code (XML DocBook) must retain the above copyright "
"notice, this list of conditions and the following disclaimer as the first "
"lines of this file unmodified."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:81
msgid ""
"Redistributions in compiled form (transformed to other DTDs, converted to "
"PDF, PostScript, RTF and other formats) must reproduce the above copyright "
"notice, this list of conditions and the following disclaimer in the "
"documentation and/or other materials provided with the distribution."
msgstr ""

#. (itstool) path: important/para
#: book.translate.xml:90
msgid ""
"THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD DOCUMENTATION PROJECT \"AS IS"
"\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE "
"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE "
"ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD DOCUMENTATION PROJECT BE "
"LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR "
"CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF "
"SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS "
"INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN "
"CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) "
"ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF "
"THE POSSIBILITY OF SUCH DAMAGE."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:107
msgid "FreeBSD is a registered trademark of the FreeBSD Foundation."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:109
msgid ""
"Apple, AirPort, FireWire, iMac, iPhone, iPad, Mac, Macintosh, Mac OS, "
"Quicktime, and TrueType are trademarks of Apple Inc., registered in the U.S. "
"and other countries."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:114
msgid ""
"IBM, AIX, OS/2, PowerPC, PS/2, S/390, and ThinkPad are trademarks of "
"International Business Machines Corporation in the United States, other "
"countries, or both."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:118
msgid ""
"IEEE, POSIX, and 802 are registered trademarks of Institute of Electrical "
"and Electronics Engineers, Inc. in the United States."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:121
msgid ""
"Intel, Celeron, Centrino, Core, EtherExpress, i386, i486, Itanium, Pentium, "
"and Xeon are trademarks or registered trademarks of Intel Corporation or its "
"subsidiaries in the United States and other countries."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:125
msgid "Linux is a registered trademark of Linus Torvalds."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:127
msgid ""
"Microsoft, IntelliMouse, MS-DOS, Outlook, Windows, Windows Media and Windows "
"NT are either registered trademarks or trademarks of Microsoft Corporation "
"in the United States and/or other countries."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:131
msgid ""
"Motif, OSF/1, and UNIX are registered trademarks and IT DialTone and The "
"Open Group are trademarks of The Open Group in the United States and other "
"countries."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:135
msgid ""
"Sun, Sun Microsystems, Java, Java Virtual Machine, JDK, JRE, JSP, JVM, "
"Netra, OpenJDK, Solaris, StarOffice, SunOS and VirtualBox are trademarks or "
"registered trademarks of Sun Microsystems, Inc. in the United States and "
"other countries."
msgstr ""

#. (itstool) path: legalnotice/para
#: book.translate.xml:140
msgid ""
"Many of the designations used by manufacturers and sellers to distinguish "
"their products are claimed as trademarks. Where those designations appear in "
"this document, and the FreeBSD Project was aware of the trademark claim, the "
"designations have been followed by the <quote>™</quote> or the <quote>®</"
"quote> symbol."
msgstr ""

#. (itstool) path: abstract/para
#: book.translate.xml:151
msgid ""
"Welcome to the Developers' Handbook. This manual is a <emphasis>work in "
"progress</emphasis> and is the work of many individuals. Many sections do "
"not yet exist and some of those that do exist need to be updated. If you are "
"interested in helping with this project, send email to the <link xlink:href="
"\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-doc\">FreeBSD "
"documentation project mailing list</link>."
msgstr ""

#. (itstool) path: abstract/para
#: book.translate.xml:157
msgid ""
"The latest version of this document is always available from the <link xlink:"
"href=\"@@URL_RELPREFIX@@/index.html\">FreeBSD World Wide Web server</link>. "
"It may also be downloaded in a variety of formats and compression options "
"from the <link xlink:href=\"https://download.freebsd.org/ftp/doc/\">FreeBSD "
"FTP server</link> or one of the numerous <link xlink:href="
"\"@@URL_RELPREFIX@@/doc/en_US.ISO8859-1/books/handbook/mirrors-ftp.html"
"\">mirror sites</link>."
msgstr ""

#. (itstool) path: part/title
#: book.translate.xml:167
msgid "Basics"
msgstr ""

#. (itstool) path: info/title
#. (itstool) path: sect1/title
#: book.translate.xml:176 book.translate.xml:430
msgid "Introduction"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:178 book.translate.xml:2997
msgid ""
"<personname><firstname>Murray</firstname><surname>Stokely</surname></"
"personname><contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:179
msgid ""
"<personname><firstname>Jeroen</firstname><surname>Ruigrok van der Werven</"
"surname></personname>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:185
msgid "Developing on FreeBSD"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:187
msgid ""
"So here we are. System all installed and you are ready to start programming. "
"But where to start? What does FreeBSD provide? What can it do for me, as a "
"programmer?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:191
msgid ""
"These are some questions which this chapter tries to answer. Of course, "
"programming has different levels of proficiency like any other trade. For "
"some it is a hobby, for others it is their profession. The information in "
"this chapter might be aimed toward the beginning programmer; indeed, it "
"could serve useful for the programmer unfamiliar with the FreeBSD platform."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:200
msgid "The BSD Vision"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:202
msgid ""
"To produce the best <trademark class=\"registered\">UNIX</trademark> like "
"operating system package possible, with due respect to the original software "
"tools ideology as well as usability, performance and stability."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:209
msgid "Architectural Guidelines"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:211
msgid "Our ideology can be described by the following guidelines"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:217
msgid ""
"Do not add new functionality unless an implementor cannot complete a real "
"application without it."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:222
msgid ""
"It is as important to decide what a system is not as to decide what it is. "
"Do not serve all the world's needs; rather, make the system extensible so "
"that additional needs can be met in an upwardly compatible fashion."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:230
msgid ""
"The only thing worse than generalizing from one example is generalizing from "
"no examples at all."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:235
msgid ""
"If a problem is not completely understood, it is probably best to provide no "
"solution at all."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:240
msgid ""
"If you can get 90 percent of the desired effect for 10 percent of the work, "
"use the simpler solution."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:245
msgid "Isolate complexity as much as possible."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:249
msgid ""
"Provide mechanism, rather than policy. In particular, place user interface "
"policy in the client's hands."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:254
msgid "From Scheifler &amp; Gettys: \"X Window System\""
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:258
msgid "The Layout of <filename>/usr/src</filename>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:261
msgid ""
"The complete source code to FreeBSD is available from our public repository. "
"The source code is normally installed in <filename>/usr/src</filename> which "
"contains the following subdirectories:"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:271
msgid "Directory"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:272
msgid "Description"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:278
msgid "<filename>bin/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:279
msgid "Source for files in <filename>/bin</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:284
msgid "<filename>cddl/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:285
msgid "Utilities covered by the Common Development and Distribution License"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:290
msgid "<filename>contrib/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:291
msgid "Source for files from contributed software"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:296
msgid "<filename>crypto/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:297
msgid "Cryptographical sources"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:301
msgid "<filename>etc/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:302
msgid "Source for files in <filename>/etc</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:306
msgid "<filename>gnu/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:307
msgid "Utilities covered by the GNU Public License"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:312
msgid "<filename>include/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:313
msgid "Source for files in <filename>/usr/include</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:317
msgid "<filename>kerberos5/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:318
msgid "Source for Kerberos version 5"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:322
msgid "<filename>lib/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:323
msgid "Source for files in <filename>/usr/lib</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:327
msgid "<filename>libexec/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:328
msgid "Source for files in <filename>/usr/libexec</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:332
msgid "<filename>release/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:333
msgid "Files required to produce a FreeBSD release"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:338
msgid "<filename>rescue/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:339
msgid "Build system for the <filename>/rescue</filename> utilities"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:345
msgid "<filename>sbin/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:346
msgid "Source for files in <filename>/sbin</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:350
msgid "<filename>secure/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:351
msgid "Contributed cryptographic sources"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:355
msgid "<filename>share/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:356
msgid "Source for files in <filename>/usr/share</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:360
msgid "<filename>sys/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:361
msgid "Kernel source files"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:365
msgid "<filename>tests/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:366
msgid "The FreeBSD test suite"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:370
msgid "<filename>tools/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:371
msgid "Tools used for maintenance and testing of FreeBSD"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:376
msgid "<filename>usr.bin/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:377
msgid "Source for files in <filename>/usr/bin</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:381
msgid "<filename>usr.sbin/</filename>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:382
msgid "Source for files in <filename>/usr/sbin</filename>"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:398
msgid "Programming Tools"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:401
msgid ""
"<personname> <firstname>James</firstname> <surname>Raynard</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:408
msgid ""
"<personname> <firstname>Murray</firstname> <surname>Stokely</surname> </"
"personname>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:418 book.translate.xml:3003 book.translate.xml:4926
#: book.translate.xml:9459
msgid "Synopsis"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:420
msgid ""
"This chapter is an introduction to using some of the programming tools "
"supplied with FreeBSD, although much of it will be applicable to many other "
"versions of <trademark class=\"registered\">UNIX</trademark>. It does "
"<emphasis>not</emphasis> attempt to describe coding in any detail. Most of "
"the chapter assumes little or no previous programming knowledge, although it "
"is hoped that most programmers will find something of value in it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:432
msgid ""
"FreeBSD offers an excellent development environment. Compilers for C and C++ "
"and an assembler come with the basic system, not to mention classic "
"<trademark class=\"registered\">UNIX</trademark> tools such as <command>sed</"
"command> and <command>awk</command>. If that is not enough, there are many "
"more compilers and interpreters in the Ports collection. The following "
"section, <link linkend=\"tools-programming\">Introduction to Programming</"
"link>, lists some of the available options. FreeBSD is very compatible with "
"standards such as <acronym><trademark class=\"registered\">POSIX</"
"trademark></acronym> and <acronym>ANSI</acronym> C, as well with its own BSD "
"heritage, so it is possible to write applications that will compile and run "
"with little or no modification on a wide range of platforms."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:445
msgid ""
"However, all this power can be rather overwhelming at first if you have "
"never written programs on a <trademark class=\"registered\">UNIX</trademark> "
"platform before. This document aims to help you get up and running, without "
"getting too deeply into more advanced topics. The intention is that this "
"document should give you enough of the basics to be able to make some sense "
"of the documentation."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:452
msgid ""
"Most of the document requires little or no knowledge of programming, "
"although it does assume a basic competence with using <trademark class="
"\"registered\">UNIX</trademark> and a willingness to learn!"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:459
msgid "Introduction to Programming"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:461
msgid ""
"A program is a set of instructions that tell the computer to do various "
"things; sometimes the instruction it has to perform depends on what happened "
"when it performed a previous instruction. This section gives an overview of "
"the two main ways in which you can give these instructions, or "
"<quote>commands</quote> as they are usually called. One way uses an "
"<firstterm>interpreter</firstterm>, the other a <firstterm>compiler</"
"firstterm>. As human languages are too difficult for a computer to "
"understand in an unambiguous way, commands are usually written in one or "
"other languages specially designed for the purpose."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:474
msgid "Interpreters"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:476
msgid ""
"With an interpreter, the language comes as an environment, where you type in "
"commands at a prompt and the environment executes them for you. For more "
"complicated programs, you can type the commands into a file and get the "
"interpreter to load the file and execute the commands in it. If anything "
"goes wrong, many interpreters will drop you into a debugger to help you "
"track down the problem."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:484
msgid ""
"The advantage of this is that you can see the results of your commands "
"immediately, and mistakes can be corrected readily. The biggest disadvantage "
"comes when you want to share your programs with someone. They must have the "
"same interpreter, or you must have some way of giving it to them, and they "
"need to understand how to use it. Also users may not appreciate being thrown "
"into a debugger if they press the wrong key! From a performance point of "
"view, interpreters can use up a lot of memory, and generally do not generate "
"code as efficiently as compilers."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:495
msgid ""
"In my opinion, interpreted languages are the best way to start if you have "
"not done any programming before. This kind of environment is typically found "
"with languages like Lisp, Smalltalk, Perl and Basic. It could also be argued "
"that the <trademark class=\"registered\">UNIX</trademark> shell "
"(<command>sh</command>, <command>csh</command>) is itself an interpreter, "
"and many people do in fact write shell <quote>scripts</quote> to help with "
"various <quote>housekeeping</quote> tasks on their machine. Indeed, part of "
"the original <trademark class=\"registered\">UNIX</trademark> philosophy was "
"to provide lots of small utility programs that could be linked together in "
"shell scripts to perform useful tasks."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:509
msgid "Interpreters Available with FreeBSD"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:511
msgid ""
"Here is a list of interpreters that are available from the FreeBSD Ports "
"Collection, with a brief discussion of some of the more popular interpreted "
"languages."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:515
msgid ""
"Instructions on how to get and install applications from the Ports "
"Collection can be found in the <link xlink:href=\"@@URL_RELPREFIX@@/doc/"
"en_US.ISO8859-1/books/handbook/ports-using.html\">Ports section</link> of "
"the handbook."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:521
msgid "<acronym>BASIC</acronym>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:524
msgid ""
"Short for Beginner's All-purpose Symbolic Instruction Code. Developed in the "
"1950s for teaching University students to program and provided with every "
"self-respecting personal computer in the 1980s, <acronym>BASIC</acronym> has "
"been the first programming language for many programmers. It is also the "
"foundation for Visual Basic."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:532
msgid ""
"The Bywater Basic Interpreter can be found in the Ports Collection as "
"<package>lang/bwbasic</package> and the Phil Cockroft's Basic Interpreter "
"(formerly Rabbit Basic) is available as <package>lang/pbasic</package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:541
msgid "Lisp"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:544
msgid ""
"A language that was developed in the late 1950s as an alternative to the "
"<quote>number-crunching</quote> languages that were popular at the time. "
"Instead of being based on numbers, Lisp is based on lists; in fact, the name "
"is short for <quote>List Processing</quote>. It is very popular in "
"<acronym>AI</acronym> (Artificial Intelligence) circles."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:552
msgid ""
"Lisp is an extremely powerful and sophisticated language, but can be rather "
"large and unwieldy."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:555
msgid ""
"Various implementations of Lisp that can run on <trademark class=\"registered"
"\">UNIX</trademark> systems are available in the Ports Collection for "
"FreeBSD. GNU Common Lisp can be found as <package>lang/gcl</package>. CLISP "
"by Bruno Haible and Michael Stoll is available as <package>lang/clisp</"
"package>. For CMUCL, which includes a highly-optimizing compiler too, or "
"simpler Lisp implementations like SLisp, which implements most of the Common "
"Lisp constructs in a few hundred lines of C code, <package>lang/cmucl</"
"package> and <package>lang/slisp</package> are available respectively."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:571
msgid "Perl"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:574
msgid ""
"Very popular with system administrators for writing scripts; also often used "
"on World Wide Web servers for writing <acronym>CGI</acronym> scripts."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:578
msgid ""
"Perl is available in the Ports Collection as <package>lang/perl5.24</"
"package> for all FreeBSD releases."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:585
msgid "Scheme"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:588
msgid ""
"A dialect of Lisp that is rather more compact and cleaner than Common Lisp. "
"Popular in Universities as it is simple enough to teach to undergraduates as "
"a first language, while it has a high enough level of abstraction to be used "
"in research work."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:594
msgid ""
"Scheme is available from the Ports Collection as <package>lang/elk</package> "
"for the Elk Scheme Interpreter. The MIT Scheme Interpreter can be found in "
"<package>lang/mit-scheme</package> and the SCM Scheme Interpreter in "
"<package>lang/scm</package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:605
msgid "Icon"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:608
msgid ""
"Icon is a high-level language with extensive facilities for processing "
"strings and structures. The version of Icon for FreeBSD can be found in the "
"Ports Collection as <package>lang/icon</package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:617
msgid "Logo"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:620
msgid ""
"Logo is a language that is easy to learn, and has been used as an "
"introductory programming language in various courses. It is an excellent "
"tool to work with when teaching programming to smaller age groups, as it "
"makes creation of elaborate geometric shapes an easy task."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:627
msgid ""
"The latest version of Logo for FreeBSD is available from the Ports "
"Collection in <package>lang/logo</package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:634
msgid "Python"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:637
msgid ""
"Python is an Object-Oriented, interpreted language. Its advocates argue that "
"it is one of the best languages to start programming with, since it is "
"relatively easy to start with, but is not limited in comparison to other "
"popular interpreted languages that are used for the development of large, "
"complex applications (Perl and Tcl are two other languages that are popular "
"for such tasks)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:646
msgid ""
"The latest version of Python is available from the Ports Collection in "
"<package>lang/python</package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:653
msgid "Ruby"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:656
msgid ""
"Ruby is an interpreter, pure object-oriented programming language. It has "
"become widely popular because of its easy to understand syntax, flexibility "
"when writing code, and the ability to easily develop and maintain large, "
"complex programs."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:662
msgid ""
"Ruby is available from the Ports Collection as <package>lang/ruby25</"
"package>."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:668
msgid "Tcl and Tk"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:671
msgid ""
"Tcl is an embeddable, interpreted language, that has become widely used and "
"became popular mostly because of its portability to many platforms. It can "
"be used both for quickly writing small, prototype applications, or (when "
"combined with Tk, a GUI toolkit) fully-fledged, featureful programs."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:678
msgid ""
"Various versions of Tcl are available as ports for FreeBSD. The latest "
"version, Tcl 8.5, can be found in <package>lang/tcl87</package>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:687
msgid "Compilers"
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:695
msgid "If you run it in the shell, you may get a core dump."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:689
msgid ""
"Compilers are rather different. First of all, you write your code in a file "
"(or files) using an editor. You then run the compiler and see if it accepts "
"your program. If it did not compile, grit your teeth and go back to the "
"editor; if it did compile and gave you a program, you can run it either at a "
"shell command prompt or in a debugger to see if it works properly.<_:"
"footnote-1/>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:698
msgid ""
"Obviously, this is not quite as direct as using an interpreter. However it "
"allows you to do a lot of things which are very difficult or even impossible "
"with an interpreter, such as writing code which interacts closely with the "
"operating system—or even writing your own operating system! It is also "
"useful if you need to write very efficient code, as the compiler can take "
"its time and optimize the code, which would not be acceptable in an "
"interpreter. Moreover, distributing a program written for a compiler is "
"usually more straightforward than one written for an interpreter—you can "
"just give them a copy of the executable, assuming they have the same "
"operating system as you."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:711
msgid ""
"As the edit-compile-run-debug cycle is rather tedious when using separate "
"programs, many commercial compiler makers have produced Integrated "
"Development Environments (<acronym>IDE</acronym>s for short). FreeBSD does "
"not include an IDE in the base system, but <package>devel/kdevelop</package> "
"is available in the Ports Collection and many use <application>Emacs</"
"application> for this purpose. Using <application>Emacs</application> as an "
"IDE is discussed in <xref linkend=\"emacs\"/>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:725
msgid "Compiling with <command>cc</command>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:727
msgid ""
"This section deals with the <application>gcc</application> and "
"<application>clang</application> compilers for C and C++, since they come "
"with the FreeBSD base system. Starting with FreeBSD 10.X <command>clang</"
"command> is installed as <command>cc</command>. The details of producing a "
"program with an interpreter vary considerably between interpreters, and are "
"usually well covered in the documentation and on-line help for the "
"interpreter."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:736
msgid ""
"Once you have written your masterpiece, the next step is to convert it into "
"something that will (hopefully!) run on FreeBSD. This usually involves "
"several steps, each of which is done by a separate program."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:743
msgid ""
"Pre-process your source code to remove comments and do other tricks like "
"expanding macros in C."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:748
msgid ""
"Check the syntax of your code to see if you have obeyed the rules of the "
"language. If you have not, it will complain!"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:754
msgid ""
"Convert the source code into assembly language—this is very close to machine "
"code, but still understandable by humans. Allegedly."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:760
msgid ""
"Convert the assembly language into machine code—yep, we are talking bits and "
"bytes, ones and zeros here."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:766
msgid ""
"Check that you have used things like functions and global variables in a "
"consistent way. For example, if you have called a non-existent function, it "
"will complain."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:773
msgid ""
"If you are trying to produce an executable from several source code files, "
"work out how to fit them all together."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:779
msgid ""
"Work out how to produce something that the system's run-time loader will be "
"able to load into memory and run."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:785
msgid "Finally, write the executable on the filesystem."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:789
msgid ""
"The word <firstterm>compiling</firstterm> is often used to refer to just "
"steps 1 to 4—the others are referred to as <firstterm>linking</firstterm>. "
"Sometimes step 1 is referred to as <firstterm>pre-processing</firstterm> and "
"steps 3-4 as <firstterm>assembling</firstterm>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:795
msgid ""
"Fortunately, almost all this detail is hidden from you, as <command>cc</"
"command> is a front end that manages calling all these programs with the "
"right arguments for you; simply typing"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:800
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc foobar.c</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:802
msgid ""
"will cause <filename>foobar.c</filename> to be compiled by all the steps "
"above. If you have more than one file to compile, just do something like"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:806
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc foo.c bar.c</userinput>"
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:812
msgid ""
"In case you did not know, a binary sort is an efficient way of sorting "
"things into order and a bubble sort is not."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:808
msgid ""
"Note that the syntax checking is just that—checking the syntax. It will not "
"check for any logical mistakes you may have made, like putting the program "
"into an infinite loop, or using a bubble sort when you meant to use a binary "
"sort.<_:footnote-1/>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:816
msgid ""
"There are lots and lots of options for <command>cc</command>, which are all "
"in the manual page. Here are a few of the most important ones, with examples "
"of how to use them."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:823
msgid "<option>-o <replaceable>filename</replaceable></option>"
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:830
msgid "The reasons for this are buried in the mists of history."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:828
msgid ""
"The output name of the file. If you do not use this option, <command>cc</"
"command> will produce an executable called <filename>a.out</filename>.<_:"
"footnote-1/>"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:835
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cc foobar.c</userinput>               <lineannotation>executable is a.out</lineannotation>\n"
"<prompt>%</prompt> <userinput>cc -o foobar foobar.c</userinput>     <lineannotation>executable is foobar</lineannotation>"
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:842
msgid "<option>-c</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:845
msgid ""
"Just compile the file, do not link it. Useful for toy programs where you "
"just want to check the syntax, or if you are using a <filename>Makefile</"
"filename>."
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:850
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -c foobar.c</userinput>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:853
msgid ""
"This will produce an <firstterm>object file</firstterm> (not an executable) "
"called <filename>foobar.o</filename>. This can be linked together with other "
"object files into an executable."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:862
msgid "<option>-g</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:865
msgid ""
"Create a debug version of the executable. This makes the compiler put "
"information into the executable about which line of which source file "
"corresponds to which function call. A debugger can use this information to "
"show the source code as you step through the program, which is "
"<emphasis>very</emphasis> useful; the disadvantage is that all this extra "
"information makes the program much bigger. Normally, you compile with "
"<option>-g</option> while you are developing a program and then compile a "
"<quote>release version</quote> without <option>-g</option> when you are "
"satisfied it works properly."
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:879
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -g foobar.c</userinput>"
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:886
msgid ""
"Note, we did not use the <option>-o</option> flag to specify the executable "
"name, so we will get an executable called <filename>a.out</filename>. "
"Producing a debug version called <filename>foobar</filename> is left as an "
"exercise for the reader!"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:882
msgid "This will produce a debug version of the program. <_:footnote-1/>"
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:896
msgid "<option>-O</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:899
msgid ""
"Create an optimized version of the executable. The compiler performs various "
"clever tricks to try to produce an executable that runs faster than normal. "
"You can add a number after the <option>-O</option> to specify a higher level "
"of optimization, but this often exposes bugs in the compiler's optimizer."
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:907
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -O -o foobar foobar.c</userinput>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:910
msgid "This will produce an optimized version of <filename>foobar</filename>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:916
msgid ""
"The following three flags will force <command>cc</command> to check that "
"your code complies to the relevant international standard, often referred to "
"as the <acronym>ANSI</acronym> standard, though strictly speaking it is an "
"<acronym>ISO</acronym> standard."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:924
msgid "<option>-Wall</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:927
msgid ""
"Enable all the warnings which the authors of <command>cc</command> believe "
"are worthwhile. Despite the name, it will not enable all the warnings "
"<command>cc</command> is capable of."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:935
msgid "<option>-ansi</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:938
msgid ""
"Turn off most, but not all, of the non-<acronym>ANSI</acronym> C features "
"provided by <command>cc</command>. Despite the name, it does not guarantee "
"strictly that your code will comply to the standard."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:947
msgid "<option>-pedantic</option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:950
msgid ""
"Turn off <emphasis>all</emphasis> <command>cc</command>'s non-<acronym>ANSI</"
"acronym> C features."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:957
msgid ""
"Without these flags, <command>cc</command> will allow you to use some of its "
"non-standard extensions to the standard. Some of these are very useful, but "
"will not work with other compilers—in fact, one of the main aims of the "
"standard is to allow people to write code that will work with any compiler "
"on any system. This is known as <firstterm>portable code</firstterm>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:965
msgid ""
"Generally, you should try to make your code as portable as possible, as "
"otherwise you may have to completely rewrite the program later to get it to "
"work somewhere else—and who knows what you may be using in a few years time?"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:971
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:974
msgid ""
"This will produce an executable <filename>foobar</filename> after checking "
"<filename>foobar.c</filename> for standard compliance."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:980
msgid "<option>-l<replaceable>library</replaceable></option>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:983
msgid "Specify a function library to be used at link time."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:986
msgid ""
"The most common example of this is when compiling a program that uses some "
"of the mathematical functions in C. Unlike most other platforms, these are "
"in a separate library from the standard C one and you have to tell the "
"compiler to add it."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:992
msgid ""
"The rule is that if the library is called "
"<filename>lib<replaceable>something</replaceable>.a</filename>, you give "
"<command>cc</command> the argument <option>-l<replaceable>something</"
"replaceable></option>. For example, the math library is <filename>libm.a</"
"filename>, so you give <command>cc</command> the argument <option>-lm</"
"option>. A common <quote>gotcha</quote> with the math library is that it has "
"to be the last library on the command line."
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1004 book.translate.xml:1047
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -o foobar foobar.c -lm</userinput>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1007
msgid ""
"This will link the math library functions into <filename>foobar</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1010
msgid ""
"If you are compiling C++ code, use <command>c++</command>. <command>c++</"
"command> can also be invoked as <command>clang++</command> on FreeBSD."
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1015
#, no-wrap
msgid "<prompt>%</prompt> <userinput>c++ -o foobar foobar.cc</userinput>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1018
msgid ""
"This will both produce an executable <filename>foobar</filename> from the C+"
"+ source file <filename>foobar.cc</filename>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1026
msgid "Common <command>cc</command> Queries and Problems"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1031
msgid ""
"I am trying to write a program which uses the <function>sin()</function> "
"function and I get an error like this. What does it mean?"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1036
#, no-wrap
msgid "/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1041
msgid ""
"When using mathematical functions like <function>sin()</function>, you have "
"to tell <command>cc</command> to link in the math library, like so:"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1054
msgid ""
"All right, I wrote this simple program to practice using <option>-lm</"
"option>. All it does is raise 2.1 to the power of 6."
msgstr ""

#. (itstool) path: informalexample/programlisting
#: book.translate.xml:1059
#, no-wrap
msgid ""
"#include &lt;stdio.h&gt;\n"
"\n"
"int main() {\n"
"\tfloat f;\n"
"\n"
"\tf = pow(2.1, 6);\n"
"\tprintf(\"2.1 ^ 6 = %f\\n\", f);\n"
"\treturn 0;\n"
"}"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1070
msgid "and I compiled it as:"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1073
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc temp.c -lm</userinput>"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1076
msgid "like you said I should, but I get this when I run it:"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1080
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>./a.out</userinput>\n"
"2.1 ^ 6 = 1023.000000"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1084
msgid "This is <emphasis>not</emphasis> the right answer! What is going on?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1089
msgid ""
"When the compiler sees you call a function, it checks if it has already seen "
"a prototype for it. If it has not, it assumes the function returns an "
"<type>int</type>, which is definitely not what you want here."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1099
msgid "So how do I fix this?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1103
msgid ""
"The prototypes for the mathematical functions are in <filename>math.h</"
"filename>. If you include this file, the compiler will be able to find the "
"prototype and it will stop doing strange things to your calculation!"
msgstr ""

#. (itstool) path: informalexample/programlisting
#: book.translate.xml:1110
#, no-wrap
msgid ""
"#include &lt;math.h&gt;\n"
"#include &lt;stdio.h&gt;\n"
"\n"
"int main() {\n"
"..."
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1117
msgid "After recompiling it as you did before, run it:"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1121
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>./a.out</userinput>\n"
"2.1 ^ 6 = 85.766121"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1125
msgid ""
"If you are using any of the mathematical functions, <emphasis>always</"
"emphasis> include <filename>math.h</filename> and remember to link in the "
"math library."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1134
msgid ""
"I compiled a file called <filename>foobar.c</filename> and I cannot find an "
"executable called <filename>foobar</filename>. Where has it gone?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1141
msgid ""
"Remember, <command>cc</command> will call the executable <filename>a.out</"
"filename> unless you tell it differently. Use the <option>-o "
"<replaceable>filename</replaceable></option> option:"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1148
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc -o foobar foobar.c</userinput>"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1155
msgid ""
"OK, I have an executable called <filename>foobar</filename>, I can see it "
"when I run <command>ls</command>, but when I type in <command>foobar</"
"command> at the command prompt it tells me there is no such file. Why can it "
"not find it?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1164
msgid ""
"Unlike <trademark class=\"registered\">MS-DOS</trademark>, <trademark class="
"\"registered\">UNIX</trademark> does not look in the current directory when "
"it is trying to find out which executable you want it to run, unless you "
"tell it to. Type <command>./foobar</command>, which means <quote>run the "
"file called <filename>foobar</filename> in the current directory.</quote>"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1175
msgid ""
"I called my executable <filename>test</filename>, but nothing happens when I "
"run it. What is going on?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1181
msgid ""
"Most <trademark class=\"registered\">UNIX</trademark> systems have a program "
"called <command>test</command> in <filename>/usr/bin</filename> and the "
"shell is picking that one up before it gets to checking the current "
"directory. Either type:"
msgstr ""

#. (itstool) path: informalexample/screen
#: book.translate.xml:1187
#, no-wrap
msgid "<prompt>%</prompt> <userinput>./test</userinput>"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1190
msgid "or choose a better name for your program!"
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1196
msgid ""
"I compiled my program and it seemed to run all right at first, then there "
"was an error and it said something about <errorname>core dumped</errorname>. "
"What does that mean?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1203
msgid ""
"The name <firstterm>core dump</firstterm> dates back to the very early days "
"of <trademark class=\"registered\">UNIX</trademark>, when the machines used "
"core memory for storing data. Basically, if the program failed under certain "
"conditions, the system would write the contents of core memory to disk in a "
"file called <filename>core</filename>, which the programmer could then pore "
"over to find out what went wrong."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1215
msgid "Fascinating stuff, but what I am supposed to do now?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1220
msgid "Use a debugger to analyze the core (see <xref linkend=\"debugging\"/>)."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1227
msgid ""
"When my program dumped core, it said something about a "
"<errorname>segmentation fault</errorname>. What is that?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1233
msgid ""
"This basically means that your program tried to perform some sort of illegal "
"operation on memory; <trademark class=\"registered\">UNIX</trademark> is "
"designed to protect the operating system and other programs from rogue "
"programs."
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1238
msgid "Common causes for this are:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1242
msgid "Trying to write to a <symbol>NULL</symbol> pointer, eg"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1245
#, no-wrap
msgid ""
"char *foo = NULL;\n"
"strcpy(foo, \"bang!\");"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1250
msgid "Using a pointer that has not been initialized, eg"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1253
#, no-wrap
msgid ""
"char *foo;\n"
"strcpy(foo, \"bang!\");"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1256
msgid ""
"The pointer will have some random value that, with luck, will point into an "
"area of memory that is not available to your program and the kernel will "
"kill your program before it can do any damage. If you are unlucky, it will "
"point somewhere inside your own program and corrupt one of your data "
"structures, causing the program to fail mysteriously."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1266
msgid "Trying to access past the end of an array, eg"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1269
#, no-wrap
msgid ""
"int bar[20];\n"
"bar[27] = 6;"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1274
msgid "Trying to store something in read-only memory, eg"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1277
#, no-wrap
msgid ""
"char *foo = \"My string\";\n"
"strcpy(foo, \"bang!\");"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1280
msgid ""
"<trademark class=\"registered\">UNIX</trademark> compilers often put string "
"literals like <literal>\"My string\"</literal> into read-only areas of "
"memory."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1286
msgid ""
"Doing naughty things with <function>malloc()</function> and "
"<function>free()</function>, eg"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1290
#, no-wrap
msgid ""
"char bar[80];\n"
"free(bar);"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:1293
msgid "or"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:1295
#, no-wrap
msgid ""
"char *foo = malloc(27);\n"
"free(foo);\n"
"free(foo);"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1301
msgid ""
"Making one of these mistakes will not always lead to an error, but they are "
"always bad practice. Some systems and compilers are more tolerant than "
"others, which is why programs that ran well on one system can crash when you "
"try them on an another."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1311
msgid ""
"Sometimes when I get a core dump it says <errorname>bus error</errorname>. "
"It says in my <trademark class=\"registered\">UNIX</trademark> book that "
"this means a hardware problem, but the computer still seems to be working. "
"Is this true?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1319
msgid ""
"No, fortunately not (unless of course you really do have a hardware "
"problem…). This is usually another way of saying that you accessed memory in "
"a way you should not have."
msgstr ""

#. (itstool) path: question/para
#: book.translate.xml:1328
msgid ""
"This dumping core business sounds as though it could be quite useful, if I "
"can make it happen when I want to. Can I do this, or do I have to wait until "
"there is an error?"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1335
msgid "Yes, just go to another console or xterm, do"
msgstr ""

#. (itstool) path: answer/screen
#: book.translate.xml:1337
#, no-wrap
msgid "<prompt>%</prompt> <userinput>ps</userinput>"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1339
msgid "to find out the process ID of your program, and do"
msgstr ""

#. (itstool) path: answer/screen
#: book.translate.xml:1342
#, no-wrap
msgid "<prompt>%</prompt> <userinput>kill -ABRT <replaceable>pid</replaceable></userinput>"
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1344
msgid ""
"where <parameter><replaceable>pid</replaceable></parameter> is the process "
"ID you looked up."
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1348
msgid ""
"This is useful if your program has got stuck in an infinite loop, for "
"instance. If your program happens to trap <symbol>SIGABRT</symbol>, there "
"are several other signals which have a similar effect."
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1353
msgid ""
"Alternatively, you can create a core dump from inside your program, by "
"calling the <function>abort()</function> function. See the manual page of "
"<citerefentry><refentrytitle>abort</refentrytitle><manvolnum>3</manvolnum></"
"citerefentry> to learn more."
msgstr ""

#. (itstool) path: answer/para
#: book.translate.xml:1358
msgid ""
"If you want to create a core dump from outside your program, but do not want "
"the process to terminate, you can use the <command>gcore</command> program. "
"See the manual page of <citerefentry><refentrytitle>gcore</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry> for more information."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:1370
msgid "Make"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1373
msgid "What is <command>make</command>?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1375
msgid ""
"When you are working on a simple program with only one or two source files, "
"typing in"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:1378
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc file1.c file2.c</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1380
msgid ""
"is not too bad, but it quickly becomes very tedious when there are several "
"files—and it can take a while to compile, too."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1384
msgid ""
"One way to get around this is to use object files and only recompile the "
"source file if the source code has changed. So we could have something like:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:1388
#, no-wrap
msgid "<prompt>%</prompt> <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> …"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1390
msgid ""
"if we had changed <filename>file37.c</filename>, but not any of the others, "
"since the last time we compiled. This may speed up the compilation quite a "
"bit, but does not solve the typing problem."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1395
msgid ""
"Or we could write a shell script to solve the typing problem, but it would "
"have to re-compile everything, making it very inefficient on a large project."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1399
msgid ""
"What happens if we have hundreds of source files lying about? What if we are "
"working in a team with other people who forget to tell us when they have "
"changed one of their source files that we use?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1404
msgid ""
"Perhaps we could put the two solutions together and write something like a "
"shell script that would contain some kind of magic rule saying when a source "
"file needs compiling. Now all we need now is a program that can understand "
"these rules, as it is a bit too complicated for the shell."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1410
msgid ""
"This program is called <command>make</command>. It reads in a file, called a "
"<firstterm>makefile</firstterm>, that tells it how different files depend on "
"each other, and works out which files need to be re-compiled and which ones "
"do not. For example, a rule could say something like <quote>if "
"<filename>fromboz.o</filename> is older than <filename>fromboz.c</filename>, "
"that means someone must have changed <filename>fromboz.c</filename>, so it "
"needs to be re-compiled.</quote> The makefile also has rules telling make "
"<emphasis>how</emphasis> to re-compile the source file, making it a much "
"more powerful tool."
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:1428
msgid ""
"They do not use the <filename>MAKEFILE</filename> form as block capitals are "
"often used for documentation files like <filename>README</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1422
msgid ""
"Makefiles are typically kept in the same directory as the source they apply "
"to, and can be called <filename>makefile</filename>, <filename>Makefile</"
"filename> or <filename>MAKEFILE</filename>. Most programmers use the name "
"<filename>Makefile</filename>, as this puts it near the top of a directory "
"listing, where it can easily be seen.<_:footnote-1/>"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1435
msgid "Example of Using <command>make</command>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1437
msgid "Here is a very simple make file:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1439
#, no-wrap
msgid ""
"foo: foo.c\n"
"\tcc -o foo foo.c"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1442
msgid "It consists of two lines, a dependency line and a creation line."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1445
msgid ""
"The dependency line here consists of the name of the program (known as the "
"<firstterm>target</firstterm>), followed by a colon, then whitespace, then "
"the name of the source file. When <command>make</command> reads this line, "
"it looks to see if <filename>foo</filename> exists; if it exists, it "
"compares the time <filename>foo</filename> was last modified to the time "
"<filename>foo.c</filename> was last modified. If <filename>foo</filename> "
"does not exist, or is older than <filename>foo.c</filename>, it then looks "
"at the creation line to find out what to do. In other words, this is the "
"rule for working out when <filename>foo.c</filename> needs to be re-compiled."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1458
msgid ""
"The creation line starts with a <token>tab</token> (press <keycap>tab</"
"keycap>) and then the command you would type to create <filename>foo</"
"filename> if you were doing it at a command prompt. If <filename>foo</"
"filename> is out of date, or does not exist, <command>make</command> then "
"executes this command to create it. In other words, this is the rule which "
"tells make how to re-compile <filename>foo.c</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1467
msgid ""
"So, when you type <userinput>make</userinput>, it will make sure that "
"<filename>foo</filename> is up to date with respect to your latest changes "
"to <filename>foo.c</filename>. This principle can be extended to "
"<filename>Makefile</filename>s with hundreds of targets—in fact, on FreeBSD, "
"it is possible to compile the entire operating system just by typing "
"<userinput>make world</userinput> in the appropriate directory!"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1476
msgid ""
"Another useful property of makefiles is that the targets do not have to be "
"programs. For instance, we could have a make file that looks like this:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1480
#, no-wrap
msgid ""
"foo: foo.c\n"
"\tcc -o foo foo.c\n"
"\n"
"install:\n"
"\tcp foo /home/me"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1486
msgid "We can tell make which target we want to make by typing:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:1489
#, no-wrap
msgid "<prompt>%</prompt> <userinput>make <replaceable>target</replaceable></userinput>"
msgstr ""

#. (itstool) path: para/buildtarget
#: book.translate.xml:1494 book.translate.xml:1503 book.translate.xml:1506
msgid "install"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1491
msgid ""
"<command>make</command> will then only look at that target and ignore any "
"others. For example, if we type <userinput>make foo</userinput> with the "
"makefile above, make will ignore the <_:buildtarget-1/> target."
msgstr ""

#. (itstool) path: para/buildtarget
#: book.translate.xml:1501
msgid "foo"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1497
msgid ""
"If we just type <userinput>make</userinput> on its own, make will always "
"look at the first target and then stop without looking at any others. So if "
"we typed <userinput>make</userinput> here, it will just go to the <_:"
"buildtarget-1/> target, re-compile <filename>foo</filename> if necessary, "
"and then stop without going on to the <_:buildtarget-2/> target."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1506
msgid ""
"Notice that the <_:buildtarget-1/> target does not actually depend on "
"anything! This means that the command on the following line is always "
"executed when we try to make that target by typing <userinput>make install</"
"userinput>. In this case, it will copy <filename>foo</filename> into the "
"user's home directory. This is often used by application makefiles, so that "
"the application can be installed in the correct directory when it has been "
"correctly compiled."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1516
msgid ""
"This is a slightly confusing subject to try to explain. If you do not quite "
"understand how <command>make</command> works, the best thing to do is to "
"write a simple program like <quote>hello world</quote> and a make file like "
"the one above and experiment. Then progress to using more than one source "
"file, or having the source file include a header file. <command>touch</"
"command> is very useful here—it changes the date on a file without you "
"having to edit it."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1527
msgid "Make and include-files"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1529
msgid ""
"C code often starts with a list of files to include, for example stdio.h. "
"Some of these files are system-include files, some of them are from the "
"project you are now working on:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1534
#, no-wrap
msgid ""
"#include &lt;stdio.h&gt;\n"
"#include \"foo.h\"\n"
"\n"
"int main(...."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1539
msgid ""
"To make sure that this file is recompiled the moment <filename>foo.h</"
"filename> is changed, you have to add it in your <filename>Makefile</"
"filename>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1543
#, no-wrap
msgid "foo: foo.c foo.h"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1545
msgid ""
"The moment your project is getting bigger and you have more and more own "
"include-files to maintain, it will be a pain to keep track of all include "
"files and the files which are depending on it. If you change an include-file "
"but forget to recompile all the files which are depending on it, the results "
"will be devastating. <command>clang</command> has an option to analyze your "
"files and to produce a list of include-files and their dependencies: "
"<option>-MM</option>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1554
msgid "If you add this to your Makefile:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1556
#, no-wrap
msgid ""
"depend:\n"
"\tcc -E -MM *.c &gt; .depend"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1559
msgid ""
"and run <userinput>make depend</userinput>, the file <filename>.depend</"
"filename> will appear with a list of object-files, C-files and the include-"
"files:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1563
#, no-wrap
msgid "foo.o: foo.c foo.h"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1565
msgid ""
"If you change <filename>foo.h</filename>, next time you run <command>make</"
"command> all files depending on <filename>foo.h</filename> will be "
"recompiled."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1569
msgid ""
"Do not forget to run <command>make depend</command> each time you add an "
"include-file to one of your files."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1574
msgid "FreeBSD Makefiles"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1576
msgid ""
"Makefiles can be rather complicated to write. Fortunately, BSD-based systems "
"like FreeBSD come with some very powerful ones as part of the system. One "
"very good example of this is the FreeBSD ports system. Here is the essential "
"part of a typical ports <filename>Makefile</filename>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1583
#, no-wrap
msgid ""
"MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/\n"
"DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz\n"
"\n"
".include &lt;bsd.port.mk&gt;"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1588
msgid ""
"Now, if we go to the directory for this port and type <userinput>make</"
"userinput>, the following happens:"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1593
msgid ""
"A check is made to see if the source code for this port is already on the "
"system."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1598
msgid ""
"If it is not, an FTP connection to the URL in <symbol>MASTER_SITES</symbol> "
"is set up to download the source."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1604
msgid ""
"The checksum for the source is calculated and compared it with one for a "
"known, good, copy of the source. This is to make sure that the source was "
"not corrupted while in transit."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1611
msgid ""
"Any changes required to make the source work on FreeBSD are applied—this is "
"known as <firstterm>patching</firstterm>."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1617
msgid ""
"Any special configuration needed for the source is done. (Many <trademark "
"class=\"registered\">UNIX</trademark> program distributions try to work out "
"which version of <trademark class=\"registered\">UNIX</trademark> they are "
"being compiled on and which optional <trademark class=\"registered\">UNIX</"
"trademark> features are present—this is where they are given the information "
"in the FreeBSD ports scenario)."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1626
msgid ""
"The source code for the program is compiled. In effect, we change to the "
"directory where the source was unpacked and do <command>make</command>—the "
"program's own make file has the necessary information to build the program."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:1634
msgid ""
"We now have a compiled version of the program. If we wish, we can test it "
"now; when we feel confident about the program, we can type <userinput>make "
"install</userinput>. This will cause the program and any supporting files it "
"needs to be copied into the correct location; an entry is also made into a "
"<database>package database</database>, so that the port can easily be "
"uninstalled later if we change our mind about it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1645
msgid ""
"Now I think you will agree that is rather impressive for a four line script!"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1648
msgid ""
"The secret lies in the last line, which tells <command>make</command> to "
"look in the system makefile called <filename>bsd.port.mk</filename>. It is "
"easy to overlook this line, but this is where all the clever stuff comes from"
"—someone has written a makefile that tells <command>make</command> to do all "
"the things above (plus a couple of other things I did not mention, including "
"handling any errors that may occur) and anyone can get access to that just "
"by putting a single line in their own make file!"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1658
msgid ""
"If you want to have a look at these system makefiles, they are in <filename>/"
"usr/share/mk</filename>, but it is probably best to wait until you have had "
"a bit of practice with makefiles, as they are very complicated (and if you "
"do look at them, make sure you have a flask of strong coffee handy!)"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1667
msgid "More Advanced Uses of <command>make</command>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1669
msgid ""
"<command>Make</command> is a very powerful tool, and can do much more than "
"the simple example above shows. Unfortunately, there are several different "
"versions of <command>make</command>, and they all differ considerably. The "
"best way to learn what they can do is probably to read the documentation—"
"hopefully this introduction will have given you a base from which you can do "
"this."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1677
msgid ""
"The version of make that comes with FreeBSD is the <application>Berkeley "
"make</application>; there is a tutorial for it in <filename>/usr/share/doc/"
"psd/12.make</filename>. To view it, do"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:1682
#, no-wrap
msgid "<prompt>%</prompt> <userinput>zmore paper.ascii.gz</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1684
msgid "in that directory."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1686
msgid ""
"Many applications in the ports use <application>GNU make</application>, "
"which has a very good set of <quote>info</quote> pages. If you have "
"installed any of these ports, <application>GNU make</application> will "
"automatically have been installed as <command>gmake</command>. It is also "
"available as a port and package in its own right."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1693
msgid ""
"To view the info pages for <application>GNU make</application>, you will "
"have to edit <filename>dir</filename> in the <filename>/usr/local/info</"
"filename> directory to add an entry for it. This involves adding a line like"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:1699
#, no-wrap
msgid " * Make: (make).                 The GNU Make utility."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1701
msgid ""
"to the file. Once you have done this, you can type <userinput>info</"
"userinput> and then select <guimenuitem>make</guimenuitem> from the menu (or "
"in <application>Emacs</application>, do <userinput>C-h i</userinput>)."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:1710
msgid "Debugging"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1713
msgid "Introduction to Available Debuggers"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1715
msgid ""
"Using a debugger allows running the program under more controlled "
"circumstances. Typically, it is possible to step through the program a line "
"at a time, inspect the value of variables, change them, tell the debugger to "
"run up to a certain point and then stop, and so on. It is also possible to "
"attach to a program that is already running, or load a core file to "
"investigate why the program crashed. It is even possible to debug the "
"kernel, though that is a little trickier than the user applications we will "
"be discussing in this section."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1726
msgid ""
"This section is intended to be a quick introduction to using debuggers and "
"does not cover specialized topics such as debugging the kernel. For more "
"information about that, refer to <xref linkend=\"kerneldebug\"/>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1731
msgid ""
"The standard debugger supplied with FreeBSD 12.1 is called <command>lldb</"
"command> (<application>LLVM debugger</application>). As it is part of the "
"standard installation for that release, there is no need to do anything "
"special to use it. It has good command help, accessible via the "
"<userinput>help</userinput> command, as well as <link xlink:href=\"https://"
"lldb.llvm.org/\">a web tutorial and documentation</link>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:1741
msgid ""
"The <command>lldb</command> command is available for FreeBSD 11.3 <link "
"xlink:href=\"@@URL_RELPREFIX@@/doc/en_US.ISO8859-1/books/handbook/ports-"
"using.html\">from ports or packages</link> as <package>devel/llvm</package>. "
"This will install the default version of lldb (currently 9.0)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1748
msgid ""
"The other debugger available with FreeBSD is called <command>gdb</command> "
"(<application>GNU debugger</application>). Unlike lldb, it is not installed "
"by default on FreeBSD 12.1; to use it, <link xlink:href=\"@@URL_RELPREFIX@@/"
"doc/en_US.ISO8859-1/books/handbook/ports-using.html\">install</link> "
"<package>devel/gdb</package> from ports or packages. The version installed "
"by default on FreeBSD 11.3 is old; instead, install <package>devel/gdb</"
"package> there as well. It has quite good on-line help, as well as a set of "
"info pages."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:1758
msgid ""
"Which one to use is largely a matter of taste. If familiar with one only, "
"use that one. People familiar with neither or both but wanting to use one "
"from inside <application>Emacs</application> will need to use <command>gdb</"
"command> as <command>lldb</command> is unsupported by <application>Emacs</"
"application>. Otherwise, try both and see which one you prefer."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:1768
msgid "Using lldb"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:1771
msgid "Starting lldb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1773
msgid "Start up lldb by typing"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1775
#, no-wrap
msgid "<prompt>%</prompt> <userinput>lldb -- <replaceable>progname</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:1779
msgid "Running a Program with lldb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1781
msgid ""
"Compile the program with <option>-g</option> to get the most out of using "
"<command>lldb</command>. It will work without, but will only display the "
"name of the function currently running, instead of the source code. If it "
"displays a line like:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1787
#, no-wrap
msgid "Breakpoint 1: where = temp`main, address = …"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1789
msgid ""
"(without an indication of source code filename and line number) when setting "
"a breakpoint, this means that the program was not compiled with <option>-g</"
"option>."
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:1794
msgid ""
"Most <command>lldb</command> commands have shorter forms that can be used "
"instead. The longer forms are used here for clarity."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1799
msgid ""
"At the <command>lldb</command> prompt, type <userinput>breakpoint set -n "
"main</userinput>. This will tell the debugger not to display the preliminary "
"set-up code in the program being run and to stop execution at the beginning "
"of the program's code. Now type <userinput>process launch</userinput> to "
"actually start the program— it will start at the beginning of the set-up "
"code and then get stopped by the debugger when it calls <function>main()</"
"function>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1809
msgid ""
"To step through the program a line at a time, type <userinput>thread step-"
"over</userinput>. When the program gets to a function call, step into it by "
"typing <userinput>thread step-in</userinput>. Once in a function call, "
"return from it by typing <userinput>thread step-out</userinput> or use "
"<userinput>up</userinput> and <userinput>down</userinput> to take a quick "
"look at the caller."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1818
msgid ""
"Here is a simple example of how to spot a mistake in a program with "
"<command>lldb</command>. This is our program (with a deliberate mistake):"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:1822 book.translate.xml:2140
#, no-wrap
msgid ""
"#include &lt;stdio.h&gt;\n"
"\n"
"int bazz(int anint);\n"
"\n"
"main() {\n"
"\tint i;\n"
"\n"
"\tprintf(\"This is my program\\n\");\n"
"\tbazz(i);\n"
"\treturn 0;\n"
"}\n"
"\n"
"int bazz(int anint) {\n"
"\tprintf(\"You gave me %d\\n\", anint);\n"
"\treturn anint;\n"
"}"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1839 book.translate.xml:2157
msgid ""
"This program sets <symbol>i</symbol> to be <literal>5</literal> and passes "
"it to a function <function>bazz()</function> which prints out the number we "
"gave it."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1844 book.translate.xml:2162
msgid "Compiling and running the program displays"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1846
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cc -g -o temp temp.c</userinput>\n"
"<prompt>%</prompt> <userinput>./temp</userinput>\n"
"This is my program\n"
"anint = -5360"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1851
msgid "That is not what was expected! Time to see what is going on!"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1854
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>lldb -- temp</userinput>\n"
"(lldb) target create \"temp\"\n"
"Current executable set to 'temp' (x86_64).\n"
"(lldb) <userinput>breakpoint set -n main</userinput>\t\t\t\t<lineannotation>Skip the set-up code</lineannotation>\n"
"Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef\t<lineannotation>lldb puts breakpoint at main()</lineannotation>\n"
"(lldb) <userinput>process launch</userinput>\t\t\t\t\t<lineannotation>Run as far as main()</lineannotation>\n"
"Process 9992 launching\n"
"Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64)\t<lineannotation>Program starts running</lineannotation>\n"
"\n"
"Process 9992 stopped\n"
"* thread #1, name = 'temp', stop reason = breakpoint 1.1\t<lineannotation>lldb stops at main()</lineannotation>\n"
"    frame #0: 0x00000000002012ef temp`main at temp.c:8:2\n"
"   5\tmain() {\n"
"   6\t\tint i;\n"
"   7\n"
"-&gt; 8\t\tprintf(\"This is my program\\n\");\t\t\t<lineannotation>Indicates the line where it stopped</lineannotation>\n"
"   9\t\tbazz(i);\n"
"   10\t\treturn 0;\n"
"   11\t}\n"
"(lldb) <userinput>thread step-over</userinput>\t\t\t<lineannotation>Go to next line</lineannotation>\n"
"This is my program\t\t\t\t\t\t<lineannotation>Program prints out</lineannotation>\n"
"Process 9992 stopped\n"
"* thread #1, name = 'temp', stop reason = step over\n"
"    frame #0: 0x0000000000201300 temp`main at temp.c:9:7\n"
"   6\t\tint i;\n"
"   7\n"
"   8\t\tprintf(\"This is my program\\n\");\n"
"-&gt; 9\t\tbazz(i);\n"
"   10\t\treturn 0;\n"
"   11\t}\n"
"   12\n"
"(lldb) <userinput>thread step-in</userinput>\t\t\t<lineannotation>step into bazz()</lineannotation>\n"
"Process 9992 stopped\n"
"* thread #1, name = 'temp', stop reason = step in\n"
"    frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29\t<lineannotation>lldb displays stack frame</lineannotation>\n"
"   11\t}\n"
"   12\n"
"   13\tint bazz(int anint) {\n"
"-&gt; 14\t\tprintf(\"You gave me %d\\n\", anint);\n"
"   15\t\treturn anint;\n"
"   16\t}\n"
"(lldb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1897
msgid ""
"Hang on a minute! How did <symbol>anint</symbol> get to be <literal>-5360</"
"literal>? Was it not set to <literal>5</literal> in <function>main()</"
"function>? Let us move up to <function>main()</function> and have a look."
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1903
#, no-wrap
msgid ""
"(lldb) <userinput>up</userinput>\t\t<lineannotation>Move up call stack</lineannotation>\n"
"frame #1: 0x000000000020130b temp`main at temp.c:9:2\t\t<lineannotation>lldb displays stack frame</lineannotation>\n"
"   6\t\tint i;\n"
"   7\n"
"   8\t\tprintf(\"This is my program\\n\");\n"
"-&gt; 9\t\tbazz(i);\n"
"   10\t\treturn 0;\n"
"   11\t}\n"
"   12\n"
"(lldb) <userinput>frame variable i</userinput>\t\t\t<lineannotation>Show us the value of i</lineannotation>\n"
"(int) i = -5360\t\t\t\t\t\t\t<lineannotation>lldb displays -5360</lineannotation>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1915 book.translate.xml:2199
msgid ""
"Oh dear! Looking at the code, we forgot to initialize <symbol>i</symbol>. We "
"meant to put"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:1918 book.translate.xml:2202
#, no-wrap
msgid ""
"<lineannotation>…</lineannotation>\n"
"main() {\n"
"\tint i;\n"
"\n"
"\ti = 5;\n"
"\tprintf(\"This is my program\\n\");\n"
"<lineannotation>…</lineannotation>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1926
msgid ""
"but we left the <literal>i=5;</literal> line out. As we did not initialize "
"<symbol>i</symbol>, it had whatever number happened to be in that area of "
"memory when the program ran, which in this case happened to be "
"<literal>-5360</literal>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:1933
msgid ""
"The <command>lldb</command> command displays the stack frame every time we "
"go into or out of a function, even if we are using <userinput>up</userinput> "
"and <userinput>down</userinput> to move around the call stack. This shows "
"the name of the function and the values of its arguments, which helps us "
"keep track of where we are and what is going on. (The stack is a storage "
"area where the program stores information about the arguments passed to "
"functions and where to go when it returns from a function call.)"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:1947
msgid "Examining a Core File with lldb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1949 book.translate.xml:2232
msgid ""
"A core file is basically a file which contains the complete state of the "
"process when it crashed. In <quote>the good old days</quote>, programmers "
"had to print out hex listings of core files and sweat over machine code "
"manuals, but now life is a bit easier. Incidentally, under FreeBSD and other "
"4.4BSD systems, a core file is called <filename><replaceable>progname</"
"replaceable>.core</filename> instead of just <filename>core</filename>, to "
"make it clearer which program a core file belongs to."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1959
msgid ""
"To examine a core file, specify the name of the core file in addition to the "
"program itself. Instead of starting up <command>lldb</command> in the usual "
"way, type <userinput>lldb -c <replaceable>progname</replaceable>.core -- "
"<replaceable>progname</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1965
msgid "The debugger will display something like this:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1967
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>lldb -c <filename><replaceable>progname</replaceable>.core</filename> -- <filename><replaceable>progname</replaceable></filename></userinput>\n"
"(lldb) target create \"<filename><replaceable>progname</replaceable></filename>\" --core \"<filename><replaceable>progname</replaceable></filename>.core\"\n"
"Core file '/home/pauamma/tmp/<filename><replaceable>progname</replaceable>.core</filename>' (x86_64) was loaded.\n"
"(lldb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1972
msgid ""
"In this case, the program was called <filename><replaceable>progname</"
"replaceable></filename>, so the core file is called "
"<filename><replaceable>progname</replaceable>.core</filename>. The debugger "
"does not display why the program crashed or where. For this, use "
"<userinput>thread backtrace all</userinput>. This will also show how the "
"function where the program dumped core was called."
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:1982
#, no-wrap
msgid ""
"(lldb) <userinput>thread backtrace all</userinput>\n"
"* thread #1, name = '<filename><replaceable>progname</replaceable></filename>', stop reason = signal SIGSEGV\n"
"  * frame #0: 0x0000000000201347 <filename><replaceable>progname</replaceable></filename>`bazz(anint=5) at temp2.c:17:10\n"
"    frame #1: 0x0000000000201312 <filename><replaceable>progname</replaceable></filename>`main at temp2.c:10:2\n"
"    frame #2: 0x000000000020110f <filename><replaceable>progname</replaceable></filename>`_start(ap=&lt;unavailable&gt;, cleanup=&lt;unavailable&gt;) at crt1.c:76:7\n"
"(lldb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:1989
msgid ""
"<literal>SIGSEGV</literal> indicates that the program tried to access memory "
"(run code or read/write data usually) at a location that does not belong to "
"it, but does not give any specifics. For that, look at the source code at "
"line 10 of file temp2.c, in <function>bazz()</function>. The backtrace also "
"says that in this case, <function>bazz()</function> was called from "
"<function>main()</function>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2000
msgid "Attaching to a Running Program with lldb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2002
msgid ""
"One of the neatest features about <command>lldb</command> is that it can "
"attach to a program that is already running. Of course, that requires "
"sufficient permissions to do so. A common problem is stepping through a "
"program that forks and wanting to trace the child, but the debugger will "
"only trace the parent."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2010
msgid ""
"To do that, start up another <command>lldb</command>, use <command>ps</"
"command> to find the process ID for the child, and do"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2014
#, no-wrap
msgid "(lldb) <userinput>process attach -p <replaceable>pid</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2016
msgid "in <command>lldb</command>, and then debug as usual."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2019 book.translate.xml:2308
msgid ""
"For that to work well, the code that calls <function>fork</function> to "
"create the child needs to do something like the following (courtesy of the "
"<command>gdb</command> info pages):"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:2024 book.translate.xml:2313
#, no-wrap
msgid ""
"<lineannotation>…</lineannotation>\n"
"if ((pid = fork()) &lt; 0)\t\t/* _Always_ check this */\n"
"\terror();\n"
"else if (pid == 0) {\t\t/* child */\n"
"\tint PauseMode = 1;\n"
"\n"
"\twhile (PauseMode)\n"
"\t\tsleep(10);\t/* Wait until someone attaches to us */\n"
"\t<lineannotation>…</lineannotation>\n"
"} else {\t\t\t/* parent */\n"
"\t<lineannotation>…</lineannotation>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2036
msgid ""
"Now all that is needed is to attach to the child, set <symbol>PauseMode</"
"symbol> to <literal>0</literal> with <userinput>expr PauseMode = 0</"
"userinput> and wait for the <function>sleep()</function> call to return."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2043
msgid "Remote Debugging Using LLDB"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:2046
msgid ""
"The described functionality is available starting with LLDB version 12.0.0. "
"Users of FreeBSD releases containing an earlier LLDB version may wish to use "
"the snapshot available in <link xlink:href=\"@@URL_RELPREFIX@@/doc/en_US."
"ISO8859-1/books/handbook/ports-using.html\">ports or packages</link>, as "
"<package>devel/llvm-devel</package>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2054
msgid ""
"Starting with LLDB 12.0.0, remote debugging is supported on FreeBSD. This "
"means that <command>lldb-server</command> can be started to debug a program "
"on one host, while the interactive <command>lldb</command> client connects "
"to it from another one."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2060
msgid ""
"To launch a new process to be debugged remotely, run <command>lldb-server</"
"command> on the remote server by typing"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2064
#, no-wrap
msgid "<prompt>%</prompt> <userinput>lldb-server g <replaceable>host:port</replaceable> -- <replaceable>progname</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2066
msgid ""
"The process will be stopped immediately after launching, and <command>lldb-"
"server</command> will wait for the client to connect."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2070
msgid ""
"Start <command>lldb</command> locally and type the following command to "
"connect to the remote server:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2074
#, no-wrap
msgid "(lldb) <userinput>gdb-remote <replaceable>host:port</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2076
msgid ""
"<command>lldb-server</command> can also attach to a running process. To do "
"that, type the following on the remote server:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2080
#, no-wrap
msgid "<prompt>%</prompt> <userinput>lldb-server g <replaceable>host:port</replaceable> --attach <replaceable>pid-or-name</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:2085
msgid "Using gdb"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2088
msgid "Starting gdb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2090
msgid "Start up gdb by typing"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2092
#, no-wrap
msgid "<prompt>%</prompt> <userinput>gdb <replaceable>progname</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2094
msgid ""
"although many people prefer to run it inside <application>Emacs</"
"application>. To do this, type:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2097
#, no-wrap
msgid "<userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2099
msgid ""
"Finally, for those finding its text-based command-prompt style off-putting, "
"there is a graphical front-end for it (<package>devel/xxgdb</package>) in "
"the Ports Collection."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2107
msgid "Running a Program with gdb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2109
msgid ""
"Compile the program with <option>-g</option> to get the most out of using "
"<command>gdb</command>. It will work without, but will only display the name "
"of the function currently running, instead of the source code. A line like:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2115
#, no-wrap
msgid "… (no debugging symbols found) …"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2117
msgid ""
"when <command>gdb</command> starts up means that the program was not "
"compiled with <option>-g</option>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2120
msgid ""
"At the <command>gdb</command> prompt, type <userinput>break main</"
"userinput>. This will tell the debugger to skip the preliminary set-up code "
"in the program being run and to stop execution at the beginning of the "
"program's code. Now type <userinput>run</userinput> to start the program— it "
"will start at the beginning of the set-up code and then get stopped by the "
"debugger when it calls <function>main()</function>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2129
msgid ""
"To step through the program a line at a time, press <command>n</command>. "
"When at a function call, step into it by pressing <command>s</command>. Once "
"in a function call, return from it by pressing <command>f</command>, or use "
"<command>up</command> and <command>down</command> to take a quick look at "
"the caller."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2136
msgid ""
"Here is a simple example of how to spot a mistake in a program with "
"<command>gdb</command>. This is our program (with a deliberate mistake):"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2164
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cc -g -o temp temp.c</userinput>\n"
"<prompt>%</prompt> <userinput>./temp</userinput>\n"
"This is my program\n"
"anint = 4231"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2169
msgid "That was not what we expected! Time to see what is going on!"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2172
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>gdb temp</userinput>\n"
"GDB is free software and you are welcome to distribute copies of it\n"
" under certain conditions; type \"show copying\" to see the conditions.\n"
"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
"(gdb) <userinput>break main</userinput>\t\t\t\t<lineannotation>Skip the set-up code</lineannotation>\n"
"Breakpoint 1 at 0x160f: file temp.c, line 9.\t<lineannotation>gdb puts breakpoint at main()</lineannotation>\n"
"(gdb) <userinput>run</userinput>\t\t\t\t\t<lineannotation>Run as far as main()</lineannotation>\n"
"Starting program: /home/james/tmp/temp\t\t<lineannotation>Program starts running</lineannotation>\n"
"\n"
"Breakpoint 1, main () at temp.c:9\t\t<lineannotation>gdb stops at main()</lineannotation>\n"
"(gdb) <userinput>n</userinput>\t\t\t\t\t\t<lineannotation>Go to next line</lineannotation>\n"
"This is my program\t\t\t\t<lineannotation>Program prints out</lineannotation>\n"
"(gdb) <userinput>s</userinput>\t\t\t\t\t\t<lineannotation>step into bazz()</lineannotation>\n"
"bazz (anint=4231) at temp.c:17\t\t\t<lineannotation>gdb displays stack frame</lineannotation>\n"
"(gdb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2189
msgid ""
"Hang on a minute! How did <symbol>anint</symbol> get to be <literal>4231</"
"literal>? Was it not set to <literal>5</literal> in <function>main()</"
"function>? Let us move up to <function>main()</function> and have a look."
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2194
#, no-wrap
msgid ""
"(gdb) <userinput>up</userinput>\t\t\t\t\t<lineannotation>Move up call stack</lineannotation>\n"
"#1  0x1625 in main () at temp.c:11\t\t<lineannotation>gdb displays stack frame</lineannotation>\n"
"(gdb) <userinput>p i</userinput>\t\t\t\t\t<lineannotation>Show us the value of i</lineannotation>\n"
"$1 = 4231\t\t\t\t\t<lineannotation>gdb displays 4231</lineannotation>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2210
msgid ""
"but we left the <literal>i=5;</literal> line out. As we did not initialize "
"<symbol>i</symbol>, it had whatever number happened to be in that area of "
"memory when the program ran, which in this case happened to be "
"<literal>4231</literal>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:2217
msgid ""
"The <command>gdb</command> command displays the stack frame every time we go "
"into or out of a function, even if we are using <command>up</command> and "
"<command>down</command> to move around the call stack. This shows the name "
"of the function and the values of its arguments, which helps us keep track "
"of where we are and what is going on. (The stack is a storage area where the "
"program stores information about the arguments passed to functions and where "
"to go when it returns from a function call.)"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2230
msgid "Examining a Core File with gdb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2242
msgid ""
"To examine a core file, start up <command>gdb</command> in the usual way. "
"Instead of typing <command>break</command> or <command>run</command>, type"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2246
#, no-wrap
msgid "(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2248
msgid ""
"If the core file is not in the current directory, type <userinput>dir /path/"
"to/core/file</userinput> first."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2251
msgid "The debugger should display something like this:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2253
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>gdb <filename><replaceable>progname</replaceable></filename></userinput>\n"
"GDB is free software and you are welcome to distribute copies of it\n"
" under certain conditions; type \"show copying\" to see the conditions.\n"
"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
"GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.\n"
"(gdb) <userinput>core <filename><replaceable>progname</replaceable>.core</filename></userinput>\n"
"Core was generated by `<filename><replaceable>progname</replaceable></filename>'.\n"
"Program terminated with signal 11, Segmentation fault.\n"
"Cannot access memory at address 0x7020796d.\n"
"#0  0x164a in bazz (anint=0x5) at temp.c:17\n"
"(gdb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2265
msgid ""
"In this case, the program was called <filename><replaceable>progname</"
"replaceable></filename>, so the core file is called "
"<filename><replaceable>progname</replaceable>.core</filename>. We can see "
"that the program crashed due to trying to access an area in memory that was "
"not available to it in a function called <function>bazz</function>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2273
msgid ""
"Sometimes it is useful to be able to see how a function was called, as the "
"problem could have occurred a long way up the call stack in a complex "
"program. <command>bt</command> causes <command>gdb</command> to print out a "
"back-trace of the call stack:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2279
#, no-wrap
msgid ""
"(gdb) <userinput>bt</userinput>\n"
"#0  0x164a in bazz (anint=0x5) at temp.c:17\n"
"#1  0xefbfd888 in end ()\n"
"#2  0x162c in main () at temp.c:11\n"
"(gdb)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2285
msgid ""
"The <function>end()</function> function is called when a program crashes; in "
"this case, the <function>bazz()</function> function was called from "
"<function>main()</function>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:2291
msgid "Attaching to a Running Program with gdb"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2293
msgid ""
"One of the neatest features about <command>gdb</command> is that it can "
"attach to a program that is already running. Of course, that requires "
"sufficient permissions to do so. A common problem is stepping through a "
"program that forks and wanting to trace the child, but the debugger will "
"only trace the parent."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2300
msgid ""
"To do that, start up another <command>gdb</command>, use <command>ps</"
"command> to find the process ID for the child, and do"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:2304
#, no-wrap
msgid "(gdb) <userinput>attach <replaceable>pid</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2306
msgid "in <command>gdb</command>, and then debug as usual."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:2325
msgid ""
"Now all that is needed is to attach to the child, set <symbol>PauseMode</"
"symbol> to <literal>0</literal>, and wait for the <function>sleep()</"
"function> call to return!"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:2333
msgid "Using Emacs as a Development Environment"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:2336
msgid "Emacs"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2338
msgid ""
"Emacs is a highly customizable editor—indeed, it has been customized to the "
"point where it is more like an operating system than an editor! Many "
"developers and sysadmins do in fact spend practically all their time working "
"inside Emacs, leaving it only to log out."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2345
msgid ""
"It is impossible even to summarize everything Emacs can do here, but here "
"are some of the features of interest to developers:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2351
msgid ""
"Very powerful editor, allowing search-and-replace on both strings and "
"regular expressions (patterns), jumping to start/end of block expression, "
"etc, etc."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2357
msgid "Pull-down menus and online help."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2361
msgid "Language-dependent syntax highlighting and indentation."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2366
msgid "Completely customizable."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2370
msgid "You can compile and debug programs within Emacs."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2375
msgid ""
"On a compilation error, you can jump to the offending line of source code."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2380
msgid ""
"Friendly-ish front-end to the <command>info</command> program used for "
"reading GNU hypertext documentation, including the documentation on Emacs "
"itself."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2386
msgid ""
"Friendly front-end to <command>gdb</command>, allowing you to look at the "
"source code as you step through your program."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2392
msgid "And doubtless many more that have been overlooked."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2394
msgid ""
"Emacs can be installed on FreeBSD using the <package>editors/emacs</package> "
"port."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2398
msgid ""
"Once it is installed, start it up and do <literal>C-h t</literal> to read an "
"Emacs tutorial—that means hold down <keycap>control</keycap>, press "
"<keycap>h</keycap>, let go of <keycap>control</keycap>, and then press "
"<keycap>t</keycap>. (Alternatively, you can use the mouse to select "
"<guimenuitem>Emacs Tutorial</guimenuitem> from the <guimenu>Help</guimenu> "
"menu.)"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2406
msgid ""
"Although Emacs does have menus, it is well worth learning the key bindings, "
"as it is much quicker when you are editing something to press a couple of "
"keys than to try to find the mouse and then click on the right place. And, "
"when you are talking to seasoned Emacs users, you will find they often "
"casually throw around expressions like <quote><literal>M-x replace-s RET foo "
"RET bar RET</literal></quote> so it is useful to know what they mean. And in "
"any case, Emacs has far too many useful functions for them to all fit on the "
"menu bars."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2417
msgid ""
"Fortunately, it is quite easy to pick up the key-bindings, as they are "
"displayed next to the menu item. My advice is to use the menu item for, say, "
"opening a file until you understand how it works and feel confident with it, "
"then try doing C-x C-f. When you are happy with that, move on to another "
"menu command."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2424
msgid ""
"If you cannot remember what a particular combination of keys does, select "
"<guimenuitem>Describe Key</guimenuitem> from the <guimenu>Help</guimenu> "
"menu and type it in—Emacs will tell you what it does. You can also use the "
"<guimenuitem>Command Apropos</guimenuitem> menu item to find out all the "
"commands which contain a particular word in them, with the key binding next "
"to it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2432
msgid ""
"By the way, the expression above means hold down the <keysym>Meta</keysym> "
"key, press <keysym>x</keysym>, release the <keysym>Meta</keysym> key, type "
"<userinput>replace-s</userinput> (short for <literal>replace-string</literal>"
"—another feature of Emacs is that you can abbreviate commands), press the "
"<keysym>return</keysym> key, type <userinput>foo</userinput> (the string you "
"want replaced), press the <keysym>return</keysym> key, type bar (the string "
"you want to replace <literal>foo</literal> with) and press <keysym>return</"
"keysym> again. Emacs will then do the search-and-replace operation you have "
"just requested."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2445
msgid ""
"If you are wondering what on earth <keysym>Meta</keysym> is, it is a special "
"key that many <trademark class=\"registered\">UNIX</trademark> workstations "
"have. Unfortunately, PC's do not have one, so it is usually <keycap>alt</"
"keycap> (or if you are unlucky, the <keysym>escape</keysym> key)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2451
msgid ""
"Oh, and to get out of Emacs, do <command>C-x C-c</command> (that means hold "
"down the <keysym>control</keysym> key, press <keysym>x</keysym>, press "
"<keysym>c</keysym> and release the <keysym>control</keysym> key). If you "
"have any unsaved files open, Emacs will ask you if you want to save them. "
"(Ignore the bit in the documentation where it says <command>C-z</command> is "
"the usual way to leave Emacs—that leaves Emacs hanging around in the "
"background, and is only really useful if you are on a system which does not "
"have virtual terminals)."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:2464
msgid "Configuring Emacs"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2466
msgid ""
"Emacs does many wonderful things; some of them are built in, some of them "
"need to be configured."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2469
msgid ""
"Instead of using a proprietary macro language for configuration, Emacs uses "
"a version of Lisp specially adapted for editors, known as Emacs Lisp. "
"Working with Emacs Lisp can be quite helpful if you want to go on and learn "
"something like Common Lisp. Emacs Lisp has many features of Common Lisp, "
"although it is considerably smaller (and thus easier to master)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2477
msgid ""
"The best way to learn Emacs Lisp is to download the <link xlink:href=\"ftp://"
"ftp.gnu.org/old-gnu/emacs/elisp-manual-19-2.4.tar.gz\">Emacs Tutorial</link>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2480
msgid ""
"However, there is no need to actually know any Lisp to get started with "
"configuring Emacs, as I have included a sample <filename>.emacs</filename>, "
"which should be enough to get you started. Just copy it into your home "
"directory and restart Emacs if it is already running; it will read the "
"commands from the file and (hopefully) give you a useful basic setup."
msgstr ""

#. (itstool) path: sect2/title
#. (itstool) path: example/title
#: book.translate.xml:2489 book.translate.xml:2557
msgid "A Sample <filename>.emacs</filename>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2491
msgid ""
"Unfortunately, there is far too much here to explain it in detail; however "
"there are one or two points worth mentioning."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2497
msgid ""
"Everything beginning with a <literal>;</literal> is a comment and is ignored "
"by Emacs."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2502
msgid ""
"In the first line, the <literal>-*- Emacs-Lisp -*-</literal> is so that we "
"can edit <filename>.emacs</filename> itself within Emacs and get all the "
"fancy features for editing Emacs Lisp. Emacs usually tries to guess this "
"based on the filename, and may not get it right for <filename>.emacs</"
"filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2512
msgid ""
"The <keysym>tab</keysym> key is bound to an indentation function in some "
"modes, so when you press the tab key, it will indent the current line of "
"code. If you want to put a <token>tab</token> character in whatever you are "
"writing, hold the <keysym>control</keysym> key down while you are pressing "
"the <keysym>tab</keysym> key."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2522
msgid ""
"This file supports syntax highlighting for C, C++, Perl, Lisp and Scheme, by "
"guessing the language from the filename."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2528
msgid ""
"Emacs already has a pre-defined function called <function>next-error</"
"function>. In a compilation output window, this allows you to move from one "
"compilation error to the next by doing <command>M-n</command>; we define a "
"complementary function, <function>previous-error</function>, that allows you "
"to go to a previous error by doing <command>M-p</command>. The nicest "
"feature of all is that <command>C-c C-c</command> will open up the source "
"file in which the error occurred and jump to the appropriate line."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2541
msgid ""
"We enable Emacs's ability to act as a server, so that if you are doing "
"something outside Emacs and you want to edit a file, you can just type in"
msgstr ""

#. (itstool) path: listitem/screen
#: book.translate.xml:2545
#, no-wrap
msgid "<prompt>%</prompt> <userinput>emacsclient <replaceable>filename</replaceable></userinput>"
msgstr ""

#. (itstool) path: footnote/para
#: book.translate.xml:2548
msgid ""
"Many Emacs users set their <envar>EDITOR</envar> environment to "
"<literal>emacsclient</literal> so this happens every time they need to edit "
"a file."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2547
msgid "and then you can edit the file in your Emacs!<_:footnote-1/>"
msgstr ""

#. (itstool) path: example/programlisting
#: book.translate.xml:2559
#, no-wrap
msgid ""
";; -*-Emacs-Lisp-*-\n"
"\n"
";; This file is designed to be re-evaled; use the variable first-time\n"
";; to avoid any problems with this.\n"
"(defvar first-time t\n"
"  \"Flag signifying this is the first time that .emacs has been evaled\")\n"
"\n"
";; Meta\n"
"(global-set-key \"\\M- \" 'set-mark-command)\n"
"(global-set-key \"\\M-\\C-h\" 'backward-kill-word)\n"
"(global-set-key \"\\M-\\C-r\" 'query-replace)\n"
"(global-set-key \"\\M-r\" 'replace-string)\n"
"(global-set-key \"\\M-g\" 'goto-line)\n"
"(global-set-key \"\\M-h\" 'help-command)\n"
"\n"
";; Function keys\n"
"(global-set-key [f1] 'manual-entry)\n"
"(global-set-key [f2] 'info)\n"
"(global-set-key [f3] 'repeat-complex-command)\n"
"(global-set-key [f4] 'advertised-undo)\n"
"(global-set-key [f5] 'eval-current-buffer)\n"
"(global-set-key [f6] 'buffer-menu)\n"
"(global-set-key [f7] 'other-window)\n"
"(global-set-key [f8] 'find-file)\n"
"(global-set-key [f9] 'save-buffer)\n"
"(global-set-key [f10] 'next-error)\n"
"(global-set-key [f11] 'compile)\n"
"(global-set-key [f12] 'grep)\n"
"(global-set-key [C-f1] 'compile)\n"
"(global-set-key [C-f2] 'grep)\n"
"(global-set-key [C-f3] 'next-error)\n"
"(global-set-key [C-f4] 'previous-error)\n"
"(global-set-key [C-f5] 'display-faces)\n"
"(global-set-key [C-f8] 'dired)\n"
"(global-set-key [C-f10] 'kill-compilation)\n"
"\n"
";; Keypad bindings\n"
"(global-set-key [up] \"\\C-p\")\n"
"(global-set-key [down] \"\\C-n\")\n"
"(global-set-key [left] \"\\C-b\")\n"
"(global-set-key [right] \"\\C-f\")\n"
"(global-set-key [home] \"\\C-a\")\n"
"(global-set-key [end] \"\\C-e\")\n"
"(global-set-key [prior] \"\\M-v\")\n"
"(global-set-key [next] \"\\C-v\")\n"
"(global-set-key [C-up] \"\\M-\\C-b\")\n"
"(global-set-key [C-down] \"\\M-\\C-f\")\n"
"(global-set-key [C-left] \"\\M-b\")\n"
"(global-set-key [C-right] \"\\M-f\")\n"
"(global-set-key [C-home] \"\\M-&lt;\")\n"
"(global-set-key [C-end] \"\\M-&gt;\")\n"
"(global-set-key [C-prior] \"\\M-&lt;\")\n"
"(global-set-key [C-next] \"\\M-&gt;\")\n"
"\n"
";; Mouse\n"
"(global-set-key [mouse-3] 'imenu)\n"
"\n"
";; Misc\n"
"(global-set-key [C-tab] \"\\C-q\\t\")\t; Control tab quotes a tab.\n"
"(setq backup-by-copying-when-mismatch t)\n"
"\n"
";; Treat 'y' or &lt;CR&gt; as yes, 'n' as no.\n"
"(fset 'yes-or-no-p 'y-or-n-p)\n"
"(define-key query-replace-map [return] 'act)\n"
"(define-key query-replace-map [?\\C-m] 'act)\n"
"\n"
";; Load packages\n"
"(require 'desktop)\n"
"(require 'tar-mode)\n"
"\n"
";; Pretty diff mode\n"
"(autoload 'ediff-buffers \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
"(autoload 'ediff-files \"ediff\" \"Intelligent Emacs interface to diff\" t)\n"
"(autoload 'ediff-files-remote \"ediff\"\n"
"  \"Intelligent Emacs interface to diff\")\n"
"\n"
"(if first-time\n"
"    (setq auto-mode-alist\n"
"\t  (append '((\"\\\\.cpp$\" . c++-mode)\n"
"\t\t    (\"\\\\.hpp$\" . c++-mode)\n"
"\t\t    (\"\\\\.lsp$\" . lisp-mode)\n"
"\t\t    (\"\\\\.scm$\" . scheme-mode)\n"
"\t\t    (\"\\\\.pl$\" . perl-mode)\n"
"\t\t    ) auto-mode-alist)))\n"
"\n"
";; Auto font lock mode\n"
"(defvar font-lock-auto-mode-list\n"
"  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
"  \"List of modes to always start in font-lock-mode\")\n"
"\n"
"(defvar font-lock-mode-keyword-alist\n"
"  '((c++-c-mode . c-font-lock-keywords)\n"
"    (perl-mode . perl-font-lock-keywords))\n"
"  \"Associations between modes and keywords\")\n"
"\n"
"(defun font-lock-auto-mode-select ()\n"
"  \"Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list\"\n"
"  (if (memq major-mode font-lock-auto-mode-list)\n"
"      (progn\n"
"\t(font-lock-mode t))\n"
"    )\n"
"  )\n"
"\n"
"(global-set-key [M-f1] 'font-lock-fontify-buffer)\n"
"\n"
";; New dabbrev stuff\n"
";(require 'new-dabbrev)\n"
"(setq dabbrev-always-check-other-buffers t)\n"
"(setq dabbrev-abbrev-char-regexp \"\\\\sw\\\\|\\\\s_\")\n"
"(add-hook 'emacs-lisp-mode-hook\n"
"\t  '(lambda ()\n"
"\t     (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
"\t     (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
"(add-hook 'c-mode-hook\n"
"\t  '(lambda ()\n"
"\t     (set (make-local-variable 'dabbrev-case-fold-search) nil)\n"
"\t     (set (make-local-variable 'dabbrev-case-replace) nil)))\n"
"(add-hook 'text-mode-hook\n"
"\t  '(lambda ()\n"
"\t     (set (make-local-variable 'dabbrev-case-fold-search) t)\n"
"\t     (set (make-local-variable 'dabbrev-case-replace) t)))\n"
"\n"
";; C++ and C mode...\n"
"(defun my-c++-mode-hook ()\n"
"  (setq tab-width 4)\n"
"  (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
"  (define-key c++-mode-map \"\\C-ce\" 'c-comment-edit)\n"
"  (setq c++-auto-hungry-initial-state 'none)\n"
"  (setq c++-delete-function 'backward-delete-char)\n"
"  (setq c++-tab-always-indent t)\n"
"  (setq c-indent-level 4)\n"
"  (setq c-continued-statement-offset 4)\n"
"  (setq c++-empty-arglist-indent 4))\n"
"\n"
"(defun my-c-mode-hook ()\n"
"  (setq tab-width 4)\n"
"  (define-key c-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
"  (define-key c-mode-map \"\\C-ce\" 'c-comment-edit)\n"
"  (setq c-auto-hungry-initial-state 'none)\n"
"  (setq c-delete-function 'backward-delete-char)\n"
"  (setq c-tab-always-indent t)\n"
";; BSD-ish indentation style\n"
"  (setq c-indent-level 4)\n"
"  (setq c-continued-statement-offset 4)\n"
"  (setq c-brace-offset -4)\n"
"  (setq c-argdecl-indent 0)\n"
"  (setq c-label-offset -4))\n"
"\n"
";; Perl mode\n"
"(defun my-perl-mode-hook ()\n"
"  (setq tab-width 4)\n"
"  (define-key c++-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
"  (setq perl-indent-level 4)\n"
"  (setq perl-continued-statement-offset 4))\n"
"\n"
";; Scheme mode...\n"
"(defun my-scheme-mode-hook ()\n"
"  (define-key scheme-mode-map \"\\C-m\" 'reindent-then-newline-and-indent))\n"
"\n"
";; Emacs-Lisp mode...\n"
"(defun my-lisp-mode-hook ()\n"
"  (define-key lisp-mode-map \"\\C-m\" 'reindent-then-newline-and-indent)\n"
"  (define-key lisp-mode-map \"\\C-i\" 'lisp-indent-line)\n"
"  (define-key lisp-mode-map \"\\C-j\" 'eval-print-last-sexp))\n"
"\n"
";; Add all of the hooks...\n"
"(add-hook 'c++-mode-hook 'my-c++-mode-hook)\n"
"(add-hook 'c-mode-hook 'my-c-mode-hook)\n"
"(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)\n"
"(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)\n"
"(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)\n"
"(add-hook 'perl-mode-hook 'my-perl-mode-hook)\n"
"\n"
";; Complement to next-error\n"
"(defun previous-error (n)\n"
"  \"Visit previous compilation error message and corresponding source code.\"\n"
"  (interactive \"p\")\n"
"  (next-error (- n)))\n"
"\n"
";; Misc...\n"
"(transient-mark-mode 1)\n"
"(setq mark-even-if-inactive t)\n"
"(setq visible-bell nil)\n"
"(setq next-line-add-newlines nil)\n"
"(setq compile-command \"make\")\n"
"(setq suggest-key-bindings nil)\n"
"(put 'eval-expression 'disabled nil)\n"
"(put 'narrow-to-region 'disabled nil)\n"
"(put 'set-goal-column 'disabled nil)\n"
"(if (&gt;= emacs-major-version 21)\n"
"\t(setq show-trailing-whitespace t))\n"
"\n"
";; Elisp archive searching\n"
"(autoload 'format-lisp-code-directory \"lispdir\" nil t)\n"
"(autoload 'lisp-dir-apropos \"lispdir\" nil t)\n"
"(autoload 'lisp-dir-retrieve \"lispdir\" nil t)\n"
"(autoload 'lisp-dir-verify \"lispdir\" nil t)\n"
"\n"
";; Font lock mode\n"
"(defun my-make-face (face color &amp;optional bold)\n"
"  \"Create a face from a color and optionally make it bold\"\n"
"  (make-face face)\n"
"  (copy-face 'default face)\n"
"  (set-face-foreground face color)\n"
"  (if bold (make-face-bold face))\n"
"  )\n"
"\n"
"(if (eq window-system 'x)\n"
"    (progn\n"
"      (my-make-face 'blue \"blue\")\n"
"      (my-make-face 'red \"red\")\n"
"      (my-make-face 'green \"dark green\")\n"
"      (setq font-lock-comment-face 'blue)\n"
"      (setq font-lock-string-face 'bold)\n"
"      (setq font-lock-type-face 'bold)\n"
"      (setq font-lock-keyword-face 'bold)\n"
"      (setq font-lock-function-name-face 'red)\n"
"      (setq font-lock-doc-string-face 'green)\n"
"      (add-hook 'find-file-hooks 'font-lock-auto-mode-select)\n"
"\n"
"      (setq baud-rate 1000000)\n"
"      (global-set-key \"\\C-cmm\" 'menu-bar-mode)\n"
"      (global-set-key \"\\C-cms\" 'scroll-bar-mode)\n"
"      (global-set-key [backspace] 'backward-delete-char)\n"
"\t\t\t\t\t;      (global-set-key [delete] 'delete-char)\n"
"      (standard-display-european t)\n"
"      (load-library \"iso-transl\")))\n"
"\n"
";; X11 or PC using direct screen writes\n"
"(if window-system\n"
"    (progn\n"
"      ;;      (global-set-key [M-f1] 'hilit-repaint-command)\n"
"      ;;      (global-set-key [M-f2] [?\\C-u M-f1])\n"
"      (setq hilit-mode-enable-list\n"
"\t    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode\n"
"\t\t  scheme-mode)\n"
"\t    hilit-auto-highlight nil\n"
"\t    hilit-auto-rehighlight 'visible\n"
"\t    hilit-inhibit-hooks nil\n"
"\t    hilit-inhibit-rebinding t)\n"
"      (require 'hilit19)\n"
"      (require 'paren))\n"
"  (setq baud-rate 2400)\t\t\t; For slow serial connections\n"
"  )\n"
"\n"
";; TTY type terminal\n"
"(if (and (not window-system)\n"
"\t (not (equal system-type 'ms-dos)))\n"
"    (progn\n"
"      (if first-time\n"
"\t  (progn\n"
"\t    (keyboard-translate ?\\C-h ?\\C-?)\n"
"\t    (keyboard-translate ?\\C-? ?\\C-h)))))\n"
"\n"
";; Under UNIX\n"
"(if (not (equal system-type 'ms-dos))\n"
"    (progn\n"
"      (if first-time\n"
"\t  (server-start))))\n"
"\n"
";; Add any face changes here\n"
"(add-hook 'term-setup-hook 'my-term-setup-hook)\n"
"(defun my-term-setup-hook ()\n"
"  (if (eq window-system 'pc)\n"
"      (progn\n"
";;\t(set-face-background 'default \"red\")\n"
"\t)))\n"
"\n"
";; Restore the \"desktop\" - do this as late as possible\n"
"(if first-time\n"
"    (progn\n"
"      (desktop-load-default)\n"
"      (desktop-read)))\n"
"\n"
";; Indicate that this file has been read at least once\n"
"(setq first-time nil)\n"
"\n"
";; No need to debug anything now\n"
"\n"
"(setq debug-on-error nil)\n"
"\n"
";; All done\n"
"(message \"All done, %s%s\" (user-login-name) \".\")"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:2846
msgid "Extending the Range of Languages Emacs Understands"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2849
msgid ""
"Now, this is all very well if you only want to program in the languages "
"already catered for in <filename>.emacs</filename> (C, C++, Perl, Lisp and "
"Scheme), but what happens if a new language called <quote>whizbang</quote> "
"comes out, full of exciting features?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2856
msgid ""
"The first thing to do is find out if whizbang comes with any files that tell "
"Emacs about the language. These usually end in <filename>.el</filename>, "
"short for <quote>Emacs Lisp</quote>. For example, if whizbang is a FreeBSD "
"port, we can locate these files by doing"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:2862
#, no-wrap
msgid "<prompt>%</prompt> <userinput>find /usr/ports/lang/whizbang -name \"*.el\" -print</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2864
msgid ""
"and install them by copying them into the Emacs site Lisp directory. On "
"FreeBSD, this is <filename>/usr/local/share/emacs/site-lisp</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2868
msgid "So for example, if the output from the find command was"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:2871
#, no-wrap
msgid "/usr/ports/lang/whizbang/work/misc/whizbang.el"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2873
msgid "we would do"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:2875
#, no-wrap
msgid "<prompt>#</prompt> <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2877
msgid ""
"Next, we need to decide what extension whizbang source files have. Let us "
"say for the sake of argument that they all end in <filename>.wiz</filename>. "
"We need to add an entry to our <filename>.emacs</filename> to make sure "
"Emacs will be able to use the information in <filename>whizbang.el</"
"filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2884
msgid ""
"Find the <symbol>auto-mode-alist entry</symbol> in <filename>.emacs</"
"filename> and add a line for whizbang, such as:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:2888
#, no-wrap
msgid ""
"<lineannotation>…</lineannotation>\n"
"(\"\\\\.lsp$\" . lisp-mode)\n"
"(\"\\\\.wiz$\" . whizbang-mode)\n"
"(\"\\\\.scm$\" . scheme-mode)\n"
"<lineannotation>…</lineannotation>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2894
msgid ""
"This means that Emacs will automatically go into <function>whizbang-mode</"
"function> when you edit a file ending in <filename>.wiz</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2898
msgid ""
"Just below this, you will find the <symbol>font-lock-auto-mode-list</symbol> "
"entry. Add <function>whizbang-mode</function> to it like so:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:2902
#, no-wrap
msgid ""
";; Auto font lock mode\n"
"(defvar font-lock-auto-mode-list\n"
"  (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)\n"
"  \"List of modes to always start in font-lock-mode\")"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2907
msgid ""
"This means that Emacs will always enable <function>font-lock-mode</function> "
"(ie syntax highlighting) when editing a <filename>.wiz</filename> file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:2911
msgid ""
"And that is all that is needed. If there is anything else you want done "
"automatically when you open up <filename>.wiz</filename>, you can add a "
"<function>whizbang-mode hook</function> (see <function>my-scheme-mode-hook</"
"function> for a simple example that adds <function>auto-indent</function>)."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:2921
msgid "Further Reading"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:2923
msgid ""
"For information about setting up a development environment for contributing "
"fixes to FreeBSD itself, please see "
"<citerefentry><refentrytitle>development</refentrytitle><manvolnum>7</"
"manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2929
msgid ""
"Brian Harvey and Matthew Wright <emphasis>Simply Scheme</emphasis> MIT 1994. "
"ISBN 0-262-08226-8"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2936
msgid ""
"Randall Schwartz <emphasis>Learning Perl</emphasis> O'Reilly 1993 ISBN "
"1-56592-042-2"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2943
msgid ""
"Patrick Henry Winston and Berthold Klaus Paul Horn <emphasis>Lisp (3rd "
"Edition)</emphasis> Addison-Wesley 1989 ISBN 0-201-08319-1"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2950
msgid ""
"Brian W. Kernighan and Rob Pike <emphasis>The Unix Programming Environment</"
"emphasis> Prentice-Hall 1984 ISBN 0-13-937681-X"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2957
msgid ""
"Brian W. Kernighan and Dennis M. Ritchie <emphasis>The C Programming "
"Language (2nd Edition)</emphasis> Prentice-Hall 1988 ISBN 0-13-110362-8"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2964
msgid ""
"Bjarne Stroustrup <emphasis>The C++ Programming Language</emphasis> Addison-"
"Wesley 1991 ISBN 0-201-53992-6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2971
msgid ""
"W. Richard Stevens <emphasis>Advanced Programming in the Unix Environment</"
"emphasis> Addison-Wesley 1992 ISBN 0-201-56317-7"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:2978
msgid ""
"W. Richard Stevens <emphasis>Unix Network Programming</emphasis> Prentice-"
"Hall 1990 ISBN 0-13-949876-1"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:2995
msgid "Secure Programming"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3005
msgid ""
"This chapter describes some of the security issues that have plagued "
"<trademark class=\"registered\">UNIX</trademark> programmers for decades and "
"some of the new tools available to help programmers avoid writing "
"exploitable code."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3011
msgid "Secure Design Methodology"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3014
msgid ""
"Writing secure applications takes a very scrutinous and pessimistic outlook "
"on life. Applications should be run with the principle of <quote>least "
"privilege</quote> so that no process is ever running with more than the bare "
"minimum access that it needs to accomplish its function. Previously tested "
"code should be reused whenever possible to avoid common mistakes that others "
"may have already fixed."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3022
msgid ""
"One of the pitfalls of the <trademark class=\"registered\">UNIX</trademark> "
"environment is how easy it is to make assumptions about the sanity of the "
"environment. Applications should never trust user input (in all its forms), "
"system resources, inter-process communication, or the timing of events. "
"<trademark class=\"registered\">UNIX</trademark> processes do not execute "
"synchronously so logical operations are rarely atomic."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3030
msgid "Buffer Overflows"
msgstr ""

#. (itstool) path: para/indexterm
#. (itstool) path: sect3/indexterm
#: book.translate.xml:3035 book.translate.xml:3254
msgid "<primary>buffer overflow</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3036
msgid "<primary>von Neumann</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3041
msgid "<primary>Morris Internet worm</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3032
msgid ""
"Buffer Overflows have been around since the very beginnings of the von "
"Neumann <xref linkend=\"COD\"/> architecture. <_:indexterm-1/> <_:"
"indexterm-2/> They first gained widespread notoriety in 1988 with the Morris "
"Internet worm. Unfortunately, the same basic attack remains <_:indexterm-3/> "
"effective today. By far the most common type of buffer overflow attack is "
"based on corrupting the stack."
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3047
msgid "<primary>stack</primary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3048
msgid "<primary>arguments</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3055
msgid "<primary>LIFO</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3056
msgid "<primary>process image</primary> <secondary>stack pointer</secondary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3065
msgid "<primary>stack frame</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3066
msgid "<primary>stack pointer</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3075
msgid "<primary>frame pointer</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3076
msgid "<primary>process image</primary> <secondary>frame pointer</secondary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3080
msgid "<primary>return address</primary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3081
msgid "<primary>stack-overflow</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3050
msgid ""
"Most modern computer systems use a stack to pass arguments to procedures and "
"to store local variables. A stack is a last in first out (LIFO) buffer in "
"the high memory area of a process image. When a program invokes a function a "
"new \"stack frame\" is <_:indexterm-1/> <_:indexterm-2/> created. This stack "
"frame consists of the arguments passed to the function as well as a dynamic "
"amount of local variable space. The \"stack pointer\" is a register that "
"holds the current <_:indexterm-3/> <_:indexterm-4/> location of the top of "
"the stack. Since this value is constantly changing as new values are pushed "
"onto the top of the stack, many implementations also provide a \"frame "
"pointer\" that is located near the beginning of a stack frame so that local "
"variables can more easily be addressed relative to this value. <xref linkend="
"\"COD\"/> The return address for function <_:indexterm-5/> <_:indexterm-6/> "
"<_:indexterm-7/> <_:indexterm-8/> calls is also stored on the stack, and "
"this is the cause of stack-overflow exploits since overflowing a local "
"variable in a function can overwrite the return address of that function, "
"potentially allowing a malicious user to execute any code he or she wants."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3089
msgid ""
"Although stack-based attacks are by far the most common, it would also be "
"possible to overrun the stack with a heap-based (malloc/free) attack."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3093
msgid ""
"The C programming language does not perform automatic bounds checking on "
"arrays or pointers as many other languages do. In addition, the standard C "
"library is filled with a handful of very dangerous functions."
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3101
msgid "<function>strcpy</function>(char *dest, const char *src)"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3103 book.translate.xml:3108
msgid "May overflow the dest buffer"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3106
msgid "<function>strcat</function>(char *dest, const char *src)"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3111
msgid "<function>getwd</function>(char *buf)"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3112
msgid "May overflow the buf buffer"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3115
msgid "<function>gets</function>(char *s)"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3116
msgid "May overflow the s buffer"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3119
msgid "<function>[vf]scanf</function>(const char *format, ...)"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3121
msgid "May overflow its arguments."
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3124
msgid "<function>realpath</function>(char *path, char resolved_path[])"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3126
msgid "May overflow the path buffer"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:3129
msgid "<function>[v]sprintf</function>(char *str, const char *format, ...)"
msgstr ""

#. (itstool) path: entry/simpara
#: book.translate.xml:3131
msgid "May overflow the str buffer."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3137
msgid "Example Buffer Overflow"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3139
msgid ""
"The following example code contains a buffer overflow designed to overwrite "
"the return address and skip the instruction immediately following the "
"function call. (Inspired by <xref linkend=\"Phrack\"/>)"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3144
#, no-wrap
msgid ""
"#include &lt;stdio.h&gt;\n"
"\n"
"void manipulate(char *buffer) {\n"
"  char newbuffer[80];\n"
"  strcpy(newbuffer,buffer);\n"
"}\n"
"\n"
"int main() {\n"
"  char ch,buffer[4096];\n"
"  int i=0;\n"
"\n"
"  while ((buffer[i++] = getchar()) != '\\n') {};\n"
"\n"
"  i=1;\n"
"  manipulate(buffer);\n"
"  i=2;\n"
"  printf(\"The value of i is : %d\\n\",i);\n"
"  return 0;\n"
"}"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3164
msgid ""
"Let us examine what the memory image of this process would look like if we "
"were to input 160 spaces into our little program before hitting return."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3168
msgid "[XXX figure here!]"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3170
msgid ""
"Obviously more malicious input can be devised to execute actual compiled "
"instructions (such as exec(/bin/sh))."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3174
msgid "Avoiding Buffer Overflows"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3181
msgid "<primary>string copy functions</primary> <secondary>strncpy</secondary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3185
msgid "<primary>string copy functions</primary> <secondary>strncat</secondary>"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:3197
msgid "<primary>NUL termination</primary>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3176
msgid ""
"The most straightforward solution to the problem of stack-overflows is to "
"always use length restricted memory and string copy functions. "
"<function>strncpy</function> and <function>strncat</function> are part of "
"the standard C library. <_:indexterm-1/> <_:indexterm-2/> These functions "
"accept a length value as a parameter which should be no larger than the size "
"of the destination buffer. These functions will then copy up to `length' "
"bytes from the source to the destination. However there are a number of "
"problems with these functions. Neither function guarantees NUL termination "
"if the size of the input buffer is as large as the <_:indexterm-3/> "
"destination. The length parameter is also used inconsistently between "
"strncpy and strncat so it is easy for programmers to get confused as to "
"their proper usage. There is also a significant performance loss compared to "
"<function>strcpy</function> when copying a short string into a large buffer "
"since <function>strncpy</function> NUL fills up the size specified."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3207
msgid ""
"Another memory copy implementation exists to get around these problems. The "
"<function>strlcpy</function> and <function>strlcat</function> functions "
"guarantee that they will always null terminate the destination string when "
"given a non-zero length argument."
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3213
msgid "<primary>string copy functions</primary> <secondary>strlcpy</secondary>"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3218
msgid "<primary>string copy functions</primary> <secondary>strlcat</secondary>"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:3223
msgid "Compiler based run-time bounds checking"
msgstr ""

#. (itstool) path: sect3/indexterm
#: book.translate.xml:3225
msgid ""
"<primary>bounds checking</primary> <secondary>compiler-based</secondary>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3228
msgid ""
"Unfortunately there is still a very large assortment of code in public use "
"which blindly copies memory around without using any of the bounded copy "
"routines we just discussed. Fortunately, there is a way to help prevent such "
"attacks — run-time bounds checking, which is implemented by several C/C++ "
"compilers."
msgstr ""

#. (itstool) path: sect3/indexterm
#: book.translate.xml:3235
msgid "<primary>ProPolice</primary>"
msgstr ""

#. (itstool) path: sect3/indexterm
#: book.translate.xml:3236
msgid "<primary>StackGuard</primary>"
msgstr ""

#. (itstool) path: sect3/indexterm
#: book.translate.xml:3237
msgid "<primary>gcc</primary>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3239
msgid ""
"ProPolice is one such compiler feature, and is integrated into "
"<citerefentry><refentrytitle>gcc</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> versions 4.1 and later. It replaces and extends the earlier "
"StackGuard <citerefentry><refentrytitle>gcc</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry> extension."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3243
msgid ""
"ProPolice helps to protect against stack-based buffer overflows and other "
"attacks by laying pseudo-random numbers in key areas of the stack before "
"calling any function. When a function returns, these <quote>canaries</quote> "
"are checked and if they are found to have been changed the executable is "
"immediately aborted. Thus any attempt to modify the return address or other "
"variable stored on the stack in an attempt to get malicious code to run is "
"unlikely to succeed, as the attacker would have to also manage to leave the "
"pseudo-random canaries untouched."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3256
msgid ""
"Recompiling your application with ProPolice is an effective means of "
"stopping most buffer-overflow attacks, but it can still be compromised."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:3262
msgid "Library based run-time bounds checking"
msgstr ""

#. (itstool) path: sect3/indexterm
#: book.translate.xml:3264
msgid "<primary>bounds checking</primary> <secondary>library-based</secondary>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3269
msgid ""
"Compiler-based mechanisms are completely useless for binary-only software "
"for which you cannot recompile. For these situations there are a number of "
"libraries which re-implement the unsafe functions of the C-library "
"(<function>strcpy</function>, <function>fscanf</function>, <function>getwd</"
"function>, etc..) and ensure that these functions can never write past the "
"stack pointer."
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3278
msgid "libsafe"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3279
msgid "libverify"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3280
msgid "libparanoia"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3283
msgid ""
"Unfortunately these library-based defenses have a number of shortcomings. "
"These libraries only protect against a very small set of security related "
"issues and they neglect to fix the actual problem. These defenses may fail "
"if the application was compiled with -fomit-frame-pointer. Also, the "
"LD_PRELOAD and LD_LIBRARY_PATH environment variables can be overwritten/"
"unset by the user."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3295
msgid "SetUID issues"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3297
msgid "<primary>seteuid</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3299
msgid ""
"There are at least 6 different IDs associated with any given process. "
"Because of this you have to be very careful with the access that your "
"process has at any given time. In particular, all seteuid applications "
"should give up their privileges as soon as it is no longer required."
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3305
msgid "<primary>user IDs</primary> <secondary>real user ID</secondary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3309
msgid "<primary>user IDs</primary> <secondary>effective user ID</secondary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3314
msgid ""
"The real user ID can only be changed by a superuser process. The "
"<application>login</application> program sets this when a user initially "
"logs in and it is seldom changed."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3318
msgid ""
"The effective user ID is set by the <function>exec()</function> functions if "
"a program has its seteuid bit set. An application can call "
"<function>seteuid()</function> at any time to set the effective user ID to "
"either the real user ID or the saved set-user-ID. When the effective user ID "
"is set by <function>exec()</function> functions, the previous value is saved "
"in the saved set-user-ID."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3328
msgid "Limiting your program's environment"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3330
msgid "<primary>chroot()</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3332
msgid ""
"The traditional method of restricting a process is with the "
"<function>chroot()</function> system call. This system call changes the root "
"directory from which all other paths are referenced for a process and any "
"child processes. For this call to succeed the process must have execute "
"(search) permission on the directory being referenced. The new environment "
"does not actually take effect until you <function>chdir()</function> into "
"your new environment. It should also be noted that a process can easily "
"break out of a chroot environment if it has root privilege. This could be "
"accomplished by creating device nodes to read kernel memory, attaching a "
"debugger to a process outside of the <citerefentry><refentrytitle>chroot</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> environment, or in "
"many other creative ways."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3347
msgid ""
"The behavior of the <function>chroot()</function> system call can be "
"controlled somewhat with the kern.chroot_allow_open_directories "
"<command>sysctl</command> variable. When this value is set to 0, "
"<function>chroot()</function> will fail with EPERM if there are any "
"directories open. If set to the default value of 1, then <function>chroot()</"
"function> will fail with EPERM if there are any directories open and the "
"process is already subject to a <function>chroot()</function> call. For any "
"other value, the check for open directories will be bypassed completely."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3358
msgid "FreeBSD's jail functionality"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3360
msgid "<primary>jail</primary>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3362
msgid ""
"The concept of a Jail extends upon the <function>chroot()</function> by "
"limiting the powers of the superuser to create a true `virtual server'. Once "
"a prison is set up all network communication must take place through the "
"specified IP address, and the power of \"root privilege\" in this jail is "
"severely constrained."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3369
msgid ""
"While in a prison, any tests of superuser power within the kernel using the "
"<function>suser()</function> call will fail. However, some calls to "
"<function>suser()</function> have been changed to a new interface "
"<function>suser_xxx()</function>. This function is responsible for "
"recognizing or denying access to superuser power for imprisoned processes."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3376
msgid "A superuser process within a jailed environment has the power to:"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3380
msgid ""
"Manipulate credential with <function>setuid</function>, <function>seteuid</"
"function>, <function>setgid</function>, <function>setegid</function>, "
"<function>setgroups</function>, <function>setreuid</function>, "
"<function>setregid</function>, <function>setlogin</function>"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3385
msgid "Set resource limits with <function>setrlimit</function>"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3386
msgid "Modify some sysctl nodes (kern.hostname)"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3388
msgid "<function>chroot()</function>"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3389
msgid ""
"Set flags on a vnode: <function>chflags</function>, <function>fchflags</"
"function>"
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3392
msgid ""
"Set attributes of a vnode such as file permission, owner, group, size, "
"access time, and modification time."
msgstr ""

#. (itstool) path: listitem/simpara
#: book.translate.xml:3395
msgid "Bind to privileged ports in the Internet domain (ports &lt; 1024)"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3399
msgid ""
"<function>Jail</function> is a very useful tool for running applications in "
"a secure environment but it does have some shortcomings. Currently, the IPC "
"mechanisms have not been converted to the <function>suser_xxx</function> so "
"applications such as MySQL cannot be run within a jail. Superuser access may "
"have a very limited meaning within a jail, but there is no way to specify "
"exactly what \"very limited\" means."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3408
msgid ""
"<trademark class=\"registered\">POSIX</trademark>.1e Process Capabilities"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3410
msgid "<primary>POSIX.1e Process Capabilities</primary>"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3411
msgid "<primary>TrustedBSD</primary>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3413
msgid ""
"<trademark class=\"registered\">POSIX</trademark> has released a working "
"draft that adds event auditing, access control lists, fine grained "
"privileges, information labeling, and mandatory access control."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3416
msgid ""
"This is a work in progress and is the focus of the <link xlink:href=\"http://"
"www.trustedbsd.org/\">TrustedBSD</link> project. Some of the initial work "
"has been committed to FreeBSD-CURRENT (cap_set_proc(3))."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3424
msgid "Trust"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3426
msgid ""
"An application should never assume that anything about the users environment "
"is sane. This includes (but is certainly not limited to): user input, "
"signals, environment variables, resources, IPC, mmaps, the filesystem "
"working directory, file descriptors, the # of open files, etc."
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3432
msgid "<primary>positive filtering</primary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3433
msgid "<primary>data validation</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3435
msgid ""
"You should never assume that you can catch all forms of invalid input that a "
"user might supply. Instead, your application should use positive filtering "
"to only allow a specific subset of inputs that you deem safe. Improper data "
"validation has been the cause of many exploits, especially with CGI scripts "
"on the world wide web. For filenames you need to be extra careful about "
"paths (\"../\", \"/\"), symbolic links, and shell escape characters."
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3444
msgid "<primary>Perl Taint mode</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3446
msgid ""
"Perl has a really cool feature called \"Taint\" mode which can be used to "
"prevent scripts from using data derived outside the program in an unsafe "
"way. This mode will check command line arguments, environment variables, "
"locale information, the results of certain syscalls (<function>readdir()</"
"function>, <function>readlink()</function>, <function>getpwxxx()</"
"function>), and all file input."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3457
msgid "Race Conditions"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3459
msgid ""
"A race condition is anomalous behavior caused by the unexpected dependence "
"on the relative timing of events. In other words, a programmer incorrectly "
"assumed that a particular event would always happen before another."
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3464
msgid "<primary>race conditions</primary> <secondary>signals</secondary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3467
msgid "<primary>race conditions</primary> <secondary>access checks</secondary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3470
msgid "<primary>race conditions</primary> <secondary>file opens</secondary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3473
msgid ""
"Some of the common causes of race conditions are signals, access checks, and "
"file opens. Signals are asynchronous events by nature so special care must "
"be taken in dealing with them. Checking access with <function>access(2)</"
"function> then <function>open(2)</function> is clearly non-atomic. Users can "
"move files in between the two calls. Instead, privileged applications should "
"<function>seteuid()</function> and then call <function>open()</function> "
"directly. Along the same lines, an application should always set a proper "
"umask before <function>open()</function> to obviate the need for spurious "
"<function>chmod()</function> calls."
msgstr ""

#. (itstool) path: chapter/title
#: book.translate.xml:3496
msgid "Localization and Internationalization - L10N and I18N"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3499
msgid "Programming I18N Compliant Applications"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3500
msgid "<primary>Qt</primary>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3501
msgid "<primary>GTK</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3502
msgid ""
"To make your application more useful for speakers of other languages, we "
"hope that you will program I18N compliant. The GNU gcc compiler and GUI "
"libraries like QT and GTK support I18N through special handling of strings. "
"Making a program I18N compliant is very easy. It allows contributors to port "
"your application to other languages quickly. Refer to the library specific "
"I18N documentation for more details."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3510
msgid ""
"In contrast with common perception, I18N compliant code is easy to write. "
"Usually, it only involves wrapping your strings with library specific "
"functions. In addition, please be sure to allow for wide or multibyte "
"character support."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3516
msgid "A Call to Unify the I18N Effort"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3518
msgid ""
"It has come to our attention that the individual I18N/L10N efforts for each "
"country has been repeating each others' efforts. Many of us have been "
"reinventing the wheel repeatedly and inefficiently. We hope that the various "
"major groups in I18N could congregate into a group effort similar to the "
"Core Team's responsibility."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3525
msgid ""
"Currently, we hope that, when you write or port I18N programs, you would "
"send it out to each country's related FreeBSD mailing list for testing. In "
"the future, we hope to create applications that work in all the languages "
"out-of-the-box without dirty hacks."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3531
msgid ""
"The <link xlink:href=\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-i18n"
"\">FreeBSD internationalization mailing list</link> has been established. If "
"you are an I18N/L10N developer, please send your comments, ideas, questions, "
"and anything you deem related to it."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3537
msgid "Perl and Python"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3538
msgid "<primary>Perl</primary>"
msgstr ""

#. (itstool) path: sect2/indexterm
#: book.translate.xml:3541
msgid "<primary>Python</primary>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3545
msgid ""
"Perl and Python have I18N and wide character handling libraries. Please use "
"them for I18N compliance."
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:3551
msgid "Localized Messages with POSIX.1 Native Language Support (NLS)"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3553
msgid ""
"<personname><firstname>Gábor</firstname><surname>Kövesdán</surname></"
"personname><contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3559
msgid ""
"Beyond the basic I18N functions, like supporting various input encodings or "
"supporting national conventions, such as the different decimal separators, "
"at a higher level of I18N, it is possible to localize the messages written "
"to the output by the various programs. A common way of doing this is using "
"the POSIX.1 NLS functions, which are provided as a part of the FreeBSD base "
"system."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3567
msgid "Organizing Localized Messages into Catalog Files"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3569
msgid ""
"POSIX.1 NLS is based on catalog files, which contain the localized messages "
"in the desired encoding. The messages are organized into sets and each "
"message is identified by an integer number in the containing set. The "
"catalog files are conventionally named after the locale they contain "
"localized messages for, followed by the <literal>.msg</literal> extension. "
"For instance, the Hungarian messages for ISO8859-2 encoding should be stored "
"in a file called <filename>hu_HU.ISO8859-2</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3578
msgid ""
"These catalog files are common text files that contain the numbered "
"messages. It is possible to write comments by starting the line with a "
"<literal>$</literal> sign. Set boundaries are also separated by special "
"comments, where the keyword <literal>set</literal> must directly follow the "
"<literal>$</literal> sign. The <literal>set</literal> keyword is then "
"followed by the set number. For example:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3585
#, no-wrap
msgid "$set 1"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3587
msgid ""
"The actual message entries start with the message number and followed by the "
"localized message. The well-known modifiers from "
"<citerefentry><refentrytitle>printf</refentrytitle><manvolnum>3</manvolnum></"
"citerefentry> are accepted:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3591
#, no-wrap
msgid "15 \"File not found: %s\\n\""
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3593
msgid ""
"The language catalog files have to be compiled into a binary form before "
"they can be opened from the program. This conversion is done with the "
"<citerefentry><refentrytitle>gencat</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> utility. Its first argument is the filename of the compiled "
"catalog and its further arguments are the input catalogs. The localized "
"messages can also be organized into more catalog files and then all of them "
"can be processed with <citerefentry><refentrytitle>gencat</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3603
msgid "Using the Catalog Files from the Source Code"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3605
msgid ""
"Using the catalog files is simple. To use the related functions, "
"<filename>nl_types.h</filename> must be included. Before using a catalog, it "
"has to be opened with <citerefentry><refentrytitle>catopen</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry>. The function takes "
"two arguments. The first parameter is the name of the installed and compiled "
"catalog. Usually, the name of the program is used, such as "
"<application>grep</application>. This name will be used when looking for the "
"compiled catalog file. The <citerefentry><refentrytitle>catopen</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> call looks for this "
"file in <filename>/usr/share/nls/<replaceable>locale</replaceable>/"
"<replaceable>catname</replaceable></filename> and in <filename>/usr/local/"
"share/nls/<replaceable>locale</replaceable>/<replaceable>catname</"
"replaceable></filename>, where <literal>locale</literal> is the locale set "
"and <literal>catname</literal> is the catalog name being discussed. The "
"second parameter is a constant, which can have two values:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:3622
msgid ""
"<literal>NL_CAT_LOCALE</literal>, which means that the used catalog file "
"will be based on <envar>LC_MESSAGES</envar>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:3627
msgid ""
"<literal>0</literal>, which means that <envar>LANG</envar> has to be used to "
"open the proper catalog."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3633
msgid ""
"The <citerefentry><refentrytitle>catopen</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> call returns a catalog identifier of type "
"<literal>nl_catd</literal>. Please refer to the manual page for a list of "
"possible returned error codes."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3637
msgid ""
"After opening a catalog <citerefentry><refentrytitle>catgets</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> can be used to "
"retrieve a message. The first parameter is the catalog identifier returned "
"by <citerefentry><refentrytitle>catopen</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry>, the second one is the number of the set, the "
"third one is the number of the messages, and the fourth one is a fallback "
"message, which will be returned if the requested message cannot be retrieved "
"from the catalog file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3644
msgid ""
"After using the catalog file, it must be closed by calling "
"<citerefentry><refentrytitle>catclose</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry>, which has one argument, the catalog id."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3649
msgid "A Practical Example"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3651
msgid ""
"The following example will demonstrate an easy solution on how to use NLS "
"catalogs in a flexible way."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3654
msgid ""
"The below lines need to be put into a common header file of the program, "
"which is included into all source files where localized messages are "
"necessary:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3658
#, no-wrap
msgid ""
"\n"
"#ifdef WITHOUT_NLS\n"
"#define getstr(n)\t nlsstr[n]\n"
"#else\n"
"#include &lt;nl_types.h&gt;\n"
"\n"
"extern nl_catd\t\t catalog;\n"
"#define getstr(n)\t catgets(catalog, 1, n, nlsstr[n])\n"
"#endif\n"
"\n"
"extern char\t\t*nlsstr[];"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3670
msgid ""
"Next, put these lines into the global declaration part of the main source "
"file:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3673
#, no-wrap
msgid ""
"\n"
"#ifndef WITHOUT_NLS\n"
"#include &lt;nl_types.h&gt;\n"
"nl_catd\t catalog;\n"
"#endif\n"
"\n"
"/*\n"
" * Default messages to use when NLS is disabled or no catalog\n"
" * is found.\n"
" */\n"
"char    *nlsstr[] = {\n"
"        \"\",\n"
"/* 1*/  \"some random message\",\n"
"/* 2*/  \"some other message\"\n"
"};"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3689
msgid ""
"Next come the real code snippets, which open, read, and close the catalog:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3692
#, no-wrap
msgid ""
"\n"
"#ifndef WITHOUT_NLS\n"
"\tcatalog = catopen(\"myapp\", NL_CAT_LOCALE);\n"
"#endif\n"
"\n"
"...\n"
"\n"
"printf(getstr(1));\n"
"\n"
"...\n"
"\n"
"#ifndef WITHOUT_NLS\n"
"\tcatclose(catalog);\n"
"#endif"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:3708
msgid "Reducing Strings to Localize"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3710
msgid ""
"There is a good way of reducing the strings that need to be localized by "
"using <application>libc</application> error messages. This is also useful to "
"just avoid duplication and provide consistent error messages for the common "
"errors that can be encountered by a great many of programs."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3716
msgid ""
"First, here is an example that does not use <application>libc</application> "
"error messages:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:3719
#, no-wrap
msgid ""
"\n"
"#include &lt;err.h&gt;\n"
"...\n"
"if (!S_ISDIR(st.st_mode))\n"
"\terrx(1, \"argument is not a directory\");\n"
"\t  "
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3726
msgid ""
"This can be transformed to print an error message by reading <varname>errno</"
"varname> and printing an error message accordingly:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:3730
#, no-wrap
msgid ""
"\n"
"#include &lt;err.h&gt;\n"
"#include &lt;errno.h&gt;\n"
"...\n"
"if (!S_ISDIR(st.st_mode)) {\n"
"\terrno = ENOTDIR;\n"
"\terr(1, NULL);\n"
"}\n"
"\t  "
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3740
msgid ""
"In this example, the custom string is eliminated, thus translators will have "
"less work when localizing the program and users will see the usual "
"<quote>Not a directory</quote> error message when they encounter this error. "
"This message will probably seem more familiar to them. Please note that it "
"was necessary to include <filename>errno.h</filename> in order to directly "
"access <varname>errno</varname>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:3748
msgid ""
"It is worth to note that there are cases when <varname>errno</varname> is "
"set automatically by a preceding call, so it is not necessary to set it "
"explicitly:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:3752
#, no-wrap
msgid ""
"\n"
"#include &lt;err.h&gt;\n"
"...\n"
"if ((p = malloc(size)) == NULL)\n"
"\terr(1, NULL);\n"
"\t  "
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:3762
msgid "Making use of <filename>bsd.nls.mk</filename>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3764
msgid ""
"Using the catalog files requires few repeatable steps, such as compiling the "
"catalogs and installing them to the proper location. In order to simplify "
"this process even more, <filename>bsd.nls.mk</filename> introduces some "
"macros. It is not necessary to include <filename>bsd.nls.mk</filename> "
"explicitly, it is pulled in from the common Makefiles, such as <filename>bsd."
"prog.mk</filename> or <filename>bsd.lib.mk</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3773
msgid ""
"Usually it is enough to define <varname>NLSNAME</varname>, which should have "
"the catalog name mentioned as the first argument of "
"<citerefentry><refentrytitle>catopen</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and list the catalog files in <varname>NLS</"
"varname> without their <literal>.msg</literal> extension. Here is an "
"example, which makes it possible to to disable NLS when used with the code "
"examples before. The <varname>WITHOUT_NLS</varname> "
"<citerefentry><refentrytitle>make</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> variable has to be defined in order to build the program "
"without NLS support."
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:3783
#, no-wrap
msgid ""
"\n"
".if !defined(WITHOUT_NLS)\n"
"NLS=\tes_ES.ISO8859-1\n"
"NLS+=\thu_HU.ISO8859-2\n"
"NLS+=\tpt_BR.ISO8859-1\n"
".else\n"
"CFLAGS+=\t-DWITHOUT_NLS\n"
".endif"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3792
msgid ""
"Conventionally, the catalog files are placed under the <filename>nls</"
"filename> subdirectory and this is the default behavior of <filename>bsd.nls."
"mk</filename>. It is possible, though to override the location of the "
"catalogs with the <varname>NLSSRCDIR</varname> "
"<citerefentry><refentrytitle>make</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> variable. The default name of the precompiled catalog files "
"also follow the naming convention mentioned before. It can be overridden by "
"setting the <varname>NLSNAME</varname> variable. There are other options to "
"fine tune the processing of the catalog files but usually it is not needed, "
"thus they are not described here. For further information on <filename>bsd."
"nls.mk</filename>, please refer to the file itself, it is short and easy to "
"understand."
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:3817
msgid "Source Tree Guidelines and Policies"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3820 book.translate.xml:3915
msgid ""
"<personname> <firstname>Poul-Henning</firstname> <surname>Kamp</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3827
msgid ""
"<personname> <firstname>Giorgos</firstname> <surname>Keramidas</surname> </"
"personname>"
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:3836
msgid ""
"This chapter documents various guidelines and policies in force for the "
"FreeBSD source tree."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3840
msgid "Style Guidelines"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3842
msgid "<primary>style</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3844
msgid ""
"Consistent coding style is extremely important, particularly with large "
"projects like FreeBSD. Code should follow the FreeBSD coding styles "
"described in <citerefentry><refentrytitle>style</refentrytitle><manvolnum>9</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>style.Makefile</"
"refentrytitle><manvolnum>5</manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:3851
msgid "<varname>MAINTAINER</varname> on Makefiles"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3853
msgid "<primary>ports maintainer</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3855
msgid ""
"If a particular portion of the FreeBSD <filename>src/</filename> "
"distribution is being maintained by a person or group of persons, this is "
"communicated through an entry in <filename>src/MAINTAINERS</filename>. "
"Maintainers of ports within the Ports Collection express their "
"maintainership to the world by adding a <varname>MAINTAINER</varname> line "
"to the <filename>Makefile</filename> of the port in question:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:3864
#, no-wrap
msgid "<varname>MAINTAINER</varname>= <replaceable>email-addresses</replaceable>"
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:3867
msgid ""
"For other parts of the repository, or for sections not listed as having a "
"maintainer, or when you are unsure who the active maintainer is, try looking "
"at the recent commit history of the relevant parts of the source tree. It is "
"quite often the case that a maintainer is not explicitly named, but the "
"people who are actively working in a part of the source tree for, say, the "
"last couple of years are interested in reviewing changes. Even if this is "
"not specifically mentioned in the documentation or the source itself, asking "
"for a review as a form of courtesy is a very reasonable thing to do."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3879
msgid "The role of the maintainer is as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:3883
msgid ""
"The maintainer owns and is responsible for that code. This means that he or "
"she is responsible for fixing bugs and answering problem reports pertaining "
"to that piece of the code, and in the case of contributed software, for "
"tracking new versions, as appropriate."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:3891
msgid ""
"Changes to directories which have a maintainer defined shall be sent to the "
"maintainer for review before being committed. Only if the maintainer does "
"not respond for an unacceptable period of time, to several emails, will it "
"be acceptable to commit changes without review by the maintainer. However, "
"it is suggested that you try to have the changes reviewed by someone else if "
"at all possible."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:3902
msgid ""
"It is of course not acceptable to add a person or group as maintainer unless "
"they agree to assume this duty. On the other hand it does not have to be a "
"committer and it can easily be a group of people."
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:3912
msgid "Contributed Software"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3922 book.translate.xml:4330
msgid ""
"<personname> <firstname>David</firstname> <surname>O'Brien</surname> </"
"personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3928
msgid ""
"<personname> <firstname>Gavin</firstname> <surname>Atkinson</surname> </"
"personname>"
msgstr ""

#. (itstool) path: sect1/indexterm
#: book.translate.xml:3937
msgid "<primary>contributed software</primary>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3939
msgid ""
"Some parts of the FreeBSD distribution consist of software that is actively "
"being maintained outside the FreeBSD project. For historical reasons, we "
"call this <emphasis>contributed</emphasis> software. Some examples are "
"<application>sendmail</application>, <application>gcc</application> and "
"<application>patch</application>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3947
msgid ""
"Over the last couple of years, various methods have been used in dealing "
"with this type of software and all have some number of advantages and "
"drawbacks. No clear winner has emerged."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3952
msgid ""
"Since this is the case, after some debate one of these methods has been "
"selected as the <quote>official</quote> method and will be required for "
"future imports of software of this kind. Furthermore, it is strongly "
"suggested that existing contributed software converge on this model over "
"time, as it has significant advantages over the old method, including the "
"ability to easily obtain diffs relative to the <quote>official</quote> "
"versions of the source by everyone (even without direct repository access). "
"This will make it significantly easier to return changes to the primary "
"developers of the contributed software."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:3964
msgid ""
"Ultimately, however, it comes down to the people actually doing the work. If "
"using this model is particularly unsuited to the package being dealt with, "
"exceptions to these rules may be granted only with the approval of the core "
"team and with the general consensus of the other developers. The ability to "
"maintain the package in the future will be a key issue in the decisions."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:3973
msgid ""
"Because it makes it harder to import future versions minor, trivial and/or "
"cosmetic changes are <emphasis>strongly discouraged</emphasis> on files that "
"are still tracking the vendor branch."
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:3981
msgid "Vendor Imports with SVN"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:3984
msgid ""
"<personname> <firstname>Dag-Erling</firstname> <surname>Smørgrav</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:3994
msgid ""
"This section describes the vendor import procedure with "
"<application>Subversion</application> in details."
msgstr ""

#. (itstool) path: step/title
#: book.translate.xml:3999
msgid "Preparing the Tree"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4001
msgid ""
"If this is your first import after the switch to <acronym>SVN</acronym>, you "
"will have to flatten and clean up the vendor tree, and bootstrap merge "
"history in the main tree. If not, you can safely omit this step."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4006
msgid ""
"During the conversion from <acronym>CVS</acronym> to <acronym>SVN</acronym>, "
"vendor branches were imported with the same layout as the main tree. For "
"example, the <application>foo</application> vendor sources ended up in "
"<filename>vendor/<replaceable>foo</replaceable>/dist/contrib/"
"<replaceable>foo</replaceable></filename>, but it is pointless and rather "
"inconvenient. What we really want is to have the vendor source directly in "
"<filename>vendor/<replaceable>foo</replaceable>/dist</filename>, like this:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4016
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cd vendor/<replaceable>foo</replaceable>/dist/contrib/<replaceable>foo</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>svn move $(svn list) ../..</userinput>\n"
"<prompt>%</prompt> <userinput>cd ../..</userinput>\n"
"<prompt>%</prompt> <userinput>svn remove contrib</userinput>\n"
"<prompt>%</prompt> <userinput>svn propdel -R svn:mergeinfo</userinput>\n"
"<prompt>%</prompt> <userinput>svn commit</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4023
msgid ""
"Note that, the <literal>propdel</literal> bit is necessary because starting "
"with 1.5, Subversion will automatically add <literal>svn:mergeinfo</literal> "
"to any directory you copy or move. In this case, you will not need this "
"information, since you are not going to merge anything from the tree you "
"deleted."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:4031
msgid ""
"You may want to flatten the tags as well. The procedure is exactly the same. "
"If you do this, put off the commit until the end."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4036
msgid ""
"Check the <filename>dist</filename> tree and perform any cleanup that is "
"deemed to be necessary. You may want to disable keyword expansion, as it "
"makes no sense on unmodified vendor code. In some cases, it can be even be "
"harmful."
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4042
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>svn propdel svn:keywords -R .</userinput>\n"
"<prompt>%</prompt> <userinput>svn commit</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4045
msgid ""
"Bootstrapping of <literal>svn:mergeinfo</literal> on the target directory "
"(in the main tree) to the revision that corresponds to the last change was "
"made to the vendor tree prior to importing new sources is also needed:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4050
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cd head/contrib/<replaceable>foo</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>svn merge --record-only ^/vendor/<replaceable>foo</replaceable>/dist@<replaceable>12345678</replaceable> .</userinput>\n"
"<prompt>%</prompt> <userinput>svn commit</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4054
msgid ""
"With some shells, the <literal>^</literal> in the above command may need to "
"be escaped with a backslash."
msgstr ""

#. (itstool) path: step/title
#: book.translate.xml:4060
msgid "Importing New Sources"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4062
msgid ""
"Prepare a full, clean tree of the vendor sources. With <acronym>SVN</"
"acronym>, we can keep a full distribution in the vendor tree without "
"bloating the main tree. Import everything but merge only what is needed."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4068
msgid ""
"Note that you will need to add any files that were added since the last "
"vendor import, and remove any that were removed. To facilitate this, you "
"should prepare sorted lists of the contents of the vendor tree and of the "
"sources you are about to import:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4074
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cd vendor/<replaceable>foo</replaceable>/dist</userinput>\n"
"<prompt>%</prompt> <userinput>svn list -R | grep -v '/$' | sort &gt; ../<replaceable>old</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>cd ../<replaceable>foo-9.9</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>find . -type f | cut -c 3- | sort &gt; ../<replaceable>new</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4079
msgid ""
"With these two files, the following command will list removed files (files "
"only in <filename><replaceable>old</replaceable></filename>):"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4083
#, no-wrap
msgid "<prompt>%</prompt> <userinput>comm -23 ../<replaceable>old</replaceable> ../<replaceable>new</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4085
msgid ""
"While the command below will list added files (files only in "
"<filename><replaceable>new</replaceable></filename>):"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4089
#, no-wrap
msgid "<prompt>%</prompt> <userinput>comm -13 ../<replaceable>old</replaceable> ../<replaceable>new</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4091
msgid "Let us put this together:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4093
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cd vendor/<replaceable>foo</replaceable>/<replaceable>foo-9.9</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>tar cf - . | tar xf - -C ../dist</userinput>\n"
"<prompt>%</prompt> <userinput>cd ../dist</userinput>\n"
"<prompt>%</prompt> <userinput>comm -23 ../<replaceable>old</replaceable> ../<replaceable>new</replaceable> | xargs svn remove</userinput>\n"
"<prompt>%</prompt> <userinput>comm -13 ../<replaceable>old</replaceable> ../<replaceable>new</replaceable> | xargs svn add</userinput>"
msgstr ""

#. (itstool) path: warning/para
#: book.translate.xml:4100
msgid ""
"If there are new directories in the new distribution, the last command will "
"fail. You will have to add the directories, and run it again. Conversely, if "
"any directories were removed, you will have to remove them manually."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4107
msgid "Check properties on any new files:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4111
msgid ""
"All text files should have <literal>svn:eol-style</literal> set to "
"<literal>native</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4117
msgid ""
"All binary files should have <literal>svn:mime-type</literal> set to "
"<literal>application/octet-stream</literal>, unless there is a more "
"appropriate media type."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4124
msgid ""
"Executable files should have <literal>svn:executable</literal> set to "
"<literal>*</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4130
msgid "There should be no other properties on any file in the tree."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:4136
msgid ""
"You are ready to commit, but you should first check the output of "
"<command>svn stat</command> and <command>svn diff</command> to make sure "
"everything is in order."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4142
msgid ""
"Once you have committed the new vendor release, you should tag it for future "
"reference. The best and quickest way is to do it directly in the repository:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4146
#, no-wrap
msgid "<prompt>%</prompt> <userinput>svn copy ^/vendor/<replaceable>foo</replaceable>/dist <replaceable>svn_base</replaceable>/vendor/<replaceable>foo</replaceable>/<replaceable>9.9</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4148
msgid ""
"To get the new tag, you can update your working copy of <filename>vendor/"
"<replaceable>foo</replaceable></filename>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:4153
msgid ""
"If you choose to do the copy in the checkout instead, do not forget to "
"remove the generated <literal>svn:mergeinfo</literal> as described above."
msgstr ""

#. (itstool) path: step/title
#: book.translate.xml:4161
msgid "Merging to <emphasis>-HEAD</emphasis>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4163
msgid ""
"After you have prepared your import, it is time to merge. Option <option>--"
"accept=postpone</option> tells <acronym>SVN</acronym> not to handle merge "
"conflicts yet, because they will be taken care of manually:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4168
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cd head/contrib/<replaceable>foo</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>svn update</userinput>\n"
"<prompt>%</prompt> <userinput>svn merge --accept=postpone ^/vendor/<replaceable>foo</replaceable>/dist</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4172
msgid ""
"Resolve any conflicts, and make sure that any files that were added or "
"removed in the vendor tree have been properly added or removed in the main "
"tree. It is always a good idea to check differences against the vendor "
"branch:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:4178
#, no-wrap
msgid "<prompt>%</prompt> <userinput>svn diff --no-diff-deleted --old=^/vendor/<replaceable>foo</replaceable>/dist --new=.</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4180
msgid ""
"<option>--no-diff-deleted</option> tells <acronym>SVN</acronym> not to check "
"files that are in the vendor tree but not in the main tree."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:4185
msgid ""
"With <acronym>SVN</acronym>, there is no concept of on or off the vendor "
"branch. If a file that previously had local modifications no longer does, "
"just remove any left-over cruft, such as FreeBSD version tags, so it no "
"longer shows up in diffs against the vendor tree."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4192
msgid ""
"If any changes are required for the world to build with the new sources, "
"make them now — and test until you are satisfied that everything build and "
"runs correctly."
msgstr ""

#. (itstool) path: step/title
#: book.translate.xml:4199
msgid "Commit"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:4201
msgid ""
"Now, you are ready to commit. Make sure you get everything in one go. "
"Ideally, you would have done all steps in a clean tree, in which case you "
"can just commit from the top of that tree. That is the best way to avoid "
"surprises. If you do it properly, the tree will move atomically from a "
"consistent state with the old code to a consistent state with the new code."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:4214
msgid "Encumbered Files"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4216
msgid ""
"It might occasionally be necessary to include an encumbered file in the "
"FreeBSD source tree. For example, if a device requires a small piece of "
"binary code to be loaded to it before the device will operate, and we do not "
"have the source to that code, then the binary file is said to be encumbered. "
"The following policies apply to including encumbered files in the FreeBSD "
"source tree."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4226
msgid ""
"Any file which is interpreted or executed by the system CPU(s) and not in "
"source format is encumbered."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4231
msgid "Any file with a license more restrictive than BSD or GNU is encumbered."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4236
msgid ""
"A file which contains downloadable binary data for use by the hardware is "
"not encumbered, unless (1) or (2) apply to it. It must be stored in an "
"architecture neutral ASCII format (file2c or uuencoding is recommended)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4243
msgid ""
"Any encumbered file requires specific approval from the <link xlink:href="
"\"@@URL_RELPREFIX@@/administration.html#t-core\">Core Team</link> before it "
"is added to the repository."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4249
msgid ""
"Encumbered files go in <filename>src/contrib</filename> or <filename>src/sys/"
"contrib</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4254
msgid ""
"The entire module should be kept together. There is no point in splitting "
"it, unless there is code-sharing with non-encumbered code."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4260
msgid ""
"Object files are named <filename><replaceable>arch</replaceable>/"
"<replaceable>filename</replaceable>.o.uu&gt;</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4265
msgid "Kernel files:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4269
msgid ""
"Should always be referenced in <filename>conf/files.*</filename> (for build "
"simplicity)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4275
msgid ""
"Should always be in <filename>LINT</filename>, but the <link xlink:href="
"\"@@URL_RELPREFIX@@/administration.html#t-core\">Core Team</link> decides "
"per case if it should be commented out or not. The <link xlink:href="
"\"@@URL_RELPREFIX@@/administration.html#t-core\">Core Team</link> can, of "
"course, change their minds later on."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4284
msgid ""
"The <firstterm>Release Engineer</firstterm> decides whether or not it goes "
"into the release."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4291
msgid "User-land files:"
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:4296
msgid "<primary>core team</primary>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4295
msgid ""
"The <link xlink:href=\"@@URL_RELPREFIX@@/administration.html#t-core\">Core "
"team</link><_:indexterm-1/> decides if the code should be part of "
"<command>make world</command>."
msgstr ""

#. (itstool) path: para/indexterm
#: book.translate.xml:4303
msgid "<primary>release engineering</primary>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4302
msgid ""
"The <link xlink:href=\"@@URL_RELPREFIX@@/administration.html#t-re\">Release "
"Engineering</link><_:indexterm-1/> decides if it goes into the release."
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:4314
msgid "Shared Libraries"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:4317
msgid ""
"<personname> <firstname>Satoshi</firstname> <surname>Asami</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:4324
msgid ""
"<personname> <firstname>Peter</firstname> <surname>Wemm</surname> </"
"personname>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4339
msgid ""
"If you are adding shared library support to a port or other piece of "
"software that does not have one, the version numbers should follow these "
"rules. Generally, the resulting numbers will have nothing to do with the "
"release version of the software."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4345
msgid "The three principles of shared library building are:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4349
msgid "Start from <literal>1.0</literal>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4353
msgid ""
"If there is a change that is backwards compatible, bump minor number (note "
"that ELF systems ignore the minor number)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4359
msgid "If there is an incompatible change, bump major number"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4364
msgid ""
"For instance, added functions and bugfixes result in the minor version "
"number being bumped, while deleted functions, changed function call syntax, "
"etc. will force the major version number to change."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4369
msgid ""
"Stick to version numbers of the form major.minor (<replaceable>x</"
"replaceable>.<replaceable>y</replaceable>). Our a.out dynamic linker does "
"not handle version numbers of the form <replaceable>x</replaceable>."
"<replaceable>y</replaceable>.<replaceable>z</replaceable> well. Any version "
"number after the <replaceable>y</replaceable> (i.e., the third digit) is "
"totally ignored when comparing shared lib version numbers to decide which "
"library to link with. Given two shared libraries that differ only in the "
"<quote>micro</quote> revision, <command>ld.so</command> will link with the "
"higher one. That is, if you link with <filename>libfoo.so.3.3.3</filename>, "
"the linker only records <literal>3.3</literal> in the headers, and will link "
"with anything starting with <replaceable>libfoo.so.3</replaceable>."
"<replaceable>(anything &gt;= 3)</replaceable>.<replaceable>(highest "
"available)</replaceable>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:4388
msgid ""
"<command>ld.so</command> will always use the highest <quote>minor</quote> "
"revision. For instance, it will use <filename>libc.so.2.2</filename> in "
"preference to <filename>libc.so.2.0</filename>, even if the program was "
"initially linked with <filename>libc.so.2.0</filename>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4395
msgid ""
"In addition, our ELF dynamic linker does not handle minor version numbers at "
"all. However, one should still specify a major and minor version number as "
"our <filename>Makefile</filename>s <quote>do the right thing</quote> based "
"on the type of system."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4401
msgid ""
"For non-port libraries, it is also our policy to change the shared library "
"version number only once between releases. In addition, it is our policy to "
"change the major shared library version number only once between major OS "
"releases (i.e., from 6.0 to 7.0). When you make a change to a system library "
"that requires the version number to be bumped, check the <filename>Makefile</"
"filename>'s commit logs. It is the responsibility of the committer to ensure "
"that the first such change since the release will result in the shared "
"library version number in the <filename>Makefile</filename> to be updated, "
"and any subsequent changes will not."
msgstr ""

#. (itstool) path: chapter/title
#: book.translate.xml:4422
msgid "Regression and Performance Testing"
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:4424
msgid ""
"Regression tests are used to exercise a particular bit of the system to "
"check that it works as expected, and to make sure that old bugs are not "
"reintroduced."
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:4428
msgid ""
"The FreeBSD regression testing tools can be found in the FreeBSD source tree "
"in the directory <filename>src/tools/regression</filename>."
msgstr ""

#. (itstool) path: section/title
#: book.translate.xml:4433
msgid "Micro Benchmark Checklist"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4435
msgid ""
"This section contains hints for doing proper micro-benchmarking on FreeBSD "
"or of FreeBSD itself."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4438
msgid ""
"It is not possible to use all of the suggestions below every single time, "
"but the more used, the better the benchmark's ability to test small "
"differences will be."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4444
msgid ""
"Disable <acronym>APM</acronym> and any other kind of clock fiddling "
"(<acronym>ACPI</acronym> ?)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4449
msgid ""
"Run in single user mode. E.g., <citerefentry><refentrytitle>cron</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry>, and other daemons "
"only add noise. The <citerefentry><refentrytitle>sshd</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> daemon can also cause "
"problems. If ssh access is required during testing either disable the SSHv1 "
"key regeneration, or kill the parent <command>sshd</command> daemon during "
"the tests."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4458
msgid ""
"Do not run <citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4462
msgid ""
"If <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> events are generated, run "
"<citerefentry><refentrytitle>syslogd</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> with an empty <filename>/etc/syslogd.conf</"
"filename>, otherwise, do not run it."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4469
msgid "Minimize disk-I/O, avoid it entirely if possible."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4473
msgid "Do not mount file systems that are not needed."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4477
msgid ""
"Mount <filename>/</filename>, <filename>/usr</filename>, and any other file "
"system as read-only if possible. This removes atime updates to disk (etc.) "
"from the I/O picture."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4484
msgid ""
"Reinitialize the read/write test file system with "
"<citerefentry><refentrytitle>newfs</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> and populate it from a <citerefentry><refentrytitle>tar</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry> or "
"<citerefentry><refentrytitle>dump</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> file before every run. Unmount and mount it before starting "
"the test. This results in a consistent file system layout. For a worldstone "
"test this would apply to <filename>/usr/obj</filename> (just reinitialize "
"with <command>newfs</command> and mount). To get 100% reproducibility, "
"populate the file system from a <citerefentry><refentrytitle>dd</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry> file (i.e.: "
"<command>dd if=myimage of=/dev/ad0s1h bs=1m</command>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4498
msgid ""
"Use malloc backed or preloaded <citerefentry><refentrytitle>md</"
"refentrytitle><manvolnum>4</manvolnum></citerefentry> partitions."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4503
msgid ""
"Reboot between individual iterations of the test, this gives a more "
"consistent state."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4508
msgid ""
"Remove all non-essential device drivers from the kernel. For instance if USB "
"is not needed for the test, do not put USB in the kernel. Drivers which "
"attach often have timeouts ticking away."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4515
msgid ""
"Unconfigure hardware that are not in use. Detach disks with "
"<citerefentry><refentrytitle>atacontrol</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>camcontrol</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> if the disks are not "
"used for the test."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4521
msgid ""
"Do not configure the network unless it is being tested, or wait until after "
"the test has been performed to ship the results off to another computer."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4525
msgid ""
"If the system must be connected to a public network, watch out for spikes of "
"broadcast traffic. Even though it is hardly noticeable, it will take up CPU "
"cycles. Multicast has similar caveats."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4532
msgid ""
"Put each file system on its own disk. This minimizes jitter from head-seek "
"optimizations."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4537
msgid ""
"Minimize output to serial or VGA consoles. Running output into files gives "
"less jitter. (Serial consoles easily become a bottleneck.) Do not touch "
"keyboard while the test is running, even <keycap>space</keycap> or "
"<keycap>back-space</keycap> shows up in the numbers."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4545
msgid ""
"Make sure the test is long enough, but not too long. If the test is too "
"short, timestamping is a problem. If it is too long temperature changes and "
"drift will affect the frequency of the quartz crystals in the computer. Rule "
"of thumb: more than a minute, less than an hour."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4553
msgid ""
"Try to keep the temperature as stable as possible around the machine. This "
"affects both quartz crystals and disk drive algorithms. To get real stable "
"clock, consider stabilized clock injection. E.g., get a OCXO + PLL, inject "
"output into clock circuits instead of motherboard xtal. Contact Poul-Henning "
"Kamp <email>phk@FreeBSD.org</email> for more information about this."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4563
msgid ""
"Run the test at least 3 times but it is better to run more than 20 times "
"both for <quote>before</quote> and <quote>after</quote> code. Try to "
"interleave if possible (i.e.: do not run 20 times before then 20 times "
"after), this makes it possible to spot environmental effects. Do not "
"interleave 1:1, but 3:3, this makes it possible to spot interaction effects."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4571
msgid ""
"A good pattern is: <literal>bababa{bbbaaa}*</literal>. This gives hint after "
"the first 1+1 runs (so it is possible to stop the test if it goes entirely "
"the wrong way), a standard deviation after the first 3+3 (gives a good "
"indication if it is going to be worth a long run) and trending and "
"interaction numbers later on."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4580
msgid ""
"Use <citerefentry><refentrytitle>ministat</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry> to see if the numbers are significant. Consider "
"buying <quote>Cartoon guide to statistics</quote> ISBN: 0062731025, highly "
"recommended, if you have forgotten or never learned about standard deviation "
"and Student's T."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4589
msgid ""
"Do not use background <citerefentry><refentrytitle>fsck</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> unless the test is a "
"benchmark of background <command>fsck</command>. Also, disable "
"<varname>background_fsck</varname> in <filename>/etc/rc.conf</filename> "
"unless the benchmark is not started at least 60+<quote><command>fsck</"
"command> runtime</quote> seconds after the boot, as "
"<citerefentry><refentrytitle>rc</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> wakes up and checks if <command>fsck</command> needs to run on "
"any file systems when background <command>fsck</command> is enabled. "
"Likewise, make sure there are no snapshots lying around unless the benchmark "
"is a test with snapshots."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4603
msgid ""
"If the benchmark show unexpected bad performance, check for things like high "
"interrupt volume from an unexpected source. Some versions of <acronym>ACPI</"
"acronym> have been reported to <quote>misbehave</quote> and generate excess "
"interrupts. To help diagnose odd test results, take a few snapshots of "
"<command>vmstat -i</command> and look for anything unusual."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4613
msgid ""
"Make sure to be careful about optimization parameters for kernel and "
"userspace, likewise debugging. It is easy to let something slip through and "
"realize later the test was not comparing the same thing."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4620
msgid ""
"Do not ever benchmark with the <literal>WITNESS</literal> and "
"<literal>INVARIANTS</literal> kernel options enabled unless the test is "
"interested to benchmarking those features. <literal>WITNESS</literal> can "
"cause 400%+ drops in performance. Likewise, userspace "
"<citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum></"
"citerefentry> parameters default differently in -CURRENT from the way they "
"ship in production releases."
msgstr ""

#. (itstool) path: section/title
#: book.translate.xml:4632
msgid "The FreeBSD Source Tinderbox"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4634
msgid "The source Tinderbox consists of:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4638
msgid ""
"A build script, <filename>tinderbox</filename>, that automates checking out "
"a specific version of the FreeBSD source tree and building it."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4643
msgid ""
"A supervisor script, <filename>tbmaster</filename>, that monitors individual "
"Tinderbox instances, logs their output, and emails failure notices."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4648
msgid ""
"A <acronym>CGI</acronym> script named <filename>index.cgi</filename> that "
"reads a set of tbmaster logs and presents an easy-to-read <acronym>HTML</"
"acronym> summary of them."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4654
msgid ""
"A set of build servers that continually test the tip of the most important "
"FreeBSD code branches."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4658
msgid ""
"A webserver that keeps a complete set of Tinderbox logs and displays an up-"
"to-date summary."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4663
msgid ""
"The scripts are maintained and were developed by Dag-Erling Smørgrav "
"<email>des@FreeBSD.org</email>, and are now written in Perl, a move on from "
"their original incarnation as shell scripts. All scripts and configuration "
"files are kept in <link xlink:href=\"https://www.freebsd.org/cgi/cvsweb.cgi/"
"projects/tinderbox/\">/projects/tinderbox/</link>."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4668
msgid ""
"For more information about the tinderbox and tbmaster scripts at this stage, "
"see their respective man pages: tinderbox(1) and tbmaster(1)."
msgstr ""

#. (itstool) path: section/title
#: book.translate.xml:4673
msgid "The <filename>index.cgi</filename> Script"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4675
msgid ""
"The <filename>index.cgi</filename> script generates the <acronym>HTML</"
"acronym> summary of tinderbox and tbmaster logs. Although originally "
"intended to be used as a <acronym>CGI</acronym> script, as indicated by its "
"name, this script can also be run from the command line or from a "
"<citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> job, in which case it will look for logs in the directory "
"where the script is located. It will automatically detect context, "
"generating <acronym>HTTP</acronym> headers when it is run as a <acronym>CGI</"
"acronym> script. It conforms to <acronym>XHTML</acronym> standards and is "
"styled using <acronym>CSS</acronym>."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4687
msgid ""
"The script starts in the <function>main()</function> block by attempting to "
"verify that it is running on the official Tinderbox website. If it is not, a "
"page indicating it is not an official website is produced, and a "
"<acronym>URL</acronym> to the official site is provided."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4693
msgid ""
"Next, it scans the log directory to get an inventory of configurations, "
"branches and architectures for which log files exist, to avoid hard-coding a "
"list into the script and potentially ending up with blank rows or columns. "
"This information is derived from the names of the log files matching the "
"following pattern:"
msgstr ""

#. (itstool) path: section/programlisting
#: book.translate.xml:4700
#, no-wrap
msgid "tinderbox-$config-$branch-$arch-$machine.{brief,full}"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4702
msgid ""
"The configurations used on the official Tinderbox build servers are named "
"for the branches they build. For example, the <literal>releng_8</literal> "
"configuration is used to build <literal>RELENG_8</literal> as well as all "
"still-supported release branches."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4708
msgid ""
"Once all of this startup procedure has been successfully completed, "
"<function>do_config()</function> is called for each configuration."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4712
msgid ""
"The <function>do_config()</function> function generates <acronym>HTML</"
"acronym> for a single Tinderbox configuration."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4716
msgid ""
"It works by first generating a header row, then iterating over each branch "
"build with the specified configuration, producing a single row of results "
"for each in the following manner:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4723
msgid "For each item:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4726
msgid "For each machine within that architecture:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4729
msgid "If a brief log file exists, then:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4732
msgid ""
"Call <function>success()</function> to determine the outcome of the build."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4736
msgid "Output the modification size."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4739
msgid ""
"Output the size of the brief log file with a link to the log file itself."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4743
msgid "If a full log file also exists, then:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4747
msgid ""
"Output the size of the full log file with a link to the log file itself."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4755
msgid "Otherwise:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4758
msgid "No output."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4768
msgid ""
"The <function>success()</function> function mentioned above scans a brief "
"log file for the string <quote>tinderbox run completed</quote> in order to "
"determine whether the build was successful."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4773
msgid ""
"Configurations and branches are sorted according to their branch rank. This "
"is computed as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4778
msgid "<literal>HEAD</literal> and <literal>CURRENT</literal> have rank 9999."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4782
msgid ""
"<literal>RELENG_<replaceable>x</replaceable></literal> has rank "
"<replaceable>xx</replaceable>99."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4786
msgid ""
"<literal>RELENG_<replaceable>x</replaceable>_<replaceable>y</replaceable></"
"literal> has rank <replaceable>xxyy</replaceable>."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4791
msgid ""
"This means that <literal>HEAD</literal> always ranks highest, and "
"<literal>RELENG</literal> branches are ranked in numerical order, with each "
"<literal>STABLE</literal> branch ranking higher than the release branches "
"forked off of it. For instance, for FreeBSD 8, the order from highest to "
"lowest would be:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4800
msgid "<literal>RELENG_8</literal> (branch rank 899)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4803
msgid "<literal>RELENG_8_3</literal> (branch rank 803)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4807
msgid "<literal>RELENG_8_2</literal> (branch rank 802)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4811
msgid "<literal>RELENG_8_1</literal> (branch rank 801)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4815
msgid "<literal>RELENG_8_0</literal> (branch rank 800)."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4820
msgid ""
"The colors that Tinderbox uses for each cell in the table are defined by "
"<acronym>CSS</acronym>. Successful builds are displayed with green text; "
"unsuccessful builds are displayed with red text. The color fades as time "
"passes since the corresponding build, with every half an hour bringing the "
"color closer to grey."
msgstr ""

#. (itstool) path: section/title
#: book.translate.xml:4829
msgid "Official Build Servers"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4831
msgid ""
"The official Tinderbox build servers are hosted by <link xlink:href=\"http://"
"www.sentex.ca\">Sentex Data Communications</link>, who also host the FreeBSD "
"Netperf Cluster."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4835
msgid "Three build servers currently exist:"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4837
msgid "<emphasis>freebsd-current.sentex.ca</emphasis> builds:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4842
msgid ""
"<literal>HEAD</literal> for amd64, arm, i386, i386/pc98, ia64, mips, "
"powerpc, powerpc64, and sparc64."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4847
msgid ""
"<literal>RELENG_9</literal> and supported 9.<replaceable>X</replaceable> "
"branches for amd64, arm, i386, i386/pc98, ia64, mips, powerpc, powerpc64, "
"and sparc64."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4854
msgid "<emphasis>freebsd-stable.sentex.ca</emphasis> builds:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4859
msgid ""
"<literal>RELENG_8</literal> and supported 8.<replaceable>X</replaceable> "
"branches for amd64, i386, i386/pc98, ia64, mips, powerpc and sparc64."
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4865
msgid "<emphasis>freebsd-legacy.sentex.ca</emphasis> builds:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4870
msgid ""
"<literal>RELENG_7</literal> and supported 7.<replaceable>X</replaceable> "
"branches for amd64, i386, i386/pc98, ia64, powerpc, and sparc64."
msgstr ""

#. (itstool) path: section/title
#: book.translate.xml:4878
msgid "Official Summary Site"
msgstr ""

#. (itstool) path: section/para
#: book.translate.xml:4880
msgid ""
"Summaries and logs from the official build servers are available online at "
"<link xlink:href=\"http://tinderbox.FreeBSD.org\">http://tinderbox.FreeBSD."
"org</link>, hosted by Dag-Erling Smørgrav <email>des@FreeBSD.org</email> and "
"set up as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4886
msgid ""
"A <citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> job checks the build servers at regular intervals and "
"downloads any new log files using <citerefentry vendor=\"ports"
"\"><refentrytitle>rsync</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:4891
msgid ""
"Apache is set up to use <filename>index.cgi</filename> as "
"<literal>DirectoryIndex</literal>."
msgstr ""

#. (itstool) path: part/title
#: book.translate.xml:4902
msgid "Interprocess Communication"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:4912
msgid "Sockets"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:4915
msgid ""
"<personname> <firstname>G. Adam</firstname> <surname>Stanislav</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4928
msgid ""
"<acronym>BSD</acronym> sockets take interprocess communications to a new "
"level. It is no longer necessary for the communicating processes to run on "
"the same machine. They still <emphasis>can</emphasis>, but they do not have "
"to."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4933
msgid ""
"Not only do these processes not have to run on the same machine, they do not "
"have to run under the same operating system. Thanks to <acronym>BSD</"
"acronym> sockets, your FreeBSD software can smoothly cooperate with a "
"program running on a <trademark class=\"registered\">Macintosh</trademark>, "
"another one running on a <trademark>Sun</trademark> workstation, yet another "
"one running under <trademark class=\"registered\">Windows</trademark> 2000, "
"all connected with an Ethernet-based local area network."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4941
msgid ""
"But your software can equally well cooperate with processes running in "
"another building, or on another continent, inside a submarine, or a space "
"shuttle."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4945
msgid ""
"It can also cooperate with processes that are not part of a computer (at "
"least not in the strict sense of the word), but of such devices as printers, "
"digital cameras, medical equipment. Just about anything capable of digital "
"communications."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:4953
msgid "Networking and Diversity"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4955
msgid ""
"We have already hinted on the <emphasis>diversity</emphasis> of networking. "
"Many different systems have to talk to each other. And they have to speak "
"the same language. They also have to <emphasis>understand</emphasis> the "
"same language the same way."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4961
msgid ""
"People often think that <emphasis>body language</emphasis> is universal. But "
"it is not. Back in my early teens, my father took me to Bulgaria. We were "
"sitting at a table in a park in Sofia, when a vendor approached us trying to "
"sell us some roasted almonds."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4967
msgid ""
"I had not learned much Bulgarian by then, so, instead of saying no, I shook "
"my head from side to side, the <quote>universal</quote> body language for "
"<emphasis>no</emphasis>. The vendor quickly started serving us some almonds."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4973
msgid ""
"I then remembered I had been told that in Bulgaria shaking your head "
"sideways meant <emphasis>yes</emphasis>. Quickly, I started nodding my head "
"up and down. The vendor noticed, took his almonds, and walked away. To an "
"uninformed observer, I did not change the body language: I continued using "
"the language of shaking and nodding my head. What changed was the "
"<emphasis>meaning</emphasis> of the body language. At first, the vendor and "
"I interpreted the same language as having completely different meaning. I "
"had to adjust my own interpretation of that language so the vendor would "
"understand."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4985
msgid ""
"It is the same with computers: The same symbols may have different, even "
"outright opposite meaning. Therefore, for two computers to understand each "
"other, they must not only agree on the same <emphasis>language</emphasis>, "
"but on the same <emphasis>interpretation</emphasis> of the language."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:4993
msgid "Protocols"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:4995
msgid ""
"While various programming languages tend to have complex syntax and use a "
"number of multi-letter reserved words (which makes them easy for the human "
"programmer to understand), the languages of data communications tend to be "
"very terse. Instead of multi-byte words, they often use individual "
"<emphasis>bits</emphasis>. There is a very convincing reason for it: While "
"data travels <emphasis>inside</emphasis> your computer at speeds approaching "
"the speed of light, it often travels considerably slower between two "
"computers."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5005
msgid ""
"Because the languages used in data communications are so terse, we usually "
"refer to them as <emphasis>protocols</emphasis> rather than languages."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5009
msgid ""
"As data travels from one computer to another, it always uses more than one "
"protocol. These protocols are <emphasis>layered</emphasis>. The data can be "
"compared to the inside of an onion: You have to peel off several layers of "
"<quote>skin</quote> to get to the data. This is best illustrated with a "
"picture:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5018
msgctxt "_"
msgid "external ref='sockets/layers' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5022
#, no-wrap
msgid ""
"+----------------+\n"
"|    Ethernet    |\n"
"|+--------------+|\n"
"||      IP      ||\n"
"||+------------+||\n"
"|||     TCP    |||\n"
"|||+----------+|||\n"
"||||   HTTP   ||||\n"
"||||+--------+||||\n"
"|||||   PNG  |||||\n"
"|||||+------+|||||\n"
"|||||| Data ||||||\n"
"|||||+------+|||||\n"
"||||+--------+||||\n"
"|||+----------+|||\n"
"||+------------+||\n"
"|+--------------+|\n"
"+----------------+"
msgstr ""

#. (itstool) path: sect1/mediaobject
#: book.translate.xml:5016
msgid ""
"<imageobject> <imagedata fileref=\"sockets/layers\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>Protocol Layers</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5047
msgid ""
"In this example, we are trying to get an image from a web page we are "
"connected to via an Ethernet."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5050
msgid ""
"The image consists of raw data, which is simply a sequence of <acronym>RGB</"
"acronym> values that our software can process, i.e., convert into an image "
"and display on our monitor."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5054
msgid ""
"Alas, our software has no way of knowing how the raw data is organized: Is "
"it a sequence of <acronym>RGB</acronym> values, or a sequence of grayscale "
"intensities, or perhaps of <acronym>CMYK</acronym> encoded colors? Is the "
"data represented by 8-bit quanta, or are they 16 bits in size, or perhaps 4 "
"bits? How many rows and columns does the image consist of? Should certain "
"pixels be transparent?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5062
msgid "I think you get the picture..."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5064
msgid ""
"To inform our software how to handle the raw data, it is encoded as a "
"<acronym>PNG</acronym> file. It could be a <acronym>GIF</acronym>, or a "
"<acronym>JPEG</acronym>, but it is a <acronym>PNG</acronym>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5069
msgid "And <acronym>PNG</acronym> is a protocol."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5071
msgid ""
"At this point, I can hear some of you yelling, <emphasis><quote>No, it is "
"not! It is a file format!</quote></emphasis>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5075
msgid ""
"Well, of course it is a file format. But from the perspective of data "
"communications, a file format is a protocol: The file structure is a "
"<emphasis>language</emphasis>, a terse one at that, communicating to our "
"<emphasis>process</emphasis> how the data is organized. Ergo, it is a "
"<emphasis>protocol</emphasis>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5082
msgid ""
"Alas, if all we received was the <acronym>PNG</acronym> file, our software "
"would be facing a serious problem: How is it supposed to know the data is "
"representing an image, as opposed to some text, or perhaps a sound, or what "
"not? Secondly, how is it supposed to know the image is in the <acronym>PNG</"
"acronym> format as opposed to <acronym>GIF</acronym>, or <acronym>JPEG</"
"acronym>, or some other image format?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5090
msgid ""
"To obtain that information, we are using another protocol: <acronym>HTTP</"
"acronym>. This protocol can tell us exactly that the data represents an "
"image, and that it uses the <acronym>PNG</acronym> protocol. It can also "
"tell us some other things, but let us stay focused on protocol layers here."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5096
msgid ""
"So, now we have some data wrapped in the <acronym>PNG</acronym> protocol, "
"wrapped in the <acronym>HTTP</acronym> protocol. How did we get it from the "
"server?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5101
msgid ""
"By using <acronym>TCP/IP</acronym> over Ethernet, that is how. Indeed, that "
"is three more protocols. Instead of continuing inside out, I am now going to "
"talk about Ethernet, simply because it is easier to explain the rest that "
"way."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5106
msgid ""
"Ethernet is an interesting system of connecting computers in a "
"<emphasis>local area network</emphasis> (<acronym>LAN</acronym>). Each "
"computer has a <emphasis>network interface card</emphasis> (<acronym>NIC</"
"acronym>), which has a unique 48-bit <acronym>ID</acronym> called its "
"<emphasis>address</emphasis>. No two Ethernet <acronym>NIC</acronym>s in the "
"world have the same address."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5115
msgid ""
"These <acronym>NIC</acronym>s are all connected with each other. Whenever "
"one computer wants to communicate with another in the same Ethernet "
"<acronym>LAN</acronym>, it sends a message over the network. Every "
"<acronym>NIC</acronym> sees the message. But as part of the Ethernet "
"<emphasis>protocol</emphasis>, the data contains the address of the "
"destination <acronym>NIC</acronym> (among other things). So, only one of all "
"the network interface cards will pay attention to it, the rest will ignore "
"it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5125
msgid ""
"But not all computers are connected to the same network. Just because we "
"have received the data over our Ethernet does not mean it originated in our "
"own local area network. It could have come to us from some other network "
"(which may not even be Ethernet based) connected with our own network via "
"the Internet."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5132
msgid ""
"All data is transferred over the Internet using <acronym>IP</acronym>, which "
"stands for <emphasis>Internet Protocol</emphasis>. Its basic role is to let "
"us know where in the world the data has arrived from, and where it is "
"supposed to go to. It does not <emphasis>guarantee</emphasis> we will "
"receive the data, only that we will know where it came from <emphasis>if</"
"emphasis> we do receive it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5140
msgid ""
"Even if we do receive the data, <acronym>IP</acronym> does not guarantee we "
"will receive various chunks of data in the same order the other computer has "
"sent it to us. So, we can receive the center of our image before we receive "
"the upper left corner and after the lower right, for example."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5146
msgid ""
"It is <acronym>TCP</acronym> (<emphasis>Transmission Control Protocol</"
"emphasis>) that asks the sender to resend any lost data and that places it "
"all into the proper order."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5150
msgid ""
"All in all, it took <emphasis>five</emphasis> different protocols for one "
"computer to communicate to another what an image looks like. We received the "
"data wrapped into the <acronym>PNG</acronym> protocol, which was wrapped "
"into the <acronym>HTTP</acronym> protocol, which was wrapped into the "
"<acronym>TCP</acronym> protocol, which was wrapped into the <acronym>IP</"
"acronym> protocol, which was wrapped into the <acronym>Ethernet</acronym> "
"protocol."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5159
msgid ""
"Oh, and by the way, there probably were several other protocols involved "
"somewhere on the way. For example, if our <acronym>LAN</acronym> was "
"connected to the Internet through a dial-up call, it used the <acronym>PPP</"
"acronym> protocol over the modem which used one (or several) of the various "
"modem protocols, et cetera, et cetera, et cetera..."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5166
msgid ""
"As a developer you should be asking by now, <emphasis><quote>How am I "
"supposed to handle it all?</quote></emphasis>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5170
msgid ""
"Luckily for you, you are <emphasis>not</emphasis> supposed to handle it all. "
"You <emphasis>are</emphasis> supposed to handle some of it, but not all of "
"it. Specifically, you need not worry about the physical connection (in our "
"case Ethernet and possibly <acronym>PPP</acronym>, etc). Nor do you need to "
"handle the Internet Protocol, or the Transmission Control Protocol."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5178
msgid ""
"In other words, you do not have to do anything to receive the data from the "
"other computer. Well, you do have to <emphasis>ask</emphasis> for it, but "
"that is almost as simple as opening a file."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5183
msgid ""
"Once you have received the data, it is up to you to figure out what to do "
"with it. In our case, you would need to understand the <acronym>HTTP</"
"acronym> protocol and the <acronym>PNG</acronym> file structure."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5188
msgid ""
"To use an analogy, all the internetworking protocols become a gray area: Not "
"so much because we do not understand how it works, but because we are no "
"longer concerned about it. The sockets interface takes care of this gray "
"area for us:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5195
msgctxt "_"
msgid "external ref='sockets/slayers' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5199
#, no-wrap
msgid ""
"+----------------+\n"
"|xxxxEthernetxxxx|\n"
"|+--------------+|\n"
"||xxxxxxIPxxxxxx||\n"
"||+------------+||\n"
"|||xxxxxTCPxxxx|||\n"
"|||+----------+|||\n"
"||||   HTTP   ||||\n"
"||||+--------+||||\n"
"|||||   PNG  |||||\n"
"|||||+------+|||||\n"
"|||||| Data ||||||\n"
"|||||+------+|||||\n"
"||||+--------+||||\n"
"|||+----------+|||\n"
"||+------------+||\n"
"|+--------------+|\n"
"+----------------+"
msgstr ""

#. (itstool) path: sect1/mediaobject
#: book.translate.xml:5193
msgid ""
"<imageobject> <imagedata fileref=\"sockets/slayers\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>Sockets "
"Covered Protocol Layers</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5224
msgid ""
"We only need to understand any protocols that tell us how to "
"<emphasis>interpret the data</emphasis>, not how to <emphasis>receive</"
"emphasis> it from another process, nor how to <emphasis>send</emphasis> it "
"to another process."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:5232
msgid "The Sockets Model"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5234
msgid ""
"<acronym>BSD</acronym> sockets are built on the basic <trademark class="
"\"registered\">UNIX</trademark> model: <emphasis>Everything is a file.</"
"emphasis> In our example, then, sockets would let us receive an "
"<emphasis>HTTP file</emphasis>, so to speak. It would then be up to us to "
"extract the <emphasis><acronym>PNG</acronym> file</emphasis> from it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5241
msgid ""
"Because of the complexity of internetworking, we cannot just use the "
"<function role=\"syscall\">open</function> system call, or the "
"<function>open()</function> C function. Instead, we need to take several "
"steps to <quote>opening</quote> a socket."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5246
msgid ""
"Once we do, however, we can start treating the <emphasis>socket</emphasis> "
"the same way we treat any <emphasis>file descriptor</emphasis>: We can "
"<function>read</function> from it, <function>write</function> to it, "
"<function>pipe</function> it, and, eventually, <function>close</function> it."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:5256
msgid "Essential Socket Functions"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:5258
msgid ""
"While FreeBSD offers different functions to work with sockets, we only "
"<emphasis>need</emphasis> four to <quote>open</quote> a socket. And in some "
"cases we only need two."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:5264
msgid "The Client-Server Difference"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:5266
msgid ""
"Typically, one of the ends of a socket-based data communication is a "
"<emphasis>server</emphasis>, the other is a <emphasis>client</emphasis>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:5271
msgid "The Common Elements"
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5274
msgid "<function>socket</function>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5276
msgid ""
"The one function used by both, clients and servers, is "
"<citerefentry><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></"
"citerefentry>. It is declared this way:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5279
#, no-wrap
msgid "int socket(int domain, int type, int protocol);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5281
msgid ""
"The return value is of the same type as that of <function>open</function>, "
"an integer. FreeBSD allocates its value from the same pool as that of file "
"handles. That is what allows sockets to be treated the same way as files."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5287
msgid ""
"The <varname>domain</varname> argument tells the system what "
"<emphasis>protocol family</emphasis> you want it to use. Many of them exist, "
"some are vendor specific, others are very common. They are declared in "
"<filename>sys/socket.h</filename>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5293
msgid ""
"Use <constant>PF_INET</constant> for <acronym>UDP</acronym>, <acronym>TCP</"
"acronym> and other Internet protocols (<acronym>IP</acronym>v4)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5297
msgid ""
"Five values are defined for the <varname>type</varname> argument, again, in "
"<filename>sys/socket.h</filename>. All of them start with "
"<quote><constant>SOCK_</constant></quote>. The most common one is "
"<constant>SOCK_STREAM</constant>, which tells the system you are asking for "
"a <emphasis>reliable stream delivery service</emphasis> (which is "
"<acronym>TCP</acronym> when used with <constant>PF_INET</constant>)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5307
msgid ""
"If you asked for <constant>SOCK_DGRAM</constant>, you would be requesting a "
"<emphasis>connectionless datagram delivery service</emphasis> (in our case, "
"<acronym>UDP</acronym>)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5312
msgid ""
"If you wanted to be in charge of the low-level protocols (such as "
"<acronym>IP</acronym>), or even network interfaces (e.g., the Ethernet), you "
"would need to specify <constant>SOCK_RAW</constant>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5317
msgid ""
"Finally, the <varname>protocol</varname> argument depends on the previous "
"two arguments, and is not always meaningful. In that case, use <constant>0</"
"constant> for its value."
msgstr ""

#. (itstool) path: note/title
#: book.translate.xml:5323
msgid "The Unconnected Socket"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:5325
msgid ""
"Nowhere, in the <function>socket</function> function have we specified to "
"what other system we should be connected. Our newly created socket remains "
"<emphasis>unconnected</emphasis>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:5330
msgid ""
"This is on purpose: To use a telephone analogy, we have just attached a "
"modem to the phone line. We have neither told the modem to make a call, nor "
"to answer if the phone rings."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5339
msgid "<varname>sockaddr</varname>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5341
msgid ""
"Various functions of the sockets family expect the address of (or pointer "
"to, to use C terminology) a small area of the memory. The various C "
"declarations in the <filename>sys/socket.h</filename> refer to it as "
"<varname>struct sockaddr</varname>. This structure is declared in the same "
"file:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5348
#, no-wrap
msgid ""
"/*\n"
" * Structure used by kernel to store most\n"
" * addresses.\n"
" */\n"
"struct sockaddr {\n"
"\tunsigned char\tsa_len;\t\t/* total length */\n"
"\tsa_family_t\tsa_family;\t/* address family */\n"
"\tchar\t\tsa_data[14];\t/* actually longer; address value */\n"
"};\n"
"#define\tSOCK_MAXADDRLEN\t255\t\t/* longest possible addresses */"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5359
msgid ""
"Please note the <emphasis>vagueness</emphasis> with which the "
"<varname>sa_data</varname> field is declared, just as an array of "
"<constant>14</constant> bytes, with the comment hinting there can be more "
"than <constant>14</constant> of them."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5365
msgid ""
"This vagueness is quite deliberate. Sockets is a very powerful interface. "
"While most people perhaps think of it as nothing more than the Internet "
"interface—and most applications probably use it for that nowadays—sockets "
"can be used for just about <emphasis>any</emphasis> kind of interprocess "
"communications, of which the Internet (or, more precisely, <acronym>IP</"
"acronym>) is only one."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5374
msgid ""
"The <filename>sys/socket.h</filename> refers to the various types of "
"protocols sockets will handle as <emphasis>address families</emphasis>, and "
"lists them right before the definition of <varname>sockaddr</varname>:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5380
#, no-wrap
msgid ""
"/*\n"
" * Address families.\n"
" */\n"
"#define\tAF_UNSPEC\t0\t\t/* unspecified */\n"
"#define\tAF_LOCAL\t1\t\t/* local to host (pipes, portals) */\n"
"#define\tAF_UNIX\t\tAF_LOCAL\t/* backward compatibility */\n"
"#define\tAF_INET\t\t2\t\t/* internetwork: UDP, TCP, etc. */\n"
"#define\tAF_IMPLINK\t3\t\t/* arpanet imp addresses */\n"
"#define\tAF_PUP\t\t4\t\t/* pup protocols: e.g. BSP */\n"
"#define\tAF_CHAOS\t5\t\t/* mit CHAOS protocols */\n"
"#define\tAF_NS\t\t6\t\t/* XEROX NS protocols */\n"
"#define\tAF_ISO\t\t7\t\t/* ISO protocols */\n"
"#define\tAF_OSI\t\tAF_ISO\n"
"#define\tAF_ECMA\t\t8\t\t/* European computer manufacturers */\n"
"#define\tAF_DATAKIT\t9\t\t/* datakit protocols */\n"
"#define\tAF_CCITT\t10\t\t/* CCITT protocols, X.25 etc */\n"
"#define\tAF_SNA\t\t11\t\t/* IBM SNA */\n"
"#define AF_DECnet\t12\t\t/* DECnet */\n"
"#define AF_DLI\t\t13\t\t/* DEC Direct data link interface */\n"
"#define AF_LAT\t\t14\t\t/* LAT */\n"
"#define\tAF_HYLINK\t15\t\t/* NSC Hyperchannel */\n"
"#define\tAF_APPLETALK\t16\t\t/* Apple Talk */\n"
"#define\tAF_ROUTE\t17\t\t/* Internal Routing Protocol */\n"
"#define\tAF_LINK\t\t18\t\t/* Link layer interface */\n"
"#define\tpseudo_AF_XTP\t19\t\t/* eXpress Transfer Protocol (no AF) */\n"
"#define\tAF_COIP\t\t20\t\t/* connection-oriented IP, aka ST II */\n"
"#define\tAF_CNT\t\t21\t\t/* Computer Network Technology */\n"
"#define pseudo_AF_RTIP\t22\t\t/* Help Identify RTIP packets */\n"
"#define\tAF_IPX\t\t23\t\t/* Novell Internet Protocol */\n"
"#define\tAF_SIP\t\t24\t\t/* Simple Internet Protocol */\n"
"#define\tpseudo_AF_PIP\t25\t\t/* Help Identify PIP packets */\n"
"#define\tAF_ISDN\t\t26\t\t/* Integrated Services Digital Network*/\n"
"#define\tAF_E164\t\tAF_ISDN\t\t/* CCITT E.164 recommendation */\n"
"#define\tpseudo_AF_KEY\t27\t\t/* Internal key-management function */\n"
"#define\tAF_INET6\t28\t\t/* IPv6 */\n"
"#define\tAF_NATM\t\t29\t\t/* native ATM access */\n"
"#define\tAF_ATM\t\t30\t\t/* ATM */\n"
"#define pseudo_AF_HDRCMPLT 31\t\t/* Used by BPF to not rewrite headers\n"
"\t\t\t\t\t * in interface output routine\n"
"\t\t\t\t\t */\n"
"#define\tAF_NETGRAPH\t32\t\t/* Netgraph sockets */\n"
"#define\tAF_SLOW\t\t33\t\t/* 802.3ad slow protocol */\n"
"#define\tAF_SCLUSTER\t34\t\t/* Sitara cluster protocol */\n"
"#define\tAF_ARP\t\t35\n"
"#define\tAF_BLUETOOTH\t36\t\t/* Bluetooth sockets */\n"
"#define\tAF_MAX\t\t37"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5427
msgid ""
"The one used for <acronym>IP</acronym> is <symbol>AF_INET</symbol>. It is a "
"symbol for the constant <constant>2</constant>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5431
msgid ""
"It is the <emphasis>address family</emphasis> listed in the "
"<varname>sa_family</varname> field of <varname>sockaddr</varname> that "
"decides how exactly the vaguely named bytes of <varname>sa_data</varname> "
"will be used."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5437
msgid ""
"Specifically, whenever the <emphasis>address family</emphasis> is "
"<symbol>AF_INET</symbol>, we can use <varname>struct sockaddr_in</varname> "
"found in <filename>netinet/in.h</filename>, wherever <varname>sockaddr</"
"varname> is expected:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5443
#, no-wrap
msgid ""
"/*\n"
" * Socket address, internet style.\n"
" */\n"
"struct sockaddr_in {\n"
"\tuint8_t\t\tsin_len;\n"
"\tsa_family_t\tsin_family;\n"
"\tin_port_t\tsin_port;\n"
"\tstruct\tin_addr sin_addr;\n"
"\tchar\tsin_zero[8];\n"
"};"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5454
msgid "We can visualize its organization this way:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5458
msgctxt "_"
msgid "external ref='sockets/sain' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5462
#, no-wrap
msgid ""
"        0        1        2       3\n"
"   +--------+--------+-----------------+\n"
" 0 |    0   | Family |       Port      |\n"
"   +--------+--------+-----------------+\n"
" 4 |             IP Address            |\n"
"   +-----------------------------------+\n"
" 8 |                 0                 |\n"
"   +-----------------------------------+\n"
"12 |                 0                 |\n"
"   +-----------------------------------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5456
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sain\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>sockaddr_in</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5479
msgid ""
"The three important fields are <varname>sin_family</varname>, which is byte "
"1 of the structure, <varname>sin_port</varname>, a 16-bit value found in "
"bytes 2 and 3, and <varname>sin_addr</varname>, a 32-bit integer "
"representation of the <acronym>IP</acronym> address, stored in bytes 4-7."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5486
msgid ""
"Now, let us try to fill it out. Let us assume we are trying to write a "
"client for the <emphasis>daytime</emphasis> protocol, which simply states "
"that its server will write a text string representing the current date and "
"time to port 13. We want to use <acronym>TCP/IP</acronym>, so we need to "
"specify <constant>AF_INET</constant> in the address family field. "
"<constant>AF_INET</constant> is defined as <constant>2</constant>. Let us "
"use the <acronym>IP</acronym> address of <systemitem class=\"ipaddress"
"\">192.43.244.18</systemitem>, which is the time server of US federal "
"government (<systemitem class=\"fqdomainname\">time.nist.gov</systemitem>)."
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5500
msgctxt "_"
msgid "external ref='sockets/sainfill' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5504
#, no-wrap
msgid ""
"        0        1        2       3\n"
"   +--------+--------+-----------------+\n"
" 0 |    0   |   2    |        13       |\n"
"   +-----------------+-----------------+\n"
" 4 |           192.43.244.18           |\n"
"   +-----------------------------------+\n"
" 8 |                 0                 |\n"
"   +-----------------------------------+\n"
"12 |                 0                 |\n"
"   +-----------------------------------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5498
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainfill\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>Specific example of sockaddr_in</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5521
msgid ""
"By the way the <varname>sin_addr</varname> field is declared as being of the "
"<varname>struct in_addr</varname> type, which is defined in "
"<filename>netinet/in.h</filename>:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5526
#, no-wrap
msgid ""
"/*\n"
" * Internet address (a structure for historical reasons)\n"
" */\n"
"struct in_addr {\n"
"\tin_addr_t s_addr;\n"
"};"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5533
msgid "In addition, <varname>in_addr_t</varname> is a 32-bit integer."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5536
msgid ""
"The <systemitem class=\"ipaddress\">192.43.244.18</systemitem> is just a "
"convenient notation of expressing a 32-bit integer by listing all of its 8-"
"bit bytes, starting with the <emphasis>most significant</emphasis> one."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5541
msgid ""
"So far, we have viewed <varname>sockaddr</varname> as an abstraction. Our "
"computer does not store <varname>short</varname> integers as a single 16-bit "
"entity, but as a sequence of 2 bytes. Similarly, it stores 32-bit integers "
"as a sequence of 4 bytes."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5547
msgid "Suppose we coded something like this:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5549
#, no-wrap
msgid ""
"sa.sin_family      = AF_INET;\n"
"sa.sin_port        = 13;\n"
"sa.sin_addr.s_addr = (((((192 &lt;&lt; 8) | 43) &lt;&lt; 8) | 244) &lt;&lt; 8) | 18;"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5553
msgid "What would the result look like?"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5555
msgid ""
"Well, that depends, of course. On a <trademark class=\"registered\">Pentium</"
"trademark>, or other x86, based computer, it would look like this:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5560 book.translate.xml:5680
msgctxt "_"
msgid "external ref='sockets/sainlsb' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5564 book.translate.xml:5684
#, no-wrap
msgid ""
"        0        1        2       3\n"
"   +--------+--------+--------+--------+\n"
" 0 |    0   |   2    |   13   |   0    |\n"
"   +--------+--------+--------+--------+\n"
" 4 |   18   |  244   |   43   |  192   |\n"
"   +-----------------------------------+\n"
" 8 |                 0                 |\n"
"   +-----------------------------------+\n"
"12 |                 0                 |\n"
"   +-----------------------------------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5558
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainlsb\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>sockaddr_in on an Intel system</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5581
msgid "On a different system, it might look like this:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5585 book.translate.xml:5707
msgctxt "_"
msgid "external ref='sockets/sainmsb' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5589 book.translate.xml:5711
#, no-wrap
msgid ""
"        0        1        2       3\n"
"   +--------+--------+--------+--------+\n"
" 0 |    0   |   2    |    0   |   13   |\n"
"   +--------+--------+--------+--------+\n"
" 4 |   192  |   43   |   244  |   18   |\n"
"   +-----------------------------------+\n"
" 8 |                 0                 |\n"
"   +-----------------------------------+\n"
"12 |                 0                 |\n"
"   +-----------------------------------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5583
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainmsb\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>sockaddr_in on an MSB system</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5606
msgid ""
"And on a PDP it might look different yet. But the above two are the most "
"common ways in use today."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5609
msgid ""
"Ordinarily, wanting to write portable code, programmers pretend that these "
"differences do not exist. And they get away with it (except when they code "
"in assembly language). Alas, you cannot get away with it that easily when "
"coding for sockets."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5615
msgid "Why?"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5617
msgid ""
"Because when communicating with another computer, you usually do not know "
"whether it stores data <emphasis>most significant byte</emphasis> "
"(<acronym>MSB</acronym>) or <emphasis>least significant byte</emphasis> "
"(<acronym>LSB</acronym>) first."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5623
msgid ""
"You might be wondering, <emphasis><quote>So, will sockets not handle it for "
"me?</quote></emphasis>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5627
msgid "It will not."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5629
msgid ""
"While that answer may surprise you at first, remember that the general "
"sockets interface only understands the <varname>sa_len</varname> and "
"<varname>sa_family</varname> fields of the <varname>sockaddr</varname> "
"structure. You do not have to worry about the byte order there (of course, "
"on FreeBSD <varname>sa_family</varname> is only 1 byte anyway, but many "
"other <trademark class=\"registered\">UNIX</trademark> systems do not have "
"<varname>sa_len</varname> and use 2 bytes for <varname>sa_family</varname>, "
"and expect the data in whatever order is native to the computer)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5640
msgid ""
"But the rest of the data is just <varname>sa_data[14]</varname> as far as "
"sockets goes. Depending on the <emphasis>address family</emphasis>, sockets "
"just forwards that data to its destination."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5645
msgid ""
"Indeed, when we enter a port number, it is because we want the other "
"computer to know what service we are asking for. And, when we are the "
"server, we read the port number so we know what service the other computer "
"is expecting from us. Either way, sockets only has to forward the port "
"number as data. It does not interpret it in any way."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5653
msgid ""
"Similarly, we enter the <acronym>IP</acronym> address to tell everyone on "
"the way where to send our data to. Sockets, again, only forwards it as data."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5657
msgid ""
"That is why, we (the <emphasis>programmers</emphasis>, not the "
"<emphasis>sockets</emphasis>) have to distinguish between the byte order "
"used by our computer and a conventional byte order to send the data in to "
"the other computer."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5663
msgid ""
"We will call the byte order our computer uses the <emphasis>host byte order</"
"emphasis>, or just the <emphasis>host order</emphasis>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5667
msgid ""
"There is a convention of sending the multi-byte data over <acronym>IP</"
"acronym> <emphasis><acronym>MSB</acronym> first</emphasis>. This, we will "
"refer to as the <emphasis>network byte order</emphasis>, or simply the "
"<emphasis>network order</emphasis>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5674
msgid ""
"Now, if we compiled the above code for an Intel based computer, our "
"<emphasis>host byte order</emphasis> would produce:"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5678
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainlsb\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>Host "
"byte order on an Intel system</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5701
msgid ""
"But the <emphasis>network byte order</emphasis> requires that we store the "
"data <acronym>MSB</acronym> first:"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5705
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainmsb\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>Network "
"byte order</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5728
msgid ""
"Unfortunately, our <emphasis>host order</emphasis> is the exact opposite of "
"the <emphasis>network order</emphasis>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5732
msgid ""
"We have several ways of dealing with it. One would be to <emphasis>reverse</"
"emphasis> the values in our code:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5736
#, no-wrap
msgid ""
"sa.sin_family      = AF_INET;\n"
"sa.sin_port        = 13 &lt;&lt; 8;\n"
"sa.sin_addr.s_addr = (((((18 &lt;&lt; 8) | 244) &lt;&lt; 8) | 43) &lt;&lt; 8) | 192;"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5740
msgid ""
"This will <emphasis>trick</emphasis> our compiler into storing the data in "
"the <emphasis>network byte order</emphasis>. In some cases, this is exactly "
"the way to do it (e.g., when programming in assembly language). In most "
"cases, however, it can cause a problem."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5747
msgid ""
"Suppose, you wrote a sockets-based program in C. You know it is going to run "
"on a <trademark class=\"registered\">Pentium</trademark>, so you enter all "
"your constants in reverse and force them to the <emphasis>network byte "
"order</emphasis>. It works well."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5753
msgid ""
"Then, some day, your trusted old <trademark class=\"registered\">Pentium</"
"trademark> becomes a rusty old <trademark class=\"registered\">Pentium</"
"trademark>. You replace it with a system whose <emphasis>host order</"
"emphasis> is the same as the <emphasis>network order</emphasis>. You need to "
"recompile all your software. All of your software continues to perform well, "
"except the one program you wrote."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5760
msgid ""
"You have since forgotten that you had forced all of your constants to the "
"opposite of the <emphasis>host order</emphasis>. You spend some quality time "
"tearing out your hair, calling the names of all gods you ever heard of (and "
"some you made up), hitting your monitor with a nerf bat, and performing all "
"the other traditional ceremonies of trying to figure out why something that "
"has worked so well is suddenly not working at all."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5769
msgid ""
"Eventually, you figure it out, say a couple of swear words, and start "
"rewriting your code."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5772
msgid ""
"Luckily, you are not the first one to face the problem. Someone else has "
"created the <citerefentry><refentrytitle>htons</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>htonl</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> C functions to convert "
"a <varname>short</varname> and <varname>long</varname> respectively from the "
"<emphasis>host byte order</emphasis> to the <emphasis>network byte order</"
"emphasis>, and the <citerefentry><refentrytitle>ntohs</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> and "
"<citerefentry><refentrytitle>ntohl</refentrytitle><manvolnum>3</manvolnum></"
"citerefentry> C functions to go the other way."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5781
msgid ""
"On <emphasis><acronym>MSB</acronym>-first</emphasis> systems these functions "
"do nothing. On <emphasis><acronym>LSB</acronym>-first</emphasis> systems "
"they convert values to the proper order."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5786
msgid ""
"So, regardless of what system your software is compiled on, your data will "
"end up in the correct order if you use these functions."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:5793
msgid "Client Functions"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:5795
msgid ""
"Typically, the client initiates the connection to the server. The client "
"knows which server it is about to call: It knows its <acronym>IP</acronym> "
"address, and it knows the <emphasis>port</emphasis> the server resides at. "
"It is akin to you picking up the phone and dialing the number (the "
"<emphasis>address</emphasis>), then, after someone answers, asking for the "
"person in charge of wingdings (the <emphasis>port</emphasis>)."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5805
msgid "<function>connect</function>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5807
msgid ""
"Once a client has created a socket, it needs to connect it to a specific "
"port on a remote system. It uses <citerefentry><refentrytitle>connect</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry>:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5811
#, no-wrap
msgid "int connect(int s, const struct sockaddr *name, socklen_t namelen);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5813
msgid ""
"The <varname>s</varname> argument is the socket, i.e., the value returned by "
"the <function>socket</function> function. The <varname>name</varname> is a "
"pointer to <varname>sockaddr</varname>, the structure we have talked about "
"extensively. Finally, <varname>namelen</varname> informs the system how many "
"bytes are in our <varname>sockaddr</varname> structure."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5821
msgid ""
"If <function>connect</function> is successful, it returns <constant>0</"
"constant>. Otherwise it returns <constant>-1</constant> and stores the error "
"code in <varname>errno</varname>."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5826
msgid ""
"There are many reasons why <function>connect</function> may fail. For "
"example, with an attempt to an Internet connection, the <acronym>IP</"
"acronym> address may not exist, or it may be down, or just too busy, or it "
"may not have a server listening at the specified port. Or it may outright "
"<emphasis>refuse</emphasis> any request for specific code."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5837
msgid "Our First Client"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5839
msgid ""
"We now know enough to write a very simple client, one that will get current "
"time from <systemitem class=\"ipaddress\">192.43.244.18</systemitem> and "
"print it to <filename>stdout</filename>."
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5843
#, no-wrap
msgid ""
"/*\n"
" * daytime.c\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" */\n"
"#include &lt;stdio.h&gt;\n"
"#include &lt;string.h&gt;\n"
"#include &lt;sys/types.h&gt;\n"
"#include &lt;sys/socket.h&gt;\n"
"#include &lt;netinet/in.h&gt;\n"
"\n"
"int main() {\n"
"  register int s;\n"
"  register int bytes;\n"
"  struct sockaddr_in sa;\n"
"  char buffer[BUFSIZ+1];\n"
"\n"
"  if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {\n"
"    perror(\"socket\");\n"
"    return 1;\n"
"  }\n"
"\n"
"  bzero(&amp;sa, sizeof sa);\n"
"\n"
"  sa.sin_family = AF_INET;\n"
"  sa.sin_port = htons(13);\n"
"  sa.sin_addr.s_addr = htonl((((((192 &lt;&lt; 8) | 43) &lt;&lt; 8) | 244) &lt;&lt; 8) | 18);\n"
"  if (connect(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {\n"
"    perror(\"connect\");\n"
"    close(s);\n"
"    return 2;\n"
"  }\n"
"\n"
"  while ((bytes = read(s, buffer, BUFSIZ)) &gt; 0)\n"
"    write(1, buffer, bytes);\n"
"\n"
"  close(s);\n"
"  return 0;\n"
"}"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5883
msgid ""
"Go ahead, enter it in your editor, save it as <filename>daytime.c</"
"filename>, then compile and run it:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:5887
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>cc -O3 -o daytime daytime.c</userinput>\n"
"<prompt>%</prompt> <userinput>./daytime</userinput>\n"
"\n"
"52079 01-06-19 02:29:25 50 0 1 543.9 UTC(NIST) *\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5893
msgid ""
"In this case, the date was June 19, 2001, the time was 02:29:25 "
"<acronym>UTC</acronym>. Naturally, your results will vary."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:5900
msgid "Server Functions"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:5902
msgid ""
"The typical server does not initiate the connection. Instead, it waits for a "
"client to call it and request services. It does not know when the client "
"will call, nor how many clients will call. It may be just sitting there, "
"waiting patiently, one moment, The next moment, it can find itself swamped "
"with requests from a number of clients, all calling in at the same time."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:5910
msgid "The sockets interface offers three basic functions to handle this."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5914
msgid "<function>bind</function>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5916
msgid ""
"Ports are like extensions to a phone line: After you dial a number, you dial "
"the extension to get to a specific person or department."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5920
msgid ""
"There are 65535 <acronym>IP</acronym> ports, but a server usually processes "
"requests that come in on only one of them. It is like telling the phone room "
"operator that we are now at work and available to answer the phone at a "
"specific extension. We use <citerefentry><refentrytitle>bind</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry> to tell sockets which "
"port we want to serve."
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5927
#, no-wrap
msgid "int bind(int s, const struct sockaddr *addr, socklen_t addrlen);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5929
msgid ""
"Beside specifying the port in <varname>addr</varname>, the server may "
"include its <acronym>IP</acronym> address. However, it can just use the "
"symbolic constant <symbol>INADDR_ANY</symbol> to indicate it will serve all "
"requests to the specified port regardless of what its <acronym>IP</acronym> "
"address is. This symbol, along with several similar ones, is declared in "
"<filename>netinet/in.h</filename>"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5938
#, no-wrap
msgid "#define\tINADDR_ANY\t\t(u_int32_t)0x00000000"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5940
msgid ""
"Suppose we were writing a server for the <emphasis>daytime</emphasis> "
"protocol over <acronym>TCP</acronym>/<acronym>IP</acronym>. Recall that it "
"uses port 13. Our <varname>sockaddr_in</varname> structure would look like "
"this:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:5948
msgctxt "_"
msgid "external ref='sockets/sainserv' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:5952
#, no-wrap
msgid ""
"        0        1        2       3\n"
"   +--------+--------+--------+--------+\n"
" 0 |    0   |   2    |    0   |   13   |\n"
"   +--------+--------+--------+--------+\n"
" 4 |                 0                 |\n"
"   +-----------------------------------+\n"
" 8 |                 0                 |\n"
"   +-----------------------------------+\n"
"12 |                 0                 |\n"
"   +-----------------------------------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:5946
msgid ""
"<imageobject> <imagedata fileref=\"sockets/sainserv\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> <phrase>Example "
"Server sockaddr_in</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5971
msgid "<function>listen</function>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5973
msgid ""
"To continue our office phone analogy, after you have told the phone central "
"operator what extension you will be at, you now walk into your office, and "
"make sure your own phone is plugged in and the ringer is turned on. Plus, "
"you make sure your call waiting is activated, so you can hear the phone ring "
"even while you are talking to someone."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5981
msgid ""
"The server ensures all of that with the <citerefentry><refentrytitle>listen</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry> function."
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:5984
#, no-wrap
msgid "int listen(int s, int backlog);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5986
msgid ""
"In here, the <varname>backlog</varname> variable tells sockets how many "
"incoming requests to accept while you are busy processing the last request. "
"In other words, it determines the maximum size of the queue of pending "
"connections."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:5994
msgid "<function>accept</function>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:5996
msgid ""
"After you hear the phone ringing, you accept the call by answering the call. "
"You have now established a connection with your client. This connection "
"remains active until either you or your client hang up."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6001
msgid ""
"The server accepts the connection by using the "
"<citerefentry><refentrytitle>accept</refentrytitle><manvolnum>2</manvolnum></"
"citerefentry> function."
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:6004
#, no-wrap
msgid "int accept(int s, struct sockaddr *addr, socklen_t *addrlen);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6006
msgid ""
"Note that this time <varname>addrlen</varname> is a pointer. This is "
"necessary because in this case it is the socket that fills out "
"<varname>addr</varname>, the <varname>sockaddr_in</varname> structure."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6011
msgid ""
"The return value is an integer. Indeed, the <function>accept</function> "
"returns a <emphasis>new socket</emphasis>. You will use this new socket to "
"communicate with the client."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6016
msgid ""
"What happens to the old socket? It continues to listen for more requests "
"(remember the <varname>backlog</varname> variable we passed to "
"<function>listen</function>?) until we <function>close</function> it."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6021
msgid ""
"Now, the new socket is meant only for communications. It is fully connected. "
"We cannot pass it to <function>listen</function> again, trying to accept "
"additional connections."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:6028
msgid "Our First Server"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6030
msgid ""
"Our first server will be somewhat more complex than our first client was: "
"Not only do we have more sockets functions to use, but we need to write it "
"as a daemon."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6035
msgid ""
"This is best achieved by creating a <emphasis>child process</emphasis> after "
"binding the port. The main process then exits and returns control to the "
"<application>shell</application> (or whatever program invoked it)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6041
msgid ""
"The child calls <function>listen</function>, then starts an endless loop, "
"which accepts a connection, serves it, and eventually closes its socket."
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:6045
#, no-wrap
msgid ""
"/*\n"
" * daytimed - a port 13 server\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" * June 19, 2001\n"
" */\n"
"#include &lt;stdio.h&gt;\n"
"#include &lt;string.h&gt;\n"
"#include &lt;time.h&gt;\n"
"#include &lt;unistd.h&gt;\n"
"#include &lt;sys/types.h&gt;\n"
"#include &lt;sys/socket.h&gt;\n"
"#include &lt;netinet/in.h&gt;\n"
"\n"
"#define BACKLOG 4\n"
"\n"
"int main() {\n"
"    register int s, c;\n"
"    int b;\n"
"    struct sockaddr_in sa;\n"
"    time_t t;\n"
"    struct tm *tm;\n"
"    FILE *client;\n"
"\n"
"    if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {\n"
"        perror(\"socket\");\n"
"        return 1;\n"
"    }\n"
"\n"
"    bzero(&amp;sa, sizeof sa);\n"
"\n"
"    sa.sin_family = AF_INET;\n"
"    sa.sin_port   = htons(13);\n"
"\n"
"    if (INADDR_ANY)\n"
"        sa.sin_addr.s_addr = htonl(INADDR_ANY);\n"
"\n"
"    if (bind(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {\n"
"        perror(\"bind\");\n"
"        return 2;\n"
"    }\n"
"\n"
"    switch (fork()) {\n"
"        case -1:\n"
"            perror(\"fork\");\n"
"            return 3;\n"
"            break;\n"
"        default:\n"
"            close(s);\n"
"            return 0;\n"
"            break;\n"
"        case 0:\n"
"            break;\n"
"    }\n"
"\n"
"    listen(s, BACKLOG);\n"
"\n"
"    for (;;) {\n"
"        b = sizeof sa;\n"
"\n"
"        if ((c = accept(s, (struct sockaddr *)&amp;sa, &amp;b)) &lt; 0) {\n"
"            perror(\"daytimed accept\");\n"
"            return 4;\n"
"        }\n"
"\n"
"        if ((client = fdopen(c, \"w\")) == NULL) {\n"
"            perror(\"daytimed fdopen\");\n"
"            return 5;\n"
"        }\n"
"\n"
"        if ((t = time(NULL)) &lt; 0) {\n"
"            perror(\"daytimed time\");\n"
"\n"
"            return 6;\n"
"        }\n"
"\n"
"        tm = gmtime(&amp;t);\n"
"        fprintf(client, \"%.4i-%.2i-%.2iT%.2i:%.2i:%.2iZ\\n\",\n"
"            tm-&gt;tm_year + 1900,\n"
"            tm-&gt;tm_mon + 1,\n"
"            tm-&gt;tm_mday,\n"
"            tm-&gt;tm_hour,\n"
"            tm-&gt;tm_min,\n"
"            tm-&gt;tm_sec);\n"
"\n"
"        fclose(client);\n"
"    }\n"
"}"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6134
msgid ""
"We start by creating a socket. Then we fill out the <varname>sockaddr_in</"
"varname> structure in <varname>sa</varname>. Note the conditional use of "
"<symbol>INADDR_ANY</symbol>:"
msgstr ""

#. (itstool) path: sect4/programlisting
#: book.translate.xml:6139
#, no-wrap
msgid ""
"if (INADDR_ANY)\n"
"        sa.sin_addr.s_addr = htonl(INADDR_ANY);"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6142
msgid ""
"Its value is <constant>0</constant>. Since we have just used "
"<function>bzero</function> on the entire structure, it would be redundant to "
"set it to <constant>0</constant> again. But if we port our code to some "
"other system where <symbol>INADDR_ANY</symbol> is perhaps not a zero, we "
"need to assign it to <varname>sa.sin_addr.s_addr</varname>. Most modern C "
"compilers are clever enough to notice that <symbol>INADDR_ANY</symbol> is a "
"constant. As long as it is a zero, they will optimize the entire conditional "
"statement out of the code."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6154
msgid ""
"After we have called <function>bind</function> successfully, we are ready to "
"become a <emphasis>daemon</emphasis>: We use <function>fork</function> to "
"create a child process. In both, the parent and the child, the <varname>s</"
"varname> variable is our socket. The parent process will not need it, so it "
"calls <function>close</function>, then it returns <constant>0</constant> to "
"inform its own parent it had terminated successfully."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6164
msgid ""
"Meanwhile, the child process continues working in the background. It calls "
"<function>listen</function> and sets its backlog to <constant>4</constant>. "
"It does not need a large value here because <emphasis>daytime</emphasis> is "
"not a protocol many clients request all the time, and because it can process "
"each request instantly anyway."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6172
msgid ""
"Finally, the daemon starts an endless loop, which performs the following "
"steps:"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:6177
msgid ""
"Call <function>accept</function>. It waits here until a client contacts it. "
"At that point, it receives a new socket, <varname>c</varname>, which it can "
"use to communicate with this particular client."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:6185
msgid ""
"It uses the C function <function>fdopen</function> to turn the socket from a "
"low-level <emphasis>file descriptor</emphasis> to a C-style <varname>FILE</"
"varname> pointer. This will allow the use of <function>fprintf</function> "
"later on."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:6194
msgid ""
"It checks the time, and prints it in the <emphasis><acronym>ISO</acronym> "
"8601</emphasis> format to the <varname>client</varname> <quote>file</quote>. "
"It then uses <function>fclose</function> to close the file. That will "
"automatically close the socket as well."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6204
msgid ""
"We can <emphasis>generalize</emphasis> this, and use it as a model for many "
"other servers:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:6209
msgctxt "_"
msgid "external ref='sockets/serv' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:6213
#, no-wrap
msgid ""
"+-----------------+\n"
"|  Create Socket  |\n"
"+-----------------+\n"
"          |\n"
"+-----------------+\n"
"|    Bind Port    |       Daemon Process\n"
"+-----------------+\n"
"          |                 +--------+\n"
"          +-------------+--&gt;|  Init  |\n"
"          |             |   +--------+\n"
"+-----------------+     |         |\n"
"|        Exit     |     |   +--------+\n"
"+-----------------+     |   | Listen |\n"
"                        |   +--------+\n"
"                        |         |\n"
"                        |   +--------+\n"
"                        |   | Accept |\n"
"                        |   +--------+\n"
"                        |         |\n"
"                        |   +--------+\n"
"                        |   | Serve  |\n"
"                        |   +--------+\n"
"                        |         |\n"
"                        |   +--------+\n"
"                        |   | Close  |\n"
"                        |&lt;--------+"
msgstr ""

#. (itstool) path: sect4/mediaobject
#: book.translate.xml:6207
msgid ""
"<imageobject> <imagedata fileref=\"sockets/serv\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>Sequential Server</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6246
msgid ""
"This flowchart is good for <emphasis>sequential servers</emphasis>, i.e., "
"servers that can serve one client at a time, just as we were able to with "
"our <emphasis>daytime</emphasis> server. This is only possible whenever "
"there is no real <quote>conversation</quote> going on between the client and "
"the server: As soon as the server detects a connection to the client, it "
"sends out some data and closes the connection. The entire operation may take "
"nanoseconds, and it is finished."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6257
msgid ""
"The advantage of this flowchart is that, except for the brief moment after "
"the parent <function>fork</function>s and before it exits, there is always "
"only one <emphasis>process</emphasis> active: Our server does not take up "
"much memory and other system resources."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6264
msgid ""
"Note that we have added <emphasis>initialize daemon</emphasis> in our "
"flowchart. We did not need to initialize our own daemon, but this is a good "
"place in the flow of the program to set up any <function>signal</function> "
"handlers, open any files we may need, etc."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6271
msgid ""
"Just about everything in the flow chart can be used literally on many "
"different servers. The <emphasis>serve</emphasis> entry is the exception. We "
"think of it as a <emphasis><quote>black box</quote></emphasis>, i.e., "
"something you design specifically for your own server, and just <quote>plug "
"it into the rest.</quote>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6279
msgid ""
"Not all protocols are that simple. Many receive a request from the client, "
"reply to it, then receive another request from the same client. Because of "
"that, they do not know in advance how long they will be serving the client. "
"Such servers usually start a new process for each client. While the new "
"process is serving its client, the daemon can continue listening for more "
"connections."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6287
msgid ""
"Now, go ahead, save the above source code as <filename>daytimed.c</filename> "
"(it is customary to end the names of daemons with the letter <constant>d</"
"constant>). After you have compiled it, try running it:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6293
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>./daytimed</userinput>\n"
"bind: Permission denied\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6297
msgid ""
"What happened here? As you will recall, the <emphasis>daytime</emphasis> "
"protocol uses port 13. But all ports below 1024 are reserved to the "
"superuser (otherwise, anyone could start a daemon pretending to serve a "
"commonly used port, while causing a security breach)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6304
msgid "Try again, this time as the superuser:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6306
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>./daytimed</userinput>\n"
"<prompt>#</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6309
msgid "What... Nothing? Let us try again:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6311
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>./daytimed</userinput>\n"
"\n"
"bind: Address already in use\n"
"<prompt>#</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6316
msgid ""
"Every port can only be bound by one program at a time. Our first attempt was "
"indeed successful: It started the child daemon and returned quietly. It is "
"still running and will continue to run until you either kill it, or any of "
"its system calls fail, or you reboot the system."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6322
msgid ""
"Fine, we know it is running in the background. But is it working? How do we "
"know it is a proper <emphasis>daytime</emphasis> server? Simple:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6326
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>telnet localhost 13</userinput>\n"
"\n"
"Trying ::1...\n"
"telnet: connect to address ::1: Connection refused\n"
"Trying 127.0.0.1...\n"
"Connected to localhost.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:04:42Z\n"
"Connection closed by foreign host.\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6337
msgid ""
"<application>telnet</application> tried the new <acronym>IP</acronym>v6, and "
"failed. It retried with <acronym>IP</acronym>v4 and succeeded. The daemon "
"works."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6342
msgid ""
"If you have access to another <trademark class=\"registered\">UNIX</"
"trademark> system via <application>telnet</application>, you can use it to "
"test accessing the server remotely. My computer does not have a static "
"<acronym>IP</acronym> address, so this is what I did:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6348
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>who</userinput>\n"
"\n"
"whizkid          ttyp0   Jun 19 16:59   (216.127.220.143)\n"
"xxx              ttyp1   Jun 19 16:06   (xx.xx.xx.xx)\n"
"<prompt>%</prompt> <userinput>telnet 216.127.220.143 13</userinput>\n"
"\n"
"Trying 216.127.220.143...\n"
"Connected to r47.bfm.org.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:31:11Z\n"
"Connection closed by foreign host.\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6361
msgid "Again, it worked. Will it work using the domain name?"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:6364
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>telnet r47.bfm.org 13</userinput>\n"
"\n"
"Trying 216.127.220.143...\n"
"Connected to r47.bfm.org.\n"
"Escape character is '^]'.\n"
"2001-06-19T21:31:40Z\n"
"Connection closed by foreign host.\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:6373
msgid ""
"By the way, <application>telnet</application> prints the "
"<emphasis>Connection closed by foreign host</emphasis> message after our "
"daemon has closed the socket. This shows us that, indeed, using "
"<function>fclose(client);</function> in our code works as advertised."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:6385
msgid "Helper Functions"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6387
msgid ""
"FreeBSD C library contains many helper functions for sockets programming. "
"For example, in our sample client we hard coded the <systemitem class="
"\"fqdomainname\">time.nist.gov</systemitem> <acronym>IP</acronym> address. "
"But we do not always know the <acronym>IP</acronym> address. Even if we do, "
"our software is more flexible if it allows the user to enter the "
"<acronym>IP</acronym> address, or even the domain name."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:6396
msgid "<function>gethostbyname</function>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6398
msgid ""
"While there is no way to pass the domain name directly to any of the sockets "
"functions, the FreeBSD C library comes with the "
"<citerefentry><refentrytitle>gethostbyname</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>gethostbyname2</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> functions, declared in "
"<filename>netdb.h</filename>."
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:6403
#, no-wrap
msgid ""
"struct hostent * gethostbyname(const char *name);\n"
"struct hostent * gethostbyname2(const char *name, int af);"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6406
msgid ""
"Both return a pointer to the <varname>hostent</varname> structure, with much "
"information about the domain. For our purposes, the <varname>h_addr_list[0]</"
"varname> field of the structure points at <varname>h_length</varname> bytes "
"of the correct address, already stored in the <emphasis>network byte order</"
"emphasis>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6413
msgid ""
"This allows us to create a much more flexible—and much more useful—version "
"of our <application>daytime</application> program:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:6417
#, no-wrap
msgid ""
"/*\n"
" * daytime.c\n"
" *\n"
" * Programmed by G. Adam Stanislav\n"
" * 19 June 2001\n"
" */\n"
"#include &lt;stdio.h&gt;\n"
"#include &lt;string.h&gt;\n"
"#include &lt;sys/types.h&gt;\n"
"#include &lt;sys/socket.h&gt;\n"
"#include &lt;netinet/in.h&gt;\n"
"#include &lt;netdb.h&gt;\n"
"\n"
"int main(int argc, char *argv[]) {\n"
"  register int s;\n"
"  register int bytes;\n"
"  struct sockaddr_in sa;\n"
"  struct hostent *he;\n"
"  char buf[BUFSIZ+1];\n"
"  char *host;\n"
"\n"
"  if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {\n"
"    perror(\"socket\");\n"
"    return 1;\n"
"  }\n"
"\n"
"  bzero(&amp;sa, sizeof sa);\n"
"\n"
"  sa.sin_family = AF_INET;\n"
"  sa.sin_port = htons(13);\n"
"\n"
"  host = (argc &gt; 1) ? (char *)argv[1] : \"time.nist.gov\";\n"
"\n"
"  if ((he = gethostbyname(host)) == NULL) {\n"
"    herror(host);\n"
"    return 2;\n"
"  }\n"
"\n"
"  bcopy(he-&gt;h_addr_list[0],&amp;sa.sin_addr, he-&gt;h_length);\n"
"\n"
"  if (connect(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {\n"
"    perror(\"connect\");\n"
"    return 3;\n"
"  }\n"
"\n"
"  while ((bytes = read(s, buf, BUFSIZ)) &gt; 0)\n"
"    write(1, buf, bytes);\n"
"\n"
"  close(s);\n"
"  return 0;\n"
"}"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6469
msgid ""
"We now can type a domain name (or an <acronym>IP</acronym> address, it works "
"both ways) on the command line, and the program will try to connect to its "
"<emphasis>daytime</emphasis> server. Otherwise, it will still default to "
"<systemitem class=\"fqdomainname\">time.nist.gov</systemitem>. However, even "
"in this case we will use <function>gethostbyname</function> rather than hard "
"coding <systemitem class=\"ipaddress\">192.43.244.18</systemitem>. That way, "
"even if its <acronym>IP</acronym> address changes in the future, we will "
"still find it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6480
msgid ""
"Since it takes virtually no time to get the time from your local server, you "
"could run <application>daytime</application> twice in a row: First to get "
"the time from <systemitem class=\"fqdomainname\">time.nist.gov</systemitem>, "
"the second time from your own system. You can then compare the results and "
"see how exact your system clock is:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:6486
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>daytime ; daytime localhost</userinput>\n"
"\n"
"\n"
"52080 01-06-20 04:02:33 50 0 0 390.2 UTC(NIST) *\n"
"2001-06-20T04:02:35Z\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6493
msgid ""
"As you can see, my system was two seconds ahead of the <acronym>NIST</"
"acronym> time."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:6498
msgid "<function>getservbyname</function>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6500
msgid ""
"Sometimes you may not be sure what port a certain service uses. The "
"<citerefentry><refentrytitle>getservbyname</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> function, also declared in <filename>netdb.h</"
"filename> comes in very handy in those cases:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:6505
#, no-wrap
msgid "struct servent * getservbyname(const char *name, const char *proto);"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6507
msgid ""
"The <varname>servent</varname> structure contains the <varname>s_port</"
"varname>, which contains the proper port, already in <emphasis>network byte "
"order</emphasis>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6511
msgid ""
"Had we not known the correct port for the <emphasis>daytime</emphasis> "
"service, we could have found it this way:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:6515
#, no-wrap
msgid ""
"struct servent *se;\n"
"  ...\n"
"  if ((se = getservbyname(\"daytime\", \"tcp\")) == NULL {\n"
"    fprintf(stderr, \"Cannot determine which port to use.\\n\");\n"
"    return 7;\n"
"  }\n"
"  sa.sin_port = se-&gt;s_port;"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:6523
msgid ""
"You usually do know the port. But if you are developing a new protocol, you "
"may be testing it on an unofficial port. Some day, you will register the "
"protocol and its port (if nowhere else, at least in your <filename>/etc/"
"services</filename>, which is where <function>getservbyname</function> "
"looks). Instead of returning an error in the above code, you just use the "
"temporary port number. Once you have listed the protocol in <filename>/etc/"
"services</filename>, your software will find its port without you having to "
"rewrite the code."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:6537
msgid "Concurrent Servers"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6539
msgid ""
"Unlike a sequential server, a <emphasis>concurrent server</emphasis> has to "
"be able to serve more than one client at a time. For example, a "
"<emphasis>chat server</emphasis> may be serving a specific client for hours—"
"it cannot wait till it stops serving a client before it serves the next one."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6545
msgid "This requires a significant change in our flowchart:"
msgstr ""

#. (itstool) path: imageobject/imagedata
#. This is a reference to an external file such as an image or video. When
#. the file changes, the md5 hash will change to let you know you need to
#. update your localized copy. The msgstr is not used at all. Set it to
#. whatever you like once you have updated your copy of the file.
#: book.translate.xml:6549
msgctxt "_"
msgid "external ref='sockets/serv2' md5='__failed__'"
msgstr ""

#. (itstool) path: textobject/literallayout
#: book.translate.xml:6553
#, no-wrap
msgid ""
"+-----------------+\n"
"|  Create Socket  |\n"
"+-----------------+\n"
"          |\n"
"+-----------------+\n"
"|    Bind Port    |       Daemon Process\n"
"+-----------------+\n"
"          |                 +--------+\n"
"          +-------------+--&gt;|  Init  |\n"
"          |             |   +--------+\n"
"+-----------------+     |         |\n"
"|        Exit     |     |   +--------+\n"
"+-----------------+     |   | Listen |\n"
"                        |   +--------+\n"
"                        |         |\n"
"                        |   +--------+\n"
"                        |   | Accept |\n"
"                        |   +--------+\n"
"                        |         |       +------------------+\n"
"                        |         +------&gt;| Close Top Socket |\n"
"                        |         |       +------------------+\n"
"                        |   +--------+             |\n"
"                        |   | Close  |    +------------------+\n"
"                        |   +--------+    |     Serve        |\n"
"                        |         |       +------------------+\n"
"                        |&lt;--------+                |\n"
"                                          +------------------+\n"
"                                          | Close Acc Socket |\n"
"                            +--------+    +------------------+\n"
"                            | Signal |             |\n"
"                            +--------+    +------------------+\n"
"                                          |      Exit        |\n"
"                                          +------------------+"
msgstr ""

#. (itstool) path: sect1/mediaobject
#: book.translate.xml:6547
msgid ""
"<imageobject> <imagedata fileref=\"sockets/serv2\"/> </imageobject> "
"<textobject> <_:literallayout-1/> </textobject> <textobject> "
"<phrase>Concurrent Server</phrase> </textobject>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6593
msgid ""
"We moved the <emphasis>serve</emphasis> from the <emphasis>daemon process</"
"emphasis> to its own <emphasis>server process</emphasis>. However, because "
"each child process inherits all open files (and a socket is treated just "
"like a file), the new process inherits not only the "
"<emphasis><quote>accepted handle,</quote></emphasis> i.e., the socket "
"returned by the <function>accept</function> call, but also the <emphasis>top "
"socket</emphasis>, i.e., the one opened by the top process right at the "
"beginning."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6603
msgid ""
"However, the <emphasis>server process</emphasis> does not need this socket "
"and should <function>close</function> it immediately. Similarly, the "
"<emphasis>daemon process</emphasis> no longer needs the <emphasis>accepted "
"socket</emphasis>, and not only should, but <emphasis>must</emphasis> "
"<function>close</function> it—otherwise, it will run out of available "
"<emphasis>file descriptors</emphasis> sooner or later."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6612
msgid ""
"After the <emphasis>server process</emphasis> is done serving, it should "
"close the <emphasis>accepted socket</emphasis>. Instead of returning to "
"<function>accept</function>, it now exits."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6617
msgid ""
"Under <trademark class=\"registered\">UNIX</trademark>, a process does not "
"really <emphasis>exit</emphasis>. Instead, it <emphasis>returns</emphasis> "
"to its parent. Typically, a parent process <function>wait</function>s for "
"its child process, and obtains a return value. However, our <emphasis>daemon "
"process</emphasis> cannot simply stop and wait. That would defeat the whole "
"purpose of creating additional processes. But if it never does "
"<function>wait</function>, its children will become <emphasis>zombies</"
"emphasis>—no longer functional but still roaming around."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6628
msgid ""
"For that reason, the <emphasis>daemon process</emphasis> needs to set "
"<emphasis>signal handlers</emphasis> in its <emphasis>initialize daemon</"
"emphasis> phase. At least a <symbol>SIGCHLD</symbol> signal has to be "
"processed, so the daemon can remove the zombie return values from the system "
"and release the system resources they are taking up."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6635
msgid ""
"That is why our flowchart now contains a <emphasis>process signals</"
"emphasis> box, which is not connected to any other box. By the way, many "
"servers also process <symbol>SIGHUP</symbol>, and typically interpret as the "
"signal from the superuser that they should reread their configuration files. "
"This allows us to change settings without having to kill and restart these "
"servers."
msgstr ""

#. (itstool) path: chapter/title
#: book.translate.xml:6652
msgid "IPv6 Internals"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:6656
msgid "IPv6/IPsec Implementation"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:6659
msgid ""
"<personname> <firstname>Yoshinobu</firstname> <surname>Inoue</surname> </"
"personname> <contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:6669
msgid ""
"This section should explain IPv6 and IPsec related implementation internals. "
"These functionalities are derived from <link xlink:href=\"http://www.kame."
"net/\">KAME project</link>"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:6675
msgid "IPv6"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:6678
msgid "Conformance"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6680
msgid ""
"The IPv6 related functions conforms, or tries to conform to the latest set "
"of IPv6 specifications. For future reference we list some of the relevant "
"documents below (<emphasis>NOTE</emphasis>: this is not a complete list - "
"this is too hard to maintain...)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6686
msgid ""
"For details please refer to specific chapter in the document, RFCs, manual "
"pages, or comments in the source code."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6690
msgid ""
"Conformance tests have been performed on the KAME STABLE kit at TAHI "
"project. Results can be viewed at <uri xlink:href=\"http://www.tahi.org/"
"report/KAME/\">http://www.tahi.org/report/KAME/</uri>. We also attended "
"University of New Hampshire IOL tests (<uri xlink:href=\"http://www.iol.unh."
"edu/\">http://www.iol.unh.edu/</uri>) in the past, with our past snapshots."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6697
msgid "RFC1639: FTP Operation Over Big Address Records (FOOBAR)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6701 book.translate.xml:6802
msgid ""
"RFC2428 is preferred over RFC1639. FTP clients will first try RFC2428, then "
"RFC1639 if failed."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6709
msgid "RFC1886: DNS Extensions to support IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6713
msgid "RFC1933: Transition Mechanisms for IPv6 Hosts and Routers"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6717
msgid "IPv4 compatible address is not supported."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6720
msgid "automatic tunneling (described in 4.3 of this RFC) is not supported."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6724
msgid ""
"<citerefentry><refentrytitle>gif</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> interface implements IPv[46]-over-IPv[46] tunnel in a generic "
"way, and it covers \"configured tunnel\" described in the spec. See <link "
"linkend=\"gif\">23.5.1.5</link> in this document for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6734
msgid "RFC1981: Path MTU Discovery for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6738
msgid "RFC2080: RIPng for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6741
msgid "usr.sbin/route6d support this."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6747
msgid "RFC2292: Advanced Sockets API for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6750
msgid ""
"For supported library functions/kernel APIs, see <filename>sys/netinet6/"
"ADVAPI</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6757
msgid "RFC2362: Protocol Independent Multicast-Sparse Mode (PIM-SM)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6761
msgid ""
"RFC2362 defines packet formats for PIM-SM. <filename>draft-ietf-pim-ipv6-01."
"txt</filename> is written based on this."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6769
msgid "RFC2373: IPv6 Addressing Architecture"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6772
msgid ""
"supports node required addresses, and conforms to the scope requirement."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6779
msgid "RFC2374: An IPv6 Aggregatable Global Unicast Address Format"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6783
msgid "supports 64-bit length of Interface ID."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6789
msgid "RFC2375: IPv6 Multicast Address Assignments"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6792
msgid "Userland applications use the well-known addresses assigned in the RFC."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6799
msgid "RFC2428: FTP Extensions for IPv6 and NATs"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6810
msgid "RFC2460: IPv6 specification"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6814
msgid "RFC2461: Neighbor discovery for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6817
msgid ""
"See <link linkend=\"neighbor-discovery\">23.5.1.2</link> in this document "
"for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6824
msgid "RFC2462: IPv6 Stateless Address Autoconfiguration"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6828
msgid ""
"See <link linkend=\"ipv6-pnp\">23.5.1.4</link> in this document for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6835
msgid "RFC2463: ICMPv6 for IPv6 specification"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6838
msgid ""
"See <link linkend=\"icmpv6\">23.5.1.9</link> in this document for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6845
msgid "RFC2464: Transmission of IPv6 Packets over Ethernet Networks"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6850
msgid "RFC2465: MIB for IPv6: Textual Conventions and General Group"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6854
msgid ""
"Necessary statistics are gathered by the kernel. Actual IPv6 MIB support is "
"provided as a patchkit for ucd-snmp."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6862
msgid "RFC2466: MIB for IPv6: ICMPv6 group"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6865
msgid ""
"Necessary statistics are gathered by the kernel. Actual IPv6 MIB support is "
"provided as patchkit for ucd-snmp."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6873
msgid "RFC2467: Transmission of IPv6 Packets over FDDI Networks"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6878
msgid "RFC2497: Transmission of IPv6 packet over ARCnet Networks"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6883
msgid "RFC2553: Basic Socket Interface Extensions for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6887
msgid ""
"IPv4 mapped address (3.7) and special behavior of IPv6 wildcard bind socket "
"(3.8) are supported. See <link linkend=\"ipv6-wildcard-socket\">23.5.1.12</"
"link> in this document for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6896
msgid "RFC2675: IPv6 Jumbograms"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6899
msgid ""
"See <link linkend=\"ipv6-jumbo\">23.5.1.7</link> in this document for "
"details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6906
msgid "RFC2710: Multicast Listener Discovery for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6911
msgid "RFC2711: IPv6 router alert option"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6915
msgid ""
"<filename>draft-ietf-ipngwg-router-renum-08</filename>: Router renumbering "
"for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6920
msgid ""
"<filename>draft-ietf-ipngwg-icmp-namelookups-02</filename>: IPv6 Name "
"Lookups Through ICMP"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6925
msgid ""
"<filename>draft-ietf-ipngwg-icmp-name-lookups-03</filename>: IPv6 Name "
"Lookups Through ICMP"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6930
msgid "<filename>draft-ietf-pim-ipv6-01.txt</filename>: PIM for IPv6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6934
msgid ""
"<citerefentry><refentrytitle>pim6dd</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> implements dense mode. <citerefentry><refentrytitle>pim6sd</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> implements sparse mode."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6941
msgid ""
"<filename>draft-itojun-ipv6-tcp-to-anycast-00</filename>: Disconnecting TCP "
"connection toward IPv6 anycast address"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6947
msgid "<filename>draft-yamamoto-wideipv6-comm-model-00</filename>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6950
msgid ""
"See <link linkend=\"ipv6-sas\">23.5.1.6</link> in this document for details."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6957
msgid ""
"<filename>draft-ietf-ipngwg-scopedaddr-format-00.txt</filename>: An "
"Extension of Format for IPv6 Scoped Addresses"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:6964
msgid "Neighbor Discovery"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6966
msgid ""
"Neighbor Discovery is fairly stable. Currently Address Resolution, "
"Duplicated Address Detection, and Neighbor Unreachability Detection are "
"supported. In the near future we will be adding Proxy Neighbor Advertisement "
"support in the kernel and Unsolicited Neighbor Advertisement transmission "
"command as admin tool."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6973
msgid ""
"If DAD fails, the address will be marked \"duplicated\" and message will be "
"generated to syslog (and usually to console). The \"duplicated\" mark can be "
"checked with <citerefentry><refentrytitle>ifconfig</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry>. It is administrators' "
"responsibility to check for and recover from DAD failures. The behavior "
"should be improved in the near future."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6980
msgid ""
"Some of the network driver loops multicast packets back to itself, even if "
"instructed not to do so (especially in promiscuous mode). In such cases DAD "
"may fail, because DAD engine sees inbound NS packet (actually from the node "
"itself) and considers it as a sign of duplicate. You may want to look at #if "
"condition marked \"heuristics\" in sys/netinet6/nd6_nbr.c:nd6_dad_timer() as "
"workaround (note that the code fragment in \"heuristics\" section is not "
"spec conformant)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:6990
msgid ""
"Neighbor Discovery specification (RFC2461) does not talk about neighbor "
"cache handling in the following cases:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:6995
msgid ""
"when there was no neighbor cache entry, node received unsolicited RS/NS/NA/"
"redirect packet without link-layer address"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7000
msgid ""
"neighbor cache handling on medium without link-layer address (we need a "
"neighbor cache entry for IsRouter bit)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7006
msgid ""
"For first case, we implemented workaround based on discussions on IETF "
"ipngwg mailing list. For more details, see the comments in the source code "
"and email thread started from (IPng 7155), dated Feb 6 1999."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7011
msgid ""
"IPv6 on-link determination rule (RFC2461) is quite different from "
"assumptions in BSD network code. At this moment, no on-link determination "
"rule is supported where default router list is empty (RFC2461, section 5.2, "
"last sentence in 2nd paragraph - note that the spec misuse the word \"host\" "
"and \"node\" in several places in the section)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7019
msgid ""
"To avoid possible DoS attacks and infinite loops, only 10 options on ND "
"packet is accepted now. Therefore, if you have 20 prefix options attached to "
"RA, only the first 10 prefixes will be recognized. If this troubles you, "
"please ask it on FREEBSD-CURRENT mailing list and/or modify nd6_maxndopt in "
"<filename>sys/netinet6/nd6.c</filename>. If there are high demands we may "
"provide sysctl knob for the variable."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7030
msgid "Scope Index"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7032
msgid ""
"IPv6 uses scoped addresses. Therefore, it is very important to specify scope "
"index (interface index for link-local address, or site index for site-local "
"address) with an IPv6 address. Without scope index, scoped IPv6 address is "
"ambiguous to the kernel, and kernel will not be able to determine the "
"outbound interface for a packet."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7040
msgid ""
"Ordinary userland applications should use advanced API (RFC2292) to specify "
"scope index, or interface index. For similar purpose, sin6_scope_id member "
"in sockaddr_in6 structure is defined in RFC2553. However, the semantics for "
"sin6_scope_id is rather vague. If you care about portability of your "
"application, we suggest you to use advanced API rather than sin6_scope_id."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7048
msgid ""
"In the kernel, an interface index for link-local scoped address is embedded "
"into 2nd 16bit-word (3rd and 4th byte) in IPv6 address. For example, you may "
"see something like:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:7053
#, no-wrap
msgid "\tfe80:1::200:f8ff:fe01:6317"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7055
msgid ""
"in the routing table and interface address structure (struct in6_ifaddr). "
"The address above is a link-local unicast address which belongs to a network "
"interface whose interface identifier is 1. The embedded index enables us to "
"identify IPv6 link local addresses over multiple interfaces effectively and "
"with only a little code change."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7062
msgid ""
"Routing daemons and configuration programs, like "
"<citerefentry><refentrytitle>route6d</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>ifconfig</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry>, will need to "
"manipulate the \"embedded\" scope index. These programs use routing sockets "
"and ioctls (like SIOCGIFADDR_IN6) and the kernel API will return IPv6 "
"addresses with 2nd 16bit-word filled in. The APIs are for manipulating "
"kernel internal structure. Programs that use these APIs have to be prepared "
"about differences in kernels anyway."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7071
msgid ""
"When you specify scoped address to the command line, NEVER write the "
"embedded form (such as ff02:1::1 or fe80:2::fedc). This is not supposed to "
"work. Always use standard form, like ff02::1 or fe80::fedc, with command "
"line option for specifying interface (like <command>ping6 -I ne0 ff02::1</"
"command>). In general, if a command does not have command line option to "
"specify outgoing interface, that command is not ready to accept scoped "
"address. This may seem to be opposite from IPv6's premise to support "
"\"dentist office\" situation. We believe that specifications need some "
"improvements for this."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7083
msgid ""
"Some of the userland tools support extended numeric IPv6 syntax, as "
"documented in <filename>draft-ietf-ipngwg-scopedaddr-format-00.txt</"
"filename>. You can specify outgoing link, by using name of the outgoing "
"interface like \"fe80::1%ne0\". This way you will be able to specify link-"
"local scoped address without much trouble."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7091
msgid ""
"To use this extension in your program, you will need to use "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry>, and <citerefentry><refentrytitle>getnameinfo</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> with NI_WITHSCOPEID. "
"The implementation currently assumes 1-to-1 relationship between a link and "
"an interface, which is stronger than what specs say."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7099
msgid "Plug and Play"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7101
msgid ""
"Most of the IPv6 stateless address autoconfiguration is implemented in the "
"kernel. Neighbor Discovery functions are implemented in the kernel as a "
"whole. Router Advertisement (RA) input for hosts is implemented in the "
"kernel. Router Solicitation (RS) output for endhosts, RS input for routers, "
"and RA output for routers are implemented in the userland."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:7110
msgid "Assignment of link-local, and special addresses"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7113
msgid ""
"IPv6 link-local address is generated from IEEE802 address (Ethernet MAC "
"address). Each of interface is assigned an IPv6 link-local address "
"automatically, when the interface becomes up (IFF_UP). Also, direct route "
"for the link-local address is added to routing table."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7119
msgid "Here is an output of netstat command:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:7121
#, no-wrap
msgid ""
"Internet6:\n"
"Destination                   Gateway                   Flags      Netif Expire\n"
"fe80:1::%ed0/64               link#1                    UC          ed0\n"
"fe80:2::%ep0/64               link#2                    UC          ep0"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7126
msgid ""
"Interfaces that has no IEEE802 address (pseudo interfaces like tunnel "
"interfaces, or ppp interfaces) will borrow IEEE802 address from other "
"interfaces, such as Ethernet interfaces, whenever possible. If there is no "
"IEEE802 hardware attached, a last resort pseudo-random value, MD5(hostname), "
"will be used as source of link-local address. If it is not suitable for your "
"usage, you will need to configure the link-local address manually."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7135
msgid ""
"If an interface is not capable of handling IPv6 (such as lack of multicast "
"support), link-local address will not be assigned to that interface. See "
"section 2 for details."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7140
msgid ""
"Each interface joins the solicited multicast address and the link-local all-"
"nodes multicast addresses (e.g., fe80::1:ff01:6317 and ff02::1, "
"respectively, on the link the interface is attached). In addition to a link-"
"local address, the loopback address (::1) will be assigned to the loopback "
"interface. Also, ::1/128 and ff01::/32 are automatically added to routing "
"table, and loopback interface joins node-local multicast group ff01::1."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:7151
msgid "Stateless address autoconfiguration on Hosts"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7153
msgid ""
"In IPv6 specification, nodes are separated into two categories: "
"<emphasis>routers</emphasis> and <emphasis>hosts</emphasis>. Routers forward "
"packets addressed to others, hosts does not forward the packets. net.inet6."
"ip6.forwarding defines whether this node is router or host (router if it is "
"1, host if it is 0)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7161
msgid ""
"When a host hears Router Advertisement from the router, a host may "
"autoconfigure itself by stateless address autoconfiguration. This behavior "
"can be controlled by net.inet6.ip6.accept_rtadv (host autoconfigures itself "
"if it is set to 1). By autoconfiguration, network address prefix for the "
"receiving interface (usually global address prefix) is added. Default route "
"is also configured. Routers periodically generate Router Advertisement "
"packets. To request an adjacent router to generate RA packet, a host can "
"transmit Router Solicitation. To generate a RS packet at any time, use the "
"<emphasis>rtsol</emphasis> command. <citerefentry><refentrytitle>rtsold</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> daemon is also "
"available. <citerefentry><refentrytitle>rtsold</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> generates Router Solicitation whenever necessary, "
"and it works great for nomadic usage (notebooks/laptops). If one wishes to "
"ignore Router Advertisements, use sysctl to set net.inet6.ip6.accept_rtadv "
"to 0."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7179
msgid ""
"To generate Router Advertisement from a router, use the "
"<citerefentry><refentrytitle>rtadvd</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry> daemon."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7182
msgid ""
"Note that, IPv6 specification assumes the following items, and nonconforming "
"cases are left unspecified:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7188
msgid "Only hosts will listen to router advertisements"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7192
msgid "Hosts have single network interface (except loopback)"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7197
msgid ""
"Therefore, this is unwise to enable net.inet6.ip6.accept_rtadv on routers, "
"or multi-interface host. A misconfigured node can behave strange "
"(nonconforming configuration allowed for those who would like to do some "
"experiments)."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7203
msgid "To summarize the sysctl knob:"
msgstr ""

#. (itstool) path: sect4/screen
#: book.translate.xml:7205
#, no-wrap
msgid ""
"\taccept_rtadv\tforwarding\trole of the node\n"
"\t---\t\t---\t\t---\n"
"\t0\t\t0\t\thost (to be manually configured)\n"
"\t0\t\t1\t\trouter\n"
"\t1\t\t0\t\tautoconfigured host\n"
"\t\t\t\t\t(spec assumes that host has single\n"
"\t\t\t\t\tinterface only, autoconfigured host\n"
"\t\t\t\t\twith multiple interface is\n"
"\t\t\t\t\tout-of-scope)\n"
"\t1\t\t1\t\tinvalid, or experimental\n"
"\t\t\t\t\t(out-of-scope of spec)"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7217
msgid ""
"RFC2462 has validation rule against incoming RA prefix information option, "
"in 5.5.3 (e). This is to protect hosts from malicious (or misconfigured) "
"routers that advertise very short prefix lifetime. There was an update from "
"Jim Bound to ipngwg mailing list (look for \"(ipng 6712)\" in the archive) "
"and it is implemented Jim's update."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7225
msgid ""
"See <link linkend=\"neighbor-discovery\">23.5.1.2</link> in the document for "
"relationship between DAD and autoconfiguration."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7232
msgid "Generic Tunnel Interface"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7234
msgid ""
"GIF (Generic InterFace) is a pseudo interface for configured tunnel. Details "
"are described in <citerefentry><refentrytitle>gif</"
"refentrytitle><manvolnum>4</manvolnum></citerefentry>. Currently"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7240
msgid "v6 in v6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7243
msgid "v6 in v4"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7246
msgid "v4 in v6"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7249
msgid "v4 in v4"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7253
msgid ""
"are available. Use <citerefentry><refentrytitle>gifconfig</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> to assign physical "
"(outer) source and destination address to gif interfaces. Configuration that "
"uses same address family for inner and outer IP header (v4 in v4, or v6 in "
"v6) is dangerous. It is very easy to configure interfaces and routing tables "
"to perform infinite level of tunneling. <emphasis>Please be warned</"
"emphasis>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7261
msgid ""
"gif can be configured to be ECN-friendly. See <link linkend=\"ipsec-ecn"
"\">23.5.4.5</link> for ECN-friendliness of tunnels, and "
"<citerefentry><refentrytitle>gif</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> for how to configure."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7264
msgid ""
"If you would like to configure an IPv4-in-IPv6 tunnel with gif interface, "
"read <citerefentry><refentrytitle>gif</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> carefully. You will need to remove IPv6 link-local "
"address automatically assigned to the gif interface."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7271
msgid "Source Address Selection"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7273
msgid ""
"Current source selection rule is scope oriented (there are some exceptions - "
"see below). For a given destination, a source IPv6 address is selected by "
"the following rule:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7280
msgid ""
"If the source address is explicitly specified by the user (e.g., via the "
"advanced API), the specified address is used."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7286
msgid ""
"If there is an address assigned to the outgoing interface (which is usually "
"determined by looking up the routing table) that has the same scope as the "
"destination address, the address is used."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7291
msgid "This is the most typical case."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7295
msgid ""
"If there is no address that satisfies the above condition, choose a global "
"address assigned to one of the interfaces on the sending node."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7301
msgid ""
"If there is no address that satisfies the above condition, and destination "
"address is site local scope, choose a site local address assigned to one of "
"the interfaces on the sending node."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7308
msgid ""
"If there is no address that satisfies the above condition, choose the "
"address associated with the routing table entry for the destination. This is "
"the last resort, which may cause scope violation."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7315
msgid ""
"For instance, ::1 is selected for ff01::1, fe80:1::200:f8ff:fe01:6317 for "
"fe80:1::2a0:24ff:feab:839b (note that embedded interface index - described "
"in <link linkend=\"ipv6-scope-index\">23.5.1.3</link> - helps us choose the "
"right source address. Those embedded indices will not be on the wire). If "
"the outgoing interface has multiple address for the scope, a source is "
"selected longest match basis (rule 3). Suppose 2001:0DB8:808:1:200:f8ff:"
"fe01:6317 and 2001:0DB8:9:124:200:f8ff:fe01:6317 are given to the outgoing "
"interface. 2001:0DB8:808:1:200:f8ff:fe01:6317 is chosen as the source for "
"the destination 2001:0DB8:800::1."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7327
msgid ""
"Note that the above rule is not documented in the IPv6 spec. It is "
"considered \"up to implementation\" item. There are some cases where we do "
"not use the above rule. One example is connected TCP session, and we use the "
"address kept in tcb as the source. Another example is source address for "
"Neighbor Advertisement. Under the spec (RFC2461 7.2.2) NA's source should be "
"the target address of the corresponding NS's target. In this case we follow "
"the spec rather than the above longest-match rule."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7337
msgid ""
"For new connections (when rule 1 does not apply), deprecated addresses "
"(addresses with preferred lifetime = 0) will not be chosen as source address "
"if other choices are available. If no other choices are available, "
"deprecated address will be used as a last resort. If there are multiple "
"choice of deprecated addresses, the above scope rule will be used to choose "
"from those deprecated addresses. If you would like to prohibit the use of "
"deprecated address for some reason, configure net.inet6.ip6.use_deprecated "
"to 0. The issue related to deprecated address is described in RFC2462 5.5.4 "
"(NOTE: there is some debate underway in IETF ipngwg on how to use "
"\"deprecated\" address)."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7352
msgid "Jumbo Payload"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7354
msgid ""
"The Jumbo Payload hop-by-hop option is implemented and can be used to send "
"IPv6 packets with payloads longer than 65,535 octets. But currently no "
"physical interface whose MTU is more than 65,535 is supported, so such "
"payloads can be seen only on the loopback interface (i.e., lo0)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7360
msgid ""
"If you want to try jumbo payloads, you first have to reconfigure the kernel "
"so that the MTU of the loopback interface is more than 65,535 bytes; add the "
"following to the kernel configuration file:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7365
msgid "<literal>options \"LARGE_LOMTU\" #To test jumbo payload</literal>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7368
msgid "and recompile the new kernel."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7370
msgid ""
"Then you can test jumbo payloads by the <citerefentry><refentrytitle>ping6</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> command with -b and -s "
"options. The -b option must be specified to enlarge the size of the socket "
"buffer and the -s option specifies the length of the packet, which should be "
"more than 65,535. For example, type as follows:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:7376
#, no-wrap
msgid "<prompt>%</prompt> <userinput>ping6 -b 70000 -s 68000 ::1</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7378
msgid ""
"The IPv6 specification requires that the Jumbo Payload option must not be "
"used in a packet that carries a fragment header. If this condition is "
"broken, an ICMPv6 Parameter Problem message must be sent to the sender. "
"specification is followed, but you cannot usually see an ICMPv6 error caused "
"by this requirement."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7385
msgid ""
"When an IPv6 packet is received, the frame length is checked and compared to "
"the length specified in the payload length field of the IPv6 header or in "
"the value of the Jumbo Payload option, if any. If the former is shorter than "
"the latter, the packet is discarded and statistics are incremented. You can "
"see the statistics as output of <citerefentry><refentrytitle>netstat</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> command with `-s -p "
"ip6' option:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:7393
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>netstat -s -p ip6</userinput>\n"
"\t  ip6:\n"
"\t\t(snip)\n"
"\t\t1 with data size &lt; data length"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7398
msgid ""
"So, kernel does not send an ICMPv6 error unless the erroneous packet is an "
"actual Jumbo Payload, that is, its packet size is more than 65,535 bytes. As "
"described above, currently no physical interface with such a huge MTU is "
"supported, so it rarely returns an ICMPv6 error."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7404
msgid ""
"TCP/UDP over jumbogram is not supported at this moment. This is because we "
"have no medium (other than loopback) to test this. Contact us if you need "
"this."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7408
msgid ""
"IPsec does not work on jumbograms. This is due to some specification twists "
"in supporting AH with jumbograms (AH header size influences payload length, "
"and this makes it real hard to authenticate inbound packet with jumbo "
"payload option as well as AH)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7414
msgid ""
"There are fundamental issues in *BSD support for jumbograms. We would like "
"to address those, but we need more time to finalize these. To name a few:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7420
msgid ""
"mbuf pkthdr.len field is typed as \"int\" in 4.4BSD, so it will not hold "
"jumbogram with len &gt; 2G on 32bit architecture CPUs. If we would like to "
"support jumbogram properly, the field must be expanded to hold 4G + IPv6 "
"header + link-layer header. Therefore, it must be expanded to at least "
"int64_t (u_int32_t is NOT enough)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7430
msgid ""
"We mistakingly use \"int\" to hold packet length in many places. We need to "
"convert them into larger integral type. It needs a great care, as we may "
"experience overflow during packet length computation."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7438
msgid ""
"We mistakingly check for ip6_plen field of IPv6 header for packet payload "
"length in various places. We should be checking mbuf pkthdr.len instead. "
"ip6_input() will perform sanity check on jumbo payload option on input, and "
"we can safely use mbuf pkthdr.len afterwards."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7447
msgid "TCP code needs a careful update in bunch of places, of course."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7454
msgid "Loop Prevention in Header Processing"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7456
msgid ""
"IPv6 specification allows arbitrary number of extension headers to be placed "
"onto packets. If we implement IPv6 packet processing code in the way BSD "
"IPv4 code is implemented, kernel stack may overflow due to long function "
"call chain. sys/netinet6 code is carefully designed to avoid kernel stack "
"overflow. Because of this, sys/netinet6 code defines its own protocol switch "
"structure, as \"struct ip6protosw\" (see <filename>netinet6/ip6protosw.h</"
"filename>). There is no such update to IPv4 part (sys/netinet) for "
"compatibility, but small change is added to its pr_input() prototype. So "
"\"struct ipprotosw\" is also defined. Because of this, if you receive IPsec-"
"over-IPv4 packet with massive number of IPsec headers, kernel stack may blow "
"up. IPsec-over-IPv6 is okay. (Off-course, for those all IPsec headers to be "
"processed, each such IPsec header must pass each IPsec check. So an "
"anonymous attacker will not be able to do such an attack.)"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7477
msgid "ICMPv6"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7479
msgid ""
"After RFC2463 was published, IETF ipngwg has decided to disallow ICMPv6 "
"error packet against ICMPv6 redirect, to prevent ICMPv6 storm on a network "
"medium. This is already implemented into the kernel."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7486
msgid "Applications"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7488
msgid ""
"For userland programming, we support IPv6 socket API as specified in "
"RFC2553, RFC2292 and upcoming Internet drafts."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7492
msgid ""
"TCP/UDP over IPv6 is available and quite stable. You can enjoy "
"<citerefentry><refentrytitle>telnet</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry>, <citerefentry><refentrytitle>ftp</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry>, <citerefentry><refentrytitle>rlogin</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry>, "
"<citerefentry><refentrytitle>rsh</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry>, <citerefentry><refentrytitle>ssh</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry>, etc. These applications are protocol independent. "
"That is, they automatically chooses IPv4 or IPv6 according to DNS."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7500
msgid "Kernel Internals"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7502
msgid ""
"While ip_forward() calls ip_output(), ip6_forward() directly calls "
"if_output() since routers must not divide IPv6 packets into fragments."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7506
msgid ""
"ICMPv6 should contain the original packet as long as possible up to 1280. "
"UDP6/IP6 port unreach, for instance, should contain all extension headers "
"and the *unchanged* UDP6 and IP6 headers. So, all IP6 functions except TCP "
"never convert network byte order into host byte order, to save the original "
"packet."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7513
msgid ""
"tcp_input(), udp6_input() and icmp6_input() can not assume that IP6 header "
"is preceding the transport headers due to extension headers. So, in6_cksum() "
"was implemented to handle packets whose IP6 header and transport header is "
"not continuous. TCP/IP6 nor UDP6/IP6 header structures do not exist for "
"checksum calculation."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7520
msgid ""
"To process IP6 header, extension headers and transport headers easily, "
"network drivers are now required to store packets in one internal mbuf or "
"one or more external mbufs. A typical old driver prepares two internal mbufs "
"for 96 - 204 bytes data, however, now such packet data is stored in one "
"external mbuf."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7527
msgid ""
"<command>netstat -s -p ip6</command> tells you whether or not your driver "
"conforms such requirement. In the following example, \"cce0\" violates the "
"requirement. (For more information, refer to Section 2.)"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:7532
#, no-wrap
msgid ""
"Mbuf statistics:\n"
"                317 one mbuf\n"
"                two or more mbuf::\n"
"                        lo0 = 8\n"
"\t\t\tcce0 = 10\n"
"                3282 one ext mbuf\n"
"                0 two or more ext mbuf"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7540
msgid ""
"Each input function calls IP6_EXTHDR_CHECK in the beginning to check if the "
"region between IP6 and its header is continuous. IP6_EXTHDR_CHECK calls "
"m_pullup() only if the mbuf has M_LOOP flag, that is, the packet comes from "
"the loopback interface. m_pullup() is never called for packets coming from "
"physical network interfaces."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7547
msgid "Both IP and IP6 reassemble functions never call m_pullup()."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7552
msgid "IPv4 Mapped Address and IPv6 Wildcard Socket"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7554
msgid ""
"RFC2553 describes IPv4 mapped address (3.7) and special behavior of IPv6 "
"wildcard bind socket (3.8). The spec allows you to:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7559
msgid "Accept IPv4 connections by AF_INET6 wildcard bind socket."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7563
msgid ""
"Transmit IPv4 packet over AF_INET6 socket by using special form of the "
"address like ::ffff:10.1.1.1."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7568
msgid ""
"but the spec itself is very complicated and does not specify how the socket "
"layer should behave. Here we call the former one \"listening side\" and the "
"latter one \"initiating side\", for reference purposes."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7573
msgid ""
"You can perform wildcard bind on both of the address families, on the same "
"port."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7576
msgid "The following table show the behavior of FreeBSD 4.x."
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:7579
#, no-wrap
msgid ""
"listening side          initiating side\n"
"                (AF_INET6 wildcard      (connection to ::ffff:10.1.1.1)\n"
"                socket gets IPv4 conn.)\n"
"                ---                     ---\n"
"FreeBSD 4.x     configurable            supported\n"
"                default: enabled"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7586
msgid ""
"The following sections will give you more details, and how you can configure "
"the behavior."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7589
msgid "Comments on listening side:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7591
msgid ""
"It looks that RFC2553 talks too little on wildcard bind issue, especially on "
"the port space issue, failure mode and relationship between AF_INET/INET6 "
"wildcard bind. There can be several separate interpretation for this RFC "
"which conform to it but behaves differently. So, to implement portable "
"application you should assume nothing about the behavior in the kernel. "
"Using <citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> is the safest way. Port number space and wildcard "
"bind issues were discussed in detail on ipv6imp mailing list, in mid March "
"1999 and it looks that there is no concrete consensus (means, up to "
"implementers). You may want to check the mailing list archives."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7604
msgid ""
"If a server application would like to accept IPv4 and IPv6 connections, "
"there will be two alternatives."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7607
msgid ""
"One is using AF_INET and AF_INET6 socket (you will need two sockets). Use "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> with AI_PASSIVE into ai_flags, and "
"<citerefentry><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></"
"citerefentry> and <citerefentry><refentrytitle>bind</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry> to all the addresses "
"returned. By opening multiple sockets, you can accept connections onto the "
"socket with proper address family. IPv4 connections will be accepted by "
"AF_INET socket, and IPv6 connections will be accepted by AF_INET6 socket."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7616
msgid ""
"Another way is using one AF_INET6 wildcard bind socket. Use "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> with AI_PASSIVE into ai_flags and with AF_INET6 "
"into ai_family, and set the 1st argument hostname to NULL. And "
"<citerefentry><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></"
"citerefentry> and <citerefentry><refentrytitle>bind</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry> to the address "
"returned. (should be IPv6 unspecified addr). You can accept either of IPv4 "
"and IPv6 packet via this one socket."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7624
msgid ""
"To support only IPv6 traffic on AF_INET6 wildcard binded socket portably, "
"always check the peer address when a connection is made toward AF_INET6 "
"listening socket. If the address is IPv4 mapped address, you may want to "
"reject the connection. You can check the condition by using "
"IN6_IS_ADDR_V4MAPPED() macro."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7631
msgid ""
"To resolve this issue more easily, there is system dependent "
"<citerefentry><refentrytitle>setsockopt</refentrytitle><manvolnum>2</"
"manvolnum></citerefentry> option, IPV6_BINDV6ONLY, used like below."
msgstr ""

#. (itstool) path: sect3/programlisting
#. (itstool) path: sect5/programlisting
#: book.translate.xml:7635 book.translate.xml:7734
#, no-wrap
msgid ""
"\tint on;\n"
"\n"
"\tsetsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,\n"
"\t\t   (char *)&amp;on, sizeof (on)) &lt; 0));"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7640
msgid "When this call succeed, then this socket only receive IPv6 packets."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7643
msgid "Comments on initiating side:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7645
msgid ""
"Advise to application implementers: to implement a portable IPv6 application "
"(which works on multiple IPv6 kernels), we believe that the following is the "
"key to the success:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7652
msgid "NEVER hardcode AF_INET nor AF_INET6."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7656
msgid ""
"Use <citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>getnameinfo</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry> throughout the system. "
"Never use gethostby*(), getaddrby*(), inet_*() or getipnodeby*(). (To update "
"existing applications to be IPv6 aware easily, sometime getipnodeby*() will "
"be useful. But if possible, try to rewrite the code to use "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and <citerefentry><refentrytitle>getnameinfo</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry>.)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7666
msgid ""
"If you would like to connect to destination, use "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> and try all the destination returned, like "
"<citerefentry><refentrytitle>telnet</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> does."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7672
msgid ""
"Some of the IPv6 stack is shipped with buggy "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry>. Ship a minimal working version with your "
"application and use that as last resort."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7679
msgid ""
"If you would like to use AF_INET6 socket for both IPv4 and IPv6 outgoing "
"connection, you will need to use "
"<citerefentry><refentrytitle>getipnodebyname</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry>. When you would like to update your existing "
"application to be IPv6 aware with minimal effort, this approach might be "
"chosen. But please note that it is a temporal solution, because "
"<citerefentry><refentrytitle>getipnodebyname</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> itself is not recommended as it does not handle "
"scoped IPv6 addresses at all. For IPv6 name resolution, "
"<citerefentry><refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</"
"manvolnum></citerefentry> is the preferred API. So you should rewrite your "
"application to use <citerefentry><refentrytitle>getaddrinfo</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry>, when you get the time "
"to do it."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7691
msgid ""
"When writing applications that make outgoing connections, story goes much "
"simpler if you treat AF_INET and AF_INET6 as totally separate address "
"family. {set,get}sockopt issue goes simpler, DNS issue will be made simpler. "
"We do not recommend you to rely upon IPv4 mapped address."
msgstr ""

#. (itstool) path: sect4/title
#: book.translate.xml:7699
msgid "unified tcp and inpcb code"
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7701
msgid ""
"FreeBSD 4.x uses shared tcp code between IPv4 and IPv6 (from sys/netinet/"
"tcp*) and separate udp4/6 code. It uses unified inpcb structure."
msgstr ""

#. (itstool) path: sect4/para
#: book.translate.xml:7705
msgid ""
"The platform can be configured to support IPv4 mapped address. Kernel "
"configuration is summarized as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7711
msgid ""
"By default, AF_INET6 socket will grab IPv4 connections in certain condition, "
"and can initiate connection to IPv4 destination embedded in IPv4 mapped IPv6 "
"address."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7718
msgid "You can disable it on entire system with sysctl like below."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7721
msgid "<command>sysctl net.inet6.ip6.mapped_addr=0</command>"
msgstr ""

#. (itstool) path: sect5/title
#: book.translate.xml:7727
msgid "Listening Side"
msgstr ""

#. (itstool) path: sect5/para
#: book.translate.xml:7729
msgid ""
"Each socket can be configured to support special AF_INET6 wildcard bind "
"(enabled by default). You can disable it on each socket basis with "
"<citerefentry><refentrytitle>setsockopt</refentrytitle><manvolnum>2</"
"manvolnum></citerefentry> like below."
msgstr ""

#. (itstool) path: sect5/para
#: book.translate.xml:7739
msgid ""
"Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following "
"conditions are satisfied:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7745
msgid "there is no AF_INET socket that matches the IPv4 connection"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7750
msgid ""
"the AF_INET6 socket is configured to accept IPv4 traffic, i.e., "
"getsockopt(IPV6_BINDV6ONLY) returns 0."
msgstr ""

#. (itstool) path: sect5/para
#: book.translate.xml:7756
msgid "There is no problem with open/close ordering."
msgstr ""

#. (itstool) path: sect5/title
#: book.translate.xml:7760
msgid "Initiating Side"
msgstr ""

#. (itstool) path: sect5/para
#: book.translate.xml:7762
msgid ""
"FreeBSD 4.x supports outgoing connection to IPv4 mapped address (::"
"ffff:10.1.1.1), if the node is configured to support IPv4 mapped address."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7770
msgid "sockaddr_storage"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7772
msgid ""
"When RFC2553 was about to be finalized, there was discussion on how struct "
"sockaddr_storage members are named. One proposal is to prepend \"__\" to the "
"members (like \"__ss_len\") as they should not be touched. The other "
"proposal was not to prepend it (like \"ss_len\") as we need to touch those "
"members directly. There was no clear consensus on it."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7780
msgid "As a result, RFC2553 defines struct sockaddr_storage as follows:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:7783
#, no-wrap
msgid ""
"\tstruct sockaddr_storage {\n"
"\t\tu_char\t__ss_len;\t/* address length */\n"
"\t\tu_char\t__ss_family;\t/* address family */\n"
"\t\t/* and bunch of padding */\n"
"\t};"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7789
msgid "On the contrary, XNET draft defines as follows:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:7791
#, no-wrap
msgid ""
"\tstruct sockaddr_storage {\n"
"\t\tu_char\tss_len;\t\t/* address length */\n"
"\t\tu_char\tss_family;\t/* address family */\n"
"\t\t/* and bunch of padding */\n"
"\t};"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7797
msgid ""
"In December 1999, it was agreed that RFC2553bis should pick the latter "
"(XNET) definition."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7800
msgid ""
"Current implementation conforms to XNET definition, based on RFC2553bis "
"discussion."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7803
msgid ""
"If you look at multiple IPv6 implementations, you will be able to see both "
"definitions. As an userland programmer, the most portable way of dealing "
"with it is to:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7809
msgid ""
"ensure ss_family and/or ss_len are available on the platform, by using GNU "
"autoconf,"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7814
msgid ""
"have -Dss_family=__ss_family to unify all occurrences (including header "
"file) into __ss_family, or"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7820
msgid "never touch __ss_family. cast to sockaddr * and use sa_family like:"
msgstr ""

#. (itstool) path: listitem/programlisting
#: book.translate.xml:7823
#, no-wrap
msgid ""
"\tstruct sockaddr_storage ss;\n"
"\tfamily = ((struct sockaddr *)&amp;ss)-&gt;sa_family"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:7832
msgid "Network Drivers"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:7834
msgid ""
"Now following two items are required to be supported by standard drivers:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7839
msgid ""
"mbuf clustering requirement. In this stable release, we changed MINCLSIZE "
"into MHLEN+1 for all the operating systems in order to make all the drivers "
"behave as we expect."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7846
msgid ""
"multicast. If <citerefentry><refentrytitle>ifmcstat</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> yields no multicast "
"group for a interface, that interface has to be patched."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:7852
msgid ""
"If any of the drivers do not support the requirements, then the drivers "
"cannot be used for IPv6 and/or IPsec communication. If you find any problem "
"with your card using IPv6/IPsec, then, please report it to the <link xlink:"
"href=\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-bugs\">FreeBSD "
"problem reports mailing list</link>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:7857
msgid ""
"(NOTE: In the past we required all PCMCIA drivers to have a call to "
"in6_ifattach(). We have no such requirement any more)"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:7863
msgid "Translator"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:7865
msgid "We categorize IPv4/IPv6 translator into 4 types:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7869
msgid ""
"<emphasis>Translator A</emphasis> --- It is used in the early stage of "
"transition to make it possible to establish a connection from an IPv6 host "
"in an IPv6 island to an IPv4 host in the IPv4 ocean."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7876
msgid ""
"<emphasis>Translator B</emphasis> --- It is used in the early stage of "
"transition to make it possible to establish a connection from an IPv4 host "
"in the IPv4 ocean to an IPv6 host in an IPv6 island."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7883
msgid ""
"<emphasis>Translator C</emphasis> --- It is used in the late stage of "
"transition to make it possible to establish a connection from an IPv4 host "
"in an IPv4 island to an IPv6 host in the IPv6 ocean."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7890
msgid ""
"<emphasis>Translator D</emphasis> --- It is used in the late stage of "
"transition to make it possible to establish a connection from an IPv6 host "
"in the IPv6 ocean to an IPv4 host in an IPv4 island."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:7899
msgid "IPsec"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:7901
msgid "IPsec is mainly organized by three components."
msgstr ""

#. (itstool) path: listitem/para
#. (itstool) path: sect3/title
#: book.translate.xml:7905 book.translate.xml:7918
msgid "Policy Management"
msgstr ""

#. (itstool) path: listitem/para
#. (itstool) path: sect3/title
#: book.translate.xml:7909 book.translate.xml:7933
msgid "Key Management"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7913
msgid "AH and ESP handling"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7920
msgid ""
"The kernel implements experimental policy management code. There are two way "
"to manage security policy. One is to configure per-socket policy using "
"<citerefentry><refentrytitle>setsockopt</refentrytitle><manvolnum>2</"
"manvolnum></citerefentry>. In this cases, policy configuration is described "
"in <citerefentry><refentrytitle>ipsec_set_policy</"
"refentrytitle><manvolnum>3</manvolnum></citerefentry>. The other is to "
"configure kernel packet filter-based policy using PF_KEY interface, via "
"<citerefentry><refentrytitle>setkey</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7928
msgid ""
"The policy entry is not re-ordered with its indexes, so the order of entry "
"when you add is very significant."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7935
msgid ""
"The key management code implemented in this kit (sys/netkey) is a home-brew "
"PFKEY v2 implementation. This conforms to RFC2367."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7939
msgid ""
"The home-brew IKE daemon, \"racoon\" is included in the kit (kame/kame/"
"racoon). Basically you will need to run racoon as daemon, then set up a "
"policy to require keys (like <command>ping -P 'out ipsec esp/transport//"
"use'</command>). The kernel will contact racoon daemon as necessary to "
"exchange keys."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:7948
msgid "AH and ESP Handling"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7950
msgid ""
"IPsec module is implemented as \"hooks\" to the standard IPv4/IPv6 "
"processing. When sending a packet, ip{,6}_output() checks if ESP/AH "
"processing is required by checking if a matching SPD (Security Policy "
"Database) is found. If ESP/AH is needed, {esp,ah}{4,6}_output() will be "
"called and mbuf will be updated accordingly. When a packet is received, {esp,"
"ah}4_input() will be called based on protocol number, i.e., (*inetsw[proto])"
"(). {esp,ah}4_input() will decrypt/check authenticity of the packet, and "
"strips off daisy-chained header and padding for ESP/AH. It is safe to strip "
"off the ESP/AH header on packet reception, since we will never use the "
"received packet in \"as is\" form."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7964
msgid ""
"By using ESP/AH, TCP4/6 effective data segment size will be affected by "
"extra daisy-chained headers inserted by ESP/AH. Our code takes care of the "
"case."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7968
msgid ""
"Basic crypto functions can be found in directory \"sys/crypto\". ESP/AH "
"transform are listed in {esp,ah}_core.c with wrapper functions. If you wish "
"to add some algorithm, add wrapper function in {esp,ah}_core.c, and add your "
"crypto algorithm code into sys/crypto."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:7974
msgid ""
"Tunnel mode is partially supported in this release, with the following "
"restrictions:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7979
msgid ""
"IPsec tunnel is not combined with GIF generic tunneling interface. It needs "
"a great care because we may create an infinite loop between ip_output() and "
"tunnelifp-&gt;if_output(). Opinion varies if it is better to unify them, or "
"not."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7987
msgid ""
"MTU and Don't Fragment bit (IPv4) considerations need more checking, but "
"basically works fine."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:7992
msgid ""
"Authentication model for AH tunnel must be revisited. We will need to "
"improve the policy management engine, eventually."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:8000
msgid "Conformance to RFCs and IDs"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8002
msgid ""
"The IPsec code in the kernel conforms (or, tries to conform) to the "
"following standards:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8005
msgid ""
"\"old IPsec\" specification documented in <filename>rfc182[5-9].txt</"
"filename>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8008
msgid ""
"\"new IPsec\" specification documented in <filename>rfc240[1-6].txt</"
"filename>, <filename>rfc241[01].txt</filename>, <filename>rfc2451.txt</"
"filename> and <filename>draft-mcdonald-simple-ipsec-api-01.txt</filename> "
"(draft expired, but you can take from <link xlink:href=\"ftp://ftp.kame.net/"
"pub/internet-drafts/\"> ftp://ftp.kame.net/pub/internet-drafts/</link>). "
"(NOTE: IKE specifications, <filename>rfc241[7-9].txt</filename> are "
"implemented in userland, as \"racoon\" IKE daemon)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8018
msgid "Currently supported algorithms are:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8021 book.translate.xml:8139
msgid "old IPsec AH"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8024 book.translate.xml:8064
msgid "null crypto checksum (no document, just for debugging)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8028
msgid ""
"keyed MD5 with 128bit crypto checksum (<filename>rfc1828.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8032
msgid "keyed SHA1 with 128bit crypto checksum (no document)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8036
msgid "HMAC MD5 with 128bit crypto checksum (<filename>rfc2085.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8040
msgid "HMAC SHA1 with 128bit crypto checksum (no document)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8047
msgid "old IPsec ESP"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8050
msgid ""
"null encryption (no document, similar to <filename>rfc2410.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8054
msgid "DES-CBC mode (<filename>rfc1829.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8061
msgid "new IPsec AH"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8068
msgid "keyed MD5 with 96bit crypto checksum (no document)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8072
msgid "keyed SHA1 with 96bit crypto checksum (no document)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8076
msgid "HMAC MD5 with 96bit crypto checksum (<filename>rfc2403.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8080
msgid "HMAC SHA1 with 96bit crypto checksum (<filename>rfc2404.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8087
msgid "new IPsec ESP"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8090
msgid "null encryption (<filename>rfc2410.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8094
msgid ""
"DES-CBC with derived IV (<filename>draft-ietf-ipsec-ciph-des-derived-01.txt</"
"filename>, draft expired)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8099
msgid "DES-CBC with explicit IV (<filename>rfc2405.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8103
msgid "3DES-CBC with explicit IV (<filename>rfc2451.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8107
msgid "BLOWFISH CBC (<filename>rfc2451.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8111
msgid "CAST128 CBC (<filename>rfc2451.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8115
msgid "RC5 CBC (<filename>rfc2451.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8119
msgid "each of the above can be combined with:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8122
msgid "ESP authentication with HMAC-MD5(96bit)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8126
msgid "ESP authentication with HMAC-SHA1(96bit)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8135
msgid "The following algorithms are NOT supported:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8143
msgid ""
"HMAC MD5 with 128bit crypto checksum + 64bit replay prevention "
"(<filename>rfc2085.txt</filename>)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8148
msgid ""
"keyed SHA1 with 160bit crypto checksum + 32bit padding (<filename>rfc1852."
"txt</filename>)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8155
msgid ""
"IPsec (in kernel) and IKE (in userland as \"racoon\") has been tested at "
"several interoperability test events, and it is known to interoperate with "
"many other implementations well. Also, current IPsec implementation as quite "
"wide coverage for IPsec crypto algorithms documented in RFC (we cover "
"algorithms without intellectual property issues only)."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:8165
msgid "ECN Consideration on IPsec Tunnels"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8167
msgid ""
"ECN-friendly IPsec tunnel is supported as described in <filename>draft-ipsec-"
"ecn-00.txt</filename>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8170
msgid ""
"Normal IPsec tunnel is described in RFC2401. On encapsulation, IPv4 TOS "
"field (or, IPv6 traffic class field) will be copied from inner IP header to "
"outer IP header. On decapsulation outer IP header will be simply dropped. "
"The decapsulation rule is not compatible with ECN, since ECN bit on the "
"outer IP TOS/traffic class field will be lost."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8177
msgid ""
"To make IPsec tunnel ECN-friendly, we should modify encapsulation and "
"decapsulation procedure. This is described in <link xlink:href=\"http://www."
"aciri.org/floyd/papers/draft-ipsec-ecn-00.txt\"> http://www.aciri.org/floyd/"
"papers/draft-ipsec-ecn-00.txt</link>, chapter 3."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8183
msgid ""
"IPsec tunnel implementation can give you three behaviors, by setting net."
"inet.ipsec.ecn (or net.inet6.ipsec6.ecn) to some value:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8189
msgid "RFC2401: no consideration for ECN (sysctl value -1)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8193
msgid "ECN forbidden (sysctl value 0)"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8196
msgid "ECN allowed (sysctl value 1)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8200
msgid ""
"Note that the behavior is configurable in per-node manner, not per-SA manner "
"(draft-ipsec-ecn-00 wants per-SA configuration, but it looks too much for "
"me)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8204
msgid ""
"The behavior is summarized as follows (see source code for more detail):"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:8207
#, no-wrap
msgid ""
"encapsulate                     decapsulate\n"
"                ---                             ---\n"
"RFC2401         copy all TOS bits               drop TOS bits on outer\n"
"                from inner to outer.            (use inner TOS bits as is)\n"
"\n"
"ECN forbidden   copy TOS bits except for ECN    drop TOS bits on outer\n"
"                (masked with 0xfc) from inner   (use inner TOS bits as is)\n"
"                to outer.  set ECN bits to 0.\n"
"\n"
"ECN allowed     copy TOS bits except for ECN    use inner TOS bits with some\n"
"                CE (masked with 0xfe) from      change.  if outer ECN CE bit\n"
"                inner to outer.                 is 1, enable ECN CE bit on\n"
"                set ECN CE bit to 0.            the inner."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8221
msgid "General strategy for configuration is as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8224
msgid ""
"if both IPsec tunnel endpoint are capable of ECN-friendly behavior, you "
"should better configure both end to <quote>ECN allowed</quote> (sysctl value "
"1)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8230
msgid ""
"if the other end is very strict about TOS bit, use \"RFC2401\" (sysctl value "
"-1)."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8234
msgid "in other cases, use \"ECN forbidden\" (sysctl value 0)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8239
msgid "The default behavior is \"ECN forbidden\" (sysctl value 0)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8242
msgid "For more information, please refer to:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8244
msgid ""
"<link xlink:href=\"http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt"
"\"> http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt</link>, RFC2481 "
"(Explicit Congestion Notification), src/sys/netinet6/{ah,esp}_input.c"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8249
msgid ""
"(Thanks goes to Kenjiro Cho <email>kjc@csl.sony.co.jp</email> for detailed "
"analysis)"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:8255
msgid "Interoperability"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8257
msgid ""
"Here are (some of) platforms that KAME code have tested IPsec/IKE "
"interoperability in the past. Note that both ends may have modified their "
"implementation, so use the following list just for reference purposes."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:8262
msgid ""
"Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure), Ericsson ACC, "
"FreeS/WAN, HITACHI, IBM <trademark class=\"registered\">AIX</trademark>, "
"IIJ, Intel, <trademark class=\"registered\">Microsoft</trademark> <trademark "
"class=\"registered\">Windows NT</trademark>, NIST (linux IPsec + plutoplus), "
"Netscreen, OpenBSD, RedCreek, Routerware, SSH, Secure Computing, Soliton, "
"Toshiba, VPNet, Yamaha RT100i"
msgstr ""

#. (itstool) path: part/title
#: book.translate.xml:8277
msgid "Kernel"
msgstr ""

#. (itstool) path: chapter/title
#: book.translate.xml:8286
msgid "Building and Installing a FreeBSD Kernel"
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:8288
msgid ""
"Being a kernel developer requires understanding of the kernel build process. "
"To debug the FreeBSD kernel it is required to be able to build one. There "
"are two known ways to do so:"
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:8292
msgid ""
"The supported procedure to build and install a kernel is documented in the "
"<link xlink:href=\"../handbook/kernelconfig-building.html\">Building and "
"Installing a Custom Kernel</link> chapter of the FreeBSD Handbook."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:8298
msgid ""
"It is supposed that the reader of this chapter is familiar with the "
"information described in the <link xlink:href=\"../handbook/kernelconfig-"
"building.html\">Building and Installing a Custom Kernel</link> chapter of "
"the FreeBSD Handbook. If this is not the case, please read through the above "
"mentioned chapter to understand how the build process works."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8307
msgid "Building the Faster but Brittle Way"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8309
msgid ""
"Building the kernel this way may be useful when working on the kernel code "
"and it may actually be faster than the documented procedure when only a "
"single option or two were tweaked in the kernel configuration file. On the "
"other hand, it might lead to unexpected kernel build breakage."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:8318
msgid ""
"Run <citerefentry><refentrytitle>config</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> to generate the kernel source code:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:8321
#, no-wrap
msgid "<prompt>#</prompt> <userinput>/usr/sbin/config <replaceable>MYKERNEL</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:8325
msgid ""
"Change into the build directory. <citerefentry><refentrytitle>config</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> will print the name of "
"this directory after being run as above."
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:8329
#, no-wrap
msgid "<prompt>#</prompt> <userinput>cd ../compile/<replaceable>MYKERNEL</replaceable></userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:8333
msgid "Compile the kernel:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:8335
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>make depend</userinput>\n"
"<prompt>#</prompt> <userinput>make</userinput>"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:8340
msgid "Install the new kernel:"
msgstr ""

#. (itstool) path: step/screen
#: book.translate.xml:8342
#, no-wrap
msgid "<prompt>#</prompt> <userinput>make install</userinput>"
msgstr ""

#. (itstool) path: info/title
#: book.translate.xml:8356
msgid "Kernel Debugging"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:8358
msgid ""
"<personname><firstname>Paul</firstname><surname>Richards</surname></"
"personname><contrib>Contributed by </contrib>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:8359
msgid ""
"<personname><firstname>Jörg</firstname><surname>Wunsch</surname></personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:8360
msgid ""
"<personname><firstname>Robert</firstname><surname>Watson</surname></"
"personname>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8367
msgid "Obtaining a Kernel Crash Dump"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8369
msgid ""
"When running a development kernel (e.g., FreeBSD-CURRENT), such as a kernel "
"under extreme conditions (e.g., very high load averages, tens of thousands "
"of connections, exceedingly high number of concurrent users, hundreds of "
"<citerefentry><refentrytitle>jail</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry>s, etc.), or using a new feature or device driver on FreeBSD-"
"STABLE (e.g., <acronym>PAE</acronym>), sometimes a kernel will panic. In the "
"event that it does, this chapter will demonstrate how to extract useful "
"information out of a crash."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8378
msgid ""
"A system reboot is inevitable once a kernel panics. Once a system is "
"rebooted, the contents of a system's physical memory (<acronym>RAM</"
"acronym>) is lost, as well as any bits that are on the swap device before "
"the panic. To preserve the bits in physical memory, the kernel makes use of "
"the swap device as a temporary place to store the bits that are in RAM "
"across a reboot after a crash. In doing this, when FreeBSD boots after a "
"crash, a kernel image can now be extracted and debugging can take place."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:8388
msgid ""
"A swap device that has been configured as a dump device still acts as a swap "
"device. Dumps to non-swap devices (such as tapes or CDRWs, for example) are "
"not supported at this time. A <quote>swap device</quote> is synonymous with "
"a <quote>swap partition.</quote>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8394
msgid "Several types of kernel crash dumps are available:"
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:8397
msgid "Full memory dumps"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8400
msgid "Hold the complete contents of physical memory."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:8406
msgid "Minidumps"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8409
msgid "Hold only memory pages in use by the kernel (FreeBSD 6.2 and higher)."
msgstr ""

#. (itstool) path: varlistentry/term
#: book.translate.xml:8415
msgid "Textdumps"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:8418
msgid ""
"Hold captured, scripted, or interactive debugger output (FreeBSD 7.1 and "
"higher)."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8424
msgid ""
"Minidumps are the default dump type as of FreeBSD 7.0, and in most cases "
"will capture all necessary information present in a full memory dump, as "
"most problems can be isolated only using kernel state."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:8430
msgid "Configuring the Dump Device"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8432
msgid ""
"Before the kernel will dump the contents of its physical memory to a dump "
"device, a dump device must be configured. A dump device is specified by "
"using the <citerefentry><refentrytitle>dumpon</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> command to tell the kernel where to save kernel "
"crash dumps. The <citerefentry><refentrytitle>dumpon</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> program must be called "
"after the swap partition has been configured with "
"<citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></"
"citerefentry>. This is normally handled by setting the <varname>dumpdev</"
"varname> variable in <citerefentry><refentrytitle>rc.conf</"
"refentrytitle><manvolnum>5</manvolnum></citerefentry> to the path of the "
"swap device (the recommended way to extract a kernel dump) or <literal>AUTO</"
"literal> to use the first configured swap device. The default for "
"<varname>dumpdev</varname> is <literal>AUTO</literal> in HEAD, and changed "
"to <literal>NO</literal> on RELENG_* branches (except for RELENG_7, which "
"was left set to <literal>AUTO</literal>). On FreeBSD 9.0-RELEASE and later "
"versions, <application>bsdinstall</application> will ask whether crash dumps "
"should be enabled on the target system during the install process."
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:8450
msgid ""
"Check <filename>/etc/fstab</filename> or "
"<citerefentry><refentrytitle>swapinfo</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> for a list of swap devices."
msgstr ""

#. (itstool) path: important/para
#: book.translate.xml:8453
msgid ""
"Make sure the <varname>dumpdir</varname> specified in "
"<citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</"
"manvolnum></citerefentry> exists before a kernel crash!"
msgstr ""

#. (itstool) path: important/screen
#: book.translate.xml:8457
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>mkdir /var/crash</userinput>\n"
"<prompt>#</prompt> <userinput>chmod 700 /var/crash</userinput>"
msgstr ""

#. (itstool) path: important/para
#: book.translate.xml:8460
msgid ""
"Also, remember that the contents of <filename>/var/crash</filename> is "
"sensitive and very likely contains confidential information such as "
"passwords."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:8467
msgid "Extracting a Kernel Dump"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8469
msgid ""
"Once a dump has been written to a dump device, the dump must be extracted "
"before the swap device is mounted. To extract a dump from a dump device, use "
"the <citerefentry><refentrytitle>savecore</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> program. If <varname>dumpdev</varname> has been "
"set in <citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</"
"manvolnum></citerefentry>, <citerefentry><refentrytitle>savecore</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> will be called "
"automatically on the first multi-user boot after the crash and before the "
"swap device is mounted. The location of the extracted core is placed in the "
"<citerefentry><refentrytitle>rc.conf</refentrytitle><manvolnum>5</"
"manvolnum></citerefentry> value <varname>dumpdir</varname>, by default "
"<filename>/var/crash</filename> and will be named <filename>vmcore.0</"
"filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8481
msgid ""
"In the event that there is already a file called <filename>vmcore.0</"
"filename> in <filename>/var/crash</filename> (or whatever <varname>dumpdir</"
"varname> is set to), the kernel will increment the trailing number for every "
"crash to avoid overwriting an existing <filename>vmcore</filename> (e.g., "
"<filename>vmcore.1</filename>). <citerefentry><refentrytitle>savecore</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> will always create a "
"symbolic link to named <filename>vmcore.last</filename> in <filename>/var/"
"crash</filename> after a dump is saved. This symbolic link can be used to "
"locate the name of the most recent dump."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8493
msgid ""
"The <citerefentry><refentrytitle>crashinfo</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> utility generates a text file containing a summary "
"of information from a full memory dump or minidump. If <varname>dumpdev</"
"varname> has been set in <citerefentry><refentrytitle>rc.conf</"
"refentrytitle><manvolnum>5</manvolnum></citerefentry>, "
"<citerefentry><refentrytitle>crashinfo</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> will be invoked automatically after "
"<citerefentry><refentrytitle>savecore</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry>. The output is saved to a file in "
"<varname>dumpdir</varname> named <filename>core.txt.<replaceable>N</"
"replaceable></filename>."
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:8502
msgid ""
"If you are testing a new kernel but need to boot a different one in order to "
"get your system up and running again, boot it only into single user mode "
"using the <option>-s</option> flag at the boot prompt, and then perform the "
"following steps:"
msgstr ""

#. (itstool) path: tip/screen
#: book.translate.xml:8507
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>fsck -p</userinput>\n"
"<prompt>#</prompt> <userinput>mount -a -t ufs</userinput>       # make sure /var/crash is writable\n"
"<prompt>#</prompt> <userinput>savecore /var/crash /dev/ad0s1b</userinput>\n"
"<prompt>#</prompt> <userinput>exit</userinput>                  # exit to multi-user"
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:8512
msgid ""
"This instructs <citerefentry><refentrytitle>savecore</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> to extract a kernel "
"dump from <filename>/dev/ad0s1b</filename> and place the contents in "
"<filename>/var/crash</filename>. Do not forget to make sure the destination "
"directory <filename>/var/crash</filename> has enough space for the dump. "
"Also, do not forget to specify the correct path to your swap device as it is "
"likely different than <filename>/dev/ad0s1b</filename>!"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:8522
msgid "Testing Kernel Dump Configuration"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8524
msgid ""
"The kernel includes a <citerefentry><refentrytitle>sysctl</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry> node that requests a "
"kernel panic. This can be used to verify that your system is properly "
"configured to save kernel crash dumps. You may wish to remount existing file "
"systems as read-only in single user mode before triggering the crash to "
"avoid data loss."
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:8530
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>shutdown now</userinput>\n"
"...\n"
"Enter full pathname of shell or RETURN for /bin/sh:\n"
"<prompt>#</prompt> <userinput>mount -a -u -r</userinput>\n"
"<prompt>#</prompt> <userinput>sysctl debug.kdb.panic=1</userinput>\n"
"debug.kdb.panic:panic: kdb_sysctl_panic\n"
"..."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:8538
msgid ""
"After rebooting, your system should save a dump in <filename>/var/crash</"
"filename> along with a matching summary from "
"<citerefentry><refentrytitle>crashinfo</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8545
msgid "Debugging a Kernel Crash Dump with <command>kgdb</command>"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:8548
msgid ""
"This section covers <citerefentry><refentrytitle>kgdb</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry>. The latest version is "
"included in the <package>devel/gdb</package>. An older version is also "
"present in FreeBSD 11 and earlier."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8553
msgid ""
"To enter into the debugger and begin getting information from the dump, "
"start kgdb:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8556
#, no-wrap
msgid "<prompt>#</prompt> <userinput>kgdb -n <replaceable>N</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8558
msgid ""
"Where <replaceable>N</replaceable> is the suffix of the <filename>vmcore."
"<replaceable>N</replaceable></filename> to examine. To open the most recent "
"dump use:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8562
#, no-wrap
msgid "<prompt>#</prompt> <userinput>kgdb -n last</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8564
msgid ""
"Normally, <citerefentry><refentrytitle>kgdb</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry> should be able to locate the kernel running at the "
"time the dump was generated. If it is not able to locate the correct kernel, "
"pass the pathname of the kernel and dump as two arguments to kgdb:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8569
#, no-wrap
msgid "<prompt>#</prompt> <userinput>kgdb /boot/kernel/kernel /var/crash/vmcore.0</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8571
msgid ""
"You can debug the crash dump using the kernel sources just like you can for "
"any other program."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8574
msgid ""
"This dump is from a 5.2-BETA kernel and the crash comes from deep within the "
"kernel. The output below has been modified to include line numbers on the "
"left. This first trace inspects the instruction pointer and obtains a back "
"trace. The address that is used on line 41 for the <command>list</command> "
"command is the instruction pointer and can be found on line 17. Most "
"developers will request having at least this information sent to them if you "
"are unable to debug the problem yourself. If, however, you do solve the "
"problem, make sure that your patch winds its way into the source tree via a "
"problem report, mailing lists, or by being able to commit it!"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8586
#, no-wrap
msgid ""
" 1:<prompt>#</prompt> <userinput>cd /usr/obj/usr/src/sys/<replaceable>KERNCONF</replaceable></userinput>\n"
" 2:<prompt>#</prompt> <userinput>kgdb kernel.debug /var/crash/vmcore.0</userinput>\n"
" 3:GNU gdb 5.2.1 (FreeBSD)\n"
" 4:Copyright 2002 Free Software Foundation, Inc.\n"
" 5:GDB is free software, covered by the GNU General Public License, and you are\n"
" 6:welcome to change it and/or distribute copies of it under certain conditions.\n"
" 7:Type \"show copying\" to see the conditions.\n"
" 8:There is absolutely no warranty for GDB.  Type \"show warranty\" for details.\n"
" 9:This GDB was configured as \"i386-undermydesk-freebsd\"...\n"
"10:panic: page fault\n"
"11:panic messages:\n"
"12:---\n"
"13:Fatal trap 12: page fault while in kernel mode\n"
"14:cpuid = 0; apic id = 00\n"
"15:fault virtual address   = 0x300\n"
"16:fault code:             = supervisor read, page not present\n"
"17:instruction pointer     = 0x8:0xc0713860\n"
"18:stack pointer           = 0x10:0xdc1d0b70\n"
"19:frame pointer           = 0x10:0xdc1d0b7c\n"
"20:code segment            = base 0x0, limit 0xfffff, type 0x1b\n"
"21:                        = DPL 0, pres 1, def32 1, gran 1\n"
"22:processor eflags        = resume, IOPL = 0\n"
"23:current process         = 14394 (uname)\n"
"24:trap number             = 12\n"
"25:panic: page fault\n"
"26      cpuid = 0;\n"
"27:Stack backtrace:\n"
"28\n"
"29:syncing disks, buffers remaining... 2199 2199 panic: mi_switch: switch in a critical section\n"
"30:cpuid = 0;\n"
"31:Uptime: 2h43m19s\n"
"32:Dumping 255 MB\n"
"33: 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240\n"
"34:---\n"
"35:Reading symbols from /boot/kernel/snd_maestro3.ko...done.\n"
"36:Loaded symbols for /boot/kernel/snd_maestro3.ko\n"
"37:Reading symbols from /boot/kernel/snd_pcm.ko...done.\n"
"38:Loaded symbols for /boot/kernel/snd_pcm.ko\n"
"39:#0  doadump () at /usr/src/sys/kern/kern_shutdown.c:240\n"
"40:240             dumping++;\n"
"41:<prompt>(kgdb)</prompt> <userinput>list *0xc0713860</userinput>\n"
"42:0xc0713860 is in lapic_ipi_wait (/usr/src/sys/i386/i386/local_apic.c:663).\n"
"43:658                     incr = 0;\n"
"44:659                     delay = 1;\n"
"45:660             } else\n"
"46:661                     incr = 1;\n"
"47:662             for (x = 0; x &lt; delay; x += incr) {\n"
"48:663                     if ((lapic-&gt;icr_lo &amp; APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE)\n"
"49:664                             return (1);\n"
"50:665                     ia32_pause();\n"
"51:666             }\n"
"52:667             return (0);\n"
"53:<prompt>(kgdb)</prompt> <userinput>backtrace</userinput>\n"
"54:#0  doadump () at /usr/src/sys/kern/kern_shutdown.c:240\n"
"55:#1  0xc055fd9b in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:372\n"
"56:#2  0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550\n"
"57:#3  0xc0567ef5 in mi_switch () at /usr/src/sys/kern/kern_synch.c:470\n"
"58:#4  0xc055fa87 in boot (howto=256) at /usr/src/sys/kern/kern_shutdown.c:312\n"
"59:#5  0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550\n"
"60:#6  0xc0720c66 in trap_fatal (frame=0xdc1d0b30, eva=0)\n"
"61:    at /usr/src/sys/i386/i386/trap.c:821\n"
"62:#7  0xc07202b3 in trap (frame=\n"
"63:      {tf_fs = -1065484264, tf_es = -1065484272, tf_ds = -1065484272, tf_edi = 1, tf_esi = 0, tf_ebp = -602076292, tf_isp = -602076324, tf_ebx = 0, tf_edx = 0, tf_ecx = 1000000, tf_eax = 243, tf_trapno = 12, tf_err = 0, tf_eip = -1066321824, tf_cs = 8, tf_eflags = 65671, tf_esp = 243, tf_ss = 0})\n"
"64:    at /usr/src/sys/i386/i386/trap.c:250\n"
"65:#8  0xc070c9f8 in calltrap () at {standard input}:94\n"
"66:#9  0xc07139f3 in lapic_ipi_vectored (vector=0, dest=0)\n"
"67:    at /usr/src/sys/i386/i386/local_apic.c:733\n"
"68:#10 0xc0718b23 in ipi_selected (cpus=1, ipi=1)\n"
"69:    at /usr/src/sys/i386/i386/mp_machdep.c:1115\n"
"70:#11 0xc057473e in kseq_notify (ke=0xcc05e360, cpu=0)\n"
"71:    at /usr/src/sys/kern/sched_ule.c:520\n"
"72:#12 0xc0575cad in sched_add (td=0xcbcf5c80)\n"
"73:    at /usr/src/sys/kern/sched_ule.c:1366\n"
"74:#13 0xc05666c6 in setrunqueue (td=0xcc05e360)\n"
"75:    at /usr/src/sys/kern/kern_switch.c:422\n"
"76:#14 0xc05752f4 in sched_wakeup (td=0xcbcf5c80)\n"
"77:    at /usr/src/sys/kern/sched_ule.c:999\n"
"78:#15 0xc056816c in setrunnable (td=0xcbcf5c80)\n"
"79:    at /usr/src/sys/kern/kern_synch.c:570\n"
"80:#16 0xc0567d53 in wakeup (ident=0xcbcf5c80)\n"
"81:    at /usr/src/sys/kern/kern_synch.c:411\n"
"82:#17 0xc05490a8 in exit1 (td=0xcbcf5b40, rv=0)\n"
"83:    at /usr/src/sys/kern/kern_exit.c:509\n"
"84:#18 0xc0548011 in sys_exit () at /usr/src/sys/kern/kern_exit.c:102\n"
"85:#19 0xc0720fd0 in syscall (frame=\n"
"86:      {tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 0, tf_esi = -1, tf_ebp = -1077940712, tf_isp = -602075788, tf_ebx = 672411944, tf_edx = 10, tf_ecx = 672411600, tf_eax = 1, tf_trapno = 12, tf_err = 2, tf_eip = 671899563, tf_cs = 31, tf_eflags = 642, tf_esp = -1077940740, tf_ss = 47})\n"
"87:    at /usr/src/sys/i386/i386/trap.c:1010\n"
"88:#20 0xc070ca4d in Xint0x80_syscall () at {standard input}:136\n"
"89:---Can't read userspace from dump, or kernel process---\n"
"90:<prompt>(kgdb)</prompt> <userinput>quit</userinput>"
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:8676
msgid ""
"If your system is crashing regularly and you are running out of disk space, "
"deleting old <filename>vmcore</filename> files in <filename>/var/crash</"
"filename> could save a considerable amount of disk space!"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8683
msgid "On-Line Kernel Debugging Using DDB"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8685
msgid ""
"While <command>kgdb</command> as an off-line debugger provides a very high "
"level of user interface, there are some things it cannot do. The most "
"important ones being breakpointing and single-stepping kernel code."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8690
msgid ""
"If you need to do low-level debugging on your kernel, there is an on-line "
"debugger available called DDB. It allows setting of breakpoints, single-"
"stepping kernel functions, examining and changing kernel variables, etc. "
"However, it cannot access kernel source files, and only has access to the "
"global and static symbols, not to the full debug information like "
"<command>kgdb</command> does."
msgstr ""

#. (itstool) path: para/programlisting
#: book.translate.xml:8699
#, no-wrap
msgid "options KDB"
msgstr ""

#. (itstool) path: para/programlisting
#: book.translate.xml:8700
#, no-wrap
msgid "options DDB"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8697
msgid ""
"To configure your kernel to include DDB, add the options <_:programlisting-1/"
"> <_:programlisting-2/> to your config file, and rebuild. (See <link xlink:"
"href=\"@@URL_RELPREFIX@@/doc/en_US.ISO8859-1/books/handbook/index.html\">The "
"FreeBSD Handbook</link> for details on configuring the FreeBSD kernel)."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8705
msgid ""
"Once your DDB kernel is running, there are several ways to enter DDB. The "
"first, and earliest way is to use the boot flag <option>-d</option>. The "
"kernel will start up in debug mode and enter DDB prior to any device "
"probing. Hence you can even debug the device probe/attach functions. To use "
"this, exit the loader's boot menu and enter <command>boot -d</command> at "
"the loader prompt."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8713
msgid ""
"The second scenario is to drop to the debugger once the system has booted. "
"There are two simple ways to accomplish this. If you would like to break to "
"the debugger from the command prompt, simply type the command:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8718
#, no-wrap
msgid "<prompt>#</prompt> <userinput>sysctl debug.kdb.enter=1</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8720
msgid ""
"Alternatively, if you are at the system console, you may use a hot-key on "
"the keyboard. The default break-to-debugger sequence is <keycombo action="
"\"simul\"><keycap>Ctrl</keycap> <keycap>Alt</keycap><keycap>ESC</keycap></"
"keycombo>. For syscons, this sequence can be remapped and some of the "
"distributed maps out there do this, so check to make sure you know the right "
"sequence to use. There is an option available for serial consoles that "
"allows the use of a serial line BREAK on the console line to enter DDB "
"(<literal>options BREAK_TO_DEBUGGER</literal> in the kernel config file). It "
"is not the default since there are a lot of serial adapters around that "
"gratuitously generate a BREAK condition, for example when pulling the cable."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8733
msgid ""
"The third way is that any panic condition will branch to DDB if the kernel "
"is configured to use it. For this reason, it is not wise to configure a "
"kernel with DDB for a machine running unattended."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8737
msgid "To obtain the unattended functionality, add:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:8739
#, no-wrap
msgid "options\tKDB_UNATTENDED"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8741
msgid "to the kernel configuration file and rebuild/reinstall."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8743
msgid ""
"The DDB commands roughly resemble some <command>gdb</command> commands. The "
"first thing you probably need to do is to set a breakpoint:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8747
#, no-wrap
msgid "<userinput>break function-name address</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8749
msgid ""
"Numbers are taken hexadecimal by default, but to make them distinct from "
"symbol names; hexadecimal numbers starting with the letters <literal>a-f</"
"literal> need to be preceded with <literal>0x</literal> (this is optional "
"for other numbers). Simple expressions are allowed, for example: "
"<literal>function-name + 0x103</literal>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8755
msgid "To exit the debugger and continue execution, type:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8758
#, no-wrap
msgid "<userinput>continue</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8760
msgid "To get a stack trace of the current thread, use:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8762
#, no-wrap
msgid "<userinput>trace</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8764
msgid ""
"To get a stack trace of an arbitrary thread, specify a process ID or thread "
"ID as a second argument to <command>trace</command>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8768
msgid "If you want to remove a breakpoint, use"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8770
#, no-wrap
msgid ""
"<userinput>del</userinput>\n"
"<userinput>del address-expression</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8773
msgid ""
"The first form will be accepted immediately after a breakpoint hit, and "
"deletes the current breakpoint. The second form can remove any breakpoint, "
"but you need to specify the exact address; this can be obtained from:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8778
#, no-wrap
msgid "<userinput>show b</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8780
msgid "or:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8782
#, no-wrap
msgid "<userinput>show break</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8784
msgid "To single-step the kernel, try:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8786
#, no-wrap
msgid "<userinput>s</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8788
msgid ""
"This will step into functions, but you can make DDB trace them until the "
"matching return statement is reached by:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8791
#, no-wrap
msgid "<userinput>n</userinput>"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:8794
msgid ""
"This is different from <command>gdb</command>'s <command>next</command> "
"statement; it is like <command>gdb</command>'s <command>finish</command>. "
"Pressing <keycap>n</keycap> more than once will cause a continue."
msgstr ""

#. (itstool) path: para/screen
#: book.translate.xml:8802
#, no-wrap
msgid ""
"<userinput>x/wx 0xf0133fe0,40</userinput>\n"
"<userinput>x/hd db_symtab_space</userinput>\n"
"<userinput>x/bc termbuf,10</userinput>\n"
"<userinput>x/s stringbuf</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8800
msgid ""
"To examine data from memory, use (for example): <_:screen-1/> for word/"
"halfword/byte access, and hexadecimal/decimal/character/ string display. The "
"number after the comma is the object count. To display the next 0x10 items, "
"simply use:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8811
#, no-wrap
msgid "<userinput>x ,10</userinput>"
msgstr ""

#. (itstool) path: para/screen
#: book.translate.xml:8815
#, no-wrap
msgid "<userinput>x/ia foofunc,10</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8813
msgid ""
"Similarly, use <_:screen-1/> to disassemble the first 0x10 instructions of "
"<function>foofunc</function>, and display them along with their offset from "
"the beginning of <function>foofunc</function>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8821
msgid "To modify memory, use the write command:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8823
#, no-wrap
msgid ""
"<userinput>w/b termbuf 0xa 0xb 0</userinput>\n"
"<userinput>w/w 0xf0010030 0 0</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8826
msgid ""
"The command modifier (<literal>b</literal>/<literal>h</literal>/<literal>w</"
"literal>) specifies the size of the data to be written, the first following "
"expression is the address to write to and the remainder is interpreted as "
"data to write to successive memory locations."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8832
msgid "If you need to know the current registers, use:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8834
#, no-wrap
msgid "<userinput>show reg</userinput>"
msgstr ""

#. (itstool) path: para/screen
#: book.translate.xml:8838
#, no-wrap
msgid "<userinput>p $eax</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8836
msgid ""
"Alternatively, you can display a single register value by e.g. <_:screen-1/> "
"and modify it by:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8842
#, no-wrap
msgid "<userinput>set $eax new-value</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8844
msgid "Should you need to call some kernel functions from DDB, simply say:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8847
#, no-wrap
msgid "<userinput>call func(arg1, arg2, ...)</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8849
msgid "The return value will be printed."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8851
msgid ""
"For a <citerefentry><refentrytitle>ps</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry> style summary of all running processes, use:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8853
#, no-wrap
msgid "<userinput>ps</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8855
msgid ""
"Now you have examined why your kernel failed, and you wish to reboot. "
"Remember that, depending on the severity of previous malfunctioning, not all "
"parts of the kernel might still be working as expected. Perform one of the "
"following actions to shut down and reboot your system:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8861
#, no-wrap
msgid "<userinput>panic</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8863
msgid ""
"This will cause your kernel to dump core and reboot, so you can later "
"analyze the core on a higher level with <citerefentry><refentrytitle>kgdb</"
"refentrytitle><manvolnum>1</manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8866
#, no-wrap
msgid "<userinput>call boot(0)</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8868
msgid ""
"Might be a good way to cleanly shut down the running system, "
"<function>sync()</function> all disks, and finally, in some cases, reboot. "
"As long as the disk and filesystem interfaces of the kernel are not damaged, "
"this could be a good way for an almost clean shutdown."
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8874
#, no-wrap
msgid "<userinput>reset</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8876
msgid ""
"This is the final way out of disaster and almost the same as hitting the Big "
"Red Button."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8879
msgid "If you need a short command summary, simply type:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8881
#, no-wrap
msgid "<userinput>help</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8883
msgid ""
"It is highly recommended to have a printed copy of the "
"<citerefentry><refentrytitle>ddb</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> manual page ready for a debugging session. Remember that it is "
"hard to read the on-line manual while single-stepping the kernel."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8890
msgid "On-Line Kernel Debugging Using Remote GDB"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8892
msgid ""
"This feature has been supported since FreeBSD 2.2, and it is actually a very "
"neat one."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8895
msgid ""
"GDB has already supported <emphasis>remote debugging</emphasis> for a long "
"time. This is done using a very simple protocol along a serial line. Unlike "
"the other methods described above, you will need two machines for doing "
"this. One is the host providing the debugging environment, including all the "
"sources, and a copy of the kernel binary with all the symbols in it, and the "
"other one is the target machine that simply runs a similar copy of the very "
"same kernel (but stripped of the debugging information)."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8904
msgid ""
"You should configure the kernel in question with <command>config -g</"
"command> if building the <quote>traditional</quote> way. If building the "
"<quote>new</quote> way, make sure that <literal>makeoptions DEBUG=-g</"
"literal> is in the configuration. In both cases, include <option>DDB</"
"option> in the configuration, and compile it as usual. This gives a large "
"binary, due to the debugging information. Copy this kernel to the target "
"machine, strip the debugging symbols off with <command>strip -x</command>, "
"and boot it using the <option>-d</option> boot option. Connect the serial "
"line of the target machine that has \"flags 080\" set on its uart device to "
"any serial line of the debugging host. See "
"<citerefentry><refentrytitle>uart</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> for information on how to set the flags on an uart device. "
"Now, on the debugging machine, go to the compile directory of the target "
"kernel, and start <command>gdb</command>:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8919
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>kgdb kernel</userinput>\n"
"GDB is free software and you are welcome to distribute copies of it\n"
" under certain conditions; type \"show copying\" to see the conditions.\n"
"There is absolutely no warranty for GDB; type \"show warranty\" for details.\n"
"GDB 4.16 (i386-unknown-freebsd),\n"
"Copyright 1996 Free Software Foundation, Inc...\n"
"<prompt>(kgdb)</prompt> "
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8927
msgid ""
"Initialize the remote debugging session (assuming the first serial port is "
"being used) by:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8930
#, no-wrap
msgid "<prompt>(kgdb)</prompt> <userinput>target remote /dev/cuau0</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8932
msgid ""
"Now, on the target host (the one that entered DDB right before even starting "
"the device probe), type:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8935
#, no-wrap
msgid ""
"Debugger(\"Boot flags requested debugger\")\n"
"Stopped at Debugger+0x35: movb\t$0, edata+0x51bc\n"
"<prompt>db&gt;</prompt> <userinput>gdb</userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8939
msgid "DDB will respond with:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8941
#, no-wrap
msgid "Next trap will enter GDB remote protocol mode"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8943
msgid ""
"Every time you type <command>gdb</command>, the mode will be toggled between "
"remote GDB and local DDB. In order to force a next trap immediately, simply "
"type <command>s</command> (step). Your hosting GDB will now gain control "
"over the target kernel:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:8948
#, no-wrap
msgid ""
"Remote debugging using /dev/cuau0\n"
"Debugger (msg=0xf01b0383 \"Boot flags requested debugger\")\n"
"    at ../../i386/i386/db_interface.c:257\n"
"<prompt>(kgdb)</prompt>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8953
msgid ""
"You can use this session almost as any other GDB session, including full "
"access to the source, running it in gud-mode inside an Emacs window (which "
"gives you an automatic source code display in another Emacs window), etc."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8960
msgid "Debugging a Console Driver"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8962
msgid ""
"Since you need a console driver to run DDB on, things are more complicated "
"if the console driver itself is failing. You might remember the use of a "
"serial console (either with modified boot blocks, or by specifying <option>-"
"h</option> at the <prompt>Boot:</prompt> prompt), and hook up a standard "
"terminal onto your first serial port. DDB works on any configured console "
"driver, including a serial console."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:8972
msgid "Debugging Deadlocks"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8974
msgid ""
"You may experience so called deadlocks, a situation where a system stops "
"doing useful work. To provide a helpful bug report in this situation, use "
"<citerefentry><refentrytitle>ddb</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> as described in the previous section. Include the output of "
"<command>ps</command> and <command>trace</command> for suspected processes "
"in the report."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8981
msgid ""
"If possible, consider doing further investigation. The recipe below is "
"especially useful if you suspect that a deadlock occurs in the VFS layer. "
"Add these options to the kernel configuration file."
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:8986
#, no-wrap
msgid ""
"makeoptions \tDEBUG=-g\n"
"options \tINVARIANTS\n"
"options \tINVARIANT_SUPPORT\n"
"options \tWITNESS\n"
"options \tWITNESS_SKIPSPIN\n"
"options \tDEBUG_LOCKS\n"
"options \tDEBUG_VFS_LOCKS\n"
"options \tDIAGNOSTIC"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:8995
msgid ""
"When a deadlock occurs, in addition to the output of the <command>ps</"
"command> command, provide information from the <command>show pcpu</command>, "
"<command>show allpcpu</command>, <command>show locks</command>, "
"<command>show alllocks</command>, <command>show lockedvnods</command> and "
"<command>alltrace</command>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9002
msgid ""
"To obtain meaningful backtraces for threaded processes, use <command>thread "
"thread-id</command> to switch to the thread stack, and do a backtrace with "
"<command>where</command>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9008
msgid "Kernel debugging with Dcons"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9010
msgid ""
"<citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> is a very simple console driver that is not directly connected "
"with any physical devices. It just reads and writes characters from and to a "
"buffer in a kernel or loader. Due to its simple nature, it is very useful "
"for kernel debugging, especially with a <trademark class=\"registered"
"\">FireWire</trademark> device. Currently, FreeBSD provides two ways to "
"interact with the buffer from outside of the kernel using "
"<citerefentry><refentrytitle>dconschat</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9019
msgid "Dcons over <trademark class=\"registered\">FireWire</trademark>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9021
msgid ""
"Most <trademark class=\"registered\">FireWire</trademark> (IEEE1394) host "
"controllers are based on the <acronym>OHCI</acronym> specification that "
"supports physical access to the host memory. This means that once the host "
"controller is initialized, we can access the host memory without the help of "
"software (kernel). We can exploit this facility for interaction with "
"<citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry>. <citerefentry><refentrytitle>dcons</"
"refentrytitle><manvolnum>4</manvolnum></citerefentry> provides similar "
"functionality as a serial console. It emulates two serial ports, one for the "
"console and <acronym>DDB</acronym>, the other for <acronym>GDB</acronym>. "
"Because remote memory access is fully handled by the hardware, the "
"<citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</manvolnum></"
"citerefentry> buffer is accessible even when the system crashes."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9034
msgid ""
"<trademark class=\"registered\">FireWire</trademark> devices are not limited "
"to those integrated into motherboards. <acronym>PCI</acronym> cards exist "
"for desktops, and a cardbus interface can be purchased for laptops."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:9040
msgid ""
"Enabling <trademark class=\"registered\">FireWire</trademark> and Dcons "
"support on the target machine"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9043
msgid ""
"To enable <trademark class=\"registered\">FireWire</trademark> and Dcons "
"support in the kernel of the <emphasis>target machine</emphasis>:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9048
msgid ""
"Make sure your kernel supports <literal>dcons</literal>, "
"<literal>dcons_crom</literal> and <literal>firewire</literal>. "
"<literal>Dcons</literal> should be statically linked with the kernel. For "
"<literal>dcons_crom</literal> and <literal>firewire</literal>, modules "
"should be OK."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9057
msgid ""
"Make sure physical <acronym>DMA</acronym> is enabled. You may need to add "
"<literal>hw.firewire.phydma_enable=1</literal> to <filename>/boot/loader."
"conf</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9063
msgid "Add options for debugging."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9066
msgid ""
"Add <literal>dcons_gdb=1</literal> in <filename>/boot/loader.conf</filename> "
"if you use GDB over <trademark class=\"registered\">FireWire</trademark>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9071
msgid "Enable <literal>dcons</literal> in <filename>/etc/ttys</filename>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9075
msgid ""
"Optionally, to force <literal>dcons</literal> to be the high-level console, "
"add <literal>hw.firewire.dcons_crom.force_console=1</literal> to "
"<filename>loader.conf</filename>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9082
msgid ""
"To enable <trademark class=\"registered\">FireWire</trademark> and Dcons "
"support in <citerefentry><refentrytitle>loader</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> on i386 or amd64:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9085
msgid ""
"Add <literal>LOADER_FIREWIRE_SUPPORT=YES</literal> in <filename>/etc/make."
"conf</filename> and rebuild <citerefentry><refentrytitle>loader</"
"refentrytitle><manvolnum>8</manvolnum></citerefentry>:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9090
#, no-wrap
msgid "<prompt>#</prompt> <userinput>cd /sys/boot/i386 &amp;&amp; make clean &amp;&amp; make &amp;&amp; make install</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9092
msgid ""
"To enable <citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> as an active low-level console, add "
"<literal>boot_multicons=\"YES\"</literal> to <filename>/boot/loader.conf</"
"filename>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9096
msgid ""
"Here are a few configuration examples. A sample kernel configuration file "
"would contain:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9099
#, no-wrap
msgid ""
"device dcons\n"
"device dcons_crom\n"
"options KDB\n"
"options DDB\n"
"options GDB\n"
"options ALT_BREAK_TO_DEBUGGER"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9106
msgid "And a sample <filename>/boot/loader.conf</filename> would contain:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9109
#, no-wrap
msgid ""
"dcons_crom_load=\"YES\"\n"
"dcons_gdb=1\n"
"boot_multicons=\"YES\"\n"
"hw.firewire.phydma_enable=1\n"
"hw.firewire.dcons_crom.force_console=1"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:9118
msgid ""
"Enabling <trademark class=\"registered\">FireWire</trademark> and Dcons "
"support on the host machine"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9121
msgid ""
"To enable <trademark class=\"registered\">FireWire</trademark> support in "
"the kernel on the <emphasis>host machine</emphasis>:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9124
#, no-wrap
msgid "<prompt>#</prompt> <userinput>kldload firewire</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9126
msgid ""
"Find out the <acronym>EUI64</acronym> (the unique 64 bit identifier) of the "
"<trademark class=\"registered\">FireWire</trademark> host controller, and "
"use <citerefentry><refentrytitle>fwcontrol</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> or <command>dmesg</command> to find the "
"<acronym>EUI64</acronym> of the target machine."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9131
msgid ""
"Run <citerefentry><refentrytitle>dconschat</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry>, with:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9133
#, no-wrap
msgid "<prompt>#</prompt> <userinput>dconschat -e \\# -br -G 12345 -t <replaceable>00-11-22-33-44-55-66-77</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9135
msgid ""
"The following key combinations can be used once "
"<citerefentry><refentrytitle>dconschat</refentrytitle><manvolnum>8</"
"manvolnum></citerefentry> is running:"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9142
msgid ""
"<keycombo action=\"seq\"> <keycap>~</keycap> <keycap>.</keycap> </keycombo>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9148
msgid "Disconnect"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9151
msgid ""
"<keycombo action=\"seq\"> <keycap>~</keycap> <keycombo action=\"simul\"> "
"<keycap>Ctrl</keycap> <keycap>B</keycap> </keycombo> </keycombo>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9160
msgid "ALT BREAK"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9163
msgid ""
"<keycombo action=\"seq\"> <keycap>~</keycap> <keycombo action=\"simul\"> "
"<keycap>Ctrl</keycap> <keycap>R</keycap> </keycombo> </keycombo>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9172
msgid "RESET target"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9175
msgid ""
"<keycombo action=\"seq\"> <keycap>~</keycap> <keycombo action=\"simul\"> "
"<keycap>Ctrl</keycap> <keycap>Z</keycap> </keycombo> </keycombo>"
msgstr ""

#. (itstool) path: row/entry
#: book.translate.xml:9184
msgid "Suspend dconschat"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9190
msgid ""
"Attach remote <acronym>GDB</acronym> by starting "
"<citerefentry><refentrytitle>kgdb</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry> with a remote debugging session:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9193
#, no-wrap
msgid "<userinput>kgdb -r :12345 kernel</userinput>"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:9197
msgid "Some general tips"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9199
msgid "Here are some general tips:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9201
msgid ""
"To take full advantage of the speed of <trademark class=\"registered"
"\">FireWire</trademark>, disable other slow console drivers:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9204
#, no-wrap
msgid ""
"<prompt>#</prompt> conscontrol delete ttyd0\t     # serial console\n"
"<prompt>#</prompt> conscontrol delete consolectl\t# video/keyboard"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9207
msgid ""
"There exists a <acronym>GDB</acronym> mode for <citerefentry vendor=\"ports"
"\"><refentrytitle>emacs</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry>; this is what you will need to add to your <filename>.emacs</"
"filename>:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9211
#, no-wrap
msgid ""
"<userinput>(setq gud-gdba-command-name \"kgdb -a -a -a -r :12345\")\n"
"(setq gdb-many-windows t)\n"
"(xterm-mouse-mode 1)\n"
"M-x gdba</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9216
msgid "And for <acronym>DDD</acronym> (<filename>devel/ddd</filename>):"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9218
#, no-wrap
msgid ""
"# remote serial protocol\n"
"LANG=C ddd --debugger kgdb -r :12345 kernel\n"
"# live core debug\n"
"LANG=C ddd --debugger kgdb kernel /dev/fwmem0.2"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9226
msgid "Dcons with KVM"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9228
msgid ""
"We can directly read the <citerefentry><refentrytitle>dcons</"
"refentrytitle><manvolnum>4</manvolnum></citerefentry> buffer via <filename>/"
"dev/mem</filename> for live systems, and in the core dump for crashed "
"systems. These give you similar output to <command>dmesg -a</command>, but "
"the <citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> buffer includes more information."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:9235
msgid "Using Dcons with KVM"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9237
msgid ""
"To use <citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> with <acronym>KVM</acronym>:"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9239
msgid ""
"Dump a <citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> buffer of a live system:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9241
#, no-wrap
msgid "<prompt>#</prompt> <userinput>dconschat -1</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9243
msgid ""
"Dump a <citerefentry><refentrytitle>dcons</refentrytitle><manvolnum>4</"
"manvolnum></citerefentry> buffer of a crash dump:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9245
#, no-wrap
msgid "<prompt>#</prompt> <userinput>dconschat -1 -M vmcore.XX</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9247
msgid "Live core debugging can be done via:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:9249
#, no-wrap
msgid ""
"<prompt>#</prompt> <userinput>fwcontrol -m target_eui64</userinput>\n"
"<prompt>#</prompt> <userinput>kgdb kernel /dev/fwmem0.2</userinput>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9256
msgid "Glossary of Kernel Options for Debugging"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9258
msgid ""
"This section provides a brief glossary of compile-time kernel options used "
"for debugging:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9263
msgid ""
"<literal>options KDB</literal>: compiles in the kernel debugger framework. "
"Required for <literal>options DDB</literal> and <literal>options GDB</"
"literal>. Little or no performance overhead. By default, the debugger will "
"be entered on panic instead of an automatic reboot."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9271
msgid ""
"<literal>options KDB_UNATTENDED</literal>: change the default value of the "
"<literal>debug.debugger_on_panic</literal> sysctl to 0, which controls "
"whether the debugger is entered on panic. When <literal>options KDB</"
"literal> is not compiled into the kernel, the behavior is to automatically "
"reboot on panic; when it is compiled into the kernel, the default behavior "
"is to drop into the debugger unless <literal>options KDB_UNATTENDED</"
"literal> is compiled in. If you want to leave the kernel debugger compiled "
"into the kernel but want the system to come back up unless you're on-hand to "
"use the debugger for diagnostics, use this option."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9284
msgid ""
"<literal>options KDB_TRACE</literal>: change the default value of the "
"<literal>debug.trace_on_panic</literal> sysctl to 1, which controls whether "
"the debugger automatically prints a stack trace on panic. Especially if "
"running with <literal>options KDB_UNATTENDED</literal>, this can be helpful "
"to gather basic debugging information on the serial or firewire console "
"while still rebooting to recover."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9294
msgid ""
"<literal>options DDB</literal>: compile in support for the console debugger, "
"DDB. This interactive debugger runs on whatever the active low-level console "
"of the system is, which includes the video console, serial console, or "
"firewire console. It provides basic integrated debugging facilities, such as "
"stack tracing, process and thread listing, dumping of lock state, VM state, "
"file system state, and kernel memory management. DDB does not require "
"software running on a second machine or being able to generate a core dump "
"or full debugging kernel symbols, and provides detailed diagnostics of the "
"kernel at run-time. Many bugs can be fully diagnosed using only DDB output. "
"This option depends on <literal>options KDB</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9309
msgid ""
"<literal>options GDB</literal>: compile in support for the remote debugger, "
"GDB, which can operate over serial cable or firewire. When the debugger is "
"entered, GDB may be attached to inspect structure contents, generate stack "
"traces, etc. Some kernel state is more awkward to access than in DDB, which "
"is able to generate useful summaries of kernel state automatically, such as "
"automatically walking lock debugging or kernel memory management structures, "
"and a second machine running the debugger is required. On the other hand, "
"GDB combines information from the kernel source and full debugging symbols, "
"and is aware of full data structure definitions, local variables, and is "
"scriptable. This option is not required to run GDB on a kernel core dump. "
"This option depends on <literal>options KDB</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9326
msgid ""
"<literal>options BREAK_TO_DEBUGGER</literal>, <literal>options "
"ALT_BREAK_TO_DEBUGGER</literal>: allow a break signal or alternative signal "
"on the console to enter the debugger. If the system hangs without a panic, "
"this is a useful way to reach the debugger. Due to the current kernel "
"locking, a break signal generated on a serial console is significantly more "
"reliable at getting into the debugger, and is generally recommended. This "
"option has little or no performance impact."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9337
msgid ""
"<literal>options INVARIANTS</literal>: compile into the kernel a large "
"number of run-time assertion checks and tests, which constantly test the "
"integrity of kernel data structures and the invariants of kernel algorithms. "
"These tests can be expensive, so are not compiled in by default, but help "
"provide useful \"fail stop\" behavior, in which certain classes of undesired "
"behavior enter the debugger before kernel data corruption occurs, making "
"them easier to debug. Tests include memory scrubbing and use-after-free "
"testing, which is one of the more significant sources of overhead. This "
"option depends on <literal>options INVARIANT_SUPPORT</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9351
msgid ""
"<literal>options INVARIANT_SUPPORT</literal>: many of the tests present in "
"<literal>options INVARIANTS</literal> require modified data structures or "
"additional kernel symbols to be defined."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9357
msgid ""
"<literal>options WITNESS</literal>: this option enables run-time lock order "
"tracking and verification, and is an invaluable tool for deadlock diagnosis. "
"WITNESS maintains a graph of acquired lock orders by lock type, and checks "
"the graph at each acquire for cycles (implicit or explicit). If a cycle is "
"detected, a warning and stack trace are generated to the console, indicating "
"that a potential deadlock might have occurred. WITNESS is required in order "
"to use the <command>show locks</command>, <command>show witness</command> "
"and <command>show alllocks</command> DDB commands. This debug option has "
"significant performance overhead, which may be somewhat mitigated through "
"the use of <literal>options WITNESS_SKIPSPIN</literal>. Detailed "
"documentation may be found in <citerefentry><refentrytitle>witness</"
"refentrytitle><manvolnum>4</manvolnum></citerefentry>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9373
msgid ""
"<literal>options WITNESS_SKIPSPIN</literal>: disable run-time checking of "
"spinlock lock order with WITNESS. As spin locks are acquired most frequently "
"in the scheduler, and scheduler events occur often, this option can "
"significantly speed up systems running with WITNESS. This option depends on "
"<literal>options WITNESS</literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9382
msgid ""
"<literal>options WITNESS_KDB</literal>: change the default value of the "
"<literal>debug.witness.kdb</literal> sysctl to 1, which causes WITNESS to "
"enter the debugger when a lock order violation is detected, rather than "
"simply printing a warning. This option depends on <literal>options WITNESS</"
"literal>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9390
msgid ""
"<literal>options SOCKBUF_DEBUG</literal>: perform extensive run-time "
"consistency checking on socket buffers, which can be useful for debugging "
"both socket bugs and race conditions in protocols and device drivers that "
"interact with sockets. This option significantly impacts network "
"performance, and may change the timing in device driver races."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9399
msgid ""
"<literal>options DEBUG_VFS_LOCKS</literal>: track lock acquisition points "
"for lockmgr/vnode locks, expanding the amount of information displayed by "
"<command>show lockedvnods</command> in DDB. This option has a measurable "
"performance impact."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9406
msgid ""
"<literal>options DEBUG_MEMGUARD</literal>: a replacement for the "
"<citerefentry><refentrytitle>malloc</refentrytitle><manvolnum>9</manvolnum></"
"citerefentry> kernel memory allocator that uses the VM system to detect "
"reads or writes from allocated memory after free. Details may be found in "
"<citerefentry><refentrytitle>memguard</refentrytitle><manvolnum>9</"
"manvolnum></citerefentry>. This option has a significant performance impact, "
"but can be very helpful in debugging kernel memory corruption bugs."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:9415
msgid ""
"<literal>options DIAGNOSTIC</literal>: enable additional, more expensive "
"diagnostic tests along the lines of <literal>options INVARIANTS</literal>."
msgstr ""

#. (itstool) path: part/title
#: book.translate.xml:9429
msgid "Architectures"
msgstr ""

#. (itstool) path: chapter/title
#: book.translate.xml:9453
msgid "x86 Assembly Language Programming"
msgstr ""

#. (itstool) path: chapter/para
#: book.translate.xml:9455
msgid ""
"<emphasis>This chapter was written by G. Adam Stanislav "
"<email>adam@redprince.net</email>.</emphasis>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9461
msgid ""
"Assembly language programming under <trademark class=\"registered\">UNIX</"
"trademark> is highly undocumented. It is generally assumed that no one would "
"ever want to use it because various <trademark class=\"registered\">UNIX</"
"trademark> systems run on different microprocessors, so everything should be "
"written in C for portability."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9467
msgid ""
"In reality, C portability is quite a myth. Even C programs need to be "
"modified when ported from one <trademark class=\"registered\">UNIX</"
"trademark> to another, regardless of what processor each runs on. Typically, "
"such a program is full of conditional statements depending on the system it "
"is compiled for."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9473
msgid ""
"Even if we believe that all of <trademark class=\"registered\">UNIX</"
"trademark> software should be written in C, or some other high-level "
"language, we still need assembly language programmers: Who else would write "
"the section of C library that accesses the kernel?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9478
msgid ""
"In this chapter I will attempt to show you how you can use assembly language "
"writing <trademark class=\"registered\">UNIX</trademark> programs, "
"specifically under FreeBSD."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9482
msgid ""
"This chapter does not explain the basics of assembly language. There are "
"enough resources about that (for a complete online course in assembly "
"language, see Randall Hyde's <link xlink:href=\"http://webster.cs.ucr.edu/"
"\">Art of Assembly Language</link>; or if you prefer a printed book, take a "
"look at Jeff Duntemann's Assembly Language Step-by-Step (ISBN: 0471375233). "
"However, once the chapter is finished, any assembly language programmer will "
"be able to write programs for FreeBSD quickly and efficiently."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9491 book.translate.xml:14885
msgid "Copyright © 2000-2001 G. Adam Stanislav. All rights reserved."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9496
msgid "The Tools"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9499
msgid "The Assembler"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9501
msgid ""
"The most important tool for assembly language programming is the assembler, "
"the software that converts assembly language code into machine language."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9505
msgid ""
"Two very different assemblers are available for FreeBSD. One is "
"<citerefentry><refentrytitle>as</refentrytitle><manvolnum>1</manvolnum></"
"citerefentry>, which uses the traditional <trademark class=\"registered"
"\">UNIX</trademark> assembly language syntax. It comes with the system."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9511
msgid ""
"The other is <application>/usr/ports/devel/nasm</application>. It uses the "
"Intel syntax. Its main advantage is that it can assemble code for many "
"operating systems. It needs to be installed separately, but is completely "
"free."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9517
msgid ""
"This chapter uses <application>nasm</application> syntax because most "
"assembly language programmers coming to FreeBSD from other operating systems "
"will find it easier to understand. And, because, quite frankly, that is what "
"I am used to."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9525
msgid "The Linker"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9527
msgid ""
"The output of the assembler, like that of any compiler, needs to be linked "
"to form an executable file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9530
msgid ""
"The standard <citerefentry><refentrytitle>ld</refentrytitle><manvolnum>1</"
"manvolnum></citerefentry> linker comes with FreeBSD. It works with the code "
"assembled with either assembler."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9538
msgid "System Calls"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9541
msgid "Default Calling Convention"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9543
msgid ""
"By default, the FreeBSD kernel uses the C calling convention. Further, "
"although the kernel is accessed using <function role=\"opcode\">int 80h</"
"function>, it is assumed the program will call a function that issues "
"<function role=\"opcode\">int 80h</function>, rather than issuing <function "
"role=\"opcode\">int 80h</function> directly."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9549
msgid ""
"This convention is very convenient, and quite superior to the <trademark "
"class=\"registered\">Microsoft</trademark> convention used by "
"<acronym><trademark class=\"registered\">MS-DOS</trademark></acronym>. Why? "
"Because the <trademark class=\"registered\">UNIX</trademark> convention "
"allows any program written in any language to access the kernel."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9555
msgid ""
"An assembly language program can do that as well. For example, we could open "
"a file:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9558
#, no-wrap
msgid ""
"kernel:\n"
"\tint\t80h\t; Call kernel\n"
"\tret\n"
"\n"
"open:\n"
"\tpush\tdword mode\n"
"\tpush\tdword flags\n"
"\tpush\tdword path\n"
"\tmov\teax, 5\n"
"\tcall\tkernel\n"
"\tadd\tesp, byte 12\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9571
msgid ""
"This is a very clean and portable way of coding. If you need to port the "
"code to a <trademark class=\"registered\">UNIX</trademark> system which uses "
"a different interrupt, or a different way of passing parameters, all you "
"need to change is the kernel procedure."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9576
msgid ""
"But assembly language programmers like to shave off cycles. The above "
"example requires a <function role=\"opcode\">call/ret</function> "
"combination. We can eliminate it by <function role=\"opcode\">push</"
"function>ing an extra dword:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9581
#, no-wrap
msgid ""
"open:\n"
"\tpush\tdword mode\n"
"\tpush\tdword flags\n"
"\tpush\tdword path\n"
"\tmov\teax, 5\n"
"\tpush\teax\t\t; Or any other dword\n"
"\tint\t80h\n"
"\tadd\tesp, byte 16"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9590
msgid ""
"The <constant>5</constant> that we have placed in <varname role=\"register"
"\">EAX</varname> identifies the kernel function, in this case <function role="
"\"syscall\">open</function>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9595
msgid "Alternate Calling Convention"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9597
msgid ""
"FreeBSD is an extremely flexible system. It offers other ways of calling the "
"kernel. For it to work, however, the system must have Linux emulation "
"installed."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9601
msgid ""
"Linux is a <trademark class=\"registered\">UNIX</trademark> like system. "
"However, its kernel uses the same system-call convention of passing "
"parameters in registers <acronym><trademark class=\"registered\">MS-DOS</"
"trademark></acronym> does. As with the <trademark class=\"registered\">UNIX</"
"trademark> convention, the function number is placed in <varname role="
"\"register\">EAX</varname>. The parameters, however, are not passed on the "
"stack but in <varname role=\"register\">EBX, ECX, EDX, ESI, EDI, EBP</"
"varname>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9608
#, no-wrap
msgid ""
"open:\n"
"\tmov\teax, 5\n"
"\tmov\tebx, path\n"
"\tmov\tecx, flags\n"
"\tmov\tedx, mode\n"
"\tint\t80h"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9615
msgid ""
"This convention has a great disadvantage over the <trademark class="
"\"registered\">UNIX</trademark> way, at least as far as assembly language "
"programming is concerned: Every time you make a kernel call you must "
"<function role=\"opcode\">push</function> the registers, then <function role="
"\"opcode\">pop</function> them later. This makes your code bulkier and "
"slower. Nevertheless, FreeBSD gives you a choice."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9623
msgid ""
"If you do choose the Linux convention, you must let the system know about "
"it. After your program is assembled and linked, you need to brand the "
"executable:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:9627
#, no-wrap
msgid "<prompt>%</prompt> <userinput>brandelf -t Linux <replaceable>filename</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9631
msgid "Which Convention Should You Use?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9633
msgid ""
"If you are coding specifically for FreeBSD, you should always use the "
"<trademark class=\"registered\">UNIX</trademark> convention: It is faster, "
"you can store global variables in registers, you do not have to brand the "
"executable, and you do not impose the installation of the Linux emulation "
"package on the target system."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9639
msgid ""
"If you want to create portable code that can also run on Linux, you will "
"probably still want to give the FreeBSD users as efficient a code as "
"possible. I will show you how you can accomplish that after I have explained "
"the basics."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9646
msgid "Call Numbers"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9648
msgid ""
"To tell the kernel which system service you are calling, place its number in "
"<varname role=\"register\">EAX</varname>. Of course, you need to know what "
"the number is."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:9653
msgid "The <filename>syscalls</filename> File"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9655
msgid ""
"The numbers are listed in <filename>syscalls</filename>. <command>locate "
"syscalls</command> finds this file in several different formats, all "
"produced automatically from <filename>syscalls.master</filename>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9660
msgid ""
"You can find the master file for the default <trademark class=\"registered"
"\">UNIX</trademark> calling convention in <filename>/usr/src/sys/kern/"
"syscalls.master</filename>. If you need to use the other convention "
"implemented in the Linux emulation mode, read <filename>/usr/src/sys/i386/"
"linux/syscalls.master</filename>."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:9668
msgid ""
"Not only do FreeBSD and Linux use different calling conventions, they "
"sometimes use different numbers for the same functions."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9673
msgid ""
"<filename>syscalls.master</filename> describes how the call is to be made:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:9676
#, no-wrap
msgid ""
"0\tSTD\tNOHIDE\t{ int nosys(void); } syscall nosys_args int\n"
"1\tSTD\tNOHIDE\t{ void exit(int rval); } exit rexit_args void\n"
"2\tSTD\tPOSIX\t{ int fork(void); }\n"
"3\tSTD\tPOSIX\t{ ssize_t read(int fd, void *buf, size_t nbyte); }\n"
"4\tSTD\tPOSIX\t{ ssize_t write(int fd, const void *buf, size_t nbyte); }\n"
"5\tSTD\tPOSIX\t{ int open(char *path, int flags, int mode); }\n"
"6\tSTD\tPOSIX\t{ int close(int fd); }\n"
"etc..."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9685
msgid ""
"It is the leftmost column that tells us the number to place in <varname role="
"\"register\">EAX</varname>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:9688
msgid ""
"The rightmost column tells us what parameters to <function role=\"opcode"
"\">push</function>. They are <function role=\"opcode\">push</function>ed "
"<emphasis>from right to left</emphasis>."
msgstr ""

#. (itstool) path: informalexample/para
#: book.translate.xml:9692
msgid ""
"For example, to <function>open</function> a file, we need to <function role="
"\"opcode\">push</function> the <varname>mode</varname> first, then "
"<varname>flags</varname>, then the address at which the <varname>path</"
"varname> is stored."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9703
msgid "Return Values"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9705
msgid ""
"A system call would not be useful most of the time if it did not return some "
"kind of a value: The file descriptor of an open file, the number of bytes "
"read to a buffer, the system time, etc."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9710
msgid ""
"Additionally, the system needs to inform us if an error occurs: A file does "
"not exist, system resources are exhausted, we passed an invalid parameter, "
"etc."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9715
msgid "Man Pages"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9717
msgid ""
"The traditional place to look for information about various system calls "
"under <trademark class=\"registered\">UNIX</trademark> systems are the "
"manual pages. FreeBSD describes its system calls in section 2, sometimes in "
"section 3."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9722
msgid ""
"For example, <citerefentry><refentrytitle>open</refentrytitle><manvolnum>2</"
"manvolnum></citerefentry> says:"
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:9727
msgid ""
"If successful, <function>open()</function> returns a non-negative integer, "
"termed a file descriptor. It returns <varname>-1</varname> on failure, and "
"sets <varname>errno</varname> to indicate the error."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9733
msgid ""
"The assembly language programmer new to <trademark class=\"registered"
"\">UNIX</trademark> and FreeBSD will immediately ask the puzzling question: "
"Where is <varname>errno</varname> and how do I get to it?"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:9738
msgid ""
"The information presented in the manual pages applies to C programs. The "
"assembly language programmer needs additional information."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9745
msgid "Where Are the Return Values?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9747
msgid ""
"Unfortunately, it depends... For most system calls it is in <varname role="
"\"register\">EAX</varname>, but not for all. A good rule of thumb, when "
"working with a system call for the first time, is to look for the return "
"value in <varname role=\"register\">EAX</varname>. If it is not there, you "
"need further research."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:9754
msgid ""
"I am aware of one system call that returns the value in <varname role="
"\"register\">EDX</varname>: <function role=\"syscall\">SYS_fork</function>. "
"All others I have worked with use <varname role=\"register\">EAX</varname>. "
"But I have not worked with them all yet."
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:9761
msgid ""
"If you cannot find the answer here or anywhere else, study "
"<application>libc</application> source code and see how it interfaces with "
"the kernel."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9768
msgid "Where Is <varname>errno</varname>?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9770
msgid "Actually, nowhere..."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9772
msgid ""
"<varname>errno</varname> is part of the C language, not the <trademark class="
"\"registered\">UNIX</trademark> kernel. When accessing kernel services "
"directly, the error code is returned in <varname role=\"register\">EAX</"
"varname>, the same register the proper return value generally ends up in."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9777
msgid ""
"This makes perfect sense. If there is no error, there is no error code. If "
"there is an error, there is no return value. One register can contain either."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9783
msgid "Determining an Error Occurred"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9785
msgid ""
"When using the standard FreeBSD calling convention, the <varname role="
"\"register\">carry flag</varname> is cleared upon success, set upon failure."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9789
msgid ""
"When using the Linux emulation mode, the signed value in <varname role="
"\"register\">EAX</varname> is non-negative upon success, and contains the "
"return value. In case of an error, the value is negative, i.e., <varname>-"
"errno</varname>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:9797
msgid "Creating Portable Code"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9799
msgid ""
"Portability is generally not one of the strengths of assembly language. Yet, "
"writing assembly language programs for different platforms is possible, "
"especially with <application>nasm</application>. I have written assembly "
"language libraries that can be assembled for such different operating "
"systems as <trademark class=\"registered\">Windows</trademark> and FreeBSD."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9806
msgid ""
"It is all the more possible when you want your code to run on two platforms "
"which, while different, are based on similar architectures."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:9810
msgid ""
"For example, FreeBSD is <trademark class=\"registered\">UNIX</trademark>, "
"Linux is <trademark class=\"registered\">UNIX</trademark> like. I only "
"mentioned three differences between them (from an assembly language "
"programmer's perspective): The calling convention, the function numbers, and "
"the way of returning values."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9816
msgid "Dealing with Function Numbers"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9818
msgid ""
"In many cases the function numbers are the same. However, even when they are "
"not, the problem is easy to deal with: Instead of using numbers in your "
"code, use constants which you have declared differently depending on the "
"target architecture:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9824
#, no-wrap
msgid ""
"%ifdef\tLINUX\n"
"%define\tSYS_execve\t11\n"
"%else\n"
"%define\tSYS_execve\t59\n"
"%endif"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9832
msgid "Dealing with Conventions"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9834
msgid ""
"Both, the calling convention, and the return value (the <varname>errno</"
"varname> problem) can be resolved with macros:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9838
#, no-wrap
msgid ""
"%ifdef\tLINUX\n"
"\n"
"%macro\tsystem\t0\n"
"\tcall\tkernel\n"
"%endmacro\n"
"\n"
"align 4\n"
"kernel:\n"
"\tpush\tebx\n"
"\tpush\tecx\n"
"\tpush\tedx\n"
"\tpush\tesi\n"
"\tpush\tedi\n"
"\tpush\tebp\n"
"\n"
"\tmov\tebx, [esp+32]\n"
"\tmov\tecx, [esp+36]\n"
"\tmov\tedx, [esp+40]\n"
"\tmov\tesi, [esp+44]\n"
"\tmov\tebp, [esp+48]\n"
"\tint\t80h\n"
"\n"
"\tpop\tebp\n"
"\tpop\tedi\n"
"\tpop\tesi\n"
"\tpop\tedx\n"
"\tpop\tecx\n"
"\tpop\tebx\n"
"\n"
"\tor\teax, eax\n"
"\tjs\t.errno\n"
"\tclc\n"
"\tret\n"
"\n"
".errno:\n"
"\tneg\teax\n"
"\tstc\n"
"\tret\n"
"\n"
"%else\n"
"\n"
"%macro\tsystem\t0\n"
"\tint\t80h\n"
"%endmacro\n"
"\n"
"%endif"
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9887
msgid "Dealing with Other Portability Issues"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9889
msgid ""
"The above solutions can handle most cases of writing code portable between "
"FreeBSD and Linux. Nevertheless, with some kernel services the differences "
"are deeper."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9893
msgid ""
"In that case, you need to write two different handlers for those particular "
"system calls, and use conditional assembly. Luckily, most of your code does "
"something other than calling the kernel, so usually you will only need a few "
"such conditional sections in your code."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9901
msgid "Using a Library"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9903
msgid ""
"You can avoid portability issues in your main code altogether by writing a "
"library of system calls. Create a separate library for FreeBSD, a different "
"one for Linux, and yet other libraries for more operating systems."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9908
msgid ""
"In your library, write a separate function (or procedure, if you prefer the "
"traditional assembly language terminology) for each system call. Use the C "
"calling convention of passing parameters. But still use <varname role="
"\"register\">EAX</varname> to pass the call number in. In that case, your "
"FreeBSD library can be very simple, as many seemingly different functions "
"can be just labels to the same code:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9916
#, no-wrap
msgid ""
"sys.open:\n"
"sys.close:\n"
"[etc...]\n"
"\tint\t80h\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9922
msgid ""
"Your Linux library will require more different functions. But even here you "
"can group system calls using the same number of parameters:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9926
#, no-wrap
msgid ""
"sys.exit:\n"
"sys.close:\n"
"[etc... one-parameter functions]\n"
"\tpush\tebx\n"
"\tmov\tebx, [esp+12]\n"
"\tint\t80h\n"
"\tpop\tebx\n"
"\tjmp\tsys.return\n"
"\n"
"...\n"
"\n"
"sys.return:\n"
"\tor\teax, eax\n"
"\tjs\tsys.err\n"
"\tclc\n"
"\tret\n"
"\n"
"sys.err:\n"
"\tneg\teax\n"
"\tstc\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9948
msgid ""
"The library approach may seem inconvenient at first because it requires you "
"to produce a separate file your code depends on. But it has many advantages: "
"For one, you only need to write it once and can use it for all your "
"programs. You can even let other assembly language programmers use it, or "
"perhaps use one written by someone else. But perhaps the greatest advantage "
"of the library is that your code can be ported to other systems, even by "
"other programmers, by simply writing a new library without any changes to "
"your code."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9958
msgid ""
"If you do not like the idea of having a library, you can at least place all "
"your system calls in a separate assembly language file and link it with your "
"main program. Here, again, all porters have to do is create a new object "
"file to link with your main program."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:9966
msgid "Using an Include File"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9968
msgid ""
"If you are releasing your software as (or with) source code, you can use "
"macros and place them in a separate file, which you include in your code."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9972
msgid ""
"Porters of your software will simply write a new include file. No library or "
"external object file is necessary, yet your code is portable without any "
"need to edit the code."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:9977
msgid ""
"This is the approach we will use throughout this chapter. We will name our "
"include file <filename>system.inc</filename>, and add to it whenever we deal "
"with a new system call."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9982
msgid ""
"We can start our <filename>system.inc</filename> by declaring the standard "
"file descriptors:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9985
#, no-wrap
msgid ""
"%define\tstdin\t0\n"
"%define\tstdout\t1\n"
"%define\tstderr\t2"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9989
msgid "Next, we create a symbolic name for each system call:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:9991
#, no-wrap
msgid ""
"%define\tSYS_nosys\t0\n"
"%define\tSYS_exit\t1\n"
"%define\tSYS_fork\t2\n"
"%define\tSYS_read\t3\n"
"%define\tSYS_write\t4\n"
"; [etc...]"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:9998
msgid ""
"We add a short, non-global procedure with a long name, so we do not "
"accidentally reuse the name in our code:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10001
#, no-wrap
msgid ""
"section\t.text\n"
"align 4\n"
"access.the.bsd.kernel:\n"
"\tint\t80h\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10007
msgid "We create a macro which takes one argument, the syscall number:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10010
#, no-wrap
msgid ""
"%macro\tsystem\t1\n"
"\tmov\teax, %1\n"
"\tcall\taccess.the.bsd.kernel\n"
"%endmacro"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10015
msgid ""
"Finally, we create macros for each syscall. These macros take no arguments."
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10018
#, no-wrap
msgid ""
"%macro\tsys.exit\t0\n"
"\tsystem\tSYS_exit\n"
"%endmacro\n"
"\n"
"%macro\tsys.fork\t0\n"
"\tsystem\tSYS_fork\n"
"%endmacro\n"
"\n"
"%macro\tsys.read\t0\n"
"\tsystem\tSYS_read\n"
"%endmacro\n"
"\n"
"%macro\tsys.write\t0\n"
"\tsystem\tSYS_write\n"
"%endmacro\n"
"\n"
"; [etc...]"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10036
msgid ""
"Go ahead, enter it into your editor and save it as <filename>system.inc</"
"filename>. We will add more to it as we discuss more syscalls."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:10043
msgid "Our First Program"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10045
msgid ""
"We are now ready for our first program, the mandatory <application>Hello, "
"World!</application>"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10048
#, no-wrap
msgid ""
"1:\t%include\t'system.inc'\n"
" 2:\n"
" 3:\tsection\t.data\n"
" 4:\thello\tdb\t'Hello, World!', 0Ah\n"
" 5:\thbytes\tequ\t$-hello\n"
" 6:\n"
" 7:\tsection\t.text\n"
" 8:\tglobal\t_start\n"
" 9:\t_start:\n"
"10:\tpush\tdword hbytes\n"
"11:\tpush\tdword hello\n"
"12:\tpush\tdword stdout\n"
"13:\tsys.write\n"
"14:\n"
"15:\tpush\tdword 0\n"
"16:\tsys.exit"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10065
msgid ""
"Here is what it does: Line 1 includes the defines, the macros, and the code "
"from <filename>system.inc</filename>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10068
msgid ""
"Lines 3-5 are the data: Line 3 starts the data section/segment. Line 4 "
"contains the string \"Hello, World!\" followed by a new line (<constant>0Ah</"
"constant>). Line 5 creates a constant that contains the length of the string "
"from line 4 in bytes."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10074
msgid ""
"Lines 7-16 contain the code. Note that FreeBSD uses the <emphasis>elf</"
"emphasis> file format for its executables, which requires every program to "
"start at the point labeled <varname>_start</varname> (or, more precisely, "
"the linker expects that). This label has to be global."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10080
msgid ""
"Lines 10-13 ask the system to write <varname>hbytes</varname> bytes of the "
"<varname>hello</varname> string to <varname>stdout</varname>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10084
msgid ""
"Lines 15-16 ask the system to end the program with the return value of "
"<constant>0</constant>. The <function role=\"syscall\">SYS_exit</function> "
"syscall never returns, so the code ends there."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10089
msgid ""
"If you have come to <trademark class=\"registered\">UNIX</trademark> from "
"<acronym><trademark class=\"registered\">MS-DOS</trademark></acronym> "
"assembly language background, you may be used to writing directly to the "
"video hardware. You will never have to worry about this in FreeBSD, or any "
"other flavor of <trademark class=\"registered\">UNIX</trademark>. As far as "
"you are concerned, you are writing to a file known as <filename>stdout</"
"filename>. This can be the video screen, or a <application>telnet</"
"application> terminal, or an actual file, or even the input of another "
"program. Which one it is, is for the system to figure out."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:10101
msgid "Assembling the Code"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10103
msgid ""
"Type the code (except the line numbers) in an editor, and save it in a file "
"named <filename>hello.asm</filename>. You need <application>nasm</"
"application> to assemble it."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:10108
msgid "Installing <application>nasm</application>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:10110
msgid "If you do not have <application>nasm</application>, type:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:10113
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>su</userinput>\n"
"Password:<userinput><replaceable>your root password</replaceable></userinput>\n"
"<prompt>#</prompt> <userinput>cd /usr/ports/devel/nasm</userinput>\n"
"<prompt>#</prompt> <userinput>make install</userinput>\n"
"<prompt>#</prompt> <userinput>exit</userinput>\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:10120
msgid ""
"You may type <userinput>make install clean</userinput> instead of just "
"<userinput>make install</userinput> if you do not want to keep "
"<application>nasm</application> source code."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:10125
msgid ""
"Either way, FreeBSD will automatically download <application>nasm</"
"application> from the Internet, compile it, and install it on your system."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10130
msgid ""
"If your system is not FreeBSD, you need to get <application>nasm</"
"application> from its <link xlink:href=\"https://sourceforge.net/projects/"
"nasm\">home page</link>. You can still use it to assemble FreeBSD code."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:10136
msgid "Now you can assemble, link, and run the code:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:10138
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>nasm -f elf hello.asm</userinput>\n"
"<prompt>%</prompt> <userinput>ld -s -o hello hello.o</userinput>\n"
"<prompt>%</prompt> <userinput>./hello</userinput>\n"
"Hello, World!\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:10148
msgid "Writing <trademark class=\"registered\">UNIX</trademark> Filters"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10150
msgid ""
"A common type of <trademark class=\"registered\">UNIX</trademark> "
"application is a filter—a program that reads data from the <filename>stdin</"
"filename>, processes it somehow, then writes the result to <filename>stdout</"
"filename>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10155
msgid ""
"In this chapter, we shall develop a simple filter, and learn how to read "
"from <filename>stdin</filename> and write to <filename>stdout</filename>. "
"This filter will convert each byte of its input into a hexadecimal number "
"followed by a blank space."
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10161
#, no-wrap
msgid ""
"%include\t'system.inc'\n"
"\n"
"section\t.data\n"
"hex\tdb\t'0123456789ABCDEF'\n"
"buffer\tdb\t0, 0, ' '\n"
"\n"
"section\t.text\n"
"global\t_start\n"
"_start:\n"
"\t; read a byte from stdin\n"
"\tpush\tdword 1\n"
"\tpush\tdword buffer\n"
"\tpush\tdword stdin\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\n"
"\t; convert it to hex\n"
"\tmovzx\teax, byte [buffer]\n"
"\tmov\tedx, eax\n"
"\tshr\tdl, 4\n"
"\tmov\tdl, [hex+edx]\n"
"\tmov\t[buffer], dl\n"
"\tand\tal, 0Fh\n"
"\tmov\tal, [hex+eax]\n"
"\tmov\t[buffer+1], al\n"
"\n"
"\t; print it\n"
"\tpush\tdword 3\n"
"\tpush\tdword buffer\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tjmp\tshort _start\n"
"\n"
".done:\n"
"\tpush\tdword 0\n"
"\tsys.exit"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10201
msgid ""
"In the data section we create an array called <varname>hex</varname>. It "
"contains the 16 hexadecimal digits in ascending order. The array is followed "
"by a buffer which we will use for both input and output. The first two bytes "
"of the buffer are initially set to <constant>0</constant>. This is where we "
"will write the two hexadecimal digits (the first byte also is where we will "
"read the input). The third byte is a space."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10210
msgid ""
"The code section consists of four parts: Reading the byte, converting it to "
"a hexadecimal number, writing the result, and eventually exiting the program."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10214
msgid ""
"To read the byte, we ask the system to read one byte from <filename>stdin</"
"filename>, and store it in the first byte of the <varname>buffer</varname>. "
"The system returns the number of bytes read in <varname role=\"register"
"\">EAX</varname>. This will be <constant>1</constant> while data is coming, "
"or <constant>0</constant>, when no more input data is available. Therefore, "
"we check the value of <varname role=\"register\">EAX</varname>. If it is "
"<constant>0</constant>, we jump to <varname>.done</varname>, otherwise we "
"continue."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10225
msgid ""
"For simplicity sake, we are ignoring the possibility of an error condition "
"at this time."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10229
msgid ""
"The hexadecimal conversion reads the byte from the <varname>buffer</varname> "
"into <varname role=\"register\">EAX</varname>, or actually just <varname "
"role=\"register\">AL</varname>, while clearing the remaining bits of "
"<varname role=\"register\">EAX</varname> to zeros. We also copy the byte to "
"<varname role=\"register\">EDX</varname> because we need to convert the "
"upper four bits (nibble) separately from the lower four bits. We store the "
"result in the first two bytes of the buffer."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10237
msgid ""
"Next, we ask the system to write the three bytes of the buffer, i.e., the "
"two hexadecimal digits and the blank space, to <filename>stdout</filename>. "
"We then jump back to the beginning of the program and process the next byte."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10242
msgid ""
"Once there is no more input left, we ask the system to exit our program, "
"returning a zero, which is the traditional value meaning the program was "
"successful."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10246
msgid ""
"Go ahead, and save the code in a file named <filename>hex.asm</filename>, "
"then type the following (the <userinput>^D</userinput> means press the "
"control key and type <userinput>D</userinput> while holding the control key "
"down):"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:10252
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>nasm -f elf hex.asm</userinput>\n"
"<prompt>%</prompt> <userinput>ld -s -o hex hex.o</userinput>\n"
"<prompt>%</prompt> <userinput>./hex</userinput>\n"
"<userinput>Hello, World!</userinput>\n"
"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A <userinput>Here I come!</userinput>\n"
"48 65 72 65 20 49 20 63 6F 6D 65 21 0A <userinput>^D</userinput> <prompt>%</prompt>"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10260
msgid ""
"If you are migrating to <trademark class=\"registered\">UNIX</trademark> "
"from <acronym><trademark class=\"registered\">MS-DOS</trademark></acronym>, "
"you may be wondering why each line ends with <constant>0A</constant> instead "
"of <constant>0D 0A</constant>. This is because <trademark class=\"registered"
"\">UNIX</trademark> does not use the cr/lf convention, but a \"new line\" "
"convention, which is <constant>0A</constant> in hexadecimal."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10268
msgid ""
"Can we improve this? Well, for one, it is a bit confusing because once we "
"have converted a line of text, our input no longer starts at the beginning "
"of the line. We can modify it to print a new line instead of a space after "
"each <constant>0A</constant>:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10274
#, no-wrap
msgid ""
"%include\t'system.inc'\n"
"\n"
"section\t.data\n"
"hex\tdb\t'0123456789ABCDEF'\n"
"buffer\tdb\t0, 0, ' '\n"
"\n"
"section\t.text\n"
"global\t_start\n"
"_start:\n"
"\tmov\tcl, ' '\n"
"\n"
".loop:\n"
"\t; read a byte from stdin\n"
"\tpush\tdword 1\n"
"\tpush\tdword buffer\n"
"\tpush\tdword stdin\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\n"
"\t; convert it to hex\n"
"\tmovzx\teax, byte [buffer]\n"
"\tmov\t[buffer+2], cl\n"
"\tcmp\tal, 0Ah\n"
"\tjne\t.hex\n"
"\tmov\t[buffer+2], al\n"
"\n"
".hex:\n"
"\tmov\tedx, eax\n"
"\tshr\tdl, 4\n"
"\tmov\tdl, [hex+edx]\n"
"\tmov\t[buffer], dl\n"
"\tand\tal, 0Fh\n"
"\tmov\tal, [hex+eax]\n"
"\tmov\t[buffer+1], al\n"
"\n"
"\t; print it\n"
"\tpush\tdword 3\n"
"\tpush\tdword buffer\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tjmp\tshort .loop\n"
"\n"
".done:\n"
"\tpush\tdword 0\n"
"\tsys.exit"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10323
msgid ""
"We have stored the space in the <varname role=\"register\">CL</varname> "
"register. We can do this safely because, unlike <trademark class=\"registered"
"\">Microsoft</trademark> <trademark class=\"registered\">Windows</"
"trademark>, <trademark class=\"registered\">UNIX</trademark> system calls do "
"not modify the value of any register they do not use to return a value in."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10328
msgid ""
"That means we only need to set <varname role=\"register\">CL</varname> once. "
"We have, therefore, added a new label <varname>.loop</varname> and jump to "
"it for the next byte instead of jumping at <varname>_start</varname>. We "
"have also added the <varname>.hex</varname> label so we can either have a "
"blank space or a new line as the third byte of the <varname>buffer</varname>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10335
msgid ""
"Once you have changed <filename>hex.asm</filename> to reflect these changes, "
"type:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:10338 book.translate.xml:10606
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>nasm -f elf hex.asm</userinput>\n"
"<prompt>%</prompt> <userinput>ld -s -o hex hex.o</userinput>\n"
"<prompt>%</prompt> <userinput>./hex</userinput>\n"
"<userinput>Hello, World!</userinput>\n"
"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
"<userinput>Here I come!</userinput>\n"
"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
"<userinput>^D</userinput> <prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10347
msgid ""
"That looks better. But this code is quite inefficient! We are making a "
"system call for every single byte twice (once to read it, another time to "
"write the output)."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:10353
msgid "Buffered Input and Output"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10355
msgid ""
"We can improve the efficiency of our code by buffering our input and output. "
"We create an input buffer and read a whole sequence of bytes at one time. "
"Then we fetch them one by one from the buffer."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10360
msgid ""
"We also create an output buffer. We store our output in it until it is full. "
"At that time we ask the kernel to write the contents of the buffer to "
"<filename>stdout</filename>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10365
msgid ""
"The program ends when there is no more input. But we still need to ask the "
"kernel to write the contents of our output buffer to <filename>stdout</"
"filename> one last time, otherwise some of our output would make it to the "
"output buffer, but never be sent out. Do not forget that, or you will be "
"wondering why some of your output is missing."
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10372
#, no-wrap
msgid ""
"%include\t'system.inc'\n"
"\n"
"%define\tBUFSIZE\t2048\n"
"\n"
"section\t.data\n"
"hex\tdb\t'0123456789ABCDEF'\n"
"\n"
"section .bss\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE\n"
"\n"
"section\t.text\n"
"global\t_start\n"
"_start:\n"
"\tsub\teax, eax\n"
"\tsub\tebx, ebx\n"
"\tsub\tecx, ecx\n"
"\tmov\tedi, obuffer\n"
"\n"
".loop:\n"
"\t; read a byte from stdin\n"
"\tcall\tgetchar\n"
"\n"
"\t; convert it to hex\n"
"\tmov\tdl, al\n"
"\tshr\tal, 4\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, dl\n"
"\tand\tal, 0Fh\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, ' '\n"
"\tcmp\tdl, 0Ah\n"
"\tjne\t.put\n"
"\tmov\tal, dl\n"
"\n"
".put:\n"
"\tcall\tputchar\n"
"\tjmp\tshort .loop\n"
"\n"
"align 4\n"
"getchar:\n"
"\tor\tebx, ebx\n"
"\tjne\t.fetch\n"
"\n"
"\tcall\tread\n"
"\n"
".fetch:\n"
"\tlodsb\n"
"\tdec\tebx\n"
"\tret\n"
"\n"
"read:\n"
"\tpush\tdword BUFSIZE\n"
"\tmov\tesi, ibuffer\n"
"\tpush\tesi\n"
"\tpush\tdword stdin\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tmov\tebx, eax\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
".done:\n"
"\tcall\twrite\t\t; flush output buffer\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"putchar:\n"
"\tstosb\n"
"\tinc\tecx\n"
"\tcmp\tecx, BUFSIZE\n"
"\tje\twrite\n"
"\tret\n"
"\n"
"align 4\n"
"write:\n"
"\tsub\tedi, ecx\t; start of buffer\n"
"\tpush\tecx\n"
"\tpush\tedi\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tsub\teax, eax\n"
"\tsub\tecx, ecx\t; buffer is empty now\n"
"\tret"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10466
msgid ""
"We now have a third section in the source code, named <varname>.bss</"
"varname>. This section is not included in our executable file, and, "
"therefore, cannot be initialized. We use <function role=\"opcode\">resb</"
"function> instead of <function role=\"opcode\">db</function>. It simply "
"reserves the requested size of uninitialized memory for our use."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10473
msgid ""
"We take advantage of the fact that the system does not modify the registers: "
"We use registers for what, otherwise, would have to be global variables "
"stored in the <varname>.data</varname> section. This is also why the "
"<trademark class=\"registered\">UNIX</trademark> convention of passing "
"parameters to system calls on the stack is superior to the Microsoft "
"convention of passing them in the registers: We can keep the registers for "
"our own use."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10482
msgid ""
"We use <varname role=\"register\">EDI</varname> and <varname role=\"register"
"\">ESI</varname> as pointers to the next byte to be read from or written to. "
"We use <varname role=\"register\">EBX</varname> and <varname role=\"register"
"\">ECX</varname> to keep count of the number of bytes in the two buffers, so "
"we know when to dump the output to, or read more input from, the system."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10488
msgid "Let us see how it works now:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:10490
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>nasm -f elf hex.asm</userinput>\n"
"<prompt>%</prompt> <userinput>ld -s -o hex hex.o</userinput>\n"
"<prompt>%</prompt> <userinput>./hex</userinput>\n"
"<userinput>Hello, World!</userinput>\n"
"<userinput>Here I come!</userinput>\n"
"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
"<userinput>^D</userinput> <prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10499
msgid ""
"Not what you expected? The program did not print the output until we pressed "
"<userinput>^D</userinput>. That is easy to fix by inserting three lines of "
"code to write the output every time we have converted a new line to "
"<constant>0A</constant>. I have marked the three lines with &gt; (do not "
"copy the &gt; in your <filename>hex.asm</filename>)."
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10507
#, no-wrap
msgid ""
"%include\t'system.inc'\n"
"\n"
"%define\tBUFSIZE\t2048\n"
"\n"
"section\t.data\n"
"hex\tdb\t'0123456789ABCDEF'\n"
"\n"
"section .bss\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE\n"
"\n"
"section\t.text\n"
"global\t_start\n"
"_start:\n"
"\tsub\teax, eax\n"
"\tsub\tebx, ebx\n"
"\tsub\tecx, ecx\n"
"\tmov\tedi, obuffer\n"
"\n"
".loop:\n"
"\t; read a byte from stdin\n"
"\tcall\tgetchar\n"
"\n"
"\t; convert it to hex\n"
"\tmov\tdl, al\n"
"\tshr\tal, 4\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, dl\n"
"\tand\tal, 0Fh\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, ' '\n"
"\tcmp\tdl, 0Ah\n"
"\tjne\t.put\n"
"\tmov\tal, dl\n"
"\n"
".put:\n"
"\tcall\tputchar\n"
"&gt;\tcmp\tal, 0Ah\n"
"&gt;\tjne\t.loop\n"
"&gt;\tcall\twrite\n"
"\tjmp\tshort .loop\n"
"\n"
"align 4\n"
"getchar:\n"
"\tor\tebx, ebx\n"
"\tjne\t.fetch\n"
"\n"
"\tcall\tread\n"
"\n"
".fetch:\n"
"\tlodsb\n"
"\tdec\tebx\n"
"\tret\n"
"\n"
"read:\n"
"\tpush\tdword BUFSIZE\n"
"\tmov\tesi, ibuffer\n"
"\tpush\tesi\n"
"\tpush\tdword stdin\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tmov\tebx, eax\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
".done:\n"
"\tcall\twrite\t\t; flush output buffer\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"putchar:\n"
"\tstosb\n"
"\tinc\tecx\n"
"\tcmp\tecx, BUFSIZE\n"
"\tje\twrite\n"
"\tret\n"
"\n"
"align 4\n"
"write:\n"
"\tsub\tedi, ecx\t; start of buffer\n"
"\tpush\tecx\n"
"\tpush\tedi\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tsub\teax, eax\n"
"\tsub\tecx, ecx\t; buffer is empty now\n"
"\tret"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10604
msgid "Now, let us see how it works:"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10615
msgid "Not bad for a 644-byte executable, is it!"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10618
msgid ""
"This approach to buffered input/output still contains a hidden danger. I "
"will discuss—and fix—it later, when I talk about the <link linkend=\"x86-"
"buffered-dark-side\">dark side of buffering</link>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:10625
msgid "How to Unread a Character"
msgstr ""

#. (itstool) path: warning/para
#: book.translate.xml:10628
msgid ""
"This may be a somewhat advanced topic, mostly of interest to programmers "
"familiar with the theory of compilers. If you wish, you may <link linkend="
"\"x86-command-line\">skip to the next section</link>, and perhaps read this "
"later."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10634
msgid ""
"While our sample program does not require it, more sophisticated filters "
"often need to look ahead. In other words, they may need to see what the next "
"character is (or even several characters). If the next character is of a "
"certain value, it is part of the token currently being processed. Otherwise, "
"it is not."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10641
msgid ""
"For example, you may be parsing the input stream for a textual string (e.g., "
"when implementing a language compiler): If a character is followed by "
"another character, or perhaps a digit, it is part of the token you are "
"processing. If it is followed by white space, or some other value, then it "
"is not part of the current token."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10648
msgid ""
"This presents an interesting problem: How to return the next character back "
"to the input stream, so it can be read again later?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10652
msgid ""
"One possible solution is to store it in a character variable, then set a "
"flag. We can modify <function>getchar</function> to check the flag, and if "
"it is set, fetch the byte from that variable instead of the input buffer, "
"and reset the flag. But, of course, that slows us down."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10659
msgid ""
"The C language has an <function>ungetc()</function> function, just for that "
"purpose. Is there a quick way to implement it in our code? I would like you "
"to scroll back up and take a look at the <function>getchar</function> "
"procedure and see if you can find a nice and fast solution before reading "
"the next paragraph. Then come back here and see my own solution."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10667
msgid ""
"The key to returning a character back to the stream is in how we are getting "
"the characters to start with:"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10670
msgid ""
"First we check if the buffer is empty by testing the value of <varname role="
"\"register\">EBX</varname>. If it is zero, we call the <function>read</"
"function> procedure."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10675
msgid ""
"If we do have a character available, we use <function role=\"opcode\">lodsb</"
"function>, then decrease the value of <varname role=\"register\">EBX</"
"varname>. The <function role=\"opcode\">lodsb</function> instruction is "
"effectively identical to:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10679
#, no-wrap
msgid ""
"mov\tal, [esi]\n"
"\tinc\tesi"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10682
msgid ""
"The byte we have fetched remains in the buffer until the next time "
"<function>read</function> is called. We do not know when that happens, but "
"we do know it will not happen until the next call to <function>getchar</"
"function>. Hence, to \"return\" the last-read byte back to the stream, all "
"we have to do is decrease the value of <varname role=\"register\">ESI</"
"varname> and increase the value of <varname role=\"register\">EBX</varname>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10690
#, no-wrap
msgid ""
"ungetc:\n"
"\tdec\tesi\n"
"\tinc\tebx\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10695
msgid ""
"But, be careful! We are perfectly safe doing this if our look-ahead is at "
"most one character at a time. If we are examining more than one upcoming "
"character and call <function>ungetc</function> several times in a row, it "
"will work most of the time, but not all the time (and will be tough to "
"debug). Why?"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10702
msgid ""
"Because as long as <function>getchar</function> does not have to call "
"<function>read</function>, all of the pre-read bytes are still in the "
"buffer, and our <function>ungetc</function> works without a glitch. But the "
"moment <function>getchar</function> calls <function>read</function>, the "
"contents of the buffer change."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10710
msgid ""
"We can always rely on <function>ungetc</function> working properly on the "
"last character we have read with <function>getchar</function>, but not on "
"anything we have read before that."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10715
msgid ""
"If your program reads more than one byte ahead, you have at least two "
"choices:"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10718
msgid ""
"If possible, modify the program so it only reads one byte ahead. This is the "
"simplest solution."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10721
msgid ""
"If that option is not available, first of all determine the maximum number "
"of characters your program needs to return to the input stream at one time. "
"Increase that number slightly, just to be sure, preferably to a multiple of "
"16—so it aligns nicely. Then modify the <varname>.bss</varname> section of "
"your code, and create a small \"spare\" buffer right before your input "
"buffer, something like this:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10730
#, no-wrap
msgid ""
"section\t.bss\n"
"\tresb\t16\t; or whatever the value you came up with\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10735
msgid ""
"You also need to modify your <function>ungetc</function> to pass the value "
"of the byte to unget in <varname role=\"register\">AL</varname>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:10738
#, no-wrap
msgid ""
"ungetc:\n"
"\tdec\tesi\n"
"\tinc\tebx\n"
"\tmov\t[esi], al\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:10744
msgid ""
"With this modification, you can call <function>ungetc</function> up to 17 "
"times in a row safely (the first call will still be within the buffer, the "
"remaining 16 may be either within the buffer or within the \"spare\")."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:10753
msgid "Command Line Arguments"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10755
msgid ""
"Our <application>hex</application> program will be more useful if it can "
"read the names of an input and output file from its command line, i.e., if "
"it can process the command line arguments. But... Where are they?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10760
msgid ""
"Before a <trademark class=\"registered\">UNIX</trademark> system starts a "
"program, it <function role=\"opcode\">push</function>es some data on the "
"stack, then jumps at the <varname>_start</varname> label of the program. "
"Yes, I said jumps, not calls. That means the data can be accessed by reading "
"<varname>[esp+offset]</varname>, or by simply <function role=\"opcode\">pop</"
"function>ping it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10766
msgid ""
"The value at the top of the stack contains the number of command line "
"arguments. It is traditionally called <varname>argc</varname>, for "
"\"argument count.\""
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10770
msgid ""
"Command line arguments follow next, all <varname>argc</varname> of them. "
"These are typically referred to as <varname>argv</varname>, for \"argument "
"value(s).\" That is, we get <varname>argv[0]</varname>, <varname>argv[1]</"
"varname>, <varname>...</varname>, <varname>argv[argc-1]</varname>. These are "
"not the actual arguments, but pointers to arguments, i.e., memory addresses "
"of the actual arguments. The arguments themselves are NUL-terminated "
"character strings."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10780
msgid ""
"The <varname>argv</varname> list is followed by a NULL pointer, which is "
"simply a <constant>0</constant>. There is more, but this is enough for our "
"purposes right now."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:10785
msgid ""
"If you have come from the <acronym><trademark class=\"registered\">MS-DOS</"
"trademark></acronym> programming environment, the main difference is that "
"each argument is in a separate string. The second difference is that there "
"is no practical limit on how many arguments there can be."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10792
msgid ""
"Armed with this knowledge, we are almost ready for the next version of "
"<filename>hex.asm</filename>. First, however, we need to add a few lines to "
"<filename>system.inc</filename>:"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10797
msgid ""
"First, we need to add two new entries to our list of system call numbers:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10800
#, no-wrap
msgid ""
"%define\tSYS_open\t5\n"
"%define\tSYS_close\t6"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10803
msgid "Then we add two new macros at the end of the file:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10805
#, no-wrap
msgid ""
"%macro\tsys.open\t0\n"
"\tsystem\tSYS_open\n"
"%endmacro\n"
"\n"
"%macro\tsys.close\t0\n"
"\tsystem\tSYS_close\n"
"%endmacro"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10813
msgid "Here, then, is our modified source code:"
msgstr ""

#. (itstool) path: sect1/programlisting
#: book.translate.xml:10815
#, no-wrap
msgid ""
"%include\t'system.inc'\n"
"\n"
"%define\tBUFSIZE\t2048\n"
"\n"
"section\t.data\n"
"fd.in\tdd\tstdin\n"
"fd.out\tdd\tstdout\n"
"hex\tdb\t'0123456789ABCDEF'\n"
"\n"
"section .bss\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE\n"
"\n"
"section\t.text\n"
"align 4\n"
"err:\n"
"\tpush\tdword 1\t\t; return failure\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"global\t_start\n"
"_start:\n"
"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
"\n"
"\tpop\tecx\n"
"\tjecxz\t.init\t\t; no more arguments\n"
"\n"
"\t; ECX contains the path to input file\n"
"\tpush\tdword 0\t\t; O_RDONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\terr\t\t; open failed\n"
"\n"
"\tadd\tesp, byte 8\n"
"\tmov\t[fd.in], eax\n"
"\n"
"\tpop\tecx\n"
"\tjecxz\t.init\t\t; no more arguments\n"
"\n"
"\t; ECX contains the path to output file\n"
"\tpush\tdword 420\t; file mode (644 octal)\n"
"\tpush\tdword 0200h | 0400h | 01h\n"
"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\terr\n"
"\n"
"\tadd\tesp, byte 12\n"
"\tmov\t[fd.out], eax\n"
"\n"
".init:\n"
"\tsub\teax, eax\n"
"\tsub\tebx, ebx\n"
"\tsub\tecx, ecx\n"
"\tmov\tedi, obuffer\n"
"\n"
".loop:\n"
"\t; read a byte from input file or stdin\n"
"\tcall\tgetchar\n"
"\n"
"\t; convert it to hex\n"
"\tmov\tdl, al\n"
"\tshr\tal, 4\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, dl\n"
"\tand\tal, 0Fh\n"
"\tmov\tal, [hex+eax]\n"
"\tcall\tputchar\n"
"\n"
"\tmov\tal, ' '\n"
"\tcmp\tdl, 0Ah\n"
"\tjne\t.put\n"
"\tmov\tal, dl\n"
"\n"
".put:\n"
"\tcall\tputchar\n"
"\tcmp\tal, dl\n"
"\tjne\t.loop\n"
"\tcall\twrite\n"
"\tjmp\tshort .loop\n"
"\n"
"align 4\n"
"getchar:\n"
"\tor\tebx, ebx\n"
"\tjne\t.fetch\n"
"\n"
"\tcall\tread\n"
"\n"
".fetch:\n"
"\tlodsb\n"
"\tdec\tebx\n"
"\tret\n"
"\n"
"read:\n"
"\tpush\tdword BUFSIZE\n"
"\tmov\tesi, ibuffer\n"
"\tpush\tesi\n"
"\tpush\tdword [fd.in]\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tmov\tebx, eax\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
".done:\n"
"\tcall\twrite\t\t; flush output buffer\n"
"\n"
"\t; close files\n"
"\tpush\tdword [fd.in]\n"
"\tsys.close\n"
"\n"
"\tpush\tdword [fd.out]\n"
"\tsys.close\n"
"\n"
"\t; return success\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"putchar:\n"
"\tstosb\n"
"\tinc\tecx\n"
"\tcmp\tecx, BUFSIZE\n"
"\tje\twrite\n"
"\tret\n"
"\n"
"align 4\n"
"write:\n"
"\tsub\tedi, ecx\t; start of buffer\n"
"\tpush\tecx\n"
"\tpush\tedi\n"
"\tpush\tdword [fd.out]\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tsub\teax, eax\n"
"\tsub\tecx, ecx\t; buffer is empty now\n"
"\tret"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10958
msgid ""
"In our <varname>.data</varname> section we now have two new variables, "
"<varname>fd.in</varname> and <varname>fd.out</varname>. We store the input "
"and output file descriptors here."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10963
msgid ""
"In the <varname>.text</varname> section we have replaced the references to "
"<varname>stdin</varname> and <varname>stdout</varname> with <varname>[fd."
"in]</varname> and <varname>[fd.out]</varname>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10968
msgid ""
"The <varname>.text</varname> section now starts with a simple error handler, "
"which does nothing but exit the program with a return value of <constant>1</"
"constant>. The error handler is before <varname>_start</varname> so we are "
"within a short distance from where the errors occur."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10974
msgid ""
"Naturally, the program execution still begins at <varname>_start</varname>. "
"First, we remove <varname>argc</varname> and <varname>argv[0]</varname> from "
"the stack: They are of no interest to us (in this program, that is)."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10980
msgid ""
"We pop <varname>argv[1]</varname> to <varname role=\"register\">ECX</"
"varname>. This register is particularly suited for pointers, as we can "
"handle NULL pointers with <function role=\"opcode\">jecxz</function>. If "
"<varname>argv[1]</varname> is not NULL, we try to open the file named in the "
"first argument. Otherwise, we continue the program as before: Reading from "
"<varname>stdin</varname>, writing to <varname>stdout</varname>. If we fail "
"to open the input file (e.g., it does not exist), we jump to the error "
"handler and quit."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10990
msgid ""
"If all went well, we now check for the second argument. If it is there, we "
"open the output file. Otherwise, we send the output to <varname>stdout</"
"varname>. If we fail to open the output file (e.g., it exists and we do not "
"have the write permission), we, again, jump to the error handler."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:10996
msgid ""
"The rest of the code is the same as before, except we close the input and "
"output files before exiting, and, as mentioned, we use <varname>[fd.in]</"
"varname> and <varname>[fd.out]</varname>."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11001
msgid "Our executable is now a whopping 768 bytes long."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11003
msgid ""
"Can we still improve it? Of course! Every program can be improved. Here are "
"a few ideas of what we could do:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11008
msgid "Have our error handler print a message to <varname>stderr</varname>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11013
msgid ""
"Add error handlers to the <function>read</function> and <function>write</"
"function> functions."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11018
msgid ""
"Close <varname>stdin</varname> when we open an input file, <varname>stdout</"
"varname> when we open an output file."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11024
msgid ""
"Add command line switches, such as <parameter>-i</parameter> and <parameter>-"
"o</parameter>, so we can list the input and output files in any order, or "
"perhaps read from <varname>stdin</varname> and write to a file."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11032
msgid "Print a usage message if command line arguments are incorrect."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11038
msgid ""
"I shall leave these enhancements as an exercise to the reader: You already "
"know everything you need to know to implement them."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:11044
msgid "<trademark class=\"registered\">UNIX</trademark> Environment"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11046
msgid ""
"An important <trademark class=\"registered\">UNIX</trademark> concept is the "
"environment, which is defined by <emphasis>environment variables</emphasis>. "
"Some are set by the system, others by you, yet others by the "
"<application>shell</application>, or any program that loads another program."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11053
msgid "How to Find Environment Variables"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11055
msgid ""
"I said earlier that when a program starts executing, the stack contains "
"<varname>argc</varname> followed by the NULL-terminated <varname>argv</"
"varname> array, followed by something else. The \"something else\" is the "
"<emphasis>environment</emphasis>, or, to be more precise, a NULL-terminated "
"array of pointers to <emphasis>environment variables</emphasis>. This is "
"often referred to as <varname>env</varname>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11064
msgid ""
"The structure of <varname>env</varname> is the same as that of "
"<varname>argv</varname>, a list of memory addresses followed by a NULL "
"(<constant>0</constant>). In this case, there is no <varname>\"envc\"</"
"varname>—we figure out where the array ends by searching for the final NULL."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11070
msgid ""
"The variables usually come in the <varname>name=value</varname> format, but "
"sometimes the <varname>=value</varname> part may be missing. We need to "
"account for that possibility."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11077
msgid "webvars"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11079
msgid ""
"I could just show you some code that prints the environment the same way the "
"<trademark class=\"registered\">UNIX</trademark> <application>env</"
"application> command does. But I thought it would be more interesting to "
"write a simple assembly language CGI utility."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:11086
msgid "CGI: a Quick Overview"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11088
msgid ""
"I have a <link xlink:href=\"http://www.whizkidtech.redprince.net/cgi-bin/"
"tutorial\">detailed <acronym>CGI</acronym> tutorial</link> on my web site, "
"but here is a very quick overview of <acronym>CGI</acronym>:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11095
msgid ""
"The web server communicates with the <acronym>CGI</acronym> program by "
"setting <emphasis>environment variables</emphasis>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11101
msgid ""
"The <acronym>CGI</acronym> program sends its output to <filename>stdout</"
"filename>. The web server reads it from there."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11107
msgid ""
"It must start with an <acronym>HTTP</acronym> header followed by two blank "
"lines."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11112
msgid ""
"It then prints the <acronym>HTML</acronym> code, or whatever other type of "
"data it is producing."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:11118
msgid ""
"While certain <emphasis>environment variables</emphasis> use standard names, "
"others vary, depending on the web server. That makes <application>webvars</"
"application> quite a useful diagnostic tool."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:11127
msgid "The Code"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11129
msgid ""
"Our <application>webvars</application> program, then, must send out the "
"<acronym>HTTP</acronym> header followed by some <acronym>HTML</acronym> mark-"
"up. It then must read the <emphasis>environment variables</emphasis> one by "
"one and send them out as part of the <acronym>HTML</acronym> page."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11136
msgid ""
"The code follows. I placed comments and explanations right inside the code:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:11139
#, no-wrap
msgid ""
";;;;;;; webvars.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";\n"
"; Copyright (c) 2000 G. Adam Stanislav\n"
"; All rights reserved.\n"
";\n"
"; Redistribution and use in source and binary forms, with or without\n"
"; modification, are permitted provided that the following conditions\n"
"; are met:\n"
"; 1. Redistributions of source code must retain the above copyright\n"
";    notice, this list of conditions and the following disclaimer.\n"
"; 2. Redistributions in binary form must reproduce the above copyright\n"
";    notice, this list of conditions and the following disclaimer in the\n"
";    documentation and/or other materials provided with the distribution.\n"
";\n"
"; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n"
"; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
"; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
"; ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"
"; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
"; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
"; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
"; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
"; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
"; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
"; SUCH DAMAGE.\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";\n"
"; Version 1.0\n"
";\n"
"; Started:\t 8-Dec-2000\n"
"; Updated:\t 8-Dec-2000\n"
";\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
"%include\t'system.inc'\n"
"\n"
"section\t.data\n"
"http\tdb\t'Content-type: text/html', 0Ah, 0Ah\n"
"\tdb\t'&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;', 0Ah\n"
"\tdb\t'&lt;!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML Strict//EN\" '\n"
"\tdb\t'\"DTD/xhtml1-strict.dtd\"&gt;', 0Ah\n"
"\tdb\t'&lt;html xmlns=\"http://www.w3.org/1999/xhtml\" '\n"
"\tdb\t'xml.lang=\"en\" lang=\"en\"&gt;', 0Ah\n"
"\tdb\t'&lt;head&gt;', 0Ah\n"
"\tdb\t'&lt;title&gt;Web Environment&lt;/title&gt;', 0Ah\n"
"\tdb\t'&lt;meta name=\"author\" content=\"G. Adam Stanislav\" /&gt;', 0Ah\n"
"\tdb\t'&lt;/head&gt;', 0Ah, 0Ah\n"
"\tdb\t'&lt;body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" '\n"
"\tdb\t'vlink=\"#840084\" alink=\"#0000ff\"&gt;', 0Ah\n"
"\tdb\t'&lt;div class=\"webvars\"&gt;', 0Ah\n"
"\tdb\t'&lt;h1&gt;Web Environment&lt;/h1&gt;', 0Ah\n"
"\tdb\t'&lt;p&gt;The following &lt;b&gt;environment variables&lt;/b&gt; are defined '\n"
"\tdb\t'on this web server:&lt;/p&gt;', 0Ah, 0Ah\n"
"\tdb\t'&lt;table align=\"center\" width=\"80\" border=\"0\" cellpadding=\"10\" '\n"
"\tdb\t'cellspacing=\"0\" class=\"webvars\"&gt;', 0Ah\n"
"httplen\tequ\t$-http\n"
"left\tdb\t'&lt;tr&gt;', 0Ah\n"
"\tdb\t'&lt;td class=\"name\"&gt;&lt;tt&gt;'\n"
"leftlen\tequ\t$-left\n"
"middle\tdb\t'&lt;/tt&gt;&lt;/td&gt;', 0Ah\n"
"\tdb\t'&lt;td class=\"value\"&gt;&lt;tt&gt;&lt;b&gt;'\n"
"midlen\tequ\t$-middle\n"
"undef\tdb\t'&lt;i&gt;(undefined)&lt;/i&gt;'\n"
"undeflen\tequ\t$-undef\n"
"right\tdb\t'&lt;/b&gt;&lt;/tt&gt;&lt;/td&gt;', 0Ah\n"
"\tdb\t'&lt;/tr&gt;', 0Ah\n"
"rightlen\tequ\t$-right\n"
"wrap\tdb\t'&lt;/table&gt;', 0Ah\n"
"\tdb\t'&lt;/div&gt;', 0Ah\n"
"\tdb\t'&lt;/body&gt;', 0Ah\n"
"\tdb\t'&lt;/html&gt;', 0Ah, 0Ah\n"
"wraplen\tequ\t$-wrap\n"
"\n"
"section\t.text\n"
"global\t_start\n"
"_start:\n"
"\t; First, send out all the http and xhtml stuff that is\n"
"\t; needed before we start showing the environment\n"
"\tpush\tdword httplen\n"
"\tpush\tdword http\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Now find how far on the stack the environment pointers\n"
"\t; are. We have 12 bytes we have pushed before \"argc\"\n"
"\tmov\teax, [esp+12]\n"
"\n"
"\t; We need to remove the following from the stack:\n"
"\t;\n"
"\t;\tThe 12 bytes we pushed for sys.write\n"
"\t;\tThe  4 bytes of argc\n"
"\t;\tThe EAX*4 bytes of argv\n"
"\t;\tThe  4 bytes of the NULL after argv\n"
"\t;\n"
"\t; Total:\n"
"\t;\t20 + eax * 4\n"
"\t;\n"
"\t; Because stack grows down, we need to ADD that many bytes\n"
"\t; to ESP.\n"
"\tlea\tesp, [esp+20+eax*4]\n"
"\tcld\t\t; This should already be the case, but let's be sure.\n"
"\n"
"\t; Loop through the environment, printing it out\n"
".loop:\n"
"\tpop\tedi\n"
"\tor\tedi, edi\t; Done yet?\n"
"\tje\tnear .wrap\n"
"\n"
"\t; Print the left part of HTML\n"
"\tpush\tdword leftlen\n"
"\tpush\tdword left\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; It may be tempting to search for the '=' in the env string next.\n"
"\t; But it is possible there is no '=', so we search for the\n"
"\t; terminating NUL first.\n"
"\tmov\tesi, edi\t; Save start of string\n"
"\tsub\tecx, ecx\n"
"\tnot\tecx\t\t; ECX = FFFFFFFF\n"
"\tsub\teax, eax\n"
"repne\tscasb\n"
"\tnot\tecx\t\t; ECX = string length + 1\n"
"\tmov\tebx, ecx\t; Save it in EBX\n"
"\n"
"\t; Now is the time to find '='\n"
"\tmov\tedi, esi\t; Start of string\n"
"\tmov\tal, '='\n"
"repne\tscasb\n"
"\tnot\tecx\n"
"\tadd\tecx, ebx\t; Length of name\n"
"\n"
"\tpush\tecx\n"
"\tpush\tesi\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Print the middle part of HTML table code\n"
"\tpush\tdword midlen\n"
"\tpush\tdword middle\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Find the length of the value\n"
"\tnot\tecx\n"
"\tlea\tebx, [ebx+ecx-1]\n"
"\n"
"\t; Print \"undefined\" if 0\n"
"\tor\tebx, ebx\n"
"\tjne\t.value\n"
"\n"
"\tmov\tebx, undeflen\n"
"\tmov\tedi, undef\n"
"\n"
".value:\n"
"\tpush\tebx\n"
"\tpush\tedi\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Print the right part of the table row\n"
"\tpush\tdword rightlen\n"
"\tpush\tdword right\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Get rid of the 60 bytes we have pushed\n"
"\tadd\tesp, byte 60\n"
"\n"
"\t; Get the next variable\n"
"\tjmp\t.loop\n"
"\n"
".wrap:\n"
"\t; Print the rest of HTML\n"
"\tpush\tdword wraplen\n"
"\tpush\tdword wrap\n"
"\tpush\tdword stdout\n"
"\tsys.write\n"
"\n"
"\t; Return success\n"
"\tpush\tdword 0\n"
"\tsys.exit"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11321
msgid ""
"This code produces a 1,396-byte executable. Most of it is data, i.e., the "
"<acronym>HTML</acronym> mark-up we need to send out."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11325
msgid "Assemble and link it as usual:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:11327
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>nasm -f elf webvars.asm</userinput>\n"
"<prompt>%</prompt> <userinput>ld -s -o webvars webvars.o</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11330
msgid ""
"To use it, you need to upload <filename>webvars</filename> to your web "
"server. Depending on how your web server is set up, you may have to store it "
"in a special <filename>cgi-bin</filename> directory, or perhaps rename it "
"with a <filename>.cgi</filename> extension."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11336
msgid ""
"Then you need to use your browser to view its output. To see its output on "
"my web server, please go to <link xlink:href=\"http://www.int80h.org/webvars/"
"\"><filename>http://www.int80h.org/webvars/</filename></link>. If curious "
"about the additional environment variables present in a password protected "
"web directory, go to <link xlink:href=\"http://www.int80h.org/private/"
"\"><filename>http://www.int80h.org/private/</filename></link>, using the "
"name <userinput>asm</userinput> and password <userinput>programmer</"
"userinput>."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:11347
msgid "Working with Files"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11349
msgid ""
"We have already done some basic file work: We know how to open and close "
"them, how to read and write them using buffers. But <trademark class="
"\"registered\">UNIX</trademark> offers much more functionality when it comes "
"to files. We will examine some of it in this section, and end up with a nice "
"file conversion utility."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11355
msgid ""
"Indeed, let us start at the end, that is, with the file conversion utility. "
"It always makes programming easier when we know from the start what the end "
"product is supposed to do."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11360
msgid ""
"One of the first programs I wrote for <trademark class=\"registered\">UNIX</"
"trademark> was <link xlink:href=\"ftp://ftp.int80h.org/unix/tuc/"
"\"><application>tuc</application></link>, a text-to-<trademark class="
"\"registered\">UNIX</trademark> file converter. It converts a text file from "
"other operating systems to a <trademark class=\"registered\">UNIX</"
"trademark> text file. In other words, it changes from different kind of line "
"endings to the newline convention of <trademark class=\"registered\">UNIX</"
"trademark>. It saves the output in a different file. Optionally, it converts "
"a <trademark class=\"registered\">UNIX</trademark> text file to a "
"<acronym>DOS</acronym> text file."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11368
msgid ""
"I have used <application>tuc</application> extensively, but always only to "
"convert from some other <acronym>OS</acronym> to <trademark class="
"\"registered\">UNIX</trademark>, never the other way. I have always wished "
"it would just overwrite the file instead of me having to send the output to "
"a different file. Most of the time, I end up using it like this:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:11375
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>tuc <replaceable>myfile tempfile</replaceable></userinput>\n"
"<prompt>%</prompt> <userinput>mv <replaceable>tempfile myfile</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11378
msgid ""
"It would be nice to have a <application>ftuc</application>, i.e., "
"<emphasis>fast tuc</emphasis>, and use it like this:"
msgstr ""

#. (itstool) path: sect1/screen
#: book.translate.xml:11382
#, no-wrap
msgid "<prompt>%</prompt> <userinput>ftuc <replaceable>myfile</replaceable></userinput>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11384
msgid ""
"In this chapter, then, we will write <application>ftuc</application> in "
"assembly language (the original <application>tuc</application> is in C), and "
"study various file-oriented kernel services in the process."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11389
msgid ""
"At first sight, such a file conversion is very simple: All you have to do is "
"strip the carriage returns, right?"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11392
msgid ""
"If you answered yes, think again: That approach will work most of the time "
"(at least with <acronym>MS DOS</acronym> text files), but will fail "
"occasionally."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11396
msgid ""
"The problem is that not all non <trademark class=\"registered\">UNIX</"
"trademark> text files end their line with the carriage return / line feed "
"sequence. Some use carriage returns without line feeds. Others combine "
"several blank lines into a single carriage return followed by several line "
"feeds. And so on."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11402
msgid ""
"A text file converter, then, must be able to handle any possible line "
"endings:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11407
msgid "carriage return / line feed"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11411
msgid "carriage return"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11415
msgid "line feed / carriage return"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11419
msgid "line feed"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:11423
msgid ""
"It should also handle files that use some kind of a combination of the above "
"(e.g., carriage return followed by several line feeds)."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11428
msgid "Finite State Machine"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11430
msgid ""
"The problem is easily solved by the use of a technique called "
"<emphasis>finite state machine</emphasis>, originally developed by the "
"designers of digital electronic circuits. A <emphasis>finite state machine</"
"emphasis> is a digital circuit whose output is dependent not only on its "
"input but on its previous input, i.e., on its state. The microprocessor is "
"an example of a <emphasis>finite state machine</emphasis>: Our assembly "
"language code is assembled to machine language in which some assembly "
"language code produces a single byte of machine language, while others "
"produce several bytes. As the microprocessor fetches the bytes from the "
"memory one by one, some of them simply change its state rather than produce "
"some output. When all the bytes of the op code are fetched, the "
"microprocessor produces some output, or changes the value of a register, etc."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11446
msgid ""
"Because of that, all software is essentially a sequence of state "
"instructions for the microprocessor. Nevertheless, the concept of "
"<emphasis>finite state machine</emphasis> is useful in software design as "
"well."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11451
msgid ""
"Our text file converter can be designer as a <emphasis>finite state machine</"
"emphasis> with three possible states. We could call them states 0-2, but it "
"will make our life easier if we give them symbolic names:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11458
msgid "<symbol>ordinary</symbol>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11462
msgid "<symbol>cr</symbol>"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11466
msgid "<symbol>lf</symbol>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11470
msgid ""
"Our program will start in the <symbol>ordinary</symbol> state. During this "
"state, the program action depends on its input as follows:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11476
msgid ""
"If the input is anything other than a carriage return or line feed, the "
"input is simply passed on to the output. The state remains unchanged."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11482
msgid ""
"If the input is a carriage return, the state is changed to <symbol>cr</"
"symbol>. The input is then discarded, i.e., no output is made."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11488
msgid ""
"If the input is a line feed, the state is changed to <symbol>lf</symbol>. "
"The input is then discarded."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11493
msgid ""
"Whenever we are in the <symbol>cr</symbol> state, it is because the last "
"input was a carriage return, which was unprocessed. What our software does "
"in this state again depends on the current input:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11500
msgid ""
"If the input is anything other than a carriage return or line feed, output a "
"line feed, then output the input, then change the state to <symbol>ordinary</"
"symbol>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11506
msgid ""
"If the input is a carriage return, we have received two (or more) carriage "
"returns in a row. We discard the input, we output a line feed, and leave the "
"state unchanged."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11513
msgid ""
"If the input is a line feed, we output the line feed and change the state to "
"<symbol>ordinary</symbol>. Note that this is not the same as the first case "
"above – if we tried to combine them, we would be outputting two line feeds "
"instead of one."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11521
msgid ""
"Finally, we are in the <symbol>lf</symbol> state after we have received a "
"line feed that was not preceded by a carriage return. This will happen when "
"our file already is in <trademark class=\"registered\">UNIX</trademark> "
"format, or whenever several lines in a row are expressed by a single "
"carriage return followed by several line feeds, or when line ends with a "
"line feed / carriage return sequence. Here is how we need to handle our "
"input in this state:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11532
msgid ""
"If the input is anything other than a carriage return or line feed, we "
"output a line feed, then output the input, then change the state to "
"<symbol>ordinary</symbol>. This is exactly the same action as in the "
"<symbol>cr</symbol> state upon receiving the same kind of input."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11541
msgid ""
"If the input is a carriage return, we discard the input, we output a line "
"feed, then change the state to <symbol>ordinary</symbol>."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:11547
msgid ""
"If the input is a line feed, we output the line feed, and leave the state "
"unchanged."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:11553
msgid "The Final State"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11555
msgid ""
"The above <emphasis>finite state machine</emphasis> works for the entire "
"file, but leaves the possibility that the final line end will be ignored. "
"That will happen whenever the file ends with a single carriage return or a "
"single line feed. I did not think of it when I wrote <application>tuc</"
"application>, just to discover that occasionally it strips the last line "
"ending."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11563
msgid ""
"This problem is easily fixed by checking the state after the entire file was "
"processed. If the state is not <symbol>ordinary</symbol>, we simply need to "
"output one last line feed."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:11569
msgid ""
"Now that we have expressed our algorithm as a <emphasis>finite state "
"machine</emphasis>, we could easily design a dedicated digital electronic "
"circuit (a \"chip\") to do the conversion for us. Of course, doing so would "
"be considerably more expensive than writing an assembly language program."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:11579
msgid "The Output Counter"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:11581
msgid ""
"Because our file conversion program may be combining two characters into "
"one, we need to use an output counter. We initialize it to <constant>0</"
"constant>, and increase it every time we send a character to the output. At "
"the end of the program, the counter will tell us what size we need to set "
"the file to."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11591
msgid "Implementing FSM in Software"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11593
msgid ""
"The hardest part of working with a <emphasis>finite state machine</emphasis> "
"is analyzing the problem and expressing it as a <emphasis>finite state "
"machine</emphasis>. That accomplished, the software almost writes itself."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11598
msgid ""
"In a high-level language, such as C, there are several main approaches. One "
"is to use a <function role=\"statement\">switch</function> statement which "
"chooses what function should be run. For example,"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11602
#, no-wrap
msgid ""
"switch (state) {\n"
"\tdefault:\n"
"\tcase REGULAR:\n"
"\t\tregular(inputchar);\n"
"\t\tbreak;\n"
"\tcase CR:\n"
"\t\tcr(inputchar);\n"
"\t\tbreak;\n"
"\tcase LF:\n"
"\t\tlf(inputchar);\n"
"\t\tbreak;\n"
"\t}"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11615
msgid ""
"Another approach is by using an array of function pointers, something like "
"this:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11618
#, no-wrap
msgid "(output[state])(inputchar);"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11620
msgid ""
"Yet another is to have <varname>state</varname> be a function pointer, set "
"to point at the appropriate function:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11624
#, no-wrap
msgid "(*state)(inputchar);"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11626
msgid ""
"This is the approach we will use in our program because it is very easy to "
"do in assembly language, and very fast, too. We will simply keep the address "
"of the right procedure in <varname role=\"register\">EBX</varname>, and then "
"just issue:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11632
#, no-wrap
msgid "call\tebx"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11634
msgid ""
"This is possibly faster than hardcoding the address in the code because the "
"microprocessor does not have to fetch the address from the memory—it is "
"already stored in one of its registers. I said <emphasis>possibly</emphasis> "
"because with the caching modern microprocessors do, either way may be "
"equally fast."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11643
msgid "Memory Mapped Files"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11645
msgid ""
"Because our program works on a single file, we cannot use the approach that "
"worked for us before, i.e., to read from an input file and to write to an "
"output file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11649
msgid ""
"<trademark class=\"registered\">UNIX</trademark> allows us to map a file, or "
"a section of a file, into memory. To do that, we first need to open the file "
"with the appropriate read/write flags. Then we use the <function role="
"\"syscall\">mmap</function> system call to map it into the memory. One nice "
"thing about <function role=\"syscall\">mmap</function> is that it "
"automatically works with virtual memory: We can map more of the file into "
"the memory than we have physical memory available, yet still access it "
"through regular memory op codes, such as <function role=\"opcode\">mov</"
"function>, <function role=\"opcode\">lods</function>, and <function role="
"\"opcode\">stos</function>. Whatever changes we make to the memory image of "
"the file will be written to the file by the system. We do not even have to "
"keep the file open: As long as it stays mapped, we can read from it and "
"write to it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11661
msgid ""
"The 32-bit Intel microprocessors can access up to four gigabytes of memory – "
"physical or virtual. The FreeBSD system allows us to use up to a half of it "
"for file mapping."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11666
msgid ""
"For simplicity sake, in this tutorial we will only convert files that can be "
"mapped into the memory in their entirety. There are probably not too many "
"text files that exceed two gigabytes in size. If our program encounters one, "
"it will simply display a message suggesting we use the original "
"<application>tuc</application> instead."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11673
msgid ""
"If you examine your copy of <filename>syscalls.master</filename>, you will "
"find two separate syscalls named <function role=\"syscall\">mmap</function>. "
"This is because of evolution of <trademark class=\"registered\">UNIX</"
"trademark>: There was the traditional <acronym>BSD</acronym> <function role="
"\"syscall\">mmap</function>, syscall 71. That one was superseded by the "
"<acronym><trademark class=\"registered\">POSIX</trademark></acronym> "
"<function role=\"syscall\">mmap</function>, syscall 197. The FreeBSD system "
"supports both because older programs were written by using the original "
"<acronym>BSD</acronym> version. But new software uses the "
"<acronym><trademark class=\"registered\">POSIX</trademark></acronym> "
"version, which is what we will use."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11685
msgid ""
"The <filename>syscalls.master</filename> lists the <acronym><trademark class="
"\"registered\">POSIX</trademark></acronym> version like this:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11688
#, no-wrap
msgid ""
"197\tSTD\tBSD\t{ caddr_t mmap(caddr_t addr, size_t len, int prot, \\\n"
"\t\t\t    int flags, int fd, long pad, off_t pos); }"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11691
msgid ""
"This differs slightly from what <citerefentry><refentrytitle>mmap</"
"refentrytitle><manvolnum>2</manvolnum></citerefentry> says. That is because "
"<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></"
"citerefentry> describes the C version."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11697
msgid ""
"The difference is in the <varname>long pad</varname> argument, which is not "
"present in the C version. However, the FreeBSD syscalls add a 32-bit pad "
"after <function role=\"opcode\">push</function>ing a 64-bit argument. In "
"this case, <varname>off_t</varname> is a 64-bit value."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11702
msgid ""
"When we are finished working with a memory-mapped file, we unmap it with the "
"<function role=\"syscall\">munmap</function> syscall:"
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:11706
msgid ""
"For an in-depth treatment of <function role=\"syscall\">mmap</function>, see "
"W. Richard Stevens' <link xlink:href=\"http://www.int80h.org/cgi-bin/isbn?"
"isbn=0130810819\">Unix Network Programming, Volume 2, Chapter 12</link>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11713
msgid "Determining File Size"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11715
msgid ""
"Because we need to tell <function role=\"syscall\">mmap</function> how many "
"bytes of the file to map into the memory, and because we want to map the "
"entire file, we need to determine the size of the file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11719
msgid ""
"We can use the <function role=\"syscall\">fstat</function> syscall to get "
"all the information about an open file that the system can give us. That "
"includes the file size."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11723
msgid ""
"Again, <filename>syscalls.master</filename> lists two versions of <function "
"role=\"syscall\">fstat</function>, a traditional one (syscall 62), and a "
"<acronym><trademark class=\"registered\">POSIX</trademark></acronym> one "
"(syscall 189). Naturally, we will use the <acronym><trademark class="
"\"registered\">POSIX</trademark></acronym> version:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11729
#, no-wrap
msgid "189\tSTD\tPOSIX\t{ int fstat(int fd, struct stat *sb); }"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11731
msgid ""
"This is a very straightforward call: We pass to it the address of a <varname "
"remap=\"structname\">stat</varname> structure and the descriptor of an open "
"file. It will fill out the contents of the <varname remap=\"structname"
"\">stat</varname> structure."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11736
msgid ""
"I do, however, have to say that I tried to declare the <varname remap="
"\"structname\">stat</varname> structure in the <varname>.bss</varname> "
"section, and <function role=\"syscall\">fstat</function> did not like it: It "
"set the carry flag indicating an error. After I changed the code to allocate "
"the structure on the stack, everything was working fine."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11745
msgid "Changing the File Size"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11747
msgid ""
"Because our program may combine carriage return / line feed sequences into "
"straight line feeds, our output may be smaller than our input. However, "
"since we are placing our output into the same file we read the input from, "
"we may have to change the size of the file."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11753
msgid ""
"The <function role=\"syscall\">ftruncate</function> system call allows us to "
"do just that. Despite its somewhat misleading name, the <function role="
"\"syscall\">ftruncate</function> system call can be used to both truncate "
"the file (make it smaller) and to grow it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11759
msgid ""
"And yes, we will find two versions of <function role=\"syscall\">ftruncate</"
"function> in <filename>syscalls.master</filename>, an older one (130), and a "
"newer one (201). We will use the newer one:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11763
#, no-wrap
msgid "201\tSTD\tBSD\t{ int ftruncate(int fd, int pad, off_t length); }"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11765
msgid "Please note that this one contains a <varname>int pad</varname> again."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:11770
msgid "ftuc"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11772
msgid ""
"We now know everything we need to write <application>ftuc</application>. We "
"start by adding some new lines in <filename>system.inc</filename>. First, we "
"define some constants and structures, somewhere at or near the beginning of "
"the file:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11778
#, no-wrap
msgid ""
";;;;;;; open flags\n"
"%define\tO_RDONLY\t0\n"
"%define\tO_WRONLY\t1\n"
"%define\tO_RDWR\t2\n"
"\n"
";;;;;;; mmap flags\n"
"%define\tPROT_NONE\t0\n"
"%define\tPROT_READ\t1\n"
"%define\tPROT_WRITE\t2\n"
"%define\tPROT_EXEC\t4\n"
";;\n"
"%define\tMAP_SHARED\t0001h\n"
"%define\tMAP_PRIVATE\t0002h\n"
"\n"
";;;;;;; stat structure\n"
"struc\tstat\n"
"st_dev\t\tresd\t1\t; = 0\n"
"st_ino\t\tresd\t1\t; = 4\n"
"st_mode\t\tresw\t1\t; = 8, size is 16 bits\n"
"st_nlink\tresw\t1\t; = 10, ditto\n"
"st_uid\t\tresd\t1\t; = 12\n"
"st_gid\t\tresd\t1\t; = 16\n"
"st_rdev\t\tresd\t1\t; = 20\n"
"st_atime\tresd\t1\t; = 24\n"
"st_atimensec\tresd\t1\t; = 28\n"
"st_mtime\tresd\t1\t; = 32\n"
"st_mtimensec\tresd\t1\t; = 36\n"
"st_ctime\tresd\t1\t; = 40\n"
"st_ctimensec\tresd\t1\t; = 44\n"
"st_size\t\tresd\t2\t; = 48, size is 64 bits\n"
"st_blocks\tresd\t2\t; = 56, ditto\n"
"st_blksize\tresd\t1\t; = 64\n"
"st_flags\tresd\t1\t; = 68\n"
"st_gen\t\tresd\t1\t; = 72\n"
"st_lspare\tresd\t1\t; = 76\n"
"st_qspare\tresd\t4\t; = 80\n"
"endstruc"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11816
msgid "We define the new syscalls:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11818
#, no-wrap
msgid ""
"%define\tSYS_mmap\t197\n"
"%define\tSYS_munmap\t73\n"
"%define\tSYS_fstat\t189\n"
"%define\tSYS_ftruncate\t201"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11823
msgid "We add the macros for their use:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11825
#, no-wrap
msgid ""
"%macro\tsys.mmap\t0\n"
"\tsystem\tSYS_mmap\n"
"%endmacro\n"
"\n"
"%macro\tsys.munmap\t0\n"
"\tsystem\tSYS_munmap\n"
"%endmacro\n"
"\n"
"%macro\tsys.ftruncate\t0\n"
"\tsystem\tSYS_ftruncate\n"
"%endmacro\n"
"\n"
"%macro\tsys.fstat\t0\n"
"\tsystem\tSYS_fstat\n"
"%endmacro"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:11841
msgid "And here is our code:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:11843
#, no-wrap
msgid ""
";;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";;\n"
";; Started:\t21-Dec-2000\n"
";; Updated:\t22-Dec-2000\n"
";;\n"
";; Copyright 2000 G. Adam Stanislav.\n"
";; All rights reserved.\n"
";;\n"
";;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
"%include\t'system.inc'\n"
"\n"
"section\t.data\n"
"\tdb\t'Copyright 2000 G. Adam Stanislav.', 0Ah\n"
"\tdb\t'All rights reserved.', 0Ah\n"
"usg\tdb\t'Usage: ftuc filename', 0Ah\n"
"usglen\tequ\t$-usg\n"
"co\tdb\t\"ftuc: Can't open file.\", 0Ah\n"
"colen\tequ\t$-co\n"
"fae\tdb\t'ftuc: File access error.', 0Ah\n"
"faelen\tequ\t$-fae\n"
"ftl\tdb\t'ftuc: File too long, use regular tuc instead.', 0Ah\n"
"ftllen\tequ\t$-ftl\n"
"mae\tdb\t'ftuc: Memory allocation error.', 0Ah\n"
"maelen\tequ\t$-mae\n"
"\n"
"section\t.text\n"
"\n"
"align 4\n"
"memerr:\n"
"\tpush\tdword maelen\n"
"\tpush\tdword mae\n"
"\tjmp\tshort error\n"
"\n"
"align 4\n"
"toolong:\n"
"\tpush\tdword ftllen\n"
"\tpush\tdword ftl\n"
"\tjmp\tshort error\n"
"\n"
"align 4\n"
"facerr:\n"
"\tpush\tdword faelen\n"
"\tpush\tdword fae\n"
"\tjmp\tshort error\n"
"\n"
"align 4\n"
"cantopen:\n"
"\tpush\tdword colen\n"
"\tpush\tdword co\n"
"\tjmp\tshort error\n"
"\n"
"align 4\n"
"usage:\n"
"\tpush\tdword usglen\n"
"\tpush\tdword usg\n"
"\n"
"error:\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\n"
"\tpush\tdword 1\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"global\t_start\n"
"_start:\n"
"\tpop\teax\t\t; argc\n"
"\tpop\teax\t\t; program name\n"
"\tpop\tecx\t\t; file to convert\n"
"\tjecxz\tusage\n"
"\n"
"\tpop\teax\n"
"\tor\teax, eax\t; Too many arguments?\n"
"\tjne\tusage\n"
"\n"
"\t; Open the file\n"
"\tpush\tdword O_RDWR\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\tcantopen\n"
"\n"
"\tmov\tebp, eax\t; Save fd\n"
"\n"
"\tsub\tesp, byte stat_size\n"
"\tmov\tebx, esp\n"
"\n"
"\t; Find file size\n"
"\tpush\tebx\n"
"\tpush\tebp\t\t; fd\n"
"\tsys.fstat\n"
"\tjc\tfacerr\n"
"\n"
"\tmov\tedx, [ebx + st_size + 4]\n"
"\n"
"\t; File is too long if EDX != 0 ...\n"
"\tor\tedx, edx\n"
"\tjne\tnear toolong\n"
"\tmov\tecx, [ebx + st_size]\n"
"\t; ... or if it is above 2 GB\n"
"\tor\tecx, ecx\n"
"\tjs\tnear toolong\n"
"\n"
"\t; Do nothing if the file is 0 bytes in size\n"
"\tjecxz\t.quit\n"
"\n"
"\t; Map the entire file in memory\n"
"\tpush\tedx\n"
"\tpush\tedx\t\t; starting at offset 0\n"
"\tpush\tedx\t\t; pad\n"
"\tpush\tebp\t\t; fd\n"
"\tpush\tdword MAP_SHARED\n"
"\tpush\tdword PROT_READ | PROT_WRITE\n"
"\tpush\tecx\t\t; entire file size\n"
"\tpush\tedx\t\t; let system decide on the address\n"
"\tsys.mmap\n"
"\tjc\tnear memerr\n"
"\n"
"\tmov\tedi, eax\n"
"\tmov\tesi, eax\n"
"\tpush\tecx\t\t; for SYS_munmap\n"
"\tpush\tedi\n"
"\n"
"\t; Use EBX for state machine\n"
"\tmov\tebx, ordinary\n"
"\tmov\tah, 0Ah\n"
"\tcld\n"
"\n"
".loop:\n"
"\tlodsb\n"
"\tcall\tebx\n"
"\tloop\t.loop\n"
"\n"
"\tcmp\tebx, ordinary\n"
"\tje\t.filesize\n"
"\n"
"\t; Output final lf\n"
"\tmov\tal, ah\n"
"\tstosb\n"
"\tinc\tedx\n"
"\n"
".filesize:\n"
"\t; truncate file to new size\n"
"\tpush\tdword 0\t\t; high dword\n"
"\tpush\tedx\t\t; low dword\n"
"\tpush\teax\t\t; pad\n"
"\tpush\tebp\n"
"\tsys.ftruncate\n"
"\n"
"\t; close it (ebp still pushed)\n"
"\tsys.close\n"
"\n"
"\tadd\tesp, byte 16\n"
"\tsys.munmap\n"
"\n"
".quit:\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"ordinary:\n"
"\tcmp\tal, 0Dh\n"
"\tje\t.cr\n"
"\n"
"\tcmp\tal, ah\n"
"\tje\t.lf\n"
"\n"
"\tstosb\n"
"\tinc\tedx\n"
"\tret\n"
"\n"
"align 4\n"
".cr:\n"
"\tmov\tebx, cr\n"
"\tret\n"
"\n"
"align 4\n"
".lf:\n"
"\tmov\tebx, lf\n"
"\tret\n"
"\n"
"align 4\n"
"cr:\n"
"\tcmp\tal, 0Dh\n"
"\tje\t.cr\n"
"\n"
"\tcmp\tal, ah\n"
"\tje\t.lf\n"
"\n"
"\txchg\tal, ah\n"
"\tstosb\n"
"\tinc\tedx\n"
"\n"
"\txchg\tal, ah\n"
"\t; fall through\n"
"\n"
".lf:\n"
"\tstosb\n"
"\tinc\tedx\n"
"\tmov\tebx, ordinary\n"
"\tret\n"
"\n"
"align 4\n"
".cr:\n"
"\tmov\tal, ah\n"
"\tstosb\n"
"\tinc\tedx\n"
"\tret\n"
"\n"
"align 4\n"
"lf:\n"
"\tcmp\tal, ah\n"
"\tje\t.lf\n"
"\n"
"\tcmp\tal, 0Dh\n"
"\tje\t.cr\n"
"\n"
"\txchg\tal, ah\n"
"\tstosb\n"
"\tinc\tedx\n"
"\n"
"\txchg\tal, ah\n"
"\tstosb\n"
"\tinc\tedx\n"
"\tmov\tebx, ordinary\n"
"\tret\n"
"\n"
"align 4\n"
".cr:\n"
"\tmov\tebx, ordinary\n"
"\tmov\tal, ah\n"
"\t; fall through\n"
"\n"
".lf:\n"
"\tstosb\n"
"\tinc\tedx\n"
"\tret"
msgstr ""

#. (itstool) path: warning/para
#: book.translate.xml:12081
msgid ""
"Do not use this program on files stored on a disk formatted by "
"<acronym><trademark class=\"registered\">MS-DOS</trademark></acronym> or "
"<trademark class=\"registered\">Windows</trademark>. There seems to be a "
"subtle bug in the FreeBSD code when using <function role=\"syscall\">mmap</"
"function> on these drives mounted under FreeBSD: If the file is over a "
"certain size, <function role=\"syscall\">mmap</function> will just fill the "
"memory with zeros, and then copy them to the file overwriting its contents."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:12094
msgid "One-Pointed Mind"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12096
msgid ""
"As a student of Zen, I like the idea of a one-pointed mind: Do one thing at "
"a time, and do it well."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12099
msgid ""
"This, indeed, is very much how <trademark class=\"registered\">UNIX</"
"trademark> works as well. While a typical <trademark class=\"registered"
"\">Windows</trademark> application is attempting to do everything imaginable "
"(and is, therefore, riddled with bugs), a typical <trademark class="
"\"registered\">UNIX</trademark> program does only one thing, and it does it "
"well."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12104
msgid ""
"The typical <trademark class=\"registered\">UNIX</trademark> user then "
"essentially assembles his own applications by writing a shell script which "
"combines the various existing programs by piping the output of one program "
"to the input of another."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12109
msgid ""
"When writing your own <trademark class=\"registered\">UNIX</trademark> "
"software, it is generally a good idea to see what parts of the problem you "
"need to solve can be handled by existing programs, and only write your own "
"programs for that part of the problem that you do not have an existing "
"solution for."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:12116
msgid "CSV"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12118
msgid ""
"I will illustrate this principle with a specific real-life example I was "
"faced with recently:"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12121
msgid ""
"I needed to extract the 11th field of each record from a database I "
"downloaded from a web site. The database was a <acronym>CSV</acronym> file, "
"i.e., a list of <emphasis>comma-separated values</emphasis>. That is quite a "
"standard format for sharing data among people who may be using different "
"database software."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12128
msgid ""
"The first line of the file contains the list of various fields separated by "
"commas. The rest of the file contains the data listed line by line, with "
"values separated by commas."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12133
msgid ""
"I tried <application>awk</application>, using the comma as a separator. But "
"because several lines contained a quoted comma, <application>awk</"
"application> was extracting the wrong field from those lines."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12138
msgid ""
"Therefore, I needed to write my own software to extract the 11th field from "
"the <acronym>CSV</acronym> file. However, going with the <trademark class="
"\"registered\">UNIX</trademark> spirit, I only needed to write a simple "
"filter that would do the following:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12145
msgid "Remove the first line from the file;"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12149
msgid "Change all unquoted commas to a different character;"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12154
msgid "Remove all quotation marks."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12158
msgid ""
"Strictly speaking, I could use <application>sed</application> to remove the "
"first line from the file, but doing so in my own program was very easy, so I "
"decided to do it and reduce the size of the pipeline."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12163
msgid ""
"At any rate, writing a program like this took me about 20 minutes. Writing a "
"program that extracts the 11th field from the <acronym>CSV</acronym> file "
"would take a lot longer, and I could not reuse it to extract some other "
"field from some other database."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12169
msgid ""
"This time I decided to let it do a little more work than a typical tutorial "
"program would:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12174
msgid "It parses its command line for options;"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12178
msgid "It displays proper usage if it finds wrong arguments;"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:12183
msgid "It produces meaningful error messages."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12187
msgid "Here is its usage message:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:12189
#, no-wrap
msgid "Usage: csv [-t&lt;delim&gt;] [-c&lt;comma&gt;] [-p] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12191
msgid "All parameters are optional, and can appear in any order."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12194
msgid ""
"The <parameter>-t</parameter> parameter declares what to replace the commas "
"with. The <constant>tab</constant> is the default here. For example, "
"<parameter>-t;</parameter> will replace all unquoted commas with semicolons."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12199
msgid ""
"I did not need the <parameter>-c</parameter> option, but it may come in "
"handy in the future. It lets me declare that I want a character other than a "
"comma replaced with something else. For example, <parameter>-c@</parameter> "
"will replace all at signs (useful if you want to split a list of email "
"addresses to their user names and domains)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12206
msgid ""
"The <parameter>-p</parameter> option preserves the first line, i.e., it does "
"not delete it. By default, we delete the first line because in a "
"<acronym>CSV</acronym> file it contains the field names rather than data."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12211
msgid ""
"The <parameter>-i</parameter> and <parameter>-o</parameter> options let me "
"specify the input and the output files. Defaults are <filename>stdin</"
"filename> and <filename>stdout</filename>, so this is a regular <trademark "
"class=\"registered\">UNIX</trademark> filter."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12217
msgid ""
"I made sure that both <parameter>-i filename</parameter> and <parameter>-"
"ifilename</parameter> are accepted. I also made sure that only one input and "
"one output files may be specified."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12222
msgid "To get the 11th field of each record, I can now do:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:12224
#, no-wrap
msgid "<prompt>%</prompt> <userinput>csv '-t;' <replaceable>data.csv</replaceable> | awk '-F;' '{print $11}'</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12226
msgid ""
"The code stores the options (except for the file descriptors) in <varname "
"role=\"register\">EDX</varname>: The comma in <varname role=\"register\">DH</"
"varname>, the new separator in <varname role=\"register\">DL</varname>, and "
"the flag for the <parameter>-p</parameter> option in the highest bit of "
"<varname role=\"register\">EDX</varname>, so a check for its sign will give "
"us a quick decision what to do."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12234
msgid "Here is the code:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:12236
#, no-wrap
msgid ""
";;;;;;; csv.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";\n"
"; Convert a comma-separated file to a something-else separated file.\n"
";\n"
"; Started:\t31-May-2001\n"
"; Updated:\t 1-Jun-2001\n"
";\n"
"; Copyright (c) 2001 G. Adam Stanislav\n"
"; All rights reserved.\n"
";\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
"\n"
"%include\t'system.inc'\n"
"\n"
"%define\tBUFSIZE\t2048\n"
"\n"
"section\t.data\n"
"fd.in\tdd\tstdin\n"
"fd.out\tdd\tstdout\n"
"usg\tdb\t'Usage: csv [-t&lt;delim&gt;] [-c&lt;comma&gt;] [-p] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]', 0Ah\n"
"usglen\tequ\t$-usg\n"
"iemsg\tdb\t\"csv: Can't open input file\", 0Ah\n"
"iemlen\tequ\t$-iemsg\n"
"oemsg\tdb\t\"csv: Can't create output file\", 0Ah\n"
"oemlen\tequ\t$-oemsg\n"
"\n"
"section .bss\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE\n"
"\n"
"section\t.text\n"
"align 4\n"
"ierr:\n"
"\tpush\tdword iemlen\n"
"\tpush\tdword iemsg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 1\t\t; return failure\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"oerr:\n"
"\tpush\tdword oemlen\n"
"\tpush\tdword oemsg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 2\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"usage:\n"
"\tpush\tdword usglen\n"
"\tpush\tdword usg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 3\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"global\t_start\n"
"_start:\n"
"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
"\tmov\tedx, (',' &lt;&lt; 8) | 9\n"
"\n"
".arg:\n"
"\tpop\tecx\n"
"\tor\tecx, ecx\n"
"\tje\tnear .init\t\t; no more arguments\n"
"\n"
"\t; ECX contains the pointer to an argument\n"
"\tcmp\tbyte [ecx], '-'\n"
"\tjne\tusage\n"
"\n"
"\tinc\tecx\n"
"\tmov\tax, [ecx]\n"
"\n"
".o:\n"
"\tcmp\tal, 'o'\n"
"\tjne\t.i\n"
"\n"
"\t; Make sure we are not asked for the output file twice\n"
"\tcmp\tdword [fd.out], stdout\n"
"\tjne\tusage\n"
"\n"
"\t; Find the path to output file - it is either at [ECX+1],\n"
"\t; i.e., -ofile --\n"
"\t; or in the next argument,\n"
"\t; i.e., -o file\n"
"\n"
"\tinc\tecx\n"
"\tor\tah, ah\n"
"\tjne\t.openoutput\n"
"\tpop\tecx\n"
"\tjecxz\tusage\n"
"\n"
".openoutput:\n"
"\tpush\tdword 420\t; file mode (644 octal)\n"
"\tpush\tdword 0200h | 0400h | 01h\n"
"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\tnear oerr\n"
"\n"
"\tadd\tesp, byte 12\n"
"\tmov\t[fd.out], eax\n"
"\tjmp\tshort .arg\n"
"\n"
".i:\n"
"\tcmp\tal, 'i'\n"
"\tjne\t.p\n"
"\n"
"\t; Make sure we are not asked twice\n"
"\tcmp\tdword [fd.in], stdin\n"
"\tjne\tnear usage\n"
"\n"
"\t; Find the path to the input file\n"
"\tinc\tecx\n"
"\tor\tah, ah\n"
"\tjne\t.openinput\n"
"\tpop\tecx\n"
"\tor\tecx, ecx\n"
"\tje near usage\n"
"\n"
".openinput:\n"
"\tpush\tdword 0\t\t; O_RDONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\tnear ierr\t\t; open failed\n"
"\n"
"\tadd\tesp, byte 8\n"
"\tmov\t[fd.in], eax\n"
"\tjmp\t.arg\n"
"\n"
".p:\n"
"\tcmp\tal, 'p'\n"
"\tjne\t.t\n"
"\tor\tah, ah\n"
"\tjne\tnear usage\n"
"\tor\tedx, 1 &lt;&lt; 31\n"
"\tjmp\t.arg\n"
"\n"
".t:\n"
"\tcmp\tal, 't'\t\t; redefine output delimiter\n"
"\tjne\t.c\n"
"\tor\tah, ah\n"
"\tje\tnear usage\n"
"\tmov\tdl, ah\n"
"\tjmp\t.arg\n"
"\n"
".c:\n"
"\tcmp\tal, 'c'\n"
"\tjne\tnear usage\n"
"\tor\tah, ah\n"
"\tje\tnear usage\n"
"\tmov\tdh, ah\n"
"\tjmp\t.arg\n"
"\n"
"align 4\n"
".init:\n"
"\tsub\teax, eax\n"
"\tsub\tebx, ebx\n"
"\tsub\tecx, ecx\n"
"\tmov\tedi, obuffer\n"
"\n"
"\t; See if we are to preserve the first line\n"
"\tor\tedx, edx\n"
"\tjs\t.loop\n"
"\n"
".firstline:\n"
"\t; get rid of the first line\n"
"\tcall\tgetchar\n"
"\tcmp\tal, 0Ah\n"
"\tjne\t.firstline\n"
"\n"
".loop:\n"
"\t; read a byte from stdin\n"
"\tcall\tgetchar\n"
"\n"
"\t; is it a comma (or whatever the user asked for)?\n"
"\tcmp\tal, dh\n"
"\tjne\t.quote\n"
"\n"
"\t; Replace the comma with a tab (or whatever the user wants)\n"
"\tmov\tal, dl\n"
"\n"
".put:\n"
"\tcall\tputchar\n"
"\tjmp\tshort .loop\n"
"\n"
".quote:\n"
"\tcmp\tal, '\"'\n"
"\tjne\t.put\n"
"\n"
"\t; Print everything until you get another quote or EOL. If it\n"
"\t; is a quote, skip it. If it is EOL, print it.\n"
".qloop:\n"
"\tcall\tgetchar\n"
"\tcmp\tal, '\"'\n"
"\tje\t.loop\n"
"\n"
"\tcmp\tal, 0Ah\n"
"\tje\t.put\n"
"\n"
"\tcall\tputchar\n"
"\tjmp\tshort .qloop\n"
"\n"
"align 4\n"
"getchar:\n"
"\tor\tebx, ebx\n"
"\tjne\t.fetch\n"
"\n"
"\tcall\tread\n"
"\n"
".fetch:\n"
"\tlodsb\n"
"\tdec\tebx\n"
"\tret\n"
"\n"
"read:\n"
"\tjecxz\t.read\n"
"\tcall\twrite\n"
"\n"
".read:\n"
"\tpush\tdword BUFSIZE\n"
"\tmov\tesi, ibuffer\n"
"\tpush\tesi\n"
"\tpush\tdword [fd.in]\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tmov\tebx, eax\n"
"\tor\teax, eax\n"
"\tje\t.done\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
".done:\n"
"\tcall\twrite\t\t; flush output buffer\n"
"\n"
"\t; close files\n"
"\tpush\tdword [fd.in]\n"
"\tsys.close\n"
"\n"
"\tpush\tdword [fd.out]\n"
"\tsys.close\n"
"\n"
"\t; return success\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"putchar:\n"
"\tstosb\n"
"\tinc\tecx\n"
"\tcmp\tecx, BUFSIZE\n"
"\tje\twrite\n"
"\tret\n"
"\n"
"align 4\n"
"write:\n"
"\tjecxz\t.ret\t; nothing to write\n"
"\tsub\tedi, ecx\t; start of buffer\n"
"\tpush\tecx\n"
"\tpush\tedi\n"
"\tpush\tdword [fd.out]\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tsub\teax, eax\n"
"\tsub\tecx, ecx\t; buffer is empty now\n"
".ret:\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12508
msgid ""
"Much of it is taken from <filename>hex.asm</filename> above. But there is "
"one important difference: I no longer call <function>write</function> "
"whenever I am outputting a line feed. Yet, the code can be used "
"interactively."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12513
msgid ""
"I have found a better solution for the interactive problem since I first "
"started writing this chapter. I wanted to make sure each line is printed out "
"separately only when needed. After all, there is no need to flush out every "
"line when used non-interactively."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12519
msgid ""
"The new solution I use now is to call <function>write</function> every time "
"I find the input buffer empty. That way, when running in the interactive "
"mode, the program reads one line from the user's keyboard, processes it, and "
"sees its input buffer is empty. It flushes its output and reads the next "
"line."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12527
msgid "The Dark Side of Buffering"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12529
msgid ""
"This change prevents a mysterious lockup in a very specific case. I refer to "
"it as the <emphasis>dark side of buffering</emphasis>, mostly because it "
"presents a danger that is not quite obvious."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12534
msgid ""
"It is unlikely to happen with a program like the <application>csv</"
"application> above, so let us consider yet another filter: In this case we "
"expect our input to be raw data representing color values, such as the "
"<emphasis>red</emphasis>, <emphasis>green</emphasis>, and <emphasis>blue</"
"emphasis> intensities of a pixel. Our output will be the negative of our "
"input."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12542
msgid ""
"Such a filter would be very simple to write. Most of it would look just like "
"all the other filters we have written so far, so I am only going to show you "
"its inner loop:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12547
#, no-wrap
msgid ""
".loop:\n"
"\tcall\tgetchar\n"
"\tnot\tal\t\t; Create a negative\n"
"\tcall\tputchar\n"
"\tjmp\tshort .loop"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12553
msgid ""
"Because this filter works with raw data, it is unlikely to be used "
"interactively."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12556
msgid ""
"But it could be called by image manipulation software. And, unless it calls "
"<function>write</function> before each call to <function>read</function>, "
"chances are it will lock up."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12561
msgid "Here is what might happen:"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12565
msgid ""
"The image editor will load our filter using the C function "
"<function>popen()</function>."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12570
msgid "It will read the first row of pixels from a bitmap or pixmap."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12575
msgid ""
"It will write the first row of pixels to the <emphasis>pipe</emphasis> "
"leading to the <varname>fd.in</varname> of our filter."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12581
msgid ""
"Our filter will read each pixel from its input, turn it to a negative, and "
"write it to its output buffer."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12587
msgid ""
"Our filter will call <function>getchar</function> to fetch the next pixel."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12592
msgid ""
"<function>getchar</function> will find an empty input buffer, so it will "
"call <function>read</function>."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12598
msgid ""
"<function>read</function> will call the <function role=\"syscall\">SYS_read</"
"function> system call."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12603
msgid ""
"The <emphasis>kernel</emphasis> will suspend our filter until the image "
"editor sends more data to the pipe."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12609
msgid ""
"The image editor will read from the other pipe, connected to the <varname>fd."
"out</varname> of our filter so it can set the first row of the output image "
"<emphasis>before</emphasis> it sends us the second row of the input."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:12617
msgid ""
"The <emphasis>kernel</emphasis> suspends the image editor until it receives "
"some output from our filter, so it can pass it on to the image editor."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12623
msgid ""
"At this point our filter waits for the image editor to send it more data to "
"process, while the image editor is waiting for our filter to send it the "
"result of the processing of the first row. But the result sits in our output "
"buffer."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12629
msgid ""
"The filter and the image editor will continue waiting for each other forever "
"(or, at least, until they are killed). Our software has just entered a <link "
"linkend=\"secure-race-conditions\">race condition</link>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12634
msgid ""
"This problem does not exist if our filter flushes its output buffer "
"<emphasis>before</emphasis> asking the <emphasis>kernel</emphasis> for more "
"input data."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:12642
msgid "Using the <acronym>FPU</acronym>"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12644
msgid ""
"Strangely enough, most of assembly language literature does not even mention "
"the existence of the <acronym>FPU</acronym>, or <emphasis>floating point "
"unit</emphasis>, let alone discuss programming it."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:12649
msgid ""
"Yet, never does assembly language shine more than when we create highly "
"optimized <acronym>FPU</acronym> code by doing things that can be done "
"<emphasis>only</emphasis> in assembly language."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:12655
msgid "Organization of the <acronym>FPU</acronym>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12657
msgid ""
"The <acronym>FPU</acronym> consists of 8 80–bit floating–point registers. "
"These are organized in a stack fashion—you can <function>push</function> a "
"value on <acronym>TOS</acronym> (<emphasis>top of stack</emphasis>) and you "
"can <function>pop</function> it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12664
msgid ""
"That said, the assembly language op codes are not <function role=\"opcode"
"\">push</function> and <function role=\"opcode\">pop</function> because "
"those are already taken."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12668
msgid ""
"You can <function>push</function> a value on <acronym>TOS</acronym> by using "
"<function role=\"opcode\">fld</function>, <function role=\"opcode\">fild</"
"function>, and <function role=\"opcode\">fbld</function>. Several other op "
"codes let you <function>push</function> many common <emphasis>constants</"
"emphasis>—such as <emphasis>pi</emphasis>—on the <acronym>TOS</acronym>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12675
msgid ""
"Similarly, you can <function>pop</function> a value by using <function role="
"\"opcode\">fst</function>, <function role=\"opcode\">fstp</function>, "
"<function role=\"opcode\">fist</function>, <function role=\"opcode\">fistp</"
"function>, and <function role=\"opcode\">fbstp</function>. Actually, only "
"the op codes that end with a <emphasis>p</emphasis> will literally "
"<function>pop</function> the value, the rest will <function>store</function> "
"it somewhere else without removing it from the <acronym>TOS</acronym>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12682
msgid ""
"We can transfer the data between the <acronym>TOS</acronym> and the computer "
"memory either as a 32–bit, 64–bit, or 80–bit <emphasis>real</emphasis>, a 16–"
"bit, 32–bit, or 64–bit <emphasis>integer</emphasis>, or an 80–bit "
"<emphasis>packed decimal</emphasis>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12689
msgid ""
"The 80–bit <emphasis>packed decimal</emphasis> is a special case of "
"<emphasis>binary coded decimal</emphasis> which is very convenient when "
"converting between the <acronym>ASCII</acronym> representation of data and "
"the internal data of the <acronym>FPU</acronym>. It allows us to use 18 "
"significant digits."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12696
msgid ""
"No matter how we represent data in the memory, the <acronym>FPU</acronym> "
"always stores it in the 80–bit <emphasis>real</emphasis> format in its "
"registers."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12700
msgid ""
"Its internal precision is at least 19 decimal digits, so even if we choose "
"to display results as <acronym>ASCII</acronym> in the full 18–digit "
"precision, we are still showing correct results."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12705
msgid ""
"We can perform mathematical operations on the <acronym>TOS</acronym>: We can "
"calculate its <emphasis>sine</emphasis>, we can <emphasis>scale</emphasis> "
"it (i.e., we can multiply or divide it by a power of 2), we can calculate "
"its base–2 <emphasis>logarithm</emphasis>, and many other things."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12713
msgid ""
"We can also <emphasis>multiply</emphasis> or <emphasis>divide</emphasis> it "
"by, <emphasis>add</emphasis> it to, or <emphasis>subtract</emphasis> it "
"from, any of the <acronym>FPU</acronym> registers (including itself)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12718
msgid ""
"The official Intel op code for the <acronym>TOS</acronym> is <varname role="
"\"register\">st</varname>, and for the <emphasis>registers</emphasis> "
"<varname role=\"register\">st(0)</varname>–<varname role=\"register\">st(7)</"
"varname>. <varname role=\"register\">st</varname> and <varname role="
"\"register\">st(0)</varname>, then, refer to the same register."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12723
msgid ""
"For whatever reasons, the original author of <application>nasm</application> "
"has decided to use different op codes, namely <varname role=\"register"
"\">st0</varname>–<varname role=\"register\">st7</varname>. In other words, "
"there are no parentheses, and the <acronym>TOS</acronym> is always <varname "
"role=\"register\">st0</varname>, never just <function role=\"opcode\">st</"
"function>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12731
msgid "The Packed Decimal Format"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12733
msgid ""
"The <emphasis>packed decimal</emphasis> format uses 10 bytes (80 bits) of "
"memory to represent 18 digits. The number represented there is always an "
"<emphasis>integer</emphasis>."
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:12739
msgid ""
"You can use it to get decimal places by multiplying the <acronym>TOS</"
"acronym> by a power of 10 first."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12744
msgid ""
"The highest bit of the highest byte (byte 9) is the <emphasis>sign bit</"
"emphasis>: If it is set, the number is <emphasis>negative</emphasis>, "
"otherwise, it is <emphasis>positive</emphasis>. The rest of the bits of this "
"byte are unused/ignored."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12750
msgid ""
"The remaining 9 bytes store the 18 digits of the number: 2 digits per byte."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12753
msgid ""
"The <emphasis>more significant digit</emphasis> is stored in the high "
"<emphasis>nibble</emphasis> (4 bits), the <emphasis>less significant digit</"
"emphasis> in the low <emphasis>nibble</emphasis>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12758
msgid ""
"That said, you might think that <constant>-1234567</constant> would be "
"stored in the memory like this (using hexadecimal notation):"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12762
#, no-wrap
msgid "80 00 00 00 00 00 01 23 45 67"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12764
msgid ""
"Alas it is not! As with everything else of Intel make, even the "
"<emphasis>packed decimal</emphasis> is <emphasis>little–endian</emphasis>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12768
msgid "That means our <constant>-1234567</constant> is stored like this:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12771
#, no-wrap
msgid "67 45 23 01 00 00 00 00 00 80"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12773
msgid "Remember that, or you will be pulling your hair out in desperation!"
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:12777
msgid ""
"The book to read—if you can find it—is Richard Startz' <link xlink:href="
"\"http://www.amazon.com/exec/obidos/ASIN/013246604X/whizkidtechnomag"
"\">8087/80287/80387 for the IBM PC &amp; Compatibles</link>. Though it does "
"seem to take the fact about the little–endian storage of the "
"<emphasis>packed decimal</emphasis> for granted. I kid you not about the "
"desperation of trying to figure out what was wrong with the filter I show "
"below <emphasis>before</emphasis> it occurred to me I should try the little–"
"endian order even for this type of data."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:12792
msgid "Excursion to Pinhole Photography"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12794
msgid ""
"To write meaningful software, we must not only understand our programming "
"tools, but also the field we are creating software for."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12798
msgid ""
"Our next filter will help us whenever we want to build a <emphasis>pinhole "
"camera</emphasis>, so, we need some background in <emphasis>pinhole "
"photography</emphasis> before we can continue."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12804
msgid "The Camera"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12806
msgid ""
"The easiest way to describe any camera ever built is as some empty space "
"enclosed in some lightproof material, with a small hole in the enclosure."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12810
msgid ""
"The enclosure is usually sturdy (e.g., a box), though sometimes it is "
"flexible (the bellows). It is quite dark inside the camera. However, the "
"hole lets light rays in through a single point (though in some cases there "
"may be several). These light rays form an image, a representation of "
"whatever is outside the camera, in front of the hole."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12818
msgid ""
"If some light sensitive material (such as film) is placed inside the camera, "
"it can capture the image."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12821
msgid ""
"The hole often contains a <emphasis>lens</emphasis>, or a lens assembly, "
"often called the <emphasis>objective</emphasis>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12827
msgid "The Pinhole"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12829
msgid ""
"But, strictly speaking, the lens is not necessary: The original cameras did "
"not use a lens but a <emphasis>pinhole</emphasis>. Even today, "
"<emphasis>pinholes</emphasis> are used, both as a tool to study how cameras "
"work, and to achieve a special kind of image."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12836
msgid ""
"The image produced by the <emphasis>pinhole</emphasis> is all equally sharp. "
"Or <emphasis>blurred</emphasis>. There is an ideal size for a pinhole: If it "
"is either larger or smaller, the image loses its sharpness."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12843
msgid "Focal Length"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12845
msgid ""
"This ideal pinhole diameter is a function of the square root of "
"<emphasis>focal length</emphasis>, which is the distance of the pinhole from "
"the film."
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12849
#, no-wrap
msgid "D = PC * sqrt(FL)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12851
msgid ""
"In here, <varname>D</varname> is the ideal diameter of the pinhole, "
"<varname>FL</varname> is the focal length, and <constant>PC</constant> is a "
"pinhole constant. According to Jay Bender, its value is <constant>0.04</"
"constant>, while Kenneth Connors has determined it to be <constant>0.037</"
"constant>. Others have proposed other values. Plus, this value is for the "
"daylight only: Other types of light will require a different constant, whose "
"value can only be determined by experimentation."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12864
msgid "The F–Number"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12866
msgid ""
"The f–number is a very useful measure of how much light reaches the film. A "
"light meter can determine that, for example, to expose a film of specific "
"sensitivity with f5.6 mkay require the exposure to last 1/1000 sec."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12872
msgid ""
"It does not matter whether it is a 35–mm camera, or a 6x9cm camera, etc. As "
"long as we know the f–number, we can determine the proper exposure."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12877
msgid "The f–number is easy to calculate:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12879
#, no-wrap
msgid "F = FL / D"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12881
msgid ""
"In other words, the f–number equals the focal length divided by the diameter "
"of the pinhole. It also means a higher f–number either implies a smaller "
"pinhole or a larger focal distance, or both. That, in turn, implies, the "
"higher the f–number, the longer the exposure has to be."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12888
msgid ""
"Furthermore, while pinhole diameter and focal distance are one–dimensional "
"measurements, both, the film and the pinhole, are two–dimensional. That "
"means that if you have measured the exposure at f–number <varname>A</"
"varname> as <varname>t</varname>, then the exposure at f–number <varname>B</"
"varname> is:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:12895
#, no-wrap
msgid "t * (B / A)²"
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12899
msgid "Normalized F–Number"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12901
msgid ""
"While many modern cameras can change the diameter of their pinhole, and thus "
"their f–number, quite smoothly and gradually, such was not always the case."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12906
msgid ""
"To allow for different f–numbers, cameras typically contained a metal plate "
"with several holes of different sizes drilled to them."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12910
msgid ""
"Their sizes were chosen according to the above formula in such a way that "
"the resultant f–number was one of standard f–numbers used on all cameras "
"everywhere. For example, a very old Kodak Duaflex IV camera in my possession "
"has three such holes for f–numbers 8, 11, and 16."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12917
msgid ""
"A more recently made camera may offer f–numbers of 2.8, 4, 5.6, 8, 11, 16, "
"22, and 32 (as well as others). These numbers were not chosen arbitrarily: "
"They all are powers of the square root of 2, though they may be rounded "
"somewha."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12925
msgid "The F–Stop"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12927
msgid ""
"A typical camera is designed in such a way that setting any of the "
"normalized f–numbers changes the feel of the dial. It will naturally "
"<emphasis>stop</emphasis> in that position. Because of that, these positions "
"of the dial are called f–stops."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12934
msgid ""
"Since the f–numbers at each stop are powers of the square root of 2, moving "
"the dial by 1 stop will double the amount of light required for proper "
"exposure. Moving it by 2 stops will quadruple the required exposure. Moving "
"the dial by 3 stops will require the increase in exposure 8 times, etc."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:12944
msgid "Designing the Pinhole Software"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:12946
msgid ""
"We are now ready to decide what exactly we want our pinhole software to do."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:12950
msgid "Processing Program Input"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12952
msgid ""
"Since its main purpose is to help us design a working pinhole camera, we "
"will use the <emphasis>focal length</emphasis> as the input to the program. "
"This is something we can determine without software: Proper focal length is "
"determined by the size of the film and by the need to shoot \"regular\" "
"pictures, wide angle pictures, or telephoto pictures."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12960
msgid ""
"Most of the programs we have written so far worked with individual "
"characters, or bytes, as their input: The <application>hex</application> "
"program converted individual bytes into a hexadecimal number, the "
"<application>csv</application> program either let a character through, or "
"deleted it, or changed it to a different character, etc."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12968
msgid ""
"One program, <application>ftuc</application> used the state machine to "
"consider at most two input bytes at a time."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12972
msgid ""
"But our <application>pinhole</application> program cannot just work with "
"individual characters, it has to deal with larger syntactic units."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12976
msgid ""
"For example, if we want the program to calculate the pinhole diameter (and "
"other values we will discuss later) at the focal lengths of <constant>100 "
"mm</constant>, <constant>150 mm</constant>, and <constant>210 mm</constant>, "
"we may want to enter something like this:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:12983
#, no-wrap
msgid "<userinput>100, 150, 210</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12985
msgid ""
"Our program needs to consider more than a single byte of input at a time. "
"When it sees the first <constant>1</constant>, it must understand it is "
"seeing the first digit of a decimal number. When it sees the <constant>0</"
"constant> and the other <constant>0</constant>, it must know it is seeing "
"more digits of the same number."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:12993
msgid ""
"When it encounters the first comma, it must know it is no longer receiving "
"the digits of the first number. It must be able to convert the digits of the "
"first number into the value of <constant>100</constant>. And the digits of "
"the second number into the value of <constant>150</constant>. And, of "
"course, the digits of the third number into the numeric value of "
"<constant>210</constant>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13002
msgid ""
"We need to decide what delimiters to accept: Do the input numbers have to be "
"separated by a comma? If so, how do we treat two numbers separated by "
"something else?"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13007
msgid ""
"Personally, I like to keep it simple. Something either is a number, so I "
"process it. Or it is not a number, so I discard it. I do not like the "
"computer complaining about me typing in an extra character when it is "
"<emphasis>obvious</emphasis> that it is an extra character. Duh!"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13014
msgid ""
"Plus, it allows me to break up the monotony of computing and type in a query "
"instead of just a number:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13018
#, no-wrap
msgid ""
"<userinput>What is the best pinhole diameter for the\n"
"\t    focal length of 150?</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13021
msgid "There is no reason for the computer to spit out a number of complaints:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13024
#, no-wrap
msgid ""
"Syntax error: What\n"
"Syntax error: is\n"
"Syntax error: the\n"
"Syntax error: best"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13029
msgid "Et cetera, et cetera, et cetera."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13031
msgid ""
"Secondly, I like the <constant>#</constant> character to denote the start of "
"a comment which extends to the end of the line. This does not take too much "
"effort to code, and lets me treat input files for my software as executable "
"scripts."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13037
msgid ""
"In our case, we also need to decide what units the input should come in: We "
"choose <emphasis>millimeters</emphasis> because that is how most "
"photographers measure the focus length."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13042
msgid ""
"Finally, we need to decide whether to allow the use of the decimal point (in "
"which case we must also consider the fact that much of the world uses a "
"decimal <emphasis>comma</emphasis>)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13047
msgid ""
"In our case allowing for the decimal point/comma would offer a false sense "
"of precision: There is little if any noticeable difference between the focus "
"lengths of <constant>50</constant> and <constant>51</constant>, so allowing "
"the user to input something like <constant>50.5</constant> is not a good "
"idea. This is my opinion, mind you, but I am the one writing this program. "
"You can make other choices in yours, of course."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:13059
msgid "Offering Options"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13061
msgid ""
"The most important thing we need to know when building a pinhole camera is "
"the diameter of the pinhole. Since we want to shoot sharp images, we will "
"use the above formula to calculate the pinhole diameter from focal length. "
"As experts are offering several different values for the <constant>PC</"
"constant> constant, we will need to have the choice."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13069
msgid ""
"It is traditional in <trademark class=\"registered\">UNIX</trademark> "
"programming to have two main ways of choosing program parameters, plus to "
"have a default for the time the user does not make a choice."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13074
msgid "Why have two ways of choosing?"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13076
msgid ""
"One is to allow a (relatively) <emphasis>permanent</emphasis> choice that "
"applies automatically each time the software is run without us having to "
"tell it over and over what we want it to do."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13082
msgid ""
"The permanent choices may be stored in a configuration file, typically found "
"in the user's home directory. The file usually has the same name as the "
"application but is started with a dot. Often <emphasis>\"rc\"</emphasis> is "
"added to the file name. So, ours could be <filename>~/.pinhole</filename> or "
"<filename>~/.pinholerc</filename>. (The <filename>~/</filename> means "
"current user's home directory.)"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13092
msgid ""
"The configuration file is used mostly by programs that have many "
"configurable parameters. Those that have only one (or a few) often use a "
"different method: They expect to find the parameter in an "
"<emphasis>environment variable</emphasis>. In our case, we might look at an "
"environment variable named <varname>PINHOLE</varname>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13100
msgid ""
"Usually, a program uses one or the other of the above methods. Otherwise, if "
"a configuration file said one thing, but an environment variable another, "
"the program might get confused (or just too complicated)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13105
msgid ""
"Because we only need to choose <emphasis>one</emphasis> such parameter, we "
"will go with the second method and search the environment for a variable "
"named <varname>PINHOLE</varname>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13110
msgid ""
"The other way allows us to make <emphasis>ad hoc</emphasis> decisions: "
"<emphasis>\"Though I usually want you to use 0.039, this time I want 0.03872."
"\"</emphasis> In other words, it allows us to <emphasis>override</emphasis> "
"the permanent choice."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13116
msgid "This type of choice is usually done with command line parameters."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13119
msgid ""
"Finally, a program <emphasis>always</emphasis> needs a <emphasis>default</"
"emphasis>. The user may not make any choices. Perhaps he does not know what "
"to choose. Perhaps he is \"just browsing.\" Preferably, the default will be "
"the value most users would choose anyway. That way they do not need to "
"choose. Or, rather, they can choose the default without an additional effort."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13127
msgid ""
"Given this system, the program may find conflicting options, and handle them "
"this way:"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13132
msgid ""
"If it finds an <emphasis>ad hoc</emphasis> choice (e.g., command line "
"parameter), it should accept that choice. It must ignore any permanent "
"choice and any default."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13139
msgid ""
"<emphasis>Otherwise</emphasis>, if it finds a permanent option (e.g., an "
"environment variable), it should accept it, and ignore the default."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13145
msgid "<emphasis>Otherwise</emphasis>, it should use the default."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13150
msgid ""
"We also need to decide what <emphasis>format</emphasis> our <constant>PC</"
"constant> option should have."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13154
msgid ""
"At first site, it seems obvious to use the <varname>PINHOLE=0.04</varname> "
"format for the environment variable, and <parameter>-p0.04</parameter> for "
"the command line."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13159
msgid ""
"Allowing that is actually a security risk. The <constant>PC</constant> "
"constant is a very small number. Naturally, we will test our software using "
"various small values of <constant>PC</constant>. But what will happen if "
"someone runs the program choosing a huge value?"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13165
msgid ""
"It may crash the program because we have not designed it to handle huge "
"numbers."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13168
msgid ""
"Or, we may spend more time on the program so it can handle huge numbers. We "
"might do that if we were writing commercial software for computer illiterate "
"audience."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13173
msgid ""
"Or, we might say, <emphasis>\"Tough! The user should know better.\"\"</"
"emphasis>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13176
msgid ""
"Or, we just may make it impossible for the user to enter a huge number. This "
"is the approach we will take: We will use an <emphasis>implied 0.</emphasis> "
"prefix."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13181
msgid ""
"In other words, if the user wants <constant>0.04</constant>, we will expect "
"him to type <parameter>-p04</parameter>, or set <varname>PINHOLE=04</"
"varname> in his environment. So, if he says <parameter>-p9999999</"
"parameter>, we will interpret it as <constant>0.9999999</constant>—still "
"ridiculous but at least safer."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13189
msgid ""
"Secondly, many users will just want to go with either Bender's constant or "
"Connors' constant. To make it easier on them, we will interpret <parameter>-"
"b</parameter> as identical to <parameter>-p04</parameter>, and <parameter>-"
"c</parameter> as identical to <parameter>-p037</parameter>."
msgstr ""

#. (itstool) path: sect3/title
#: book.translate.xml:13198
msgid "The Output"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13200
msgid ""
"We need to decide what we want our software to send to the output, and in "
"what format."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13203
msgid ""
"Since our input allows for an unspecified number of focal length entries, it "
"makes sense to use a traditional database–style output of showing the result "
"of the calculation for each focal length on a separate line, while "
"separating all values on one line by a <constant>tab</constant> character."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13210
msgid ""
"Optionally, we should also allow the user to specify the use of the "
"<acronym>CSV</acronym> format we have studied earlier. In this case, we will "
"print out a line of comma–separated names describing each field of every "
"line, then show our results as before, but substituting a <constant>comma</"
"constant> for the <constant>tab</constant>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13218
msgid ""
"We need a command line option for the <acronym>CSV</acronym> format. We "
"cannot use <parameter>-c</parameter> because that already means "
"<emphasis>use Connors' constant</emphasis>. For some strange reason, many "
"web sites refer to <acronym>CSV</acronym> files as <emphasis>\"Excel "
"spreadsheet\"</emphasis> (though the <acronym>CSV</acronym> format predates "
"Excel). We will, therefore, use the <parameter>-e</parameter> switch to "
"inform our software we want the output in the <acronym>CSV</acronym> format."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13230
msgid ""
"We will start each line of the output with the focal length. This may sound "
"repetitious at first, especially in the interactive mode: The user types in "
"the focal length, and we are repeating it."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13235
msgid ""
"But the user can type several focal lengths on one line. The input can also "
"come in from a file or from the output of another program. In that case the "
"user does not see the input at all."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13240
msgid ""
"By the same token, the output can go to a file which we will want to examine "
"later, or it could go to the printer, or become the input of another program."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13244
msgid ""
"So, it makes perfect sense to start each line with the focal length as "
"entered by the user."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13247
msgid ""
"No, wait! Not as entered by the user. What if the user types in something "
"like this:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13250
#, no-wrap
msgid "<userinput>00000000150</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13252
msgid "Clearly, we need to strip those leading zeros."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13254
msgid ""
"So, we might consider reading the user input as is, converting it to binary "
"inside the <acronym>FPU</acronym>, and printing it out from there."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13258 book.translate.xml:13586
msgid "But..."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13260
msgid "What if the user types something like this:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13262
#, no-wrap
msgid "<userinput>17459765723452353453534535353530530534563507309676764423</userinput>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13264
msgid ""
"Ha! The packed decimal <acronym>FPU</acronym> format lets us input 18–digit "
"numbers. But the user has entered more than 18 digits. How do we handle that?"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13269
msgid ""
"Well, we <emphasis>could</emphasis> modify our code to read the first 18 "
"digits, enter it to the <acronym>FPU</acronym>, then read more, multiply "
"what we already have on the <acronym>TOS</acronym> by 10 raised to the "
"number of additional digits, then <function>add</function> to it."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13276
msgid ""
"Yes, we could do that. But in <emphasis>this</emphasis> program it would be "
"ridiculous (in a different one it may be just the thing to do): Even the "
"circumference of the Earth expressed in millimeters only takes 11 digits. "
"Clearly, we cannot build a camera that large (not yet, anyway)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13283
msgid ""
"So, if the user enters such a huge number, he is either bored, or testing "
"us, or trying to break into the system, or playing games—doing anything but "
"designing a pinhole camera."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13288
msgid "What will we do?"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13290
msgid "We will slap him in the face, in a manner of speaking:"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13293
#, no-wrap
msgid "17459765723452353453534535353530530534563507309676764423\t???\t???\t???\t???\t???"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13295
msgid ""
"To achieve that, we will simply ignore any leading zeros. Once we find a non–"
"zero digit, we will initialize a counter to <constant>0</constant> and start "
"taking three steps:"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13302
msgid "Send the digit to the output."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13306
msgid ""
"Append the digit to a buffer we will use later to produce the packed decimal "
"we can send to the <acronym>FPU</acronym>."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13312
msgid "Increase the counter."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13316
msgid ""
"Now, while we are taking these three steps, we also need to watch out for "
"one of two conditions:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:13321
msgid ""
"If the counter grows above 18, we stop appending to the buffer. We continue "
"reading the digits and sending them to the output."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:13327
msgid ""
"If, or rather <emphasis>when</emphasis>, the next input character is not a "
"digit, we are done inputting for now."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:13331
msgid ""
"Incidentally, we can simply discard the non–digit, unless it is a "
"<constant>#</constant>, which we must return to the input stream. It starts "
"a comment, so we must see it after we are done producing output and start "
"looking for more input."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13340
msgid ""
"That still leaves one possibility uncovered: If all the user enters is a "
"zero (or several zeros), we will never find a non–zero to display."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13344
msgid ""
"We can determine this has happened whenever our counter stays at "
"<constant>0</constant>. In that case we need to send <constant>0</constant> "
"to the output, and perform another \"slap in the face\":"
msgstr ""

#. (itstool) path: sect3/screen
#: book.translate.xml:13349
#, no-wrap
msgid "0\t???\t???\t???\t???\t???"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13351
msgid ""
"Once we have displayed the focal length and determined it is valid (greater "
"than <constant>0</constant> but not exceeding 18 digits), we can calculate "
"the pinhole diameter."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13356
msgid ""
"It is not by coincidence that <emphasis>pinhole</emphasis> contains the word "
"<emphasis>pin</emphasis>. Indeed, many a pinhole literally is a "
"<emphasis>pin hole</emphasis>, a hole carefully punched with the tip of a "
"pin."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13362
msgid ""
"That is because a typical pinhole is very small. Our formula gets the result "
"in millimeters. We will multiply it by <constant>1000</constant>, so we can "
"output the result in <emphasis>microns</emphasis>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13367
msgid ""
"At this point we have yet another trap to face: <emphasis>Too much precision."
"</emphasis>"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13370
msgid ""
"Yes, the <acronym>FPU</acronym> was designed for high precision mathematics. "
"But we are not dealing with high precision mathematics. We are dealing with "
"physics (optics, specifically)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13375
msgid ""
"Suppose we want to convert a truck into a pinhole camera (we would not be "
"the first ones to do that!). Suppose its box is <constant>12</constant> "
"meters long, so we have the focal length of <constant>12000</constant>. "
"Well, using Bender's constant, it gives us square root of <constant>12000</"
"constant> multiplied by <constant>0.04</constant>, which is "
"<constant>4.381780460</constant> millimeters, or <constant>4381.780460</"
"constant> microns."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13385
msgid ""
"Put either way, the result is absurdly precise. Our truck is not "
"<emphasis>exactly</emphasis> <constant>12000</constant> millimeters long. We "
"did not measure its length with such a precision, so stating we need a "
"pinhole with the diameter of <constant>4.381780460</constant> millimeters "
"is, well, deceiving. <constant>4.4</constant> millimeters would do just fine."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:13395
msgid ""
"I \"only\" used ten digits in the above example. Imagine the absurdity of "
"going for all 18!"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13399
msgid ""
"We need to limit the number of significant digits of our result. One way of "
"doing it is by using an integer representing microns. So, our truck would "
"need a pinhole with the diameter of <constant>4382</constant> microns. "
"Looking at that number, we still decide that <constant>4400</constant> "
"microns, or <constant>4.4</constant> millimeters is close enough."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13408
msgid ""
"Additionally, we can decide that no matter how big a result we get, we only "
"want to display four significant digits (or any other number of them, of "
"course). Alas, the <acronym>FPU</acronym> does not offer rounding to a "
"specific number of digits (after all, it does not view the numbers as "
"decimal but as binary)."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13415
msgid ""
"We, therefore, must devise an algorithm to reduce the number of significant "
"digits."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13418
msgid ""
"Here is mine (I think it is awkward—if you know a better one, "
"<emphasis>please</emphasis>, let me know):"
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13424
msgid "Initialize a counter to <constant>0</constant>."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13429
msgid ""
"While the number is greater than or equal to <constant>10000</constant>, "
"divide it by <constant>10</constant> and increase the counter."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13436
msgid "Output the result."
msgstr ""

#. (itstool) path: step/para
#: book.translate.xml:13440
msgid ""
"While the counter is greater than <constant>0</constant>, output "
"<constant>0</constant> and decrease the counter."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:13447
msgid ""
"The <constant>10000</constant> is only good if you want <emphasis>four</"
"emphasis> significant digits. For any other number of significant digits, "
"replace <constant>10000</constant> with <constant>10</constant> raised to "
"the number of significant digits."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13454
msgid ""
"We will, then, output the pinhole diameter in microns, rounded off to four "
"significant digits."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13457
msgid ""
"At this point, we know the <emphasis>focal length</emphasis> and the "
"<emphasis>pinhole diameter</emphasis>. That means we have enough information "
"to also calculate the <emphasis>f–number</emphasis>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13463
msgid ""
"We will display the f–number, rounded to four significant digits. Chances "
"are the f–number will tell us very little. To make it more meaningful, we "
"can find the nearest <emphasis>normalized f–number</emphasis>, i.e., the "
"nearest power of the square root of 2."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13470
msgid ""
"We do that by multiplying the actual f–number by itself, which, of course, "
"will give us its <function>square</function>. We will then calculate its "
"base–2 logarithm, which is much easier to do than calculating the base–"
"square–root–of–2 logarithm! We will round the result to the nearest integer. "
"Next, we will raise 2 to the result. Actually, the <acronym>FPU</acronym> "
"gives us a good shortcut to do that: We can use the <function role=\"opcode"
"\">fscale</function> op code to \"scale\" 1, which is analogous to <function "
"role=\"opcode\">shift</function>ing an integer left. Finally, we calculate "
"the square root of it all, and we have the nearest normalized f–number."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13484
msgid ""
"If all that sounds overwhelming—or too much work, perhaps—it may become much "
"clearer if you see the code. It takes 9 op codes altogether:"
msgstr ""

#. (itstool) path: sect3/programlisting
#: book.translate.xml:13488
#, no-wrap
msgid ""
"fmul\tst0, st0\n"
"\tfld1\n"
"\tfld\tst1\n"
"\tfyl2x\n"
"\tfrndint\n"
"\tfld1\n"
"\tfscale\n"
"\tfsqrt\n"
"\tfstp\tst1"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13498
msgid ""
"The first line, <function role=\"opcode\">fmul st0, st0</function>, squares "
"the contents of the <acronym>TOS</acronym> (top of the stack, same as "
"<varname role=\"register\">st</varname>, called <varname role=\"register"
"\">st0</varname> by <application>nasm</application>). The <function role="
"\"opcode\">fld1</function> pushes <constant>1</constant> on the "
"<acronym>TOS</acronym>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13506
msgid ""
"The next line, <function role=\"opcode\">fld st1</function>, pushes the "
"square back to the <acronym>TOS</acronym>. At this point the square is both "
"in <varname role=\"register\">st</varname> and <varname role=\"register"
"\">st(2)</varname> (it will become clear why we leave a second copy on the "
"stack in a moment). <varname role=\"register\">st(1)</varname> contains "
"<constant>1</constant>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13514
msgid ""
"Next, <function role=\"opcode\">fyl2x</function> calculates base–2 logarithm "
"of <varname role=\"register\">st</varname> multiplied by <varname role="
"\"register\">st(1)</varname>. That is why we placed <constant>1</constant> "
"on <varname role=\"register\">st(1)</varname> before."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13519
msgid ""
"At this point, <varname role=\"register\">st</varname> contains the "
"logarithm we have just calculated, <varname role=\"register\">st(1)</"
"varname> contains the square of the actual f–number we saved for later."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13523
msgid ""
"<function role=\"opcode\">frndint</function> rounds the <acronym>TOS</"
"acronym> to the nearest integer. <function role=\"opcode\">fld1</function> "
"pushes a <constant>1</constant>. <function role=\"opcode\">fscale</function> "
"shifts the <constant>1</constant> we have on the <acronym>TOS</acronym> by "
"the value in <varname role=\"register\">st(1)</varname>, effectively raising "
"2 to <varname role=\"register\">st(1)</varname>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13530
msgid ""
"Finally, <function role=\"opcode\">fsqrt</function> calculates the square "
"root of the result, i.e., the nearest normalized f–number."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13534
msgid ""
"We now have the nearest normalized f–number on the <acronym>TOS</acronym>, "
"the base–2 logarithm rounded to the nearest integer in <varname role="
"\"register\">st(1)</varname>, and the square of the actual f–number in "
"<varname role=\"register\">st(2)</varname>. We are saving the value in "
"<varname role=\"register\">st(2)</varname> for later."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13541
msgid ""
"But we do not need the contents of <varname role=\"register\">st(1)</"
"varname> anymore. The last line, <function role=\"opcode\">fstp st1</"
"function>, places the contents of <varname role=\"register\">st</varname> to "
"<varname role=\"register\">st(1)</varname>, and pops. As a result, what was "
"<varname role=\"register\">st(1)</varname> is now <varname role=\"register"
"\">st</varname>, what was <varname role=\"register\">st(2)</varname> is now "
"<varname role=\"register\">st(1)</varname>, etc. The new <varname role="
"\"register\">st</varname> contains the normalized f–number. The new <varname "
"role=\"register\">st(1)</varname> contains the square of the actual f–number "
"we have stored there for posterity."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13552
msgid ""
"At this point, we are ready to output the normalized f–number. Because it is "
"normalized, we will not round it off to four significant digits, but will "
"send it out in its full precision."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13557
msgid ""
"The normalized f-number is useful as long as it is reasonably small and can "
"be found on our light meter. Otherwise we need a different method of "
"determining proper exposure."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13562
msgid ""
"Earlier we have figured out the formula of calculating proper exposure at an "
"arbitrary f–number from that measured at a different f–number."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13566
msgid ""
"Every light meter I have ever seen can determine proper exposure at f5.6. We "
"will, therefore, calculate an <emphasis>\"f5.6 multiplier,\"</emphasis> i."
"e., by how much we need to multiply the exposure measured at f5.6 to "
"determine the proper exposure for our pinhole camera."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13573
msgid ""
"From the above formula we know this factor can be calculated by dividing our "
"f–number (the actual one, not the normalized one) by <constant>5.6</"
"constant>, and squaring the result."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13578
msgid ""
"Mathematically, dividing the square of our f–number by the square of "
"<constant>5.6</constant> will give us the same result."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13582
msgid ""
"Computationally, we do not want to square two numbers when we can only "
"square one. So, the first solution seems better at first."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13588
msgid ""
"<constant>5.6</constant> is a <emphasis>constant</emphasis>. We do not have "
"to have our <acronym>FPU</acronym> waste precious cycles. We can just tell "
"it to divide the square of the f–number by whatever <constant>5.6²</"
"constant> equals to. Or we can divide the f–number by <constant>5.6</"
"constant>, and then square the result. The two ways now seem equal."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13597
msgid "But, they are not!"
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13599
msgid ""
"Having studied the principles of photography above, we remember that the "
"<constant>5.6</constant> is actually square root of 2 raised to the fifth "
"power. An <emphasis>irrational</emphasis> number. The square of this number "
"is <emphasis>exactly</emphasis> <constant>32</constant>."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13606
msgid ""
"Not only is <constant>32</constant> an integer, it is a power of 2. We do "
"not need to divide the square of the f–number by <constant>32</constant>. We "
"only need to use <function role=\"opcode\">fscale</function> to shift it "
"right by five positions. In the <acronym>FPU</acronym> lingo it means we "
"will <function role=\"opcode\">fscale</function> it with <varname role="
"\"register\">st(1)</varname> equal to <constant>-5</constant>. That is "
"<emphasis>much faster</emphasis> than a division."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13615
msgid ""
"So, now it has become clear why we have saved the square of the f–number on "
"the top of the <acronym>FPU</acronym> stack. The calculation of the f5.6 "
"multiplier is the easiest calculation of this entire program! We will output "
"it rounded to four significant digits."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13622
msgid ""
"There is one more useful number we can calculate: The number of stops our f–"
"number is from f5.6. This may help us if our f–number is just outside the "
"range of our light meter, but we have a shutter which lets us set various "
"speeds, and this shutter uses stops."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13628
msgid ""
"Say, our f–number is 5 stops from f5.6, and the light meter says we should "
"use 1/1000 sec. Then we can set our shutter speed to 1/1000 first, then move "
"the dial by 5 stops."
msgstr ""

#. (itstool) path: sect3/para
#: book.translate.xml:13633
msgid ""
"This calculation is quite easy as well. All we have to do is to calculate "
"the base-2 logarithm of the f5.6 multiplier we had just calculated (though "
"we need its value from before we rounded it off). We then output the result "
"rounded to the nearest integer. We do not need to worry about having more "
"than four significant digits in this one: The result is most likely to have "
"only one or two digits anyway."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:13645
msgid "FPU Optimizations"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13647
msgid ""
"In assembly language we can optimize the <acronym>FPU</acronym> code in ways "
"impossible in high languages, including C."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13651
msgid ""
"Whenever a C function needs to calculate a floating–point value, it loads "
"all necessary variables and constants into <acronym>FPU</acronym> registers. "
"It then does whatever calculation is required to get the correct result. "
"Good C compilers can optimize that part of the code really well."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13658
msgid ""
"It \"returns\" the value by leaving the result on the <acronym>TOS</"
"acronym>. However, before it returns, it cleans up. Any variables and "
"constants it used in its calculation are now gone from the <acronym>FPU</"
"acronym>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13664
msgid ""
"It cannot do what we just did above: We calculated the square of the f–"
"number and kept it on the stack for later use by another function."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13668
msgid ""
"We <emphasis>knew</emphasis> we would need that value later on. We also knew "
"we had enough room on the stack (which only has room for 8 numbers) to store "
"it there."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13673
msgid ""
"A C compiler has no way of knowing that a value it has on the stack will be "
"required again in the very near future."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13677
msgid ""
"Of course, the C programmer may know it. But the only recourse he has is to "
"store the value in a memory variable."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13681
msgid ""
"That means, for one, the value will be changed from the 80-bit precision "
"used internally by the <acronym>FPU</acronym> to a C <emphasis>double</"
"emphasis> (64 bits) or even <emphasis>single</emphasis> (32 bits)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13687
msgid ""
"That also means that the value must be moved from the <acronym>TOS</acronym> "
"into the memory, and then back again. Alas, of all <acronym>FPU</acronym> "
"operations, the ones that access the computer memory are the slowest."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13692
msgid ""
"So, whenever programming the <acronym>FPU</acronym> in assembly language, "
"look for the ways of keeping intermediate results on the <acronym>FPU</"
"acronym> stack."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13696
msgid ""
"We can take that idea even further! In our program we are using a "
"<emphasis>constant</emphasis> (the one we named <constant>PC</constant>)."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13700
msgid ""
"It does not matter how many pinhole diameters we are calculating: 1, 10, 20, "
"1000, we are always using the same constant. Therefore, we can optimize our "
"program by keeping the constant on the stack all the time."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13705
msgid ""
"Early on in our program, we are calculating the value of the above constant. "
"We need to divide our input by <constant>10</constant> for every digit in "
"the constant."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13710
msgid ""
"It is much faster to multiply than to divide. So, at the start of our "
"program, we divide <constant>10</constant> into <constant>1</constant> to "
"obtain <constant>0.1</constant>, which we then keep on the stack: Instead of "
"dividing the input by <constant>10</constant> for every digit, we multiply "
"it by <constant>0.1</constant>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13718
msgid ""
"By the way, we do not input <constant>0.1</constant> directly, even though "
"we could. We have a reason for that: While <constant>0.1</constant> can be "
"expressed with just one decimal place, we do not know how many "
"<emphasis>binary</emphasis> places it takes. We, therefore, let the "
"<acronym>FPU</acronym> calculate its binary value to its own high precision."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13726
msgid ""
"We are using other constants: We multiply the pinhole diameter by "
"<constant>1000</constant> to convert it from millimeters to microns. We "
"compare numbers to <constant>10000</constant> when we are rounding them off "
"to four significant digits. So, we keep both, <constant>1000</constant> and "
"<constant>10000</constant>, on the stack. And, of course, we reuse the "
"<constant>0.1</constant> when rounding off numbers to four digits."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13736
msgid ""
"Last but not least, we keep <constant>-5</constant> on the stack. We need it "
"to scale the square of the f–number, instead of dividing it by <constant>32</"
"constant>. It is not by coincidence we load this constant last. That makes "
"it the top of the stack when only the constants are on it. So, when the "
"square of the f–number is being scaled, the <constant>-5</constant> is at "
"<varname role=\"register\">st(1)</varname>, precisely where <function role="
"\"opcode\">fscale</function> expects it to be."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13747
msgid ""
"It is common to create certain constants from scratch instead of loading "
"them from the memory. That is what we are doing with <constant>-5</constant>:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:13751
#, no-wrap
msgid ""
"\tfld1\t\t\t; TOS =  1\n"
"\tfadd\tst0, st0\t; TOS =  2\n"
"\tfadd\tst0, st0\t; TOS =  4\n"
"\tfld1\t\t\t; TOS =  1\n"
"\tfaddp\tst1, st0\t; TOS =  5\n"
"\tfchs\t\t\t; TOS = -5"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:13758
msgid ""
"We can generalize all these optimizations into one rule: <emphasis>Keep "
"repeat values on the stack!</emphasis>"
msgstr ""

#. (itstool) path: tip/para
#: book.translate.xml:13762
msgid ""
"<emphasis><trademark class=\"registered\">PostScript</trademark></emphasis> "
"is a stack–oriented programming language. There are many more books "
"available about <trademark class=\"registered\">PostScript</trademark> than "
"about the <acronym>FPU</acronym> assembly language: Mastering <trademark "
"class=\"registered\">PostScript</trademark> will help you master the "
"<acronym>FPU</acronym>."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:13772
msgid "<application>pinhole</application>—The Code"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:13774
#, no-wrap
msgid ""
";;;;;;; pinhole.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";\n"
"; Find various parameters of a pinhole camera construction and use\n"
";\n"
"; Started:\t 9-Jun-2001\n"
"; Updated:\t10-Jun-2001\n"
";\n"
"; Copyright (c) 2001 G. Adam Stanislav\n"
"; All rights reserved.\n"
";\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
"\n"
"%include\t'system.inc'\n"
"\n"
"%define\tBUFSIZE\t2048\n"
"\n"
"section\t.data\n"
"align 4\n"
"ten\tdd\t10\n"
"thousand\tdd\t1000\n"
"tthou\tdd\t10000\n"
"fd.in\tdd\tstdin\n"
"fd.out\tdd\tstdout\n"
"envar\tdb\t'PINHOLE='\t; Exactly 8 bytes, or 2 dwords long\n"
"pinhole\tdb\t'04,', \t\t; Bender's constant (0.04)\n"
"connors\tdb\t'037', 0Ah\t; Connors' constant\n"
"usg\tdb\t'Usage: pinhole [-b] [-c] [-e] [-p &lt;value&gt;] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]', 0Ah\n"
"usglen\tequ\t$-usg\n"
"iemsg\tdb\t\"pinhole: Can't open input file\", 0Ah\n"
"iemlen\tequ\t$-iemsg\n"
"oemsg\tdb\t\"pinhole: Can't create output file\", 0Ah\n"
"oemlen\tequ\t$-oemsg\n"
"pinmsg\tdb\t\"pinhole: The PINHOLE constant must not be 0\", 0Ah\n"
"pinlen\tequ\t$-pinmsg\n"
"toobig\tdb\t\"pinhole: The PINHOLE constant may not exceed 18 decimal places\", 0Ah\n"
"biglen\tequ\t$-toobig\n"
"huhmsg\tdb\t9, '???'\n"
"separ\tdb\t9, '???'\n"
"sep2\tdb\t9, '???'\n"
"sep3\tdb\t9, '???'\n"
"sep4\tdb\t9, '???', 0Ah\n"
"huhlen\tequ\t$-huhmsg\n"
"header\tdb\t'focal length in millimeters,pinhole diameter in microns,'\n"
"\tdb\t'F-number,normalized F-number,F-5.6 multiplier,stops '\n"
"\tdb\t'from F-5.6', 0Ah\n"
"headlen\tequ\t$-header\n"
"\n"
"section .bss\n"
"ibuffer\tresb\tBUFSIZE\n"
"obuffer\tresb\tBUFSIZE\n"
"dbuffer\tresb\t20\t\t; decimal input buffer\n"
"bbuffer\tresb\t10\t\t; BCD buffer\n"
"\n"
"section\t.text\n"
"align 4\n"
"huh:\n"
"\tcall\twrite\n"
"\tpush\tdword huhlen\n"
"\tpush\tdword huhmsg\n"
"\tpush\tdword [fd.out]\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tret\n"
"\n"
"align 4\n"
"perr:\n"
"\tpush\tdword pinlen\n"
"\tpush\tdword pinmsg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 4\t\t; return failure\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"consttoobig:\n"
"\tpush\tdword biglen\n"
"\tpush\tdword toobig\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 5\t\t; return failure\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"ierr:\n"
"\tpush\tdword iemlen\n"
"\tpush\tdword iemsg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 1\t\t; return failure\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"oerr:\n"
"\tpush\tdword oemlen\n"
"\tpush\tdword oemsg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 2\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"usage:\n"
"\tpush\tdword usglen\n"
"\tpush\tdword usg\n"
"\tpush\tdword stderr\n"
"\tsys.write\n"
"\tpush\tdword 3\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"global\t_start\n"
"_start:\n"
"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
"\tsub\tesi, esi\n"
"\n"
".arg:\n"
"\tpop\tecx\n"
"\tor\tecx, ecx\n"
"\tje\tnear .getenv\t\t; no more arguments\n"
"\n"
"\t; ECX contains the pointer to an argument\n"
"\tcmp\tbyte [ecx], '-'\n"
"\tjne\tusage\n"
"\n"
"\tinc\tecx\n"
"\tmov\tax, [ecx]\n"
"\tinc\tecx\n"
"\n"
".o:\n"
"\tcmp\tal, 'o'\n"
"\tjne\t.i\n"
"\n"
"\t; Make sure we are not asked for the output file twice\n"
"\tcmp\tdword [fd.out], stdout\n"
"\tjne\tusage\n"
"\n"
"\t; Find the path to output file - it is either at [ECX+1],\n"
"\t; i.e., -ofile --\n"
"\t; or in the next argument,\n"
"\t; i.e., -o file\n"
"\n"
"\tor\tah, ah\n"
"\tjne\t.openoutput\n"
"\tpop\tecx\n"
"\tjecxz\tusage\n"
"\n"
".openoutput:\n"
"\tpush\tdword 420\t; file mode (644 octal)\n"
"\tpush\tdword 0200h | 0400h | 01h\n"
"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\tnear oerr\n"
"\n"
"\tadd\tesp, byte 12\n"
"\tmov\t[fd.out], eax\n"
"\tjmp\tshort .arg\n"
"\n"
".i:\n"
"\tcmp\tal, 'i'\n"
"\tjne\t.p\n"
"\n"
"\t; Make sure we are not asked twice\n"
"\tcmp\tdword [fd.in], stdin\n"
"\tjne\tnear usage\n"
"\n"
"\t; Find the path to the input file\n"
"\tor\tah, ah\n"
"\tjne\t.openinput\n"
"\tpop\tecx\n"
"\tor\tecx, ecx\n"
"\tje near usage\n"
"\n"
".openinput:\n"
"\tpush\tdword 0\t\t; O_RDONLY\n"
"\tpush\tecx\n"
"\tsys.open\n"
"\tjc\tnear ierr\t\t; open failed\n"
"\n"
"\tadd\tesp, byte 8\n"
"\tmov\t[fd.in], eax\n"
"\tjmp\t.arg\n"
"\n"
".p:\n"
"\tcmp\tal, 'p'\n"
"\tjne\t.c\n"
"\tor\tah, ah\n"
"\tjne\t.pcheck\n"
"\n"
"\tpop\tecx\n"
"\tor\tecx, ecx\n"
"\tje\tnear usage\n"
"\n"
"\tmov\tah, [ecx]\n"
"\n"
".pcheck:\n"
"\tcmp\tah, '0'\n"
"\tjl\tnear usage\n"
"\tcmp\tah, '9'\n"
"\tja\tnear usage\n"
"\tmov\tesi, ecx\n"
"\tjmp\t.arg\n"
"\n"
".c:\n"
"\tcmp\tal, 'c'\n"
"\tjne\t.b\n"
"\tor\tah, ah\n"
"\tjne\tnear usage\n"
"\tmov\tesi, connors\n"
"\tjmp\t.arg\n"
"\n"
".b:\n"
"\tcmp\tal, 'b'\n"
"\tjne\t.e\n"
"\tor\tah, ah\n"
"\tjne\tnear usage\n"
"\tmov\tesi, pinhole\n"
"\tjmp\t.arg\n"
"\n"
".e:\n"
"\tcmp\tal, 'e'\n"
"\tjne\tnear usage\n"
"\tor\tah, ah\n"
"\tjne\tnear usage\n"
"\tmov\tal, ','\n"
"\tmov\t[huhmsg], al\n"
"\tmov\t[separ], al\n"
"\tmov\t[sep2], al\n"
"\tmov\t[sep3], al\n"
"\tmov\t[sep4], al\n"
"\tjmp\t.arg\n"
"\n"
"align 4\n"
".getenv:\n"
"\t; If ESI = 0, we did not have a -p argument,\n"
"\t; and need to check the environment for \"PINHOLE=\"\n"
"\tor\tesi, esi\n"
"\tjne\t.init\n"
"\n"
"\tsub\tecx, ecx\n"
"\n"
".nextenv:\n"
"\tpop\tesi\n"
"\tor\tesi, esi\n"
"\tje\t.default\t; no PINHOLE envar found\n"
"\n"
"\t; check if this envar starts with 'PINHOLE='\n"
"\tmov\tedi, envar\n"
"\tmov\tcl, 2\t\t; 'PINHOLE=' is 2 dwords long\n"
"rep\tcmpsd\n"
"\tjne\t.nextenv\n"
"\n"
"\t; Check if it is followed by a digit\n"
"\tmov\tal, [esi]\n"
"\tcmp\tal, '0'\n"
"\tjl\t.default\n"
"\tcmp\tal, '9'\n"
"\tjbe\t.init\n"
"\t; fall through\n"
"\n"
"align 4\n"
".default:\n"
"\t; We got here because we had no -p argument,\n"
"\t; and did not find the PINHOLE envar.\n"
"\tmov\tesi, pinhole\n"
"\t; fall through\n"
"\n"
"align 4\n"
".init:\n"
"\tsub\teax, eax\n"
"\tsub\tebx, ebx\n"
"\tsub\tecx, ecx\n"
"\tsub\tedx, edx\n"
"\tmov\tedi, dbuffer+1\n"
"\tmov\tbyte [dbuffer], '0'\n"
"\n"
"\t; Convert the pinhole constant to real\n"
".constloop:\n"
"\tlodsb\n"
"\tcmp\tal, '9'\n"
"\tja\t.setconst\n"
"\tcmp\tal, '0'\n"
"\tje\t.processconst\n"
"\tjb\t.setconst\n"
"\n"
"\tinc\tdl\n"
"\n"
".processconst:\n"
"\tinc\tcl\n"
"\tcmp\tcl, 18\n"
"\tja\tnear consttoobig\n"
"\tstosb\n"
"\tjmp\tshort .constloop\n"
"\n"
"align 4\n"
".setconst:\n"
"\tor\tdl, dl\n"
"\tje\tnear perr\n"
"\n"
"\tfinit\n"
"\tfild\tdword [tthou]\n"
"\n"
"\tfld1\n"
"\tfild\tdword [ten]\n"
"\tfdivp\tst1, st0\n"
"\n"
"\tfild\tdword [thousand]\n"
"\tmov\tedi, obuffer\n"
"\n"
"\tmov\tebp, ecx\n"
"\tcall\tbcdload\n"
"\n"
".constdiv:\n"
"\tfmul\tst0, st2\n"
"\tloop\t.constdiv\n"
"\n"
"\tfld1\n"
"\tfadd\tst0, st0\n"
"\tfadd\tst0, st0\n"
"\tfld1\n"
"\tfaddp\tst1, st0\n"
"\tfchs\n"
"\n"
"\t; If we are creating a CSV file,\n"
"\t; print header\n"
"\tcmp\tbyte [separ], ','\n"
"\tjne\t.bigloop\n"
"\n"
"\tpush\tdword headlen\n"
"\tpush\tdword header\n"
"\tpush\tdword [fd.out]\n"
"\tsys.write\n"
"\n"
".bigloop:\n"
"\tcall\tgetchar\n"
"\tjc\tnear done\n"
"\n"
"\t; Skip to the end of the line if you got '#'\n"
"\tcmp\tal, '#'\n"
"\tjne\t.num\n"
"\tcall\tskiptoeol\n"
"\tjmp\tshort .bigloop\n"
"\n"
".num:\n"
"\t; See if you got a number\n"
"\tcmp\tal, '0'\n"
"\tjl\t.bigloop\n"
"\tcmp\tal, '9'\n"
"\tja\t.bigloop\n"
"\n"
"\t; Yes, we have a number\n"
"\tsub\tebp, ebp\n"
"\tsub\tedx, edx\n"
"\n"
".number:\n"
"\tcmp\tal, '0'\n"
"\tje\t.number0\n"
"\tmov\tdl, 1\n"
"\n"
".number0:\n"
"\tor\tdl, dl\t\t; Skip leading 0's\n"
"\tje\t.nextnumber\n"
"\tpush\teax\n"
"\tcall\tputchar\n"
"\tpop\teax\n"
"\tinc\tebp\n"
"\tcmp\tebp, 19\n"
"\tjae\t.nextnumber\n"
"\tmov\t[dbuffer+ebp], al\n"
"\n"
".nextnumber:\n"
"\tcall\tgetchar\n"
"\tjc\t.work\n"
"\tcmp\tal, '#'\n"
"\tje\t.ungetc\n"
"\tcmp\tal, '0'\n"
"\tjl\t.work\n"
"\tcmp\tal, '9'\n"
"\tja\t.work\n"
"\tjmp\tshort .number\n"
"\n"
".ungetc:\n"
"\tdec\tesi\n"
"\tinc\tebx\n"
"\n"
".work:\n"
"\t; Now, do all the work\n"
"\tor\tdl, dl\n"
"\tje\tnear .work0\n"
"\n"
"\tcmp\tebp, 19\n"
"\tjae\tnear .toobig\n"
"\n"
"\tcall\tbcdload\n"
"\n"
"\t; Calculate pinhole diameter\n"
"\n"
"\tfld\tst0\t; save it\n"
"\tfsqrt\n"
"\tfmul\tst0, st3\n"
"\tfld\tst0\n"
"\tfmul\tst5\n"
"\tsub\tebp, ebp\n"
"\n"
"\t; Round off to 4 significant digits\n"
".diameter:\n"
"\tfcom\tst0, st7\n"
"\tfstsw\tax\n"
"\tsahf\n"
"\tjb\t.printdiameter\n"
"\tfmul\tst0, st6\n"
"\tinc\tebp\n"
"\tjmp\tshort .diameter\n"
"\n"
".printdiameter:\n"
"\tcall\tprintnumber\t; pinhole diameter\n"
"\n"
"\t; Calculate F-number\n"
"\n"
"\tfdivp\tst1, st0\n"
"\tfld\tst0\n"
"\n"
"\tsub\tebp, ebp\n"
"\n"
".fnumber:\n"
"\tfcom\tst0, st6\n"
"\tfstsw\tax\n"
"\tsahf\n"
"\tjb\t.printfnumber\n"
"\tfmul\tst0, st5\n"
"\tinc\tebp\n"
"\tjmp\tshort .fnumber\n"
"\n"
".printfnumber:\n"
"\tcall\tprintnumber\t; F number\n"
"\n"
"\t; Calculate normalized F-number\n"
"\tfmul\tst0, st0\n"
"\tfld1\n"
"\tfld\tst1\n"
"\tfyl2x\n"
"\tfrndint\n"
"\tfld1\n"
"\tfscale\n"
"\tfsqrt\n"
"\tfstp\tst1\n"
"\n"
"\tsub\tebp, ebp\n"
"\tcall\tprintnumber\n"
"\n"
"\t; Calculate time multiplier from F-5.6\n"
"\n"
"\tfscale\n"
"\tfld\tst0\n"
"\n"
"\t; Round off to 4 significant digits\n"
".fmul:\n"
"\tfcom\tst0, st6\n"
"\tfstsw\tax\n"
"\tsahf\n"
"\n"
"\tjb\t.printfmul\n"
"\tinc\tebp\n"
"\tfmul\tst0, st5\n"
"\tjmp\tshort .fmul\n"
"\n"
".printfmul:\n"
"\tcall\tprintnumber\t; F multiplier\n"
"\n"
"\t; Calculate F-stops from 5.6\n"
"\n"
"\tfld1\n"
"\tfxch\tst1\n"
"\tfyl2x\n"
"\n"
"\tsub\tebp, ebp\n"
"\tcall\tprintnumber\n"
"\n"
"\tmov\tal, 0Ah\n"
"\tcall\tputchar\n"
"\tjmp\t.bigloop\n"
"\n"
".work0:\n"
"\tmov\tal, '0'\n"
"\tcall\tputchar\n"
"\n"
"align 4\n"
".toobig:\n"
"\tcall\thuh\n"
"\tjmp\t.bigloop\n"
"\n"
"align 4\n"
"done:\n"
"\tcall\twrite\t\t; flush output buffer\n"
"\n"
"\t; close files\n"
"\tpush\tdword [fd.in]\n"
"\tsys.close\n"
"\n"
"\tpush\tdword [fd.out]\n"
"\tsys.close\n"
"\n"
"\tfinit\n"
"\n"
"\t; return success\n"
"\tpush\tdword 0\n"
"\tsys.exit\n"
"\n"
"align 4\n"
"skiptoeol:\n"
"\t; Keep reading until you come to cr, lf, or eof\n"
"\tcall\tgetchar\n"
"\tjc\tdone\n"
"\tcmp\tal, 0Ah\n"
"\tjne\t.cr\n"
"\tret\n"
"\n"
".cr:\n"
"\tcmp\tal, 0Dh\n"
"\tjne\tskiptoeol\n"
"\tret\n"
"\n"
"align 4\n"
"getchar:\n"
"\tor\tebx, ebx\n"
"\tjne\t.fetch\n"
"\n"
"\tcall\tread\n"
"\n"
".fetch:\n"
"\tlodsb\n"
"\tdec\tebx\n"
"\tclc\n"
"\tret\n"
"\n"
"read:\n"
"\tjecxz\t.read\n"
"\tcall\twrite\n"
"\n"
".read:\n"
"\tpush\tdword BUFSIZE\n"
"\tmov\tesi, ibuffer\n"
"\tpush\tesi\n"
"\tpush\tdword [fd.in]\n"
"\tsys.read\n"
"\tadd\tesp, byte 12\n"
"\tmov\tebx, eax\n"
"\tor\teax, eax\n"
"\tje\t.empty\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
".empty:\n"
"\tadd\tesp, byte 4\n"
"\tstc\n"
"\tret\n"
"\n"
"align 4\n"
"putchar:\n"
"\tstosb\n"
"\tinc\tecx\n"
"\tcmp\tecx, BUFSIZE\n"
"\tje\twrite\n"
"\tret\n"
"\n"
"align 4\n"
"write:\n"
"\tjecxz\t.ret\t; nothing to write\n"
"\tsub\tedi, ecx\t; start of buffer\n"
"\tpush\tecx\n"
"\tpush\tedi\n"
"\tpush\tdword [fd.out]\n"
"\tsys.write\n"
"\tadd\tesp, byte 12\n"
"\tsub\teax, eax\n"
"\tsub\tecx, ecx\t; buffer is empty now\n"
".ret:\n"
"\tret\n"
"\n"
"align 4\n"
"bcdload:\n"
"\t; EBP contains the number of chars in dbuffer\n"
"\tpush\tecx\n"
"\tpush\tesi\n"
"\tpush\tedi\n"
"\n"
"\tlea\tecx, [ebp+1]\n"
"\tlea\tesi, [dbuffer+ebp-1]\n"
"\tshr\tecx, 1\n"
"\n"
"\tstd\n"
"\n"
"\tmov\tedi, bbuffer\n"
"\tsub\teax, eax\n"
"\tmov\t[edi], eax\n"
"\tmov\t[edi+4], eax\n"
"\tmov\t[edi+2], ax\n"
"\n"
".loop:\n"
"\tlodsw\n"
"\tsub\tax, 3030h\n"
"\tshl\tal, 4\n"
"\tor\tal, ah\n"
"\tmov\t[edi], al\n"
"\tinc\tedi\n"
"\tloop\t.loop\n"
"\n"
"\tfbld\t[bbuffer]\n"
"\n"
"\tcld\n"
"\tpop\tedi\n"
"\tpop\tesi\n"
"\tpop\tecx\n"
"\tsub\teax, eax\n"
"\tret\n"
"\n"
"align 4\n"
"printnumber:\n"
"\tpush\tebp\n"
"\tmov\tal, [separ]\n"
"\tcall\tputchar\n"
"\n"
"\t; Print the integer at the TOS\n"
"\tmov\tebp, bbuffer+9\n"
"\tfbstp\t[bbuffer]\n"
"\n"
"\t; Check the sign\n"
"\tmov\tal, [ebp]\n"
"\tdec\tebp\n"
"\tor\tal, al\n"
"\tjns\t.leading\n"
"\n"
"\t; We got a negative number (should never happen)\n"
"\tmov\tal, '-'\n"
"\tcall\tputchar\n"
"\n"
".leading:\n"
"\t; Skip leading zeros\n"
"\tmov\tal, [ebp]\n"
"\tdec\tebp\n"
"\tor\tal, al\n"
"\tjne\t.first\n"
"\tcmp\tebp, bbuffer\n"
"\tjae\t.leading\n"
"\n"
"\t; We are here because the result was 0.\n"
"\t; Print '0' and return\n"
"\tmov\tal, '0'\n"
"\tjmp\tputchar\n"
"\n"
".first:\n"
"\t; We have found the first non-zero.\n"
"\t; But it is still packed\n"
"\ttest\tal, 0F0h\n"
"\tjz\t.second\n"
"\tpush\teax\n"
"\tshr\tal, 4\n"
"\tadd\tal, '0'\n"
"\tcall\tputchar\n"
"\tpop\teax\n"
"\tand\tal, 0Fh\n"
"\n"
".second:\n"
"\tadd\tal, '0'\n"
"\tcall\tputchar\n"
"\n"
".next:\n"
"\tcmp\tebp, bbuffer\n"
"\tjb\t.done\n"
"\n"
"\tmov\tal, [ebp]\n"
"\tpush\teax\n"
"\tshr\tal, 4\n"
"\tadd\tal, '0'\n"
"\tcall\tputchar\n"
"\tpop\teax\n"
"\tand\tal, 0Fh\n"
"\tadd\tal, '0'\n"
"\tcall\tputchar\n"
"\n"
"\tdec\tebp\n"
"\tjmp\tshort .next\n"
"\n"
".done:\n"
"\tpop\tebp\n"
"\tor\tebp, ebp\n"
"\tje\t.ret\n"
"\n"
".zeros:\n"
"\tmov\tal, '0'\n"
"\tcall\tputchar\n"
"\tdec\tebp\n"
"\tjne\t.zeros\n"
"\n"
".ret:\n"
"\tret"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14472
msgid ""
"The code follows the same format as all the other filters we have seen "
"before, with one subtle exception:"
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14476
msgid ""
"We are no longer assuming that the end of input implies the end of things to "
"do, something we took for granted in the <emphasis>character–oriented</"
"emphasis> filters."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14481
msgid ""
"This filter does not process characters. It processes a <emphasis>language</"
"emphasis> (albeit a very simple one, consisting only of numbers)."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14485
msgid "When we have no more input, it can mean one of two things:"
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:14490
msgid "We are done and can quit. This is the same as before."
msgstr ""

#. (itstool) path: listitem/para
#: book.translate.xml:14495
msgid ""
"The last character we have read was a digit. We have stored it at the end of "
"our <acronym>ASCII</acronym>–to–float conversion buffer. We now need to "
"convert the contents of that buffer into a number and write the last line of "
"our output."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14504
msgid ""
"For that reason, we have modified our <function>getchar</function> and our "
"<function>read</function> routines to return with the <varname role="
"\"register\">carry flag</varname> <emphasis>clear</emphasis> whenever we are "
"fetching another character from the input, or the <varname role=\"register"
"\">carry flag</varname> <emphasis>set</emphasis> whenever there is no more "
"input."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14513
msgid ""
"Of course, we are still using assembly language magic to do that! Take a "
"good look at <function>getchar</function>. It <emphasis>always</emphasis> "
"returns with the <varname role=\"register\">carry flag</varname> "
"<emphasis>clear</emphasis>."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14518
msgid ""
"Yet, our main code relies on the <varname role=\"register\">carry flag</"
"varname> to tell it when to quit—and it works."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14521
msgid ""
"The magic is in <function>read</function>. Whenever it receives more input "
"from the system, it just returns to <function>getchar</function>, which "
"fetches a character from the input buffer, <emphasis>clears</emphasis> the "
"<varname role=\"register\">carry flag</varname> and returns."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14526
msgid ""
"But when <function>read</function> receives no more input from the system, "
"it does <emphasis>not</emphasis> return to <function>getchar</function> at "
"all. Instead, the <function role=\"opcode\">add esp, byte 4</function> op "
"code adds <constant>4</constant> to <varname role=\"register\">ESP</"
"varname>, <emphasis>sets</emphasis> the <varname role=\"register\">carry "
"flag</varname>, and returns."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14534
msgid ""
"So, where does it return to? Whenever a program uses the <function role="
"\"opcode\">call</function> op code, the microprocessor <function role="
"\"opcode\">push</function>es the return address, i.e., it stores it on the "
"top of the stack (not the <acronym>FPU</acronym> stack, the system stack, "
"which is in the memory). When a program uses the <function role=\"opcode"
"\">ret</function> op code, the microprocessor <function role=\"opcode\">pop</"
"function>s the return value from the stack, and jumps to the address that "
"was stored there."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14544
msgid ""
"But since we added <constant>4</constant> to <varname role=\"register\">ESP</"
"varname> (which is the stack pointer register), we have effectively given "
"the microprocessor a minor case of <emphasis>amnesia</emphasis>: It no "
"longer remembers it was <function>getchar</function> that <function role="
"\"opcode\">call</function>ed <function>read</function>."
msgstr ""

#. (itstool) path: blockquote/para
#: book.translate.xml:14550
msgid ""
"And since <function>getchar</function> never <function role=\"opcode\">push</"
"function>ed anything before <function role=\"opcode\">call</function>ing "
"<function>read</function>, the top of the stack now contains the return "
"address to whatever or whoever <function role=\"opcode\">call</function>ed "
"<function>getchar</function>. As far as that caller is concerned, he "
"<function role=\"opcode\">call</function>ed <function>getchar</function>, "
"which <function role=\"opcode\">ret</function>urned with the <varname role="
"\"register\">carry flag</varname> set!"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14558
msgid ""
"Other than that, the <function>bcdload</function> routine is caught up in "
"the middle of a Lilliputian conflict between the Big–Endians and the Little–"
"Endians."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14562
msgid ""
"It is converting the text representation of a number into that number: The "
"text is stored in the big–endian order, but the <emphasis>packed decimal</"
"emphasis> is little–endian."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14567
msgid ""
"To solve the conflict, we use the <function>std</function> op code early on. "
"We cancel it with <function>cld</function> later on: It is quite important "
"we do not <function>call</function> anything that may depend on the default "
"setting of the <emphasis>direction flag</emphasis> while <function>std</"
"function> is active."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14574
msgid ""
"Everything else in this code should be quit eclear, providing you have read "
"the entire chapter that precedes it."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14578
msgid ""
"It is a classical example of the adage that programming requires a lot of "
"thought and only a little coding. Once we have thought through every tiny "
"detail, the code almost writes itself."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:14585
msgid "Using <application>pinhole</application>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14587
msgid ""
"Because we have decided to make the program <emphasis>ignore</emphasis> any "
"input except for numbers (and even those inside a comment), we can actually "
"perform <emphasis>textual queries</emphasis>. We do not <emphasis>have to</"
"emphasis>, but we <emphasis>can</emphasis>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14594
msgid ""
"In my humble opinion, forming a textual query, instead of having to follow a "
"very strict syntax, makes software much more user friendly."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14598
msgid ""
"Suppose we want to build a pinhole camera to use the 4x5 inch film. The "
"standard focal length for that film is about 150mm. We want to "
"<emphasis>fine–tune</emphasis> our focal length so the pinhole diameter is "
"as round a number as possible. Let us also suppose we are quite comfortable "
"with cameras but somewhat intimidated by computers. Rather than just have to "
"type in a bunch of numbers, we want to <emphasis>ask</emphasis> a couple of "
"questions."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14607
msgid "Our session might look like this:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14609
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>pinhole\n"
"\n"
"Computer,\n"
"\n"
"What size pinhole do I need for the focal length of 150?</userinput>\n"
"150\t490\t306\t362\t2930\t12\n"
"<userinput>Hmmm... How about 160?</userinput>\n"
"160\t506\t316\t362\t3125\t12\n"
"<userinput>Let's make it 155, please.</userinput>\n"
"155\t498\t311\t362\t3027\t12\n"
"<userinput>Ah, let's try 157...</userinput>\n"
"157\t501\t313\t362\t3066\t12\n"
"<userinput>156?</userinput>\n"
"156\t500\t312\t362\t3047\t12\n"
"<userinput>That's it! Perfect! Thank you very much!\n"
"^D</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14626
msgid ""
"We have found that while for the focal length of 150, our pinhole diameter "
"should be 490 microns, or 0.49 mm, if we go with the almost identical focal "
"length of 156 mm, we can get away with a pinhole diameter of exactly one "
"half of a millimeter."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:14634
msgid "Scripting"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14636
msgid ""
"Because we have chosen the <constant>#</constant> character to denote the "
"start of a comment, we can treat our <application>pinhole</application> "
"software as a <emphasis>scripting language</emphasis>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14641
msgid ""
"You have probably seen <application>shell</application> <emphasis>scripts</"
"emphasis> that start with:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:14644
#, no-wrap
msgid "#! /bin/sh"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14646
msgid "...or..."
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:14648
#, no-wrap
msgid "#!/bin/sh"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14650
msgid ""
"...because the blank space after the <function>#!</function> is optional."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14653
msgid ""
"Whenever <trademark class=\"registered\">UNIX</trademark> is asked to run an "
"executable file which starts with the <function>#!</function>, it assumes "
"the file is a script. It adds the command to the rest of the first line of "
"the script, and tries to execute that."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14659
msgid ""
"Suppose now that we have installed <application>pinhole</application> in "
"<application>/usr/local/bin/</application>, we can now write a script to "
"calculate various pinhole diameters suitable for various focal lengths "
"commonly used with the 120 film."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14665
msgid "The script might look something like this:"
msgstr ""

#. (itstool) path: sect2/programlisting
#: book.translate.xml:14667
#, no-wrap
msgid ""
"#! /usr/local/bin/pinhole -b -i\n"
"# Find the best pinhole diameter\n"
"# for the 120 film\n"
"\n"
"### Standard\n"
"80\n"
"\n"
"### Wide angle\n"
"30, 40, 50, 60, 70\n"
"\n"
"### Telephoto\n"
"100, 120, 140"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14680
msgid ""
"Because 120 is a medium size film, we may name this file "
"<application>medium</application>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14683
msgid ""
"We can set its permissions to execute, and run it as if it were a program:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14686
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>chmod 755 medium</userinput>\n"
"<prompt>%</prompt> <userinput>./medium</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14689
msgid ""
"<trademark class=\"registered\">UNIX</trademark> will interpret that last "
"command as:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14691
#, no-wrap
msgid "<prompt>%</prompt> <userinput>/usr/local/bin/pinhole -b -i ./medium</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14693
msgid "It will run that command and display:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14695
#, no-wrap
msgid ""
"80\t358\t224\t256\t1562\t11\n"
"30\t219\t137\t128\t586\t9\n"
"40\t253\t158\t181\t781\t10\n"
"50\t283\t177\t181\t977\t10\n"
"60\t310\t194\t181\t1172\t10\n"
"70\t335\t209\t181\t1367\t10\n"
"100\t400\t250\t256\t1953\t11\n"
"120\t438\t274\t256\t2344\t11\n"
"140\t473\t296\t256\t2734\t11"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14705
msgid "Now, let us enter:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14707
#, no-wrap
msgid "<prompt>%</prompt> <userinput>./medium -c</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14709
msgid "<trademark class=\"registered\">UNIX</trademark> will treat that as:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14711
#, no-wrap
msgid "<prompt>%</prompt> <userinput>/usr/local/bin/pinhole -b -i ./medium -c</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14713
msgid ""
"That gives it two conflicting options: <parameter>-b</parameter> and "
"<parameter>-c</parameter> (Use Bender's constant and use Connors' constant). "
"We have programmed it so later options override early ones—our program will "
"calculate everything using Connors' constant:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14720
#, no-wrap
msgid ""
"80\t331\t242\t256\t1826\t11\n"
"30\t203\t148\t128\t685\t9\n"
"40\t234\t171\t181\t913\t10\n"
"50\t262\t191\t181\t1141\t10\n"
"60\t287\t209\t181\t1370\t10\n"
"70\t310\t226\t256\t1598\t11\n"
"100\t370\t270\t256\t2283\t11\n"
"120\t405\t296\t256\t2739\t11\n"
"140\t438\t320\t362\t3196\t12"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14730
msgid ""
"We decide we want to go with Bender's constant after all. We want to save "
"its values as a comma–separated file:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14734
#, no-wrap
msgid ""
"<prompt>%</prompt> <userinput>./medium -b -e &gt; bender</userinput>\n"
"<prompt>%</prompt> <userinput>cat bender</userinput>\n"
"focal length in millimeters,pinhole diameter in microns,F-number,normalized F-number,F-5.6 multiplier,stops from F-5.6\n"
"80,358,224,256,1562,11\n"
"30,219,137,128,586,9\n"
"40,253,158,181,781,10\n"
"50,283,177,181,977,10\n"
"60,310,194,181,1172,10\n"
"70,335,209,181,1367,10\n"
"100,400,250,256,1953,11\n"
"120,438,274,256,2344,11\n"
"140,473,296,256,2734,11\n"
"<prompt>%</prompt>"
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:14751
msgid "Caveats"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14753
msgid ""
"Assembly language programmers who \"grew up\" under <acronym><trademark "
"class=\"registered\">MS-DOS</trademark></acronym> and <trademark class="
"\"registered\">Windows</trademark> often tend to take shortcuts. Reading the "
"keyboard scan codes and writing directly to video memory are two classical "
"examples of practices which, under <acronym><trademark class=\"registered"
"\">MS-DOS</trademark></acronym> are not frowned upon but considered the "
"right thing to do."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14760
msgid ""
"The reason? Both the <acronym>PC BIOS</acronym> and <acronym><trademark "
"class=\"registered\">MS-DOS</trademark></acronym> are notoriously slow when "
"performing these operations."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14764
msgid ""
"You may be tempted to continue similar practices in the <trademark class="
"\"registered\">UNIX</trademark> environment. For example, I have seen a web "
"site which explains how to access the keyboard scan codes on a popular "
"<trademark class=\"registered\">UNIX</trademark> clone."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14769
msgid ""
"That is generally a <emphasis>very bad idea</emphasis> in <trademark class="
"\"registered\">UNIX</trademark> environment! Let me explain why."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:14773
msgid "<trademark class=\"registered\">UNIX</trademark> Is Protected"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14775
msgid ""
"For one thing, it may simply not be possible. <trademark class=\"registered"
"\">UNIX</trademark> runs in protected mode. Only the kernel and device "
"drivers are allowed to access hardware directly. Perhaps a particular "
"<trademark class=\"registered\">UNIX</trademark> clone will let you read the "
"keyboard scan codes, but chances are a real <trademark class=\"registered"
"\">UNIX</trademark> operating system will not. And even if one version may "
"let you do it, the next one may not, so your carefully crafted software may "
"become a dinosaur overnight."
msgstr ""

#. (itstool) path: sect2/title
#: book.translate.xml:14786
msgid "<trademark class=\"registered\">UNIX</trademark> Is an Abstraction"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14788
msgid ""
"But there is a much more important reason not to try accessing the hardware "
"directly (unless, of course, you are writing a device driver), even on the "
"<trademark class=\"registered\">UNIX</trademark> like systems that let you "
"do it:"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14793
msgid ""
"<emphasis><trademark class=\"registered\">UNIX</trademark> is an abstraction!"
"</emphasis>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14795
msgid ""
"There is a major difference in the philosophy of design between "
"<acronym><trademark class=\"registered\">MS-DOS</trademark></acronym> and "
"<trademark class=\"registered\">UNIX</trademark>. <acronym><trademark class="
"\"registered\">MS-DOS</trademark></acronym> was designed as a single-user "
"system. It is run on a computer with a keyboard and a video screen attached "
"directly to that computer. User input is almost guaranteed to come from that "
"keyboard. Your program's output virtually always ends up on that screen."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14804
msgid ""
"This is NEVER guaranteed under <trademark class=\"registered\">UNIX</"
"trademark>. It is quite common for a <trademark class=\"registered\">UNIX</"
"trademark> user to pipe and redirect program input and output:"
msgstr ""

#. (itstool) path: sect2/screen
#: book.translate.xml:14808
#, no-wrap
msgid "<prompt>%</prompt> <userinput>program1 | program2 | program3 &gt; file1</userinput>"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14810
msgid ""
"If you have written <application>program2</application>, your input does not "
"come from the keyboard but from the output of <application>program1</"
"application>. Similarly, your output does not go to the screen but becomes "
"the input for <application>program3</application> whose output, in turn, "
"goes to <filename>file1</filename>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14817
msgid ""
"But there is more! Even if you made sure that your input comes from, and "
"your output goes to, the terminal, there is no guarantee the terminal is a "
"PC: It may not have its video memory where you expect it, nor may its "
"keyboard be producing <acronym>PC</acronym>-style scan codes. It may be a "
"<trademark class=\"registered\">Macintosh</trademark>, or any other computer."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14824
msgid ""
"Now you may be shaking your head: My software is in <acronym>PC</acronym> "
"assembly language, how can it run on a <trademark class=\"registered"
"\">Macintosh</trademark>? But I did not say your software would be running "
"on a <trademark class=\"registered\">Macintosh</trademark>, only that its "
"terminal may be a <trademark class=\"registered\">Macintosh</trademark>."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14830
msgid ""
"Under <trademark class=\"registered\">UNIX</trademark>, the terminal does "
"not have to be directly attached to the computer that runs your software, it "
"can even be on another continent, or, for that matter, on another planet. It "
"is perfectly possible that a <trademark class=\"registered\">Macintosh</"
"trademark> user in Australia connects to a <trademark class=\"registered"
"\">UNIX</trademark> system in North America (or anywhere else) via "
"<application>telnet</application>. The software then runs on one computer, "
"while the terminal is on a different computer: If you try to read the scan "
"codes, you will get the wrong input!"
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14841
msgid ""
"Same holds true about any other hardware: A file you are reading may be on a "
"disk you have no direct access to. A camera you are reading images from may "
"be on a space shuttle, connected to you via satellites."
msgstr ""

#. (itstool) path: sect2/para
#: book.translate.xml:14846
msgid ""
"That is why under <trademark class=\"registered\">UNIX</trademark> you must "
"never make any assumptions about where your data is coming from and going "
"to. Always let the system handle the physical access to the hardware."
msgstr ""

#. (itstool) path: note/para
#: book.translate.xml:14852
msgid ""
"These are caveats, not absolute rules. Exceptions are possible. For example, "
"if a text editor has determined it is running on a local machine, it may "
"want to read the scan codes directly for improved control. I am not "
"mentioning these caveats to tell you what to do or what not to do, just to "
"make you aware of certain pitfalls that await you if you have just arrived "
"to <trademark class=\"registered\">UNIX</trademark> form <acronym><trademark "
"class=\"registered\">MS-DOS</trademark></acronym>. Of course, creative "
"people often break rules, and it is OK as long as they know they are "
"breaking them and why."
msgstr ""

#. (itstool) path: sect1/title
#: book.translate.xml:14867
msgid "Acknowledgements"
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14869
msgid ""
"This tutorial would never have been possible without the help of many "
"experienced FreeBSD programmers from the <link xlink:href=\"http://lists."
"FreeBSD.org/mailman/listinfo/freebsd-hackers\">FreeBSD technical discussions "
"mailing list</link>, many of whom have patiently answered my questions, and "
"pointed me in the right direction in my attempts to explore the inner "
"workings of <trademark class=\"registered\">UNIX</trademark> system "
"programming in general and FreeBSD in particular."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14876
msgid ""
"Thomas M. Sommers opened the door for me . His <link xlink:href=\"https://"
"web.archive.org/web/20090914064615/http://www.codebreakers-journal.com/"
"content/view/262/27\">How do I write \"Hello, world\" in FreeBSD assembler?</"
"link> web page was my first encounter with an example of assembly language "
"programming under FreeBSD."
msgstr ""

#. (itstool) path: sect1/para
#: book.translate.xml:14881
msgid ""
"Jake Burkholder has kept the door open by willingly answering all of my "
"questions and supplying me with example assembly language source code."
msgstr ""

#. (itstool) path: part/title
#: book.translate.xml:14894
msgid "Appendices"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14900
msgid ""
"<personname><firstname>Dave</firstname><othername role=\"MI\">A</"
"othername><surname>Patterson</surname></personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14901
msgid ""
"<personname><firstname>John</firstname><othername role=\"MI\">L</"
"othername><surname>Hennessy</surname></personname>"
msgstr ""

#. (itstool) path: biblioentry/copyright
#: book.translate.xml:14903
msgid "<year>1998</year><holder>Morgan Kaufmann Publishers, Inc.</holder>"
msgstr ""

#. (itstool) path: biblioentry/biblioid
#: book.translate.xml:14905
msgid "1-55860-428-6"
msgstr ""

#. (itstool) path: publisher/publishername
#: book.translate.xml:14907
msgid "Morgan Kaufmann Publishers, Inc."
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14909
msgid "Computer Organization and Design"
msgstr ""

#. (itstool) path: biblioentry/subtitle
#: book.translate.xml:14910
msgid "The Hardware / Software Interface"
msgstr ""

#. (itstool) path: biblioentry/pagenums
#: book.translate.xml:14911 book.translate.xml:14925 book.translate.xml:14939
msgid "1-2"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14916
msgid ""
"<personname><firstname>W.</firstname><othername role=\"Middle\">Richard</"
"othername><surname>Stevens</surname></personname>"
msgstr ""

#. (itstool) path: biblioentry/copyright
#: book.translate.xml:14918
msgid "<year>1993</year><holder>Addison Wesley Longman, Inc.</holder>"
msgstr ""

#. (itstool) path: biblioentry/biblioid
#: book.translate.xml:14920
msgid "0-201-56317-7"
msgstr ""

#. (itstool) path: publisher/publishername
#: book.translate.xml:14922
msgid "Addison Wesley Longman, Inc."
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14924
msgid "Advanced Programming in the Unix Environment"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14930
msgid ""
"<personname><firstname>Marshall</firstname><othername role=\"Middle\">Kirk</"
"othername><surname>McKusick</surname></personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14931
msgid ""
"<personname><firstname>George</firstname><surname>Neville-Neil</surname></"
"personname>"
msgstr ""

#. (itstool) path: biblioentry/copyright
#: book.translate.xml:14933
msgid "<year>2004</year><holder>Addison-Wesley</holder>"
msgstr ""

#. (itstool) path: biblioentry/biblioid
#: book.translate.xml:14934
msgid "0-201-70245-2"
msgstr ""

#. (itstool) path: publisher/publishername
#: book.translate.xml:14936
msgid "Addison-Wesley"
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14938
msgid "The Design and Implementation of the FreeBSD Operating System"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14944
msgid ""
"<personname><firstname>Aleph</firstname><surname>One</surname></personname>"
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14946
msgid "Phrack 49; \"Smashing the Stack for Fun and Profit\""
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14951
msgid ""
"<personname><firstname>Chrispin</firstname><surname>Cowan</surname></"
"personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14952
msgid ""
"<personname><firstname>Calton</firstname><surname>Pu</surname></personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14953
msgid ""
"<personname><firstname>Dave</firstname><surname>Maier</surname></personname>"
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14955
msgid ""
"StackGuard; Automatic Adaptive Detection and Prevention of Buffer-Overflow "
"Attacks"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14961
msgid ""
"<personname><firstname>Todd</firstname><surname>Miller</surname></personname>"
msgstr ""

#. (itstool) path: authorgroup/author
#: book.translate.xml:14962
msgid ""
"<personname><firstname>Theo</firstname><surname>de Raadt</surname></"
"personname>"
msgstr ""

#. (itstool) path: biblioentry/citetitle
#: book.translate.xml:14964
msgid "strlcpy and strlcat -- consistent, safe string copy and concatenation."
msgstr ""
