aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/books/developers-handbook
diff options
context:
space:
mode:
authorDanilo G. Baio <dbaio@FreeBSD.org>2022-08-07 13:50:34 +0000
committerDanilo G. Baio <dbaio@FreeBSD.org>2022-08-07 13:50:34 +0000
commite5b116889d4d6dc56803b0efc3f4d304ef929c83 (patch)
tree7f003d7b633ea9e2fb815b09a3ecbbd2fb17785c /documentation/content/en/books/developers-handbook
parent3e68ca2c7beaeced1a0c52dbb40a1414cce7a72a (diff)
Diffstat (limited to 'documentation/content/en/books/developers-handbook')
-rw-r--r--documentation/content/en/books/developers-handbook/_index.po59
-rw-r--r--documentation/content/en/books/developers-handbook/bibliography/_index.po75
-rw-r--r--documentation/content/en/books/developers-handbook/book.po59
-rw-r--r--documentation/content/en/books/developers-handbook/introduction/_index.po403
-rw-r--r--documentation/content/en/books/developers-handbook/ipv6/_index.po2133
-rw-r--r--documentation/content/en/books/developers-handbook/kernelbuild/_index.po119
-rw-r--r--documentation/content/en/books/developers-handbook/kerneldebug/_index.po1681
-rw-r--r--documentation/content/en/books/developers-handbook/l10n/_index.po487
-rw-r--r--documentation/content/en/books/developers-handbook/parti.po29
-rw-r--r--documentation/content/en/books/developers-handbook/partii.po29
-rw-r--r--documentation/content/en/books/developers-handbook/partiii.po29
-rw-r--r--documentation/content/en/books/developers-handbook/partiv.po29
-rw-r--r--documentation/content/en/books/developers-handbook/partv.po29
-rw-r--r--documentation/content/en/books/developers-handbook/policies/_index.po711
-rw-r--r--documentation/content/en/books/developers-handbook/secure/_index.po624
-rw-r--r--documentation/content/en/books/developers-handbook/sockets/_index.po2246
-rw-r--r--documentation/content/en/books/developers-handbook/testing/_index.po614
-rw-r--r--documentation/content/en/books/developers-handbook/tools/_index.po3377
-rw-r--r--documentation/content/en/books/developers-handbook/x86/_index.po8103
19 files changed, 20836 insertions, 0 deletions
diff --git a/documentation/content/en/books/developers-handbook/_index.po b/documentation/content/en/books/developers-handbook/_index.po
new file mode 100644
index 0000000000..f0e9b26e16
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/_index.po
@@ -0,0 +1,59 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-07-07 23:23-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/_index.adoc:1
+#, no-wrap
+msgid "For people who want to develop software for FreeBSD (and not just people who are developing FreeBSD itself)"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/_index.adoc:17
+#, no-wrap
+msgid "FreeBSD Developers' Handbook"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/_index.adoc:50
+msgid "Abstract"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/_index.adoc:55
+msgid ""
+"Welcome to the Developers' Handbook. This manual is a _work in progress_ "
+"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 {freebsd-doc}."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/_index.adoc:58
+msgid ""
+"The latest version of this document is always available from the link:"
+"https://www.FreeBSD.org[FreeBSD World Wide Web server]. It may also be "
+"downloaded in a variety of formats and compression options from the link:"
+"https://download.freebsd.org/doc/[FreeBSD download server] or one of the "
+"numerous extref:{handbook}[mirror sites, mirrors]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/_index.adoc:59
+msgid "'''"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/bibliography/_index.po b/documentation/content/en/books/developers-handbook/bibliography/_index.po
new file mode 100644
index 0000000000..321b3f7619
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/bibliography/_index.po
@@ -0,0 +1,75 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:20-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:1
+#, no-wrap
+msgid "FreeBSD Developers Handbook Bibliography"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:13
+#, no-wrap
+msgid "Appendices"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:51
+msgid ""
+"[[COD,1]] [1] Dave A Patterson and John L Hennessy. Copyright(R) 1998 Morgan "
+"Kaufmann Publishers, Inc. 1-55860-428-6. Morgan Kaufmann Publishers, Inc. "
+"Computer Organization and Design. The Hardware / Software Interface. 1-2."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:53
+msgid ""
+"[[APUE, 2]] [2] W. Richard Stevens. Copyright(R) 1993 Addison Wesley "
+"Longman, Inc. 0-201-56317-7. Addison Wesley Longman, Inc. Advanced "
+"Programming in the Unix Environment. 1-2."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:55
+msgid ""
+"[[DIFOS, 3]] [3] Marshall Kirk McKusick and George Neville-Neil. "
+"Copyright(R) 2004 Addison-Wesley. 0-201-70245-2. Addison-Wesley. The Design "
+"and Implementation of the FreeBSD Operating System. 1-2."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:57
+msgid ""
+"[[Phrack, 4]] [4] Aleph One. Phrack 49; \"Smashing the Stack for Fun and "
+"Profit\"."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:59
+msgid ""
+"[[StackGuard, 5]] [5] Chrispin Cowan, Calton Pu, and Dave Maier. StackGuard; "
+"Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/bibliography/_index.adoc:61
+msgid ""
+"[[OpenBSD, 6]] [6] Todd Miller and Theo de Raadt. strlcpy and strlcat -- "
+"consistent, safe string copy and concatenation."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/book.po b/documentation/content/en/books/developers-handbook/book.po
new file mode 100644
index 0000000000..3cf61902ab
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/book.po
@@ -0,0 +1,59 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-07-07 23:23-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/book.adoc:1
+#, no-wrap
+msgid "For people who want to develop software for FreeBSD (and not just people who are developing FreeBSD itself)"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/book.adoc:1
+#: documentation/content/en/books/developers-handbook/book.adoc:12
+#, no-wrap
+msgid "FreeBSD Developers' Handbook"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/book.adoc:49
+msgid "Abstract"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/book.adoc:54
+msgid ""
+"Welcome to the Developers' Handbook. This manual is a _work in progress_ "
+"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 {freebsd-doc}."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/book.adoc:57
+msgid ""
+"The latest version of this document is always available from the link:"
+"https://www.FreeBSD.org[FreeBSD World Wide Web server]. It may also be "
+"downloaded in a variety of formats and compression options from the link:"
+"https://download.freebsd.org/doc/[FreeBSD download server] or one of the "
+"numerous extref:{handbook}[mirror sites, mirrors]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/book.adoc:59
+msgid "'''"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/introduction/_index.po b/documentation/content/en/books/developers-handbook/introduction/_index.po
new file mode 100644
index 0000000000..2ff0c70cfa
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/introduction/_index.po
@@ -0,0 +1,403 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 10:28-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:1
+#, no-wrap
+msgid "Introduction to the FreeBSD Developers Handbook"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:1
+#, no-wrap
+msgid "Chapter 1. Introduction"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:16
+#, no-wrap
+msgid "Introduction"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:54
+#, no-wrap
+msgid "Developing on FreeBSD"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:59
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:65
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:67
+#, no-wrap
+msgid "The BSD Vision"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:70
+msgid ""
+"To produce the best UNIX(R) like operating system package possible, with due "
+"respect to the original software tools ideology as well as usability, "
+"performance and stability."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:72
+#, no-wrap
+msgid "Architectural Guidelines"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:75
+msgid "Our ideology can be described by the following guidelines"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:77
+msgid ""
+"Do not add new functionality unless an implementor cannot complete a real "
+"application without it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:78
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:79
+msgid ""
+"The only thing worse than generalizing from one example is generalizing from "
+"no examples at all."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:80
+msgid ""
+"If a problem is not completely understood, it is probably best to provide no "
+"solution at all."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:81
+msgid ""
+"If you can get 90 percent of the desired effect for 10 percent of the work, "
+"use the simpler solution."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:82
+msgid "Isolate complexity as much as possible."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:83
+msgid ""
+"Provide mechanism, rather than policy. In particular, place user interface "
+"policy in the client's hands."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:85
+msgid "From Scheifler & Gettys: \"X Window System\""
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:87
+#, no-wrap
+msgid "The Layout of /usr/src"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:91
+msgid ""
+"The complete source code to FreeBSD is available from our public "
+"repository. The source code is normally installed in [.filename]#/usr/src# "
+"which contains the following subdirectories:"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:96
+#, no-wrap
+msgid "Directory"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:98
+#, no-wrap
+msgid "Description"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:99
+#, no-wrap
+msgid "[.filename]#bin/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:101
+#, no-wrap
+msgid "Source for files in [.filename]#/bin#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:102
+#, no-wrap
+msgid "[.filename]#cddl/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:104
+#, no-wrap
+msgid "Utilities covered by the Common Development and Distribution License"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:105
+#, no-wrap
+msgid "[.filename]#contrib/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:107
+#, no-wrap
+msgid "Source for files from contributed software"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:108
+#, no-wrap
+msgid "[.filename]#crypto/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:110
+#, no-wrap
+msgid "Cryptographical sources"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:111
+#, no-wrap
+msgid "[.filename]#etc/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:113
+#, no-wrap
+msgid "Source for files in [.filename]#/etc#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:114
+#, no-wrap
+msgid "[.filename]#gnu/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:116
+#, no-wrap
+msgid "Utilities covered by the GNU Public License"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:117
+#, no-wrap
+msgid "[.filename]#include/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:119
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/include#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:120
+#, no-wrap
+msgid "[.filename]#kerberos5/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:122
+#, no-wrap
+msgid "Source for Kerberos version 5"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:123
+#, no-wrap
+msgid "[.filename]#lib/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:125
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/lib#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:126
+#, no-wrap
+msgid "[.filename]#libexec/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:128
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/libexec#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:129
+#, no-wrap
+msgid "[.filename]#release/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:131
+#, no-wrap
+msgid "Files required to produce a FreeBSD release"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:132
+#, no-wrap
+msgid "[.filename]#rescue/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:134
+#, no-wrap
+msgid "Build system for the [.filename]#/rescue# utilities"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:135
+#, no-wrap
+msgid "[.filename]#sbin/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:137
+#, no-wrap
+msgid "Source for files in [.filename]#/sbin#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:138
+#, no-wrap
+msgid "[.filename]#secure/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:140
+#, no-wrap
+msgid "Contributed cryptographic sources"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:141
+#, no-wrap
+msgid "[.filename]#share/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:143
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/share#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:144
+#, no-wrap
+msgid "[.filename]#sys/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:146
+#, no-wrap
+msgid "Kernel source files"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:147
+#, no-wrap
+msgid "[.filename]#tests/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:149
+#, no-wrap
+msgid "The FreeBSD test suite"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:150
+#, no-wrap
+msgid "[.filename]#tools/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:152
+#, no-wrap
+msgid "Tools used for maintenance and testing of FreeBSD"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:153
+#, no-wrap
+msgid "[.filename]#usr.bin/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:155
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/bin#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:156
+#, no-wrap
+msgid "[.filename]#usr.sbin/#"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/introduction/_index.adoc:157
+#, no-wrap
+msgid "Source for files in [.filename]#/usr/sbin#"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/ipv6/_index.po b/documentation/content/en/books/developers-handbook/ipv6/_index.po
new file mode 100644
index 0000000000..4ee80fb5ef
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/ipv6/_index.po
@@ -0,0 +1,2133 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:21-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:15
+#, no-wrap
+msgid "IPv6 Internals"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:1
+#, no-wrap
+msgid "Chapter 8. IPv6 Internals"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:53
+#, no-wrap
+msgid "IPv6/IPsec Implementation"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:57
+msgid ""
+"This section should explain IPv6 and IPsec related implementation "
+"internals. These functionalities are derived from http://www.kame.net/[KAME "
+"project]"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:59
+#, no-wrap
+msgid "IPv6"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:61
+#, no-wrap
+msgid "Conformance"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:65
+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 (_NOTE_: this is not a complete list - this is too hard to "
+"maintain...)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:67
+msgid ""
+"For details please refer to specific chapter in the document, RFCs, manual "
+"pages, or comments in the source code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:71
+msgid ""
+"Conformance tests have been performed on the KAME STABLE kit at TAHI "
+"project. Results can be viewed at http://www.tahi.org/report/KAME/[http://"
+"www.tahi.org/report/KAME/]. We also attended University of New Hampshire "
+"IOL tests (http://www.iol.unh.edu/[http://www.iol.unh.edu/]) in the past, "
+"with our past snapshots."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:73
+msgid "RFC1639: FTP Operation Over Big Address Records (FOOBAR)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:75
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:111
+msgid ""
+"RFC2428 is preferred over RFC1639. FTP clients will first try RFC2428, then "
+"RFC1639 if failed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:77
+msgid "RFC1886: DNS Extensions to support IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:78
+msgid "RFC1933: Transition Mechanisms for IPv6 Hosts and Routers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:80
+msgid "IPv4 compatible address is not supported."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:81
+msgid "automatic tunneling (described in 4.3 of this RFC) is not supported."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:82
+msgid ""
+"man:gif[4] interface implements IPv[46]-over-IPv[46] tunnel in a generic "
+"way, and it covers \"configured tunnel\" described in the spec. See "
+"<<gif,23.5.1.5>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:84
+msgid "RFC1981: Path MTU Discovery for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:85
+msgid "RFC2080: RIPng for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:87
+msgid "usr.sbin/route6d support this."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:89
+msgid "RFC2292: Advanced Sockets API for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:91
+msgid ""
+"For supported library functions/kernel APIs, see [.filename]#sys/netinet6/"
+"ADVAPI#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:93
+msgid "RFC2362: Protocol Independent Multicast-Sparse Mode (PIM-SM)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:95
+msgid ""
+"RFC2362 defines packet formats for PIM-SM. [.filename]#draft-ietf-pim-"
+"ipv6-01.txt# is written based on this."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:97
+msgid "RFC2373: IPv6 Addressing Architecture"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:99
+msgid ""
+"supports node required addresses, and conforms to the scope requirement."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:101
+msgid "RFC2374: An IPv6 Aggregatable Global Unicast Address Format"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:103
+msgid "supports 64-bit length of Interface ID."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:105
+msgid "RFC2375: IPv6 Multicast Address Assignments"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:107
+msgid "Userland applications use the well-known addresses assigned in the RFC."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:109
+msgid "RFC2428: FTP Extensions for IPv6 and NATs"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:113
+msgid "RFC2460: IPv6 specification"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:114
+msgid "RFC2461: Neighbor discovery for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:116
+msgid "See <<neighbor-discovery,23.5.1.2>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:118
+msgid "RFC2462: IPv6 Stateless Address Autoconfiguration"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:120
+msgid "See <<ipv6-pnp,23.5.1.4>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:122
+msgid "RFC2463: ICMPv6 for IPv6 specification"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:124
+msgid "See <<icmpv6,23.5.1.9>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:126
+msgid "RFC2464: Transmission of IPv6 Packets over Ethernet Networks"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:127
+msgid "RFC2465: MIB for IPv6: Textual Conventions and General Group"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:129
+msgid ""
+"Necessary statistics are gathered by the kernel. Actual IPv6 MIB support is "
+"provided as a patchkit for ucd-snmp."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:131
+msgid "RFC2466: MIB for IPv6: ICMPv6 group"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:133
+msgid ""
+"Necessary statistics are gathered by the kernel. Actual IPv6 MIB support is "
+"provided as patchkit for ucd-snmp."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:135
+msgid "RFC2467: Transmission of IPv6 Packets over FDDI Networks"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:136
+msgid "RFC2497: Transmission of IPv6 packet over ARCnet Networks"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:137
+msgid "RFC2553: Basic Socket Interface Extensions for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:139
+msgid ""
+"IPv4 mapped address (3.7) and special behavior of IPv6 wildcard bind socket "
+"(3.8) are supported. See <<ipv6-wildcard-socket,23.5.1.12>> in this document "
+"for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:141
+msgid "RFC2675: IPv6 Jumbograms"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:143
+msgid "See <<ipv6-jumbo,23.5.1.7>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:145
+msgid "RFC2710: Multicast Listener Discovery for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:146
+msgid "RFC2711: IPv6 router alert option"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:147
+msgid ""
+"[.filename]#draft-ietf-ipngwg-router-renum-08#: Router renumbering for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:148
+msgid ""
+"[.filename]#draft-ietf-ipngwg-icmp-namelookups-02#: IPv6 Name Lookups "
+"Through ICMP"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:149
+msgid ""
+"[.filename]#draft-ietf-ipngwg-icmp-name-lookups-03#: IPv6 Name Lookups "
+"Through ICMP"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:150
+msgid "[.filename]#draft-ietf-pim-ipv6-01.txt#: PIM for IPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:152
+msgid ""
+"man:pim6dd[8] implements dense mode. man:pim6sd[8] implements sparse mode."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:154
+msgid ""
+"[.filename]#draft-itojun-ipv6-tcp-to-anycast-00#: Disconnecting TCP "
+"connection toward IPv6 anycast address"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:155
+msgid "[.filename]#draft-yamamoto-wideipv6-comm-model-00#"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:157
+msgid "See <<ipv6-sas,23.5.1.6>> in this document for details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:159
+msgid ""
+"[.filename]#draft-ietf-ipngwg-scopedaddr-format-00.txt#: An Extension of "
+"Format for IPv6 Scoped Addresses"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:161
+#, no-wrap
+msgid "Neighbor Discovery"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:166
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:171
+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 man:ifconfig[8]. It is administrators' responsibility to "
+"check for and recover from DAD failures. The behavior should be improved in "
+"the near future."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:175
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:177
+msgid ""
+"Neighbor Discovery specification (RFC2461) does not talk about neighbor "
+"cache handling in the following cases:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:179
+msgid ""
+"when there was no neighbor cache entry, node received unsolicited RS/NS/NA/"
+"redirect packet without link-layer address"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:180
+msgid ""
+"neighbor cache handling on medium without link-layer address (we need a "
+"neighbor cache entry for IsRouter bit)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:183
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:186
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:191
+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#. If there are high demands we may provide "
+"sysctl knob for the variable."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:193
+#, no-wrap
+msgid "Scope Index"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:198
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:203
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:206
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:210
+#, no-wrap
+msgid "\tfe80:1::200:f8ff:fe01:6317\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:215
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:220
+msgid ""
+"Routing daemons and configuration programs, like man:route6d[8] and man:"
+"ifconfig[8], 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:227
+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 `ping6 -I ne0 ff02::1`). 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:231
+msgid ""
+"Some of the userland tools support extended numeric IPv6 syntax, as "
+"documented in [.filename]#draft-ietf-ipngwg-scopedaddr-format-00.txt#. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:234
+msgid ""
+"To use this extension in your program, you will need to use man:"
+"getaddrinfo[3], and man:getnameinfo[3] 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:236
+#, no-wrap
+msgid "Plug and Play"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:242
+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 ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:243
+#, no-wrap
+msgid "Assignment of link-local, and special addresses"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:248
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:250
+msgid "Here is an output of netstat command:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:257
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:262
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:265
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:269
+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 ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:270
+#, no-wrap
+msgid "Stateless address autoconfiguration on Hosts"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:274
+msgid ""
+"In IPv6 specification, nodes are separated into two categories: _routers_ "
+"and _hosts_. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:283
+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 "
+"_rtsol_ command. man:rtsold[8] daemon is also available. man:rtsold[8] "
+"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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:285
+msgid ""
+"To generate Router Advertisement from a router, use the man:rtadvd[8] daemon."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:287
+msgid ""
+"Note that, IPv6 specification assumes the following items, and nonconforming "
+"cases are left unspecified:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:289
+msgid "Only hosts will listen to router advertisements"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:290
+msgid "Hosts have single network interface (except loopback)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:293
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:295
+msgid "To summarize the sysctl knob:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:309
+#, 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)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:314
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:316
+msgid ""
+"See <<neighbor-discovery,23.5.1.2>> in the document for relationship between "
+"DAD and autoconfiguration."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:318
+#, no-wrap
+msgid "Generic Tunnel Interface"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:322
+msgid ""
+"GIF (Generic InterFace) is a pseudo interface for configured tunnel. "
+"Details are described in man:gif[4]. Currently"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:324
+msgid "v6 in v6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:325
+msgid "v6 in v4"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:326
+msgid "v4 in v6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:327
+msgid "v4 in v4"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:332
+msgid ""
+"are available. Use man:gifconfig[8] 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. _Please be warned_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:335
+msgid ""
+"gif can be configured to be ECN-friendly. See <<ipsec-ecn,23.5.4.5>> for "
+"ECN-friendliness of tunnels, and man:gif[4] for how to configure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:338
+msgid ""
+"If you would like to configure an IPv4-in-IPv6 tunnel with gif interface, "
+"read man:gif[4] carefully. You will need to remove IPv6 link-local address "
+"automatically assigned to the gif interface."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:340
+#, no-wrap
+msgid "Source Address Selection"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:344
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:346
+msgid ""
+"If the source address is explicitly specified by the user (e.g., via the "
+"advanced API), the specified address is used."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:347
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:349
+msgid "This is the most typical case."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:350
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:351
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:352
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:357
+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 <<ipv6-scope-index,23.5.1.3>> - 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:364
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:370
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:372
+#, no-wrap
+msgid "Jumbo Payload"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:376
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:378
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:380
+msgid "`options \"LARGE_LOMTU\" #To test jumbo payload`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:382
+msgid "and recompile the new kernel."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:386
+msgid ""
+"Then you can test jumbo payloads by the man:ping6[8] 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:390
+#, no-wrap
+msgid "% ping6 -b 70000 -s 68000 ::1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:395
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:399
+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 man:netstat[8] command with `-s -p "
+"ip6' option:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:406
+#, no-wrap
+msgid ""
+"% netstat -s -p ip6\n"
+"\t ip6:\n"
+"\t\t(snip)\n"
+"\t\t1 with data size < data length\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:410
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:413
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:416
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:420
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:424
+msgid ""
+"mbuf pkthdr.len field is typed as \"int\" in 4.4BSD, so it will not hold "
+"jumbogram with len > 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:426
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:427
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:428
+msgid "TCP code needs a careful update in bunch of places, of course."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:429
+#, no-wrap
+msgid "Loop Prevention in Header Processing"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:440
+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, so sys/netinet6 code defines its own protocol switch structure, as "
+"\"struct ip6protosw\" (see [.filename]#netinet6/ip6protosw.h#). 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. As a result, if you receive IPsec-over-IPv4 packet with massive "
+"number of IPsec headers, kernel stack may blow up. IPsec-over-IPv6 is "
+"okay. (Of-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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:442
+#, no-wrap
+msgid "ICMPv6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:446
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:447
+#, no-wrap
+msgid "Applications"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:450
+msgid ""
+"For userland programming, we support IPv6 socket API as specified in "
+"RFC2553, RFC2292 and upcoming Internet drafts."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:455
+msgid ""
+"TCP/UDP over IPv6 is available and quite stable. You can enjoy man:"
+"telnet[1], man:ftp[1], man:rlogin[1], man:rsh[1], man:ssh[1], etc. These "
+"applications are protocol independent. That is, they automatically chooses "
+"IPv4 or IPv6 according to DNS."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:456
+#, no-wrap
+msgid "Kernel Internals"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:459
+msgid ""
+"While ip_forward() calls ip_output(), ip6_forward() directly calls "
+"if_output() since routers must not divide IPv6 packets into fragments."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:463
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:467
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:470
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:474
+msgid ""
+"`netstat -s -p ip6` 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:484
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:489
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:491
+msgid "Both IP and IP6 reassemble functions never call m_pullup()."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:493
+#, no-wrap
+msgid "IPv4 Mapped Address and IPv6 Wildcard Socket"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:497
+msgid ""
+"RFC2553 describes IPv4 mapped address (3.7) and special behavior of IPv6 "
+"wildcard bind socket (3.8). The spec allows you to:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:499
+msgid "Accept IPv4 connections by AF_INET6 wildcard bind socket."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:500
+msgid ""
+"Transmit IPv4 packet over AF_INET6 socket by using special form of the "
+"address like ::ffff:10.1.1.1."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:503
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:505
+msgid ""
+"You can perform wildcard bind on both of the address families, on the same "
+"port."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:507
+msgid "The following table show the behavior of FreeBSD 4.x."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:516
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:519
+msgid ""
+"The following sections will give you more details, and how you can configure "
+"the behavior."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:521
+msgid "Comments on listening side:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:528
+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 man:getaddrinfo[3] 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:530
+msgid ""
+"If a server application would like to accept IPv4 and IPv6 connections, "
+"there will be two alternatives."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:535
+msgid ""
+"One is using AF_INET and AF_INET6 socket (you will need two sockets). Use "
+"man:getaddrinfo[3] with AI_PASSIVE into ai_flags, and man:socket[2] and man:"
+"bind[2] 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:541
+msgid ""
+"Another way is using one AF_INET6 wildcard bind socket. Use man:"
+"getaddrinfo[3] with AI_PASSIVE into ai_flags and with AF_INET6 into "
+"ai_family, and set the 1st argument hostname to NULL. And man:socket[2] and "
+"man:bind[2] to the address returned. (should be IPv6 unspecified addr). "
+"You can accept either of IPv4 and IPv6 packet via this one socket."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:545
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:547
+msgid ""
+"To resolve this issue more easily, there is system dependent man:"
+"setsockopt[2] option, IPV6_BINDV6ONLY, used like below."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:551
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:598
+#, no-wrap
+msgid "\tint on;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:554
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:601
+#, no-wrap
+msgid ""
+"\tsetsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,\n"
+"\t\t (char *)&on, sizeof (on)) < 0));\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:557
+msgid "When this call succeed, then this socket only receive IPv6 packets."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:559
+msgid "Comments on initiating side:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:561
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:563
+msgid "NEVER hardcode AF_INET nor AF_INET6."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:564
+msgid ""
+"Use man:getaddrinfo[3] and man:getnameinfo[3] 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 man:"
+"getaddrinfo[3] and man:getnameinfo[3].)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:565
+msgid ""
+"If you would like to connect to destination, use man:getaddrinfo[3] and try "
+"all the destination returned, like man:telnet[1] does."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:566
+msgid ""
+"Some of the IPv6 stack is shipped with buggy man:getaddrinfo[3]. Ship a "
+"minimal working version with your application and use that as last resort."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:572
+msgid ""
+"If you would like to use AF_INET6 socket for both IPv4 and IPv6 outgoing "
+"connection, you will need to use man:getipnodebyname[3]. 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 man:getipnodebyname[3] itself is not recommended "
+"as it does not handle scoped IPv6 addresses at all. For IPv6 name "
+"resolution, man:getaddrinfo[3] is the preferred API. So you should rewrite "
+"your application to use man:getaddrinfo[3], when you get the time to do it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:576
+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 ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:577
+#, no-wrap
+msgid "unified tcp and inpcb code"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:581
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:584
+msgid ""
+"The platform can be configured to support IPv4 mapped address. Kernel "
+"configuration is summarized as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:586
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:587
+msgid "You can disable it on entire system with sysctl like below."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:589
+msgid "`sysctl net.inet6.ip6.mapped_addr=0`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:591
+msgid "====== Listening Side"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:594
+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 man:"
+"setsockopt[2] like below."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:604
+msgid ""
+"Wildcard AF_INET6 socket grabs IPv4 connection if and only if the following "
+"conditions are satisfied:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:606
+msgid "there is no AF_INET socket that matches the IPv4 connection"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:607
+msgid ""
+"the AF_INET6 socket is configured to accept IPv4 traffic, i.e., "
+"getsockopt(IPV6_BINDV6ONLY) returns 0."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:609
+msgid "There is no problem with open/close ordering."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:611
+msgid "====== Initiating Side"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:613
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:614
+#, no-wrap
+msgid "sockaddr_storage"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:620
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:622
+msgid "As a result, RFC2553 defines struct sockaddr_storage as follows:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:630
+#, 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};\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:633
+msgid "On the contrary, XNET draft defines as follows:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:641
+#, 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};\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:644
+msgid ""
+"In December 1999, it was agreed that RFC2553bis should pick the latter "
+"(XNET) definition."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:646
+msgid ""
+"Current implementation conforms to XNET definition, based on RFC2553bis "
+"discussion."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:649
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:651
+msgid ""
+"ensure ss_family and/or ss_len are available on the platform, by using GNU "
+"autoconf,"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:652
+msgid ""
+"have -Dss_family=__ss_family to unify all occurrences (including header "
+"file) into __ss_family, or"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:653
+msgid "never touch __ss_family. cast to sockaddr * and use sa_family like:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:658
+#, no-wrap
+msgid ""
+"\tstruct sockaddr_storage ss;\n"
+"\tfamily = ((struct sockaddr *)&ss)->sa_family\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:660
+#, no-wrap
+msgid "Network Drivers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:663
+msgid ""
+"Now following two items are required to be supported by standard drivers:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:665
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:666
+msgid ""
+"multicast. If man:ifmcstat[8] yields no multicast group for a interface, "
+"that interface has to be patched."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:669
+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 {freebsd-"
+"bugs}."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:672
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:673
+#, no-wrap
+msgid "Translator"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:676
+msgid "We categorize IPv4/IPv6 translator into 4 types:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:678
+msgid ""
+"_Translator A_ --- 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:679
+msgid ""
+"_Translator B_ --- 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:680
+msgid ""
+"_Translator C_ --- 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:681
+msgid ""
+"_Translator D_ --- 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:683
+#, no-wrap
+msgid "IPsec"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:686
+msgid "IPsec is mainly organized by three components."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:688
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:691
+#, no-wrap
+msgid "Policy Management"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:689
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:701
+#, no-wrap
+msgid "Key Management"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:690
+msgid "AH and ESP handling"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:698
+msgid ""
+"The kernel implements experimental policy management code. There are two "
+"way to manage security policy. One is to configure per-socket policy using "
+"man:setsockopt[2]. In this cases, policy configuration is described in man:"
+"ipsec_set_policy[3]. The other is to configure kernel packet filter-based "
+"policy using PF_KEY interface, via man:setkey[8]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:700
+msgid ""
+"The policy entry is not re-ordered with its indexes, so the order of entry "
+"when you add is very significant."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:705
+msgid ""
+"The key management code implemented in this kit (sys/netkey) is a home-brew "
+"PFKEY v2 implementation. This conforms to RFC2367."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:709
+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 `ping -P 'out ipsec esp/transport//use'`). The "
+"kernel will contact racoon daemon as necessary to exchange keys."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:710
+#, no-wrap
+msgid "AH and ESP Handling"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:718
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:721
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:725
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:727
+msgid ""
+"Tunnel mode is partially supported in this release, with the following "
+"restrictions:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:729
+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->if_output(). Opinion varies if it is better to unify them, or not."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:730
+msgid ""
+"MTU and Don't Fragment bit (IPv4) considerations need more checking, but "
+"basically works fine."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:731
+msgid ""
+"Authentication model for AH tunnel must be revisited. We will need to "
+"improve the policy management engine, eventually."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:732
+#, no-wrap
+msgid "Conformance to RFCs and IDs"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:735
+msgid ""
+"The IPsec code in the kernel conforms (or, tries to conform) to the "
+"following standards:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:737
+msgid "\"old IPsec\" specification documented in [.filename]#rfc182[5-9].txt#"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:740
+msgid ""
+"\"new IPsec\" specification documented in [.filename]#rfc240[1-6].txt#, [."
+"filename]#rfc241[01].txt#, [.filename]#rfc2451.txt# and [.filename]#draft-"
+"mcdonald-simple-ipsec-api-01.txt# (draft expired, but you can take from link:"
+"ftp://ftp.kame.net/pub/internet-drafts/[ ftp://ftp.kame.net/pub/internet-"
+"drafts/]). (NOTE: IKE specifications, [.filename]#rfc241[7-9].txt# are "
+"implemented in userland, as \"racoon\" IKE daemon)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:742
+msgid "Currently supported algorithms are:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:744
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:781
+msgid "old IPsec AH"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:746
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:759
+msgid "null crypto checksum (no document, just for debugging)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:747
+msgid "keyed MD5 with 128bit crypto checksum ([.filename]#rfc1828.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:748
+msgid "keyed SHA1 with 128bit crypto checksum (no document)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:749
+msgid "HMAC MD5 with 128bit crypto checksum ([.filename]#rfc2085.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:750
+msgid "HMAC SHA1 with 128bit crypto checksum (no document)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:752
+msgid "old IPsec ESP"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:754
+msgid "null encryption (no document, similar to [.filename]#rfc2410.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:755
+msgid "DES-CBC mode ([.filename]#rfc1829.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:757
+msgid "new IPsec AH"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:760
+msgid "keyed MD5 with 96bit crypto checksum (no document)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:761
+msgid "keyed SHA1 with 96bit crypto checksum (no document)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:762
+msgid "HMAC MD5 with 96bit crypto checksum ([.filename]#rfc2403.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:763
+msgid "HMAC SHA1 with 96bit crypto checksum ([.filename]#rfc2404.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:765
+msgid "new IPsec ESP"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:767
+msgid "null encryption ([.filename]#rfc2410.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:768
+msgid ""
+"DES-CBC with derived IV ([.filename]#draft-ietf-ipsec-ciph-des-derived-01."
+"txt#, draft expired)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:769
+msgid "DES-CBC with explicit IV ([.filename]#rfc2405.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:770
+msgid "3DES-CBC with explicit IV ([.filename]#rfc2451.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:771
+msgid "BLOWFISH CBC ([.filename]#rfc2451.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:772
+msgid "CAST128 CBC ([.filename]#rfc2451.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:773
+msgid "RC5 CBC ([.filename]#rfc2451.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:774
+msgid "each of the above can be combined with:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:776
+msgid "ESP authentication with HMAC-MD5(96bit)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:777
+msgid "ESP authentication with HMAC-SHA1(96bit)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:779
+msgid "The following algorithms are NOT supported:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:783
+msgid ""
+"HMAC MD5 with 128bit crypto checksum + 64bit replay prevention ([."
+"filename]#rfc2085.txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:784
+msgid ""
+"keyed SHA1 with 160bit crypto checksum + 32bit padding ([.filename]#rfc1852."
+"txt#)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:787
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:789
+#, no-wrap
+msgid "ECN Consideration on IPsec Tunnels"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:792
+msgid ""
+"ECN-friendly IPsec tunnel is supported as described in [.filename]#draft-"
+"ipsec-ecn-00.txt#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:797
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:800
+msgid ""
+"To make IPsec tunnel ECN-friendly, we should modify encapsulation and "
+"decapsulation procedure. This is described in http://www.aciri.org/floyd/"
+"papers/draft-ipsec-ecn-00.txt[ http://www.aciri.org/floyd/papers/draft-ipsec-"
+"ecn-00.txt], chapter 3."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:802
+msgid ""
+"IPsec tunnel implementation can give you three behaviors, by setting net."
+"inet.ipsec.ecn (or net.inet6.ipsec6.ecn) to some value:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:804
+msgid "RFC2401: no consideration for ECN (sysctl value -1)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:805
+msgid "ECN forbidden (sysctl value 0)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:806
+msgid "ECN allowed (sysctl value 1)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:808
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:810
+msgid ""
+"The behavior is summarized as follows (see source code for more detail):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:817
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:821
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:826
+#, no-wrap
+msgid ""
+"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.\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:829
+msgid "General strategy for configuration is as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:831
+msgid ""
+"if both IPsec tunnel endpoint are capable of ECN-friendly behavior, you "
+"should better configure both end to \"ECN allowed\" (sysctl value 1)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:832
+msgid ""
+"if the other end is very strict about TOS bit, use \"RFC2401\" (sysctl value "
+"-1)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:833
+msgid "in other cases, use \"ECN forbidden\" (sysctl value 0)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:835
+msgid "The default behavior is \"ECN forbidden\" (sysctl value 0)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:837
+msgid "For more information, please refer to:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:839
+msgid ""
+"http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt[ http://www.aciri."
+"org/floyd/papers/draft-ipsec-ecn-00.txt], RFC2481 (Explicit Congestion "
+"Notification), src/sys/netinet6/{ah,esp}_input.c"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:841
+msgid ""
+"(Thanks goes to Kenjiro Cho mailto:kjc@csl.sony.co.jp[kjc@csl.sony.co.jp] "
+"for detailed analysis)"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:842
+#, no-wrap
+msgid "Interoperability"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:846
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/ipv6/_index.adoc:847
+msgid ""
+"Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure), Ericsson ACC, "
+"FreeS/WAN, HITACHI, IBM AIX(R), IIJ, Intel, Microsoft(R) Windows NT(R), NIST "
+"(linux IPsec + plutoplus), Netscreen, OpenBSD, RedCreek, Routerware, SSH, "
+"Secure Computing, Soliton, Toshiba, VPNet, Yamaha RT100i"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/kernelbuild/_index.po b/documentation/content/en/books/developers-handbook/kernelbuild/_index.po
new file mode 100644
index 0000000000..8a0d5140af
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/kernelbuild/_index.po
@@ -0,0 +1,119 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:21-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:14
+#, no-wrap
+msgid "Building and Installing a FreeBSD Kernel"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:1
+#, no-wrap
+msgid "Chapter 9. Building and Installing a FreeBSD Kernel"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:54
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:56
+msgid ""
+"The supported procedure to build and install a kernel is documented in the "
+"extref:{handbook}[Building and Installing a Custom Kernel, kernelconfig-"
+"building] chapter of the FreeBSD Handbook."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:61
+msgid ""
+"It is supposed that the reader of this chapter is familiar with the "
+"information described in the extref:{handbook}[Building and Installing a "
+"Custom Kernel, kernelconfig-building] 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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:64
+#, no-wrap
+msgid "Building the Faster but Brittle Way"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:68
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:71
+msgid "Run man:config[8] to generate the kernel source code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:75
+#, no-wrap
+msgid "# /usr/sbin/config MYKERNEL\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:78
+msgid ""
+"Change into the build directory. man:config[8] will print the name of this "
+"directory after being run as above."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:82
+#, no-wrap
+msgid "# cd ../compile/MYKERNEL\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:85
+msgid "Compile the kernel:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:90
+#, no-wrap
+msgid ""
+"# make depend\n"
+"# make\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:93
+msgid "Install the new kernel:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kernelbuild/_index.adoc:97
+#, no-wrap
+msgid "# make install\n"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/kerneldebug/_index.po b/documentation/content/en/books/developers-handbook/kerneldebug/_index.po
new file mode 100644
index 0000000000..4dae2e378f
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/kerneldebug/_index.po
@@ -0,0 +1,1681 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 10:28-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:1
+#, no-wrap
+msgid "FreeBSD Kernel Debugging"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:1
+#, no-wrap
+msgid "Chapter 10. Kernel Debugging"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:17
+#, no-wrap
+msgid "Kernel Debugging"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:55
+#, no-wrap
+msgid "Obtaining a Kernel Crash Dump"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:60
+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 man:"
+"jail[8]s, etc.), or using a new feature or device driver on FreeBSD-STABLE "
+"(e.g., PAE), 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:65
+msgid ""
+"A system reboot is inevitable once a kernel panics. Once a system is "
+"rebooted, the contents of a system's physical memory (RAM) 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 ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:71
+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 \"swap device\" is synonymous with a \"swap "
+"partition.\""
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:74
+msgid "Several types of kernel crash dumps are available:"
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:75
+#, no-wrap
+msgid "Full memory dumps"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:77
+msgid "Hold the complete contents of physical memory."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:78
+#, no-wrap
+msgid "Minidumps"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:80
+msgid "Hold only memory pages in use by the kernel (FreeBSD 6.2 and higher)."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:81
+#, no-wrap
+msgid "Textdumps"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:83
+msgid ""
+"Hold captured, scripted, or interactive debugger output (FreeBSD 7.1 and "
+"higher)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:85
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:87
+#, no-wrap
+msgid "Configuring the Dump Device"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:95
+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 man:dumpon[8] command to tell the kernel where to save kernel "
+"crash dumps. The man:dumpon[8] program must be called after the swap "
+"partition has been configured with man:swapon[8]. This is normally handled "
+"by setting the `dumpdev` variable in man:rc.conf[5] to the path of the swap "
+"device (the recommended way to extract a kernel dump) or `AUTO` to use the "
+"first configured swap device. The default for `dumpdev` is `AUTO` in HEAD, "
+"and changed to `NO` on RELENG_* branches (except for RELENG_7, which was "
+"left set to `AUTO`). On FreeBSD 9.0-RELEASE and later versions, bsdinstall "
+"will ask whether crash dumps should be enabled on the target system during "
+"the install process."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:99
+msgid ""
+"Check [.filename]#/etc/fstab# or man:swapinfo[8] for a list of swap devices."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:104
+msgid ""
+"Make sure the `dumpdir` specified in man:rc.conf[5] exists before a kernel "
+"crash!"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:109
+#, no-wrap
+msgid ""
+"# mkdir /var/crash\n"
+"# chmod 700 /var/crash\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:112
+msgid ""
+"Also, remember that the contents of [.filename]#/var/crash# is sensitive and "
+"very likely contains confidential information such as passwords."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:115
+#, no-wrap
+msgid "Extracting a Kernel Dump"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:121
+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 man:savecore[8] program. If `dumpdev` has been set in man:rc."
+"conf[5], man:savecore[8] 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 man:rc.conf[5] value "
+"`dumpdir`, by default [.filename]#/var/crash# and will be named [."
+"filename]#vmcore.0#."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:125
+msgid ""
+"In the event that there is already a file called [.filename]#vmcore.0# in [."
+"filename]#/var/crash# (or whatever `dumpdir` is set to), the kernel will "
+"increment the trailing number for every crash to avoid overwriting an "
+"existing [.filename]#vmcore# (e.g., [.filename]#vmcore.1#). man:savecore[8] "
+"will always create a symbolic link to named [.filename]#vmcore.last# in [."
+"filename]#/var/crash# after a dump is saved. This symbolic link can be used "
+"to locate the name of the most recent dump."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:129
+msgid ""
+"The man:crashinfo[8] utility generates a text file containing a summary of "
+"information from a full memory dump or minidump. If `dumpdev` has been set "
+"in man:rc.conf[5], man:crashinfo[8] will be invoked automatically after man:"
+"savecore[8]. The output is saved to a file in `dumpdir` named [."
+"filename]#core.txt.N#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:134
+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 `-s` flag at the boot prompt, and then perform the following steps:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:141
+#, no-wrap
+msgid ""
+"# fsck -p\n"
+"# mount -a -t ufs # make sure /var/crash is writable\n"
+"# savecore /var/crash /dev/ad0s1b\n"
+"# exit # exit to multi-user\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:146
+msgid ""
+"This instructs man:savecore[8] to extract a kernel dump from [.filename]#/"
+"dev/ad0s1b# and place the contents in [.filename]#/var/crash#. Do not "
+"forget to make sure the destination directory [.filename]#/var/crash# 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#!"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:148
+#, no-wrap
+msgid "Testing Kernel Dump Configuration"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:153
+msgid ""
+"The kernel includes a man:sysctl[8] 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:163
+#, no-wrap
+msgid ""
+"# shutdown now\n"
+"...\n"
+"Enter full pathname of shell or RETURN for /bin/sh:\n"
+"# mount -a -u -r\n"
+"# sysctl debug.kdb.panic=1\n"
+"debug.kdb.panic:panic: kdb_sysctl_panic\n"
+"...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:166
+msgid ""
+"After rebooting, your system should save a dump in [.filename]#/var/crash# "
+"along with a matching summary from man:crashinfo[8]."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:168
+#, no-wrap
+msgid "Debugging a Kernel Crash Dump with `kgdb`"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:175
+msgid ""
+"This section covers man:kgdb[1]. The latest version is included in the "
+"package:devel/gdb[]. An older version is also present in FreeBSD 11 and "
+"earlier."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:178
+msgid ""
+"To enter into the debugger and begin getting information from the dump, "
+"start kgdb:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:182
+#, no-wrap
+msgid "# kgdb -n N\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:186
+msgid ""
+"Where _N_ is the suffix of the [.filename]#vmcore.N# to examine. To open "
+"the most recent dump use:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:190
+#, no-wrap
+msgid "# kgdb -n last\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:194
+msgid ""
+"Normally, man:kgdb[1] 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:198
+#, no-wrap
+msgid "# kgdb /boot/kernel/kernel /var/crash/vmcore.0\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:201
+msgid ""
+"You can debug the crash dump using the kernel sources just like you can for "
+"any other program."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:208
+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 `list` 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:301
+#, no-wrap
+msgid ""
+" 1:# cd /usr/obj/usr/src/sys/KERNCONF\n"
+" 2:# kgdb kernel.debug /var/crash/vmcore.0\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:(kgdb) list *0xc0713860\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 < delay; x += incr) {\n"
+"48:663 if ((lapic->icr_lo & 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:(kgdb) backtrace\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:(kgdb) quit\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:307
+msgid ""
+"If your system is crashing regularly and you are running out of disk space, "
+"deleting old [.filename]#vmcore# files in [.filename]#/var/crash# could save "
+"a considerable amount of disk space!"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:310
+#, no-wrap
+msgid "On-Line Kernel Debugging Using DDB"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:314
+msgid ""
+"While `kgdb` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:318
+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 `kgdb` "
+"does."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:320
+msgid "To configure your kernel to include DDB, add the options"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:323
+#, no-wrap
+msgid "options KDB\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:328
+#, no-wrap
+msgid "options DDB\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:332
+msgid ""
+"to your config file, and rebuild. (See extref:{handbook}[The FreeBSD "
+"Handbook] for details on configuring the FreeBSD kernel)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:338
+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 `-d`. 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 `boot -d` at the loader prompt."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:342
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:346
+#, no-wrap
+msgid "# sysctl debug.kdb.enter=1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:353
+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 kbd:[Ctrl+Alt"
+"+ESC]. 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 "
+"(`options BREAK_TO_DEBUGGER` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:356
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:358
+msgid "To obtain the unattended functionality, add:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:362
+#, no-wrap
+msgid "options\tKDB_UNATTENDED\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:365
+msgid "to the kernel configuration file and rebuild/reinstall."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:368
+msgid ""
+"The DDB commands roughly resemble some `gdb` commands. The first thing you "
+"probably need to do is to set a breakpoint:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:372
+#, no-wrap
+msgid " break function-name address\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:377
+msgid ""
+"Numbers are taken hexadecimal by default, but to make them distinct from "
+"symbol names; hexadecimal numbers starting with the letters `a-f` need to be "
+"preceded with `0x` (this is optional for other numbers). Simple expressions "
+"are allowed, for example: `function-name + 0x103`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:379
+msgid "To exit the debugger and continue execution, type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:383
+#, no-wrap
+msgid " continue\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:386
+msgid "To get a stack trace of the current thread, use:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:390
+#, no-wrap
+msgid " trace\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:393
+msgid ""
+"To get a stack trace of an arbitrary thread, specify a process ID or thread "
+"ID as a second argument to `trace`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:395
+msgid "If you want to remove a breakpoint, use"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:400
+#, no-wrap
+msgid ""
+" del\n"
+" del address-expression\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:404
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:408
+#, no-wrap
+msgid " show b\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:411
+msgid "or:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:415
+#, no-wrap
+msgid " show break\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:418
+msgid "To single-step the kernel, try:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:422
+#, no-wrap
+msgid " s\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:425
+msgid ""
+"This will step into functions, but you can make DDB trace them until the "
+"matching return statement is reached by:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:429
+#, no-wrap
+msgid " n\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:435
+msgid ""
+"This is different from ``gdb``'s `next` statement; it is like ``gdb``'s "
+"`finish`. Pressing kbd:[n] more than once will cause a continue."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:438
+msgid "To examine data from memory, use (for example):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:445
+#, no-wrap
+msgid ""
+" x/wx 0xf0133fe0,40\n"
+" x/hd db_symtab_space\n"
+" x/bc termbuf,10\n"
+" x/s stringbuf\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:450
+msgid ""
+"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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:454
+#, no-wrap
+msgid " x ,10\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:457
+msgid "Similarly, use"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:461
+#, no-wrap
+msgid " x/ia foofunc,10\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:464
+msgid ""
+"to disassemble the first 0x10 instructions of `foofunc`, and display them "
+"along with their offset from the beginning of `foofunc`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:466
+msgid "To modify memory, use the write command:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:471
+#, no-wrap
+msgid ""
+" w/b termbuf 0xa 0xb 0\n"
+" w/w 0xf0010030 0 0\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:475
+msgid ""
+"The command modifier (`b`/`h`/`w`) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:477
+msgid "If you need to know the current registers, use:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:481
+#, no-wrap
+msgid " show reg\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:484
+msgid "Alternatively, you can display a single register value by e.g."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:488
+#, no-wrap
+msgid " p $eax\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:491
+msgid "and modify it by:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:495
+#, no-wrap
+msgid " set $eax new-value\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:498
+msgid "Should you need to call some kernel functions from DDB, simply say:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:502
+#, no-wrap
+msgid " call func(arg1, arg2, ...)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:505
+msgid "The return value will be printed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:507
+msgid "For a man:ps[1] style summary of all running processes, use:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:511
+#, no-wrap
+msgid " ps\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:516
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:520
+#, no-wrap
+msgid " panic\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:523
+msgid ""
+"This will cause your kernel to dump core and reboot, so you can later "
+"analyze the core on a higher level with man:kgdb[1]."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:527
+#, no-wrap
+msgid " call boot(0)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:531
+msgid ""
+"Might be a good way to cleanly shut down the running system, `sync()` 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:535
+#, no-wrap
+msgid " reset\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:538
+msgid ""
+"This is the final way out of disaster and almost the same as hitting the Big "
+"Red Button."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:540
+msgid "If you need a short command summary, simply type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:544
+#, no-wrap
+msgid " help\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:548
+msgid ""
+"It is highly recommended to have a printed copy of the man:ddb[4] manual "
+"page ready for a debugging session. Remember that it is hard to read the on-"
+"line manual while single-stepping the kernel."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:550
+#, no-wrap
+msgid "On-Line Kernel Debugging Using Remote GDB"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:554
+msgid ""
+"The FreeBSD kernel provides a second KDB backend for on-line debugging: man:"
+"gdb[4]. This feature has been supported since FreeBSD 2.2, and it is "
+"actually a very neat one."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:560
+msgid ""
+"GDB has supported _remote debugging_ for a long time. This is done using a "
+"very simple protocol along a serial line. Unlike the other debugging "
+"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. The other is the "
+"target machine that runs a copy of the very same kernel (optionally stripped "
+"of the debugging information)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:562
+msgid ""
+"In order to use remote GDB, ensure that the following options are present in "
+"your kernel configuration:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:567
+#, no-wrap
+msgid ""
+"makeoptions DEBUG=-g\n"
+"options KDB\n"
+"options GDB\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:570
+msgid ""
+"Note that the `GDB` option is turned off by default in `GENERIC` kernels on -"
+"STABLE and -RELEASE branches, but enabled on -CURRENT."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:574
+msgid ""
+"Once built, copy the kernel to the target machine, and boot it. 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 man:uart[4] for "
+"information on how to set the flags on a uart device."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:577
+msgid ""
+"The target machine must be made to enter the GDB backend, either due to a "
+"panic or by taking a purposeful trap into the debugger. Before doing this, "
+"select the GDB debugger backend:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:581
+#, no-wrap
+msgid ""
+"# sysctl debug.kdb.current=gdb\n"
+"debug.kdb.current: ddb -> gdb\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:588
+msgid ""
+"The supported backends can be listed by the `debug.kdb.available` sysctl. "
+"If the kernel configuration includes `options DDB`, then man:ddb[4] will be "
+"selected by default. If `gdb` does not appear in the list of available "
+"backends, then the debug serial port may not have been configured correctly."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:591
+msgid "Then, force entry to the debugger:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:595
+#, no-wrap
+msgid ""
+"# sysctl debug.kdb.enter=1\n"
+"debug.kdb.enter: 0KDB: enter: sysctl debug.kdb.enter\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:599
+msgid ""
+"The target machine now awaits connection from a remote GDB client. On the "
+"debugging machine, go to the compile directory of the target kernel, and "
+"start `gdb`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:610
+#, no-wrap
+msgid ""
+"# cd /usr/obj/usr/src/amd64.amd64/sys/GENERIC/\n"
+"# kgdb kernel\n"
+"GNU gdb (GDB) 10.2 [GDB v10.2 for FreeBSD]\n"
+"Copyright (C) 2021 Free Software Foundation, Inc.\n"
+"...\n"
+"Reading symbols from kernel...\n"
+"Reading symbols from /usr/obj/usr/src/amd64.amd64/sys/GENERIC/kernel.debug...\n"
+"(kgdb)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:613
+msgid ""
+"Initialize the remote debugging session (assuming the first serial port is "
+"being used) by:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:617
+#, no-wrap
+msgid "(kgdb) target remote /dev/cuau0\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:620
+msgid "Your hosting GDB will now gain control over the target kernel:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:627
+#, no-wrap
+msgid ""
+"Remote debugging using /dev/cuau0\n"
+"kdb_enter (why=<optimized out>, msg=<optimized out>) at /usr/src/sys/kern/subr_kdb.c:506\n"
+"506 kdb_why = KDB_WHY_UNSET;\n"
+"(kgdb)\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:635
+msgid ""
+"Depending on the compiler used, some local variables may appear as "
+"`<optimized out>`, preventing them from being inspected directly by `gdb`. "
+"If this causes problems while debugging, it is possible to build the kernel "
+"at a decreased optimization level, which may improve the visibility of some "
+"variables. This can be done by passing `COPTFLAGS=-O1` to man:make[1]. "
+"However, certain classes of kernel bugs may manifest differently (or not at "
+"all) when the optimization level is changed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:639
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:641
+#, no-wrap
+msgid "Debugging a Console Driver"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:647
+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 `-h` at "
+"the `Boot:` prompt), and hook up a standard terminal onto your first serial "
+"port. DDB works on any configured console driver, including a serial "
+"console."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:649
+#, no-wrap
+msgid "Debugging Deadlocks"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:654
+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 "
+"man:ddb[4] as described in the previous section. Include the output of `ps` "
+"and `trace` for suspected processes in the report."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:658
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:669
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:672
+msgid ""
+"When a deadlock occurs, in addition to the output of the `ps` command, "
+"provide information from the `show pcpu`, `show allpcpu`, `show locks`, "
+"`show alllocks`, `show lockedvnods` and `alltrace`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:674
+msgid ""
+"To obtain meaningful backtraces for threaded processes, use `thread thread-"
+"id` to switch to the thread stack, and do a backtrace with `where`."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:676
+#, no-wrap
+msgid "Kernel debugging with Dcons"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:682
+msgid ""
+"man:dcons[4] 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 FireWire(R) device. Currently, "
+"FreeBSD provides two ways to interact with the buffer from outside of the "
+"kernel using man:dconschat[8]."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:683
+#, no-wrap
+msgid "Dcons over FireWire(R)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:691
+msgid ""
+"Most FireWire(R) (IEEE1394) host controllers are based on the OHCI "
+"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 man:dcons[4]. man:dcons[4] provides similar functionality "
+"as a serial console. It emulates two serial ports, one for the console and "
+"DDB, the other for GDB. Since remote memory access is fully handled by the "
+"hardware, the man:dcons[4] buffer is accessible even when the system crashes."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:694
+msgid ""
+"FireWire(R) devices are not limited to those integrated into motherboards. "
+"PCI cards exist for desktops, and a cardbus interface can be purchased for "
+"laptops."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:695
+#, no-wrap
+msgid "Enabling FireWire(R) and Dcons support on the target machine"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:698
+msgid ""
+"To enable FireWire(R) and Dcons support in the kernel of the _target "
+"machine_:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:700
+msgid ""
+"Make sure your kernel supports `dcons`, `dcons_crom` and `firewire`. `Dcons` "
+"should be statically linked with the kernel. For `dcons_crom` and "
+"`firewire`, modules should be OK."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:701
+msgid ""
+"Make sure physical DMA is enabled. You may need to add `hw.firewire."
+"phydma_enable=1` to [.filename]#/boot/loader.conf#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:702
+msgid "Add options for debugging."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:703
+msgid ""
+"Add `dcons_gdb=1` in [.filename]#/boot/loader.conf# if you use GDB over "
+"FireWire(R)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:704
+msgid "Enable `dcons` in [.filename]#/etc/ttys#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:705
+msgid ""
+"Optionally, to force `dcons` to be the high-level console, add `hw.firewire."
+"dcons_crom.force_console=1` to [.filename]#loader.conf#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:707
+msgid ""
+"To enable FireWire(R) and Dcons support in man:loader[8] on i386 or amd64:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:709
+msgid ""
+"Add `LOADER_FIREWIRE_SUPPORT=YES` in [.filename]#/etc/make.conf# and rebuild "
+"man:loader[8]:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:713
+#, no-wrap
+msgid "# cd /sys/boot/i386 && make clean && make && make install\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:716
+msgid ""
+"To enable man:dcons[4] as an active low-level console, add `boot_multicons="
+"\"YES\"` to [.filename]#/boot/loader.conf#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:719
+msgid ""
+"Here are a few configuration examples. A sample kernel configuration file "
+"would contain:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:728
+#, no-wrap
+msgid ""
+"device dcons\n"
+"device dcons_crom\n"
+"options KDB\n"
+"options DDB\n"
+"options GDB\n"
+"options ALT_BREAK_TO_DEBUGGER\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:731
+msgid "And a sample [.filename]#/boot/loader.conf# would contain:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:739
+#, 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\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:741
+#, no-wrap
+msgid "Enabling FireWire(R) and Dcons support on the host machine"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:744
+msgid "To enable FireWire(R) support in the kernel on the _host machine_:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:748
+#, no-wrap
+msgid "# kldload firewire\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:751
+msgid ""
+"Find out the EUI64 (the unique 64 bit identifier) of the FireWire(R) host "
+"controller, and use man:fwcontrol[8] or `dmesg` to find the EUI64 of the "
+"target machine."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:753
+msgid "Run man:dconschat[8], with:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:757
+#, no-wrap
+msgid "# dconschat -e \\# -br -G 12345 -t 00-11-22-33-44-55-66-77\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:760
+msgid ""
+"The following key combinations can be used once man:dconschat[8] is running:"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:766
+#, no-wrap
+msgid "kbd:[~+.]"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:768
+#, no-wrap
+msgid "Disconnect"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:769
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:772
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:775
+#, no-wrap
+msgid "kbd:[~]"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:771
+#, no-wrap
+msgid "ALT BREAK"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:774
+#, no-wrap
+msgid "RESET target"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:776
+#, no-wrap
+msgid "Suspend dconschat"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:779
+msgid ""
+"Attach remote GDB by starting man:kgdb[1] with a remote debugging session:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:783
+#, no-wrap
+msgid " kgdb -r :12345 kernel\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:785
+#, no-wrap
+msgid "Some general tips"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:788
+msgid "Here are some general tips:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:790
+msgid ""
+"To take full advantage of the speed of FireWire(R), disable other slow "
+"console drivers:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:795
+#, no-wrap
+msgid ""
+"# conscontrol delete ttyd0\t # serial console\n"
+"# conscontrol delete consolectl\t# video/keyboard\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:798
+msgid ""
+"There exists a GDB mode for man:emacs[1]; this is what you will need to add "
+"to your [.filename]#.emacs#:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:805
+#, no-wrap
+msgid ""
+"(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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:808
+msgid "And for DDD ([.filename]#devel/ddd#):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:815
+#, 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\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:817
+#, no-wrap
+msgid "Dcons with KVM"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:821
+msgid ""
+"We can directly read the man:dcons[4] buffer via [.filename]#/dev/mem# for "
+"live systems, and in the core dump for crashed systems. These give you "
+"similar output to `dmesg -a`, but the man:dcons[4] buffer includes more "
+"information."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:822
+#, no-wrap
+msgid "Using Dcons with KVM"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:825
+msgid "To use man:dcons[4] with KVM:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:827
+msgid "Dump a man:dcons[4] buffer of a live system:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:831
+#, no-wrap
+msgid "# dconschat -1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:834
+msgid "Dump a man:dcons[4] buffer of a crash dump:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:838
+#, no-wrap
+msgid "# dconschat -1 -M vmcore.XX\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:841
+msgid "Live core debugging can be done via:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:846
+#, no-wrap
+msgid ""
+"# fwcontrol -m target_eui64\n"
+"# kgdb kernel /dev/fwmem0.2\n"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:849
+#, no-wrap
+msgid "Glossary of Kernel Options for Debugging"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:852
+msgid ""
+"This section provides a brief glossary of compile-time kernel options used "
+"for debugging:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:854
+msgid ""
+"`options KDB`: compiles in the kernel debugger framework. Required for "
+"`options DDB` and `options GDB`. Little or no performance overhead. By "
+"default, the debugger will be entered on panic instead of an automatic "
+"reboot."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:855
+msgid ""
+"`options KDB_UNATTENDED`: change the default value of the `debug."
+"debugger_on_panic` sysctl to 0, which controls whether the debugger is "
+"entered on panic. When `options KDB` 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 `options "
+"KDB_UNATTENDED` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:856
+msgid ""
+"`options KDB_TRACE`: change the default value of the `debug.trace_on_panic` "
+"sysctl to 1, which controls whether the debugger automatically prints a "
+"stack trace on panic. Especially if running with `options KDB_UNATTENDED`, "
+"this can be helpful to gather basic debugging information on the serial or "
+"firewire console while still rebooting to recover."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:857
+msgid ""
+"`options DDB`: 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 `options KDB`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:858
+msgid ""
+"`options GDB`: 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 `options KDB`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:859
+msgid ""
+"`options BREAK_TO_DEBUGGER`, `options ALT_BREAK_TO_DEBUGGER`: 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:860
+msgid ""
+"`options INVARIANTS`: 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 `options "
+"INVARIANT_SUPPORT`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:861
+msgid ""
+"`options INVARIANT_SUPPORT`: many of the tests present in `options "
+"INVARIANTS` require modified data structures or additional kernel symbols to "
+"be defined."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:862
+msgid ""
+"`options WITNESS`: 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 `show locks`, `show witness` and `show alllocks` DDB commands. This "
+"debug option has significant performance overhead, which may be somewhat "
+"mitigated through the use of `options WITNESS_SKIPSPIN`. Detailed "
+"documentation may be found in man:witness[4]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:863
+msgid ""
+"`options WITNESS_SKIPSPIN`: 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 `options WITNESS`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:864
+msgid ""
+"`options WITNESS_KDB`: change the default value of the `debug.witness.kdb` "
+"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 `options WITNESS`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:865
+msgid ""
+"`options SOCKBUF_DEBUG`: 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:866
+msgid ""
+"`options DEBUG_VFS_LOCKS`: track lock acquisition points for lockmgr/vnode "
+"locks, expanding the amount of information displayed by `show lockedvnods` "
+"in DDB. This option has a measurable performance impact."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:867
+msgid ""
+"`options DEBUG_MEMGUARD`: a replacement for the man:malloc[9] kernel memory "
+"allocator that uses the VM system to detect reads or writes from allocated "
+"memory after free. Details may be found in man:memguard[9]. This option has "
+"a significant performance impact, but can be very helpful in debugging "
+"kernel memory corruption bugs."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:868
+msgid ""
+"`options DIAGNOSTIC`: enable additional, more expensive diagnostic tests "
+"along the lines of `options INVARIANTS`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:869
+msgid ""
+"`options KASAN`: enable the Kernel Address Sanitizer. This enables compiler "
+"instrumentation which can be used to detect invalid memory accesses in the "
+"kernel, such as use-after-frees and buffer overflows. This largely "
+"supersedes `options DEBUG_MEMGUARD`. See man:kasan[9] for details, and for "
+"the currently supported platforms."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/kerneldebug/_index.adoc:869
+msgid ""
+"`options KMSAN`: enable the Kernel Memory Sanitizer. This enables compiler "
+"instrumentation which can be used to detect uses of uninitialized memory. "
+"See man:kmsan[9] for details, and for the currently supported platforms."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/l10n/_index.po b/documentation/content/en/books/developers-handbook/l10n/_index.po
new file mode 100644
index 0000000000..92fe40e244
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/l10n/_index.po
@@ -0,0 +1,487 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:21-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:1
+#, no-wrap
+msgid "Localization and Internationalization - L10N and I18N in FreeBSD"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:1
+#, no-wrap
+msgid "Chapter 4. Localization and Internationalization - L10N and I18N"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:14
+#, no-wrap
+msgid "Localization and Internationalization - L10N and I18N"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:52
+#, no-wrap
+msgid "Programming I18N Compliant Applications"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:59
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:63
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:64
+#, no-wrap
+msgid "A Call to Unify the I18N Effort"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:69
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:72
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:75
+msgid ""
+"The {freebsd-i18n} has been established. If you are an I18N/L10N developer, "
+"please send your comments, ideas, questions, and anything you deem related "
+"to it."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:76
+#, no-wrap
+msgid "Perl and Python"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:80
+msgid ""
+"Perl and Python have I18N and wide character handling libraries. Please use "
+"them for I18N compliance."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:82
+#, no-wrap
+msgid "Localized Messages with POSIX.1 Native Language Support (NLS)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:86
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:88
+#, no-wrap
+msgid "Organizing Localized Messages into Catalog Files"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:94
+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 `.msg` extension. For instance, the "
+"Hungarian messages for ISO8859-2 encoding should be stored in a file called "
+"[.filename]#hu_HU.ISO8859-2#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:99
+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 `$` "
+"sign. Set boundaries are also separated by special comments, where the "
+"keyword `set` must directly follow the `$` sign. The `set` keyword is then "
+"followed by the set number. For example:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:103
+#, no-wrap
+msgid "$set 1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:107
+msgid ""
+"The actual message entries start with the message number and followed by the "
+"localized message. The well-known modifiers from man:printf[3] are accepted:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:111
+#, no-wrap
+msgid "15 \"File not found: %s\\n\"\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:117
+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 man:"
+"gencat[1] 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 man:gencat[1]."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:119
+#, no-wrap
+msgid "Using the Catalog Files from the Source Code"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:130
+msgid ""
+"Using the catalog files is simple. To use the related functions, [."
+"filename]#nl_types.h# must be included. Before using a catalog, it has to "
+"be opened with man:catopen[3]. 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 grep. This name will be used when "
+"looking for the compiled catalog file. The man:catopen[3] call looks for "
+"this file in [.filename]#/usr/share/nls/locale/catname# and in [.filename]#/"
+"usr/local/share/nls/locale/catname#, where `locale` is the locale set and "
+"`catname` is the catalog name being discussed. The second parameter is a "
+"constant, which can have two values:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:132
+msgid ""
+"`NL_CAT_LOCALE`, which means that the used catalog file will be based on "
+"`LC_MESSAGES`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:133
+msgid "`0`, which means that `LANG` has to be used to open the proper catalog."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:136
+msgid ""
+"The man:catopen[3] call returns a catalog identifier of type `nl_catd`. "
+"Please refer to the manual page for a list of possible returned error codes."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:139
+msgid ""
+"After opening a catalog man:catgets[3] can be used to retrieve a message. "
+"The first parameter is the catalog identifier returned by man:catopen[3], "
+"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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:141
+msgid ""
+"After using the catalog file, it must be closed by calling man:catclose[3], "
+"which has one argument, the catalog id."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:143
+#, no-wrap
+msgid "A Practical Example"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:146
+msgid ""
+"The following example will demonstrate an easy solution on how to use NLS "
+"catalogs in a flexible way."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:148
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:155
+#, no-wrap
+msgid ""
+"#ifdef WITHOUT_NLS\n"
+"#define getstr(n)\t nlsstr[n]\n"
+"#else\n"
+"#include nl_types.h\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:159
+#, no-wrap
+msgid ""
+"extern nl_catd\t\t catalog;\n"
+"#define getstr(n)\t catgets(catalog, 1, n, nlsstr[n])\n"
+"#endif\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:161
+#, no-wrap
+msgid "extern char\t\t*nlsstr[];\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:164
+msgid ""
+"Next, put these lines into the global declaration part of the main source "
+"file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:171
+#, no-wrap
+msgid ""
+"#ifndef WITHOUT_NLS\n"
+"#include nl_types.h\n"
+"nl_catd\t catalog;\n"
+"#endif\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:181
+#, no-wrap
+msgid ""
+"/*\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"
+"};\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:184
+msgid ""
+"Next come the real code snippets, which open, read, and close the catalog:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:190
+#, no-wrap
+msgid ""
+"#ifndef WITHOUT_NLS\n"
+"\tcatalog = catopen(\"myapp\", NL_CAT_LOCALE);\n"
+"#endif\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:192
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:196
+#, no-wrap
+msgid "...\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:194
+#, no-wrap
+msgid "printf(getstr(1));\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:200
+#, no-wrap
+msgid ""
+"#ifndef WITHOUT_NLS\n"
+"\tcatclose(catalog);\n"
+"#endif\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:202
+#, no-wrap
+msgid "Reducing Strings to Localize"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:206
+msgid ""
+"There is a good way of reducing the strings that need to be localized by "
+"using libc 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:208
+msgid "First, here is an example that does not use libc error messages:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:215
+#, no-wrap
+msgid ""
+"#include err.h\n"
+"...\n"
+"if (!S_ISDIR(st.st_mode))\n"
+"\terrx(1, \"argument is not a directory\");\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:218
+msgid ""
+"This can be transformed to print an error message by reading `errno` and "
+"printing an error message accordingly:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:228
+#, no-wrap
+msgid ""
+"#include err.h\n"
+"#include errno.h\n"
+"...\n"
+"if (!S_ISDIR(st.st_mode)) {\n"
+"\terrno = ENOTDIR;\n"
+"\terr(1, NULL);\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:233
+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 \"Not a "
+"directory\" 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# in order to directly access `errno`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:235
+msgid ""
+"It is worth to note that there are cases when `errno` is set automatically "
+"by a preceding call, so it is not necessary to set it explicitly:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:242
+#, no-wrap
+msgid ""
+"#include err.h\n"
+"...\n"
+"if ((p = malloc(size)) == NULL)\n"
+"\terr(1, NULL);\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:245
+#, no-wrap
+msgid "Making use of [.filename]#bsd.nls.mk#"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:250
+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# introduces some macros. It "
+"is not necessary to include [.filename]#bsd.nls.mk# explicitly, it is pulled "
+"in from the common Makefiles, such as [.filename]#bsd.prog.mk# or [."
+"filename]#bsd.lib.mk#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:254
+msgid ""
+"Usually it is enough to define `NLSNAME`, which should have the catalog name "
+"mentioned as the first argument of man:catopen[3] and list the catalog files "
+"in `NLS` without their `.msg` extension. Here is an example, which makes it "
+"possible to to disable NLS when used with the code examples before. The "
+"`WITHOUT_NLS` man:make[1] variable has to be defined in order to build the "
+"program without NLS support."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:264
+#, no-wrap
+msgid ""
+".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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/l10n/_index.adoc:271
+msgid ""
+"Conventionally, the catalog files are placed under the [.filename]#nls# "
+"subdirectory and this is the default behavior of [.filename]#bsd.nls.mk#. "
+"It is possible, though to override the location of the catalogs with the "
+"`NLSSRCDIR` man:make[1] variable. The default name of the precompiled "
+"catalog files also follow the naming convention mentioned before. It can be "
+"overridden by setting the `NLSNAME` 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#, please refer to the file itself, it is short and easy "
+"to understand."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/parti.po b/documentation/content/en/books/developers-handbook/parti.po
new file mode 100644
index 0000000000..2633ca0fc2
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/parti.po
@@ -0,0 +1,29 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-01-08 11:34-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/parti.adoc:1
+#, no-wrap
+msgid "Part I. Basics"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/parti.adoc:11
+#, no-wrap
+msgid "Basics"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/partii.po b/documentation/content/en/books/developers-handbook/partii.po
new file mode 100644
index 0000000000..38000c08ae
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/partii.po
@@ -0,0 +1,29 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-01-08 11:34-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/partii.adoc:1
+#, no-wrap
+msgid "Part II. Interprocess Communication"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/partii.adoc:11
+#, no-wrap
+msgid "Interprocess Communication"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/partiii.po b/documentation/content/en/books/developers-handbook/partiii.po
new file mode 100644
index 0000000000..ae1194a66e
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/partiii.po
@@ -0,0 +1,29 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-01-08 11:34-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/partiii.adoc:1
+#, no-wrap
+msgid "Part III. Kernel"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/partiii.adoc:11
+#, no-wrap
+msgid "Kernel"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/partiv.po b/documentation/content/en/books/developers-handbook/partiv.po
new file mode 100644
index 0000000000..9731bd3d63
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/partiv.po
@@ -0,0 +1,29 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-01-08 11:34-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/partiv.adoc:1
+#, no-wrap
+msgid "Part IV. Architectures"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/partiv.adoc:11
+#, no-wrap
+msgid "Architectures"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/partv.po b/documentation/content/en/books/developers-handbook/partv.po
new file mode 100644
index 0000000000..c1d910f5c0
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/partv.po
@@ -0,0 +1,29 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-01-08 11:34-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/partv.adoc:1
+#, no-wrap
+msgid "Part V. Appendices"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/partv.adoc:11
+#, no-wrap
+msgid "Appendices"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/policies/_index.po b/documentation/content/en/books/developers-handbook/policies/_index.po
new file mode 100644
index 0000000000..baed8e799f
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/policies/_index.po
@@ -0,0 +1,711 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:20-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:16
+#, no-wrap
+msgid "Source Tree Guidelines and Policies"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:1
+#, no-wrap
+msgid "Chapter 5. Source Tree Guidelines and Policies"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:54
+msgid ""
+"This chapter documents various guidelines and policies in force for the "
+"FreeBSD source tree."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:56
+#, no-wrap
+msgid "Style Guidelines"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:60
+msgid ""
+"Consistent coding style is extremely important, particularly with large "
+"projects like FreeBSD. Code should follow the FreeBSD coding styles "
+"described in man:style[9] and man:style.Makefile[5]."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:62
+#, no-wrap
+msgid "`MAINTAINER` on Makefiles"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:66
+msgid ""
+"If a particular portion of the FreeBSD [.filename]#src/# distribution is "
+"being maintained by a person or group of persons, this is communicated "
+"through an entry in [.filename]#src/MAINTAINERS#. Maintainers of ports "
+"within the Ports Collection express their maintainership to the world by "
+"adding a `MAINTAINER` line to the [.filename]#Makefile# of the port in "
+"question:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:70
+#, no-wrap
+msgid "MAINTAINER= email-addresses\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:77
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:80
+msgid "The role of the maintainer is as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:82
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:83
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:84
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:86
+#, no-wrap
+msgid "Contributed Software"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:91
+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 _contributed_ software. Some examples are sendmail, gcc and patch."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:94
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:98
+msgid ""
+"Since this is the case, after some debate one of these methods has been "
+"selected as the \"official\" 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 \"official\" 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:102
+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 ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:106
+msgid ""
+"Because it makes it harder to import future versions minor, trivial and/or "
+"cosmetic changes are _strongly discouraged_ on files that are still tracking "
+"the vendor branch."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:109
+#, no-wrap
+msgid "Vendor Imports with SVN"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:112
+msgid ""
+"This section describes the vendor import procedure with Subversion in "
+"details."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:115
+#, no-wrap
+msgid "*Preparing the Tree*\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:118
+msgid ""
+"If this is your first import after the switch to SVN, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:122
+msgid ""
+"During the conversion from CVS to SVN, vendor branches were imported with "
+"the same layout as the main tree. For example, the foo vendor sources ended "
+"up in [.filename]#vendor/foo/dist/contrib/foo#, but it is pointless and "
+"rather inconvenient. What we really want is to have the vendor source "
+"directly in [.filename]#vendor/foo/dist#, like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:131
+#, no-wrap
+msgid ""
+"% cd vendor/foo/dist/contrib/foo\n"
+"% svn move $(svn list) ../..\n"
+"% cd ../..\n"
+"% svn remove contrib\n"
+"% svn propdel -R svn:mergeinfo\n"
+"% svn commit\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:135
+msgid ""
+"Note that, the `propdel` bit is necessary because starting with 1.5, "
+"Subversion will automatically add `svn:mergeinfo` 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 ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:141
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:146
+msgid ""
+"Check the [.filename]#dist# 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:151
+#, no-wrap
+msgid ""
+"% svn propdel svn:keywords -R .\n"
+"% svn commit\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:154
+msgid ""
+"Bootstrapping of `svn:mergeinfo` 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:160
+#, no-wrap
+msgid ""
+"% cd head/contrib/foo\n"
+"% svn merge --record-only ^/vendor/foo/dist@12345678 .\n"
+"% svn commit\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:163
+msgid ""
+"With some shells, the `^` in the above command may need to be escaped with a "
+"backslash."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:164
+#, no-wrap
+msgid "*Importing New Sources*\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:168
+msgid ""
+"Prepare a full, clean tree of the vendor sources. With SVN, we can keep a "
+"full distribution in the vendor tree without bloating the main tree. Import "
+"everything but merge only what is needed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:171
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:178
+#, no-wrap
+msgid ""
+"% cd vendor/foo/dist\n"
+"% svn list -R | grep -v '/$' | sort > ../old\n"
+"% cd ../foo-9.9\n"
+"% find . -type f | cut -c 3- | sort > ../new\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:181
+msgid ""
+"With these two files, the following command will list removed files (files "
+"only in [.filename]#old#):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:185
+#, no-wrap
+msgid "% comm -23 ../old ../new\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:188
+msgid ""
+"While the command below will list added files (files only in [."
+"filename]#new#):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:192
+#, no-wrap
+msgid "% comm -13 ../old ../new\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:195
+msgid "Let us put this together:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:203
+#, no-wrap
+msgid ""
+"% cd vendor/foo/foo-9.9\n"
+"% tar cf - . | tar xf - -C ../dist\n"
+"% cd ../dist\n"
+"% comm -23 ../old ../new | xargs svn remove\n"
+"% comm -13 ../old ../new | xargs svn add\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:210
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:213
+msgid "Check properties on any new files:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:215
+msgid "All text files should have `svn:eol-style` set to `native`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:216
+msgid ""
+"All binary files should have `svn:mime-type` set to `application/octet-"
+"stream`, unless there is a more appropriate media type."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:217
+msgid "Executable files should have `svn:executable` set to `*`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:218
+msgid "There should be no other properties on any file in the tree."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:222
+msgid ""
+"You are ready to commit, but you should first check the output of `svn stat` "
+"and `svn diff` to make sure everything is in order."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:226
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:230
+#, no-wrap
+msgid "% svn copy ^/vendor/foo/dist svn_base/vendor/foo/9.9\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:233
+msgid ""
+"To get the new tag, you can update your working copy of [.filename]#vendor/"
+"foo#."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:237
+msgid ""
+"If you choose to do the copy in the checkout instead, do not forget to "
+"remove the generated `svn:mergeinfo` as described above."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:240
+#, no-wrap
+msgid "*Merging to __-HEAD__*\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:243
+msgid ""
+"After you have prepared your import, it is time to merge. Option `--"
+"accept=postpone` tells SVN not to handle merge conflicts yet, because they "
+"will be taken care of manually:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:249
+#, no-wrap
+msgid ""
+"% cd head/contrib/foo\n"
+"% svn update\n"
+"% svn merge --accept=postpone ^/vendor/foo/dist\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:252
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:256
+#, no-wrap
+msgid "% svn diff --no-diff-deleted --old=^/vendor/foo/dist --new=.\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:259
+msgid ""
+"`--no-diff-deleted` tells SVN not to check files that are in the vendor tree "
+"but not in the main tree."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:265
+msgid ""
+"With SVN, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:268
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:269
+#, no-wrap
+msgid "*Commit*\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:275
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:277
+#, no-wrap
+msgid "Encumbered Files"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:283
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:285
+msgid ""
+"Any file which is interpreted or executed by the system CPU(s) and not in "
+"source format is encumbered."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:286
+msgid "Any file with a license more restrictive than BSD or GNU is encumbered."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:287
+msgid ""
+"A file which contains downloadable binary data for use by the hardware is "
+"not encumbered, unless (1) or (2) apply to it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:288
+msgid ""
+"Any encumbered file requires specific approval from the link:https://www."
+"FreeBSD.org/administration/#t-core[Core Team] before it is added to the "
+"repository."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:289
+msgid ""
+"Encumbered files go in [.filename]#src/contrib# or [.filename]#src/sys/"
+"contrib#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:290
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:292
+msgid ""
+"In the past binary files were typically uuencoded, and named [."
+"filename]#arch/filename.o.uu#. This is no longer necessary, and binary "
+"files may be added to the repository unchanged."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:293
+msgid "Kernel files:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:294
+msgid ""
+"Should always be referenced in [.filename]#conf/files.*# (for build "
+"simplicity)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:295
+msgid ""
+"Should always be in [.filename]#LINT#, but the link:https://www.FreeBSD.org/"
+"administration/#t-core[Core Team] decides per case if it should be commented "
+"out or not. The link:https://www.FreeBSD.org/administration/#t-core[Core "
+"Team] can, of course, change their minds later on."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:296
+msgid "The _Release Engineer_ decides whether or not it goes into the release."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:298
+msgid "User-land files:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:299
+msgid ""
+"The link:https://www.FreeBSD.org/administration/#t-core[Core team] decides "
+"if the code should be part of `make world`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:300
+msgid ""
+"The link:https://www.FreeBSD.org/administration/#t-re[Release Engineering] "
+"decides if it goes into the release."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:302
+#, no-wrap
+msgid "Shared Libraries"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:306
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:308
+msgid "For ports:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:310
+msgid "Prefer using the number already selected by upstream"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:311
+msgid "If upstream provides symbol versioning, ensure that we use their script"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:313
+msgid "For the base system:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:315
+msgid "Start library version from 1"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:316
+msgid "It is strongly recommended to add symbol versioning to the new library"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:317
+msgid ""
+"If there is an incompatible change, handle it with symbol versioning, "
+"maintaining backward ABI compatibility"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:318
+msgid ""
+"If this is impossible, or the library does not use symbol versioning, bump "
+"the library version"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:319
+msgid ""
+"Before even considering bumping library version for symbol-versioned "
+"library, consult with Release Engineering team, providing reasons why the "
+"change is so important that it should be allowed despite breaking the ABI"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:321
+msgid ""
+"For instance, added functions and bugfixes not changing the interfaces are "
+"fine, while deleted functions, changed function call syntax, etc. should "
+"either provide backward-compat symbols, or will force the major version "
+"number to change."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:323
+msgid ""
+"It is the duty of the committer making the change to handle library "
+"versioning."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/policies/_index.adoc:328
+msgid ""
+"The ELF dynamic linker matches library names literally. There is a popular "
+"convention where library version is written in the form `libexample.so.x.y`, "
+"where x is the major version, and y is minor. Common practice is to set the "
+"library' soname (`DT_SONAME` ELF tag) to `libexample.so.x`, and set up "
+"symlinks `libexample.so.x->libexample.so.x.y`, `libexample.so->libexample.so."
+"x` on library installation for the latest minor version y. Then, since the "
+"static linker searches for `libexample.so` when the `-lexample` command line "
+"option is specified, objects linked with libexample get a dependency on the "
+"right library. Almost all popular build systems use this scheme "
+"automatically."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/secure/_index.po b/documentation/content/en/books/developers-handbook/secure/_index.po
new file mode 100644
index 0000000000..c298451c7b
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/secure/_index.po
@@ -0,0 +1,624 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 10:28-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:1
+#, no-wrap
+msgid "Secure Programming in FreeBSD"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:1
+#, no-wrap
+msgid "Chapter 3. Secure Programming"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:15
+#, no-wrap
+msgid "Secure Programming"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:53
+#, no-wrap
+msgid "Synopsis"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:56
+msgid ""
+"This chapter describes some of the security issues that have plagued UNIX(R) "
+"programmers for decades and some of the new tools available to help "
+"programmers avoid writing exploitable code."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:58
+#, no-wrap
+msgid "Secure Design Methodology"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:63
+msgid ""
+"Writing secure applications takes a very scrutinous and pessimistic outlook "
+"on life. Applications should be run with the principle of \"least privilege"
+"\" 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:67
+msgid ""
+"One of the pitfalls of the UNIX(R) 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. UNIX(R) processes do not execute "
+"synchronously so logical operations are rarely atomic."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:69
+#, no-wrap
+msgid "Buffer Overflows"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:75
+msgid ""
+"Buffer Overflows have been around since the very beginnings of the von "
+"Neumann crossref:bibliography[cod,1] architecture. They first gained "
+"widespread notoriety in 1988 with the Morris Internet worm. Unfortunately, "
+"the same basic attack remains effective today. By far the most common type "
+"of buffer overflow attack is based on corrupting the stack."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:84
+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 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 "
+"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. crossref:bibliography[cod,1] The return address for function "
+"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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:87
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:90
+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 ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:96
+#, no-wrap
+msgid "`strcpy`(char *dest, const char *src)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:100
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:105
+#, no-wrap
+msgid "May overflow the dest buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:101
+#, no-wrap
+msgid "`strcat`(char *dest, const char *src)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:106
+#, no-wrap
+msgid "`getwd`(char *buf)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:110
+#, no-wrap
+msgid "May overflow the buf buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:111
+#, no-wrap
+msgid "`gets`(char *s)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:115
+#, no-wrap
+msgid "May overflow the s buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:116
+#, no-wrap
+msgid "`[vf]scanf`(const char *format, ...)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:120
+#, no-wrap
+msgid "May overflow its arguments."
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:121
+#, no-wrap
+msgid "`realpath`(char *path, char resolved_path[])"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:125
+#, no-wrap
+msgid "May overflow the path buffer"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:126
+#, no-wrap
+msgid "`[v]sprintf`(char *str, const char *format, ...)"
+msgstr ""
+
+#. type: Table
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:129
+#, no-wrap
+msgid "May overflow the str buffer."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:131
+#, no-wrap
+msgid "Example Buffer Overflow"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:134
+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 crossref:bibliography[Phrack,4])"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:138
+#, no-wrap
+msgid "#include <stdio.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:143
+#, no-wrap
+msgid ""
+"void manipulate(char *buffer) {\n"
+" char newbuffer[80];\n"
+" strcpy(newbuffer,buffer);\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:147
+#, no-wrap
+msgid ""
+"int main() {\n"
+" char ch,buffer[4096];\n"
+" int i=0;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:149
+#, no-wrap
+msgid " while ((buffer[i++] = getchar()) != '\\n') {};\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:156
+#, no-wrap
+msgid ""
+" i=1;\n"
+" manipulate(buffer);\n"
+" i=2;\n"
+" printf(\"The value of i is : %d\\n\",i);\n"
+" return 0;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:159
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:163
+msgid ""
+"Obviously more malicious input can be devised to execute actual compiled "
+"instructions (such as exec(/bin/sh))."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:164
+#, no-wrap
+msgid "Avoiding Buffer Overflows"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:174
+msgid ""
+"The most straightforward solution to the problem of stack-overflows is to "
+"always use length restricted memory and string copy functions. `strncpy` "
+"and `strncat` are part of the standard C library. 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 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 `strcpy` when copying a "
+"short string into a large buffer since `strncpy` NUL fills up the size "
+"specified."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:177
+msgid ""
+"Another memory copy implementation exists to get around these problems. The "
+"`strlcpy` and `strlcat` functions guarantee that they will always null "
+"terminate the destination string when given a non-zero length argument."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:178
+#, no-wrap
+msgid "Compiler based run-time bounds checking"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:182
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:185
+msgid ""
+"ProPolice is one such compiler feature, and is integrated into man:gcc[1] "
+"versions 4.1 and later. It replaces and extends the earlier StackGuard man:"
+"gcc[1] extension."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:189
+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 \"canaries\" 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:191
+msgid ""
+"Recompiling your application with ProPolice is an effective means of "
+"stopping most buffer-overflow attacks, but it can still be compromised."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:192
+#, no-wrap
+msgid "Library based run-time bounds checking"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:196
+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 "
+"(`strcpy`, `fscanf`, `getwd`, etc..) and ensure that these functions can "
+"never write past the stack pointer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:198
+msgid "libsafe"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:199
+msgid "libverify"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:200
+msgid "libparanoia"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:205
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:207
+#, no-wrap
+msgid "SetUID issues"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:211
+msgid ""
+"There are at least 6 different IDs associated with any given process, and "
+"you must therefore 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:214
+msgid ""
+"The real user ID can only be changed by a superuser process. The login "
+"program sets this when a user initially logs in and it is seldom changed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:218
+msgid ""
+"The effective user ID is set by the `exec()` functions if a program has its "
+"seteuid bit set. An application can call `seteuid()` 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 `exec()` functions, the previous value is "
+"saved in the saved set-user-ID."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:220
+#, no-wrap
+msgid "Limiting your program's environment"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:228
+msgid ""
+"The traditional method of restricting a process is with the `chroot()` "
+"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 `chdir()` 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 man:"
+"chroot[8] environment, or in many other creative ways."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:233
+msgid ""
+"The behavior of the `chroot()` system call can be controlled somewhat with "
+"the kern.chroot_allow_open_directories `sysctl` variable. When this value "
+"is set to 0, `chroot()` will fail with EPERM if there are any directories "
+"open. If set to the default value of 1, then `chroot()` will fail with "
+"EPERM if there are any directories open and the process is already subject "
+"to a `chroot()` call. For any other value, the check for open directories "
+"will be bypassed completely."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:234
+#, no-wrap
+msgid "FreeBSD's jail functionality"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:238
+msgid ""
+"The concept of a Jail extends upon the `chroot()` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:242
+msgid ""
+"While in a prison, any tests of superuser power within the kernel using the "
+"`suser()` call will fail. However, some calls to `suser()` have been "
+"changed to a new interface `suser_xxx()`. This function is responsible for "
+"recognizing or denying access to superuser power for imprisoned processes."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:244
+msgid "A superuser process within a jailed environment has the power to:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:246
+msgid ""
+"Manipulate credential with `setuid`, `seteuid`, `setgid`, `setegid`, "
+"`setgroups`, `setreuid`, `setregid`, `setlogin`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:247
+msgid "Set resource limits with `setrlimit`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:248
+msgid "Modify some sysctl nodes (kern.hostname)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:249
+msgid "`chroot()`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:250
+msgid "Set flags on a vnode: `chflags`, `fchflags`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:251
+msgid ""
+"Set attributes of a vnode such as file permission, owner, group, size, "
+"access time, and modification time."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:252
+msgid "Bind to privileged ports in the Internet domain (ports < 1024)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:256
+msgid ""
+"`Jail` 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 `suser_xxx` 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:257
+#, no-wrap
+msgid "POSIX(R).1e Process Capabilities"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:260
+msgid ""
+"POSIX(R) has released a working draft that adds event auditing, access "
+"control lists, fine grained privileges, information labeling, and mandatory "
+"access control."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:263
+msgid ""
+"This is a work in progress and is the focus of the http://www.trustedbsd.org/"
+"[TrustedBSD] project. Some of the initial work has been committed to "
+"FreeBSD-CURRENT (cap_set_proc(3))."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:265
+#, no-wrap
+msgid "Trust"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:269
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:274
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:277
+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 (`readdir()`, "
+"`readlink()`, `getpwxxx()`), and all file input."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:279
+#, no-wrap
+msgid "Race Conditions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:283
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/secure/_index.adoc:289
+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 `access(2)` then "
+"`open(2)` is clearly non-atomic. Users can move files in between the two "
+"calls. Instead, privileged applications should `seteuid()` and then call "
+"`open()` directly. Along the same lines, an application should always set a "
+"proper umask before `open()` to obviate the need for spurious `chmod()` "
+"calls."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/sockets/_index.po b/documentation/content/en/books/developers-handbook/sockets/_index.po
new file mode 100644
index 0000000000..946ca418e3
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/sockets/_index.po
@@ -0,0 +1,2246 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:21-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: YAML Front Matter: description
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1
+#, no-wrap
+msgid "FreeBSD Sockets"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1
+#, no-wrap
+msgid "Chapter 7. Sockets"
+msgstr ""
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:15
+#, no-wrap
+msgid "Sockets"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:53
+#, no-wrap
+msgid "Synopsis"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:58
+msgid ""
+"BSD 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 _can_, but they do not have to."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:61
+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 BSD sockets, your "
+"FreeBSD software can smoothly cooperate with a program running on a "
+"Macintosh(R), another one running on a Sun(TM) workstation, yet another one "
+"running under Windows(R) 2000, all connected with an Ethernet-based local "
+"area network."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:63
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:66
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:68
+#, no-wrap
+msgid "Networking and Diversity"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:74
+msgid ""
+"We have already hinted on the _diversity_ of networking. Many different "
+"systems have to talk to each other. And they have to speak the same "
+"language. They also have to _understand_ the same language the same way."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:79
+msgid ""
+"People often think that _body language_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:82
+msgid ""
+"I had not learned much Bulgarian by then, so, instead of saying no, I shook "
+"my head from side to side, the \"universal\" body language for _no_. The "
+"vendor quickly started serving us some almonds."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:90
+msgid ""
+"I then remembered I had been told that in Bulgaria shaking your head "
+"sideways meant _yes_. 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 _meaning_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:94
+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 _language_, but on the same "
+"_interpretation_ of the language."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:96
+#, no-wrap
+msgid "Protocols"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:103
+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 _bits_. "
+"There is a very convincing reason for it: While data travels _inside_ your "
+"computer at speeds approaching the speed of light, it often travels "
+"considerably slower between two computers."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:105
+msgid ""
+"As the languages used in data communications are so terse, we usually refer "
+"to them as _protocols_ rather than languages."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:110
+msgid ""
+"As data travels from one computer to another, it always uses more than one "
+"protocol. These protocols are _layered_. The data can be compared to the "
+"inside of an onion: You have to peel off several layers of \"skin\" to get "
+"to the data. This is best illustrated with a picture:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:111
+#, no-wrap
+msgid "Protocol Layers"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:112
+#, no-wrap
+msgid "layers.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:115
+msgid ""
+"In this example, we are trying to get an image from a web page we are "
+"connected to via an Ethernet."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:118
+msgid ""
+"The image consists of raw data, which is simply a sequence of RGB values "
+"that our software can process, i.e., convert into an image and display on "
+"our monitor."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:123
+msgid ""
+"Alas, our software has no way of knowing how the raw data is organized: Is "
+"it a sequence of RGB values, or a sequence of grayscale intensities, or "
+"perhaps of CMYK 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:125
+msgid "I think you get the picture..."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:128
+msgid ""
+"To inform our software how to handle the raw data, it is encoded as a PNG "
+"file. It could be a GIF, or a JPEG, but it is a PNG."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:130
+msgid "And PNG is a protocol."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:132
+msgid ""
+"At this point, I can hear some of you yelling, _\"No, it is not! It is a "
+"file format!\"_"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:137
+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 "
+"_language_, a terse one at that, communicating to our _process_ how the data "
+"is organized. Ergo, it is a _protocol_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:140
+msgid ""
+"Alas, if all we received was the PNG 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 PNG format as opposed to GIF, "
+"or JPEG, or some other image format?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:144
+msgid ""
+"To obtain that information, we are using another protocol: HTTP. This "
+"protocol can tell us exactly that the data represents an image, and that it "
+"uses the PNG protocol. It can also tell us some other things, but let us "
+"stay focused on protocol layers here."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:147
+msgid ""
+"So, now we have some data wrapped in the PNG protocol, wrapped in the HTTP "
+"protocol. How did we get it from the server?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:151
+msgid ""
+"By using TCP/IP 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:155
+msgid ""
+"Ethernet is an interesting system of connecting computers in a _local area "
+"network_ (LAN). Each computer has a _network interface card_ (NIC), which "
+"has a unique 48-bit ID called its _address_. No two Ethernet NICs in the "
+"world have the same address."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:161
+msgid ""
+"These NICs are all connected with each other. Whenever one computer wants "
+"to communicate with another in the same Ethernet LAN, it sends a message "
+"over the network. Every NIC sees the message. But as part of the Ethernet "
+"_protocol_, the data contains the address of the destination NIC (among "
+"other things). So, only one of all the network interface cards will pay "
+"attention to it, the rest will ignore it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:165
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:169
+msgid ""
+"All data is transferred over the Internet using IP, which stands for "
+"_Internet Protocol_. 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 "
+"_guarantee_ we will receive the data, only that we will know where it came "
+"from _if_ we do receive it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:172
+msgid ""
+"Even if we do receive the data, IP 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:174
+msgid ""
+"It is TCP (_Transmission Control Protocol_) that asks the sender to resend "
+"any lost data and that places it all into the proper order."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:177
+msgid ""
+"All in all, it took _five_ different protocols for one computer to "
+"communicate to another what an image looks like. We received the data "
+"wrapped into the PNG protocol, which was wrapped into the HTTP protocol, "
+"which was wrapped into the TCP protocol, which was wrapped into the IP "
+"protocol, which was wrapped into the Ethernet protocol."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:181
+msgid ""
+"Oh, and by the way, there probably were several other protocols involved "
+"somewhere on the way. For example, if our LAN was connected to the Internet "
+"through a dial-up call, it used the PPP protocol over the modem which used "
+"one (or several) of the various modem protocols, et cetera, et cetera, et "
+"cetera..."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:183
+msgid ""
+"As a developer you should be asking by now, _\"How am I supposed to handle "
+"it all?\"_"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:188
+msgid ""
+"Luckily for you, you are _not_ supposed to handle it all. You _are_ "
+"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 "
+"PPP, etc). Nor do you need to handle the Internet Protocol, or the "
+"Transmission Control Protocol."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:191
+msgid ""
+"In other words, you do not have to do anything to receive the data from the "
+"other computer. Well, you do have to _ask_ for it, but that is almost as "
+"simple as opening a file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:194
+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 HTTP protocol and "
+"the PNG file structure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:198
+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 ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:199
+#, no-wrap
+msgid "Sockets Covered Protocol Layers"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:200
+#, no-wrap
+msgid "slayers.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:203
+msgid ""
+"We only need to understand any protocols that tell us how to _interpret the "
+"data_, not how to _receive_ it from another process, nor how to _send_ it to "
+"another process."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:205
+#, no-wrap
+msgid "The Sockets Model"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:210
+msgid ""
+"BSD sockets are built on the basic UNIX(R) model: _Everything is a file._ In "
+"our example, then, sockets would let us receive an _HTTP file_, so to "
+"speak. It would then be up to us to extract the _PNG file_ from it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:213
+msgid ""
+"Due to the complexity of internetworking, we cannot just use the `open` "
+"system call, or the `open()` C function. Instead, we need to take several "
+"steps to \"opening\" a socket."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:216
+msgid ""
+"Once we do, however, we can start treating the _socket_ the same way we "
+"treat any _file descriptor_: We can `read` from it, `write` to it, `pipe` "
+"it, and, eventually, `close` it."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:218
+#, no-wrap
+msgid "Essential Socket Functions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:222
+msgid ""
+"While FreeBSD offers different functions to work with sockets, we only "
+"_need_ four to \"open\" a socket. And in some cases we only need two."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:224
+#, no-wrap
+msgid "The Client-Server Difference"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:227
+msgid ""
+"Typically, one of the ends of a socket-based data communication is a "
+"_server_, the other is a _client_."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:229
+#, no-wrap
+msgid "The Common Elements"
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:232
+#, no-wrap
+msgid "`socket`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:236
+msgid ""
+"The one function used by both, clients and servers, is man:socket[2]. It is "
+"declared this way:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:240
+#, no-wrap
+msgid "int socket(int domain, int type, int protocol);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:245
+msgid ""
+"The return value is of the same type as that of `open`, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:249
+msgid ""
+"The `domain` argument tells the system what _protocol family_ 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#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:251
+msgid "Use `PF_INET` for UDP, TCP and other Internet protocols (IPv4)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:255
+msgid ""
+"Five values are defined for the `type` argument, again, in [.filename]#sys/"
+"socket.h#. All of them start with \"`SOCK_`\". The most common one is "
+"`SOCK_STREAM`, which tells the system you are asking for a _reliable stream "
+"delivery service_ (which is TCP when used with `PF_INET`)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:257
+msgid ""
+"If you asked for `SOCK_DGRAM`, you would be requesting a _connectionless "
+"datagram delivery service_ (in our case, UDP)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:259
+msgid ""
+"If you wanted to be in charge of the low-level protocols (such as IP), or "
+"even network interfaces (e.g., the Ethernet), you would need to specify "
+"`SOCK_RAW`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:262
+msgid ""
+"Finally, the `protocol` argument depends on the previous two arguments, and "
+"is not always meaningful. In that case, use `0` for its value."
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:264
+#, no-wrap
+msgid "The Unconnected Socket"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:268
+msgid ""
+"Nowhere, in the `socket` function have we specified to what other system we "
+"should be connected. Our newly created socket remains _unconnected_."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:271
+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 ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:274
+#, no-wrap
+msgid "`sockaddr`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:279
+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# refer to it as `struct "
+"sockaddr`. This structure is declared in the same file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:292
+#, 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 */\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:296
+msgid ""
+"Please note the _vagueness_ with which the `sa_data` field is declared, just "
+"as an array of `14` bytes, with the comment hinting there can be more than "
+"`14` of them."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:299
+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 _any_ kind of interprocess communications, of "
+"which the Internet (or, more precisely, IP) is only one."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:302
+msgid ""
+"The [.filename]#sys/socket.h# refers to the various types of protocols "
+"sockets will handle as _address families_, and lists them right before the "
+"definition of `sockaddr`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:351
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:355
+msgid "The one used for IP is AF_INET. It is a symbol for the constant `2`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:357
+msgid ""
+"It is the _address family_ listed in the `sa_family` field of `sockaddr` "
+"that decides how exactly the vaguely named bytes of `sa_data` will be used."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:359
+msgid ""
+"Specifically, whenever the _address family_ is AF_INET, we can use `struct "
+"sockaddr_in` found in [.filename]#netinet/in.h#, wherever `sockaddr` is "
+"expected:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:372
+#, 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"
+"};\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:375
+msgid "We can visualize its organization this way:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:376
+#, no-wrap
+msgid "sockaddr_in structure"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:377
+#, no-wrap
+msgid "sain.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:380
+msgid ""
+"The three important fields are `sin_family`, which is byte 1 of the "
+"structure, `sin_port`, a 16-bit value found in bytes 2 and 3, and "
+"`sin_addr`, a 32-bit integer representation of the IP address, stored in "
+"bytes 4-7."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:386
+msgid ""
+"Now, let us try to fill it out. Let us assume we are trying to write a "
+"client for the _daytime_ 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 TCP/IP, so we need to specify `AF_INET` in the address family "
+"field. `AF_INET` is defined as `2`. Let us use the IP address of "
+"`192.43.244.18`, which is the time server of US federal government (`time."
+"nist.gov`)."
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:387
+#, no-wrap
+msgid "Specific example of sockaddr_in"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:388
+#, no-wrap
+msgid "sainfill.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:391
+msgid ""
+"By the way the `sin_addr` field is declared as being of the `struct in_addr` "
+"type, which is defined in [.filename]#netinet/in.h#:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:400
+#, no-wrap
+msgid ""
+"/*\n"
+" * Internet address (a structure for historical reasons)\n"
+" */\n"
+"struct in_addr {\n"
+"\tin_addr_t s_addr;\n"
+"};\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:403
+msgid "In addition, `in_addr_t` is a 32-bit integer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:405
+msgid ""
+"The `192.43.244.18` is just a convenient notation of expressing a 32-bit "
+"integer by listing all of its 8-bit bytes, starting with the _most "
+"significant_ one."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:409
+msgid ""
+"So far, we have viewed `sockaddr` as an abstraction. Our computer does not "
+"store `short` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:411
+msgid "Suppose we coded something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:417
+#, no-wrap
+msgid ""
+"sa.sin_family = AF_INET;\n"
+"sa.sin_port = 13;\n"
+"sa.sin_addr.s_addr = (((((192 << 8) | 43) << 8) | 244) << 8) | 18;\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:420
+msgid "What would the result look like?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:423
+msgid ""
+"Well, that depends, of course. On a Pentium(R), or other x86, based "
+"computer, it would look like this:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:424
+#, no-wrap
+msgid "sockaddr_in on an Intel system"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:425
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:471
+#, no-wrap
+msgid "sainlsb.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:428
+msgid "On a different system, it might look like this:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:429
+#, no-wrap
+msgid "sockaddr_in on an MSB system"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:430
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:476
+#, no-wrap
+msgid "sainmsb.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:434
+msgid ""
+"And on a PDP it might look different yet. But the above two are the most "
+"common ways in use today."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:438
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:440
+msgid "Why?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:442
+msgid ""
+"Because when communicating with another computer, you usually do not know "
+"whether it stores data _most significant byte_ (MSB) or _least significant "
+"byte_ (LSB) first."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:444
+msgid "You might be wondering, _\"So, will sockets not handle it for me?\"_"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:446
+msgid "It will not."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:449
+msgid ""
+"While that answer may surprise you at first, remember that the general "
+"sockets interface only understands the `sa_len` and `sa_family` fields of "
+"the `sockaddr` structure. You do not have to worry about the byte order "
+"there (of course, on FreeBSD `sa_family` is only 1 byte anyway, but many "
+"other UNIX(R) systems do not have `sa_len` and use 2 bytes for `sa_family`, "
+"and expect the data in whatever order is native to the computer)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:452
+msgid ""
+"But the rest of the data is just `sa_data[14]` as far as sockets goes. "
+"Depending on the _address family_, sockets just forwards that data to its "
+"destination."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:457
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:460
+msgid ""
+"Similarly, we enter the IP address to tell everyone on the way where to send "
+"our data to. Sockets, again, only forwards it as data."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:462
+msgid ""
+"That is why, we (the _programmers_, not the _sockets_) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:464
+msgid ""
+"We will call the byte order our computer uses the _host byte order_, or just "
+"the _host order_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:467
+msgid ""
+"There is a convention of sending the multi-byte data over IP _MSB first_. "
+"This, we will refer to as the _network byte order_, or simply the _network "
+"order_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:469
+msgid ""
+"Now, if we compiled the above code for an Intel based computer, our _host "
+"byte order_ would produce:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:470
+#, no-wrap
+msgid "Host byte order on an Intel system"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:474
+msgid "But the _network byte order_ requires that we store the data MSB first:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:475
+#, no-wrap
+msgid "Network byte order"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:479
+msgid ""
+"Unfortunately, our _host order_ is the exact opposite of the _network order_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:482
+msgid ""
+"We have several ways of dealing with it. One would be to _reverse_ the "
+"values in our code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:488
+#, no-wrap
+msgid ""
+"sa.sin_family = AF_INET;\n"
+"sa.sin_port = 13 << 8;\n"
+"sa.sin_addr.s_addr = (((((18 << 8) | 244) << 8) | 43) << 8) | 192;\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:493
+msgid ""
+"This will _trick_ our compiler into storing the data in the _network byte "
+"order_. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:497
+msgid ""
+"Suppose, you wrote a sockets-based program in C. You know it is going to "
+"run on a Pentium(R), so you enter all your constants in reverse and force "
+"them to the _network byte order_. It works well."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:502
+msgid ""
+"Then, some day, your trusted old Pentium(R) becomes a rusty old Pentium(R). "
+"You replace it with a system whose _host order_ is the same as the _network "
+"order_. You need to recompile all your software. All of your software "
+"continues to perform well, except the one program you wrote."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:506
+msgid ""
+"You have since forgotten that you had forced all of your constants to the "
+"opposite of the _host order_. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:508
+msgid ""
+"Eventually, you figure it out, say a couple of swear words, and start "
+"rewriting your code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:511
+msgid ""
+"Luckily, you are not the first one to face the problem. Someone else has "
+"created the man:htons[3] and man:htonl[3] C functions to convert a `short` "
+"and `long` respectively from the _host byte order_ to the _network byte "
+"order_, and the man:ntohs[3] and man:ntohl[3] C functions to go the other "
+"way."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:514
+msgid ""
+"On _MSB-first_ systems these functions do nothing. On _LSB-first_ systems "
+"they convert values to the proper order."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:516
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:518
+#, no-wrap
+msgid "Client Functions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:523
+msgid ""
+"Typically, the client initiates the connection to the server. The client "
+"knows which server it is about to call: It knows its IP address, and it "
+"knows the _port_ the server resides at. It is akin to you picking up the "
+"phone and dialing the number (the _address_), then, after someone answers, "
+"asking for the person in charge of wingdings (the _port_)."
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:525
+#, no-wrap
+msgid "`connect`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:528
+msgid ""
+"Once a client has created a socket, it needs to connect it to a specific "
+"port on a remote system. It uses man:connect[2]:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:532
+#, no-wrap
+msgid "int connect(int s, const struct sockaddr *name, socklen_t namelen);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:537
+msgid ""
+"The `s` argument is the socket, i.e., the value returned by the `socket` "
+"function. The `name` is a pointer to `sockaddr`, the structure we have "
+"talked about extensively. Finally, `namelen` informs the system how many "
+"bytes are in our `sockaddr` structure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:540
+msgid ""
+"If `connect` is successful, it returns `0`. Otherwise it returns `-1` and "
+"stores the error code in `errno`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:544
+msgid ""
+"There are many reasons why `connect` may fail. For example, with an attempt "
+"to an Internet connection, the IP 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 _refuse_ any request for specific code."
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:546
+#, no-wrap
+msgid "Our First Client"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:549
+msgid ""
+"We now know enough to write a very simple client, one that will get current "
+"time from `192.43.244.18` and print it to [.filename]#stdout#."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:562
+#, no-wrap
+msgid ""
+"/*\n"
+" * daytime.c\n"
+" *\n"
+" * Programmed by G. Adam Stanislav\n"
+" */\n"
+"#include <stdio.h>\n"
+"#include <string.h>\n"
+"#include <sys/types.h>\n"
+"#include <sys/socket.h>\n"
+"#include <netinet/in.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:568
+#, no-wrap
+msgid ""
+"int main() {\n"
+" register int s;\n"
+" register int bytes;\n"
+" struct sockaddr_in sa;\n"
+" char buffer[BUFSIZ+1];\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:573
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:995
+#, no-wrap
+msgid ""
+" if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {\n"
+" perror(\"socket\");\n"
+" return 1;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:575
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:997
+#, no-wrap
+msgid " bzero(&sa, sizeof sa);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:584
+#, no-wrap
+msgid ""
+" sa.sin_family = AF_INET;\n"
+" sa.sin_port = htons(13);\n"
+" sa.sin_addr.s_addr = htonl((((((192 << 8) | 43) << 8) | 244) << 8) | 18);\n"
+" if (connect(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
+" perror(\"connect\");\n"
+" close(s);\n"
+" return 2;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:587
+#, no-wrap
+msgid ""
+" while ((bytes = read(s, buffer, BUFSIZ)) > 0)\n"
+" write(1, buffer, bytes);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:591
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1021
+#, no-wrap
+msgid ""
+" close(s);\n"
+" return 0;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:594
+msgid ""
+"Go ahead, enter it in your editor, save it as [.filename]#daytime.c#, then "
+"compile and run it:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:599
+#, no-wrap
+msgid ""
+"% cc -O3 -o daytime daytime.c\n"
+"% ./daytime\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:602
+#, no-wrap
+msgid ""
+"52079 01-06-19 02:29:25 50 0 1 543.9 UTC(NIST) *\n"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:606
+msgid ""
+"In this case, the date was June 19, 2001, the time was 02:29:25 UTC. "
+"Naturally, your results will vary."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:608
+#, no-wrap
+msgid "Server Functions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:614
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:616
+msgid "The sockets interface offers three basic functions to handle this."
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:618
+#, no-wrap
+msgid "`bind`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:621
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:625
+msgid ""
+"There are 65535 IP 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 man:bind[2] to tell sockets which port we want to serve."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:629
+#, no-wrap
+msgid "int bind(int s, const struct sockaddr *addr, socklen_t addrlen);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:634
+msgid ""
+"Beside specifying the port in `addr`, the server may include its IP "
+"address. However, it can just use the symbolic constant INADDR_ANY to "
+"indicate it will serve all requests to the specified port regardless of what "
+"its IP address is. This symbol, along with several similar ones, is "
+"declared in [.filename]#netinet/in.h#"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:638
+#, no-wrap
+msgid "#define\tINADDR_ANY\t\t(u_int32_t)0x00000000\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:643
+msgid ""
+"Suppose we were writing a server for the _daytime_ protocol over TCP/IP. "
+"Recall that it uses port 13. Our `sockaddr_in` structure would look like "
+"this:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:644
+#, no-wrap
+msgid "Example Server sockaddr_in"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:645
+#, no-wrap
+msgid "sainserv.png"
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:648
+#, no-wrap
+msgid "`listen`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:652
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:654
+msgid "The server ensures all of that with the man:listen[2] function."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:658
+#, no-wrap
+msgid "int listen(int s, int backlog);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:662
+msgid ""
+"In here, the `backlog` 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 ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:664
+#, no-wrap
+msgid "`accept`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:669
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:671
+msgid "The server accepts the connection by using the man:accept[2] function."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:675
+#, no-wrap
+msgid "int accept(int s, struct sockaddr *addr, socklen_t *addrlen);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:679
+msgid ""
+"Note that this time `addrlen` is a pointer. This is necessary because in "
+"this case it is the socket that fills out `addr`, the `sockaddr_in` "
+"structure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:683
+msgid ""
+"The return value is an integer. Indeed, the `accept` returns a _new "
+"socket_. You will use this new socket to communicate with the client."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:685
+msgid ""
+"What happens to the old socket? It continues to listen for more requests "
+"(remember the `backlog` variable we passed to `listen`?) until we `close` it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:689
+msgid ""
+"Now, the new socket is meant only for communications. It is fully "
+"connected. We cannot pass it to `listen` again, trying to accept additional "
+"connections."
+msgstr ""
+
+#. type: Title =====
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:691
+#, no-wrap
+msgid "Our First Server"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:695
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:698
+msgid ""
+"This is best achieved by creating a _child process_ after binding the port. "
+"The main process then exits and returns control to the shell (or whatever "
+"program invoked it)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:700
+msgid ""
+"The child calls `listen`, then starts an endless loop, which accepts a "
+"connection, serves it, and eventually closes its socket."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:716
+#, no-wrap
+msgid ""
+"/*\n"
+" * daytimed - a port 13 server\n"
+" *\n"
+" * Programmed by G. Adam Stanislav\n"
+" * June 19, 2001\n"
+" */\n"
+"#include <stdio.h>\n"
+"#include <string.h>\n"
+"#include <time.h>\n"
+"#include <unistd.h>\n"
+"#include <sys/types.h>\n"
+"#include <sys/socket.h>\n"
+"#include <netinet/in.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:718
+#, no-wrap
+msgid "#define BACKLOG 4\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:726
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:731
+#, no-wrap
+msgid ""
+" if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {\n"
+" perror(\"socket\");\n"
+" return 1;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:733
+#, no-wrap
+msgid " bzero(&sa, sizeof sa);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:736
+#, no-wrap
+msgid ""
+" sa.sin_family = AF_INET;\n"
+" sa.sin_port = htons(13);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:739
+#, no-wrap
+msgid ""
+" if (INADDR_ANY)\n"
+" sa.sin_addr.s_addr = htonl(INADDR_ANY);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:744
+#, no-wrap
+msgid ""
+" if (bind(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
+" perror(\"bind\");\n"
+" return 2;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:757
+#, no-wrap
+msgid ""
+" 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:759
+#, no-wrap
+msgid " listen(s, BACKLOG);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:762
+#, no-wrap
+msgid ""
+" for (;;) {\n"
+" b = sizeof sa;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:767
+#, no-wrap
+msgid ""
+" if ((c = accept(s, (struct sockaddr *)&sa, &b)) < 0) {\n"
+" perror(\"daytimed accept\");\n"
+" return 4;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:772
+#, no-wrap
+msgid ""
+" if ((client = fdopen(c, \"w\")) == NULL) {\n"
+" perror(\"daytimed fdopen\");\n"
+" return 5;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:775
+#, no-wrap
+msgid ""
+" if ((t = time(NULL)) < 0) {\n"
+" perror(\"daytimed time\");\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:778
+#, no-wrap
+msgid ""
+" return 6;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:787
+#, no-wrap
+msgid ""
+" tm = gmtime(&t);\n"
+" fprintf(client, \"%.4i-%.2i-%.2iT%.2i:%.2i:%.2iZ\\n\",\n"
+" tm->tm_year + 1900,\n"
+" tm->tm_mon + 1,\n"
+" tm->tm_mday,\n"
+" tm->tm_hour,\n"
+" tm->tm_min,\n"
+" tm->tm_sec);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:791
+#, no-wrap
+msgid ""
+" fclose(client);\n"
+" }\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:796
+msgid ""
+"We start by creating a socket. Then we fill out the `sockaddr_in` structure "
+"in `sa`. Note the conditional use of INADDR_ANY:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:801
+#, no-wrap
+msgid ""
+"if (INADDR_ANY)\n"
+" sa.sin_addr.s_addr = htonl(INADDR_ANY);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:808
+msgid ""
+"Its value is `0`. Since we have just used `bzero` on the entire structure, "
+"it would be redundant to set it to `0` again. But if we port our code to "
+"some other system where INADDR_ANY is perhaps not a zero, we need to assign "
+"it to `sa.sin_addr.s_addr`. Most modern C compilers are clever enough to "
+"notice that INADDR_ANY is a constant. As long as it is a zero, they will "
+"optimize the entire conditional statement out of the code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:812
+msgid ""
+"After we have called `bind` successfully, we are ready to become a _daemon_: "
+"We use `fork` to create a child process. In both, the parent and the child, "
+"the `s` variable is our socket. The parent process will not need it, so it "
+"calls `close`, then it returns `0` to inform its own parent it had "
+"terminated successfully."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:817
+msgid ""
+"Meanwhile, the child process continues working in the background. It calls "
+"`listen` and sets its backlog to `4`. It does not need a large value here "
+"because _daytime_ is not a protocol many clients request all the time, and "
+"because it can process each request instantly anyway."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:819
+msgid ""
+"Finally, the daemon starts an endless loop, which performs the following "
+"steps:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:822
+msgid ""
+"Call `accept`. It waits here until a client contacts it. At that point, it "
+"receives a new socket, `c`, which it can use to communicate with this "
+"particular client."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:823
+msgid ""
+"It uses the C function `fdopen` to turn the socket from a low-level _file "
+"descriptor_ to a C-style `FILE` pointer. This will allow the use of "
+"`fprintf` later on."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:824
+msgid ""
+"It checks the time, and prints it in the _ISO 8601_ format to the `client` "
+"\"file\". It then uses `fclose` to close the file. That will automatically "
+"close the socket as well."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:826
+msgid "We can _generalize_ this, and use it as a model for many other servers:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:827
+#, no-wrap
+msgid "Sequential Server"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:828
+#, no-wrap
+msgid "serv.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:834
+msgid ""
+"This flowchart is good for _sequential servers_, i.e., servers that can "
+"serve one client at a time, just as we were able to with our _daytime_ "
+"server. This is only possible whenever there is no real \"conversation\" "
+"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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:837
+msgid ""
+"The advantage of this flowchart is that, except for the brief moment after "
+"the parent ``fork``s and before it exits, there is always only one _process_ "
+"active: Our server does not take up much memory and other system resources."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:841
+msgid ""
+"Note that we have added _initialize daemon_ 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 `signal` handlers, open any files we may need, etc."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:845
+msgid ""
+"Just about everything in the flow chart can be used literally on many "
+"different servers. The _serve_ entry is the exception. We think of it as a "
+"_\"black box\"_, i.e., something you design specifically for your own "
+"server, and just \"plug it into the rest.\""
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:851
+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. As a "
+"result, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:854
+msgid ""
+"Now, go ahead, save the above source code as [.filename]#daytimed.c# (it is "
+"customary to end the names of daemons with the letter `d`). After you have "
+"compiled it, try running it:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:860
+#, no-wrap
+msgid ""
+"% ./daytimed\n"
+"bind: Permission denied\n"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:864
+msgid ""
+"What happened here? As you will recall, the _daytime_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:866
+msgid "Try again, this time as the superuser:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:871
+#, no-wrap
+msgid ""
+"# ./daytimed\n"
+"#\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:874
+msgid "What... Nothing? Let us try again:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:878
+#, no-wrap
+msgid "# ./daytimed\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:881
+#, no-wrap
+msgid ""
+"bind: Address already in use\n"
+"#\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:886
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:889
+msgid ""
+"Fine, we know it is running in the background. But is it working? How do we "
+"know it is a proper _daytime_ server? Simple:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:893
+#, no-wrap
+msgid "% telnet localhost 13\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:902
+#, no-wrap
+msgid ""
+"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"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:907
+msgid ""
+"telnet tried the new IPv6, and failed. It retried with IPv4 and succeeded. "
+"The daemon works."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:910
+msgid ""
+"If you have access to another UNIX(R) system via telnet, you can use it to "
+"test accessing the server remotely. My computer does not have a static IP "
+"address, so this is what I did:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:914
+#, no-wrap
+msgid "% who\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:918
+#, no-wrap
+msgid ""
+"whizkid ttyp0 Jun 19 16:59 (216.127.220.143)\n"
+"xxx ttyp1 Jun 19 16:06 (xx.xx.xx.xx)\n"
+"% telnet 216.127.220.143 13\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:925
+#, no-wrap
+msgid ""
+"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"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:928
+msgid "Again, it worked. Will it work using the domain name?"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:932
+#, no-wrap
+msgid "% telnet r47.bfm.org 13\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:939
+#, no-wrap
+msgid ""
+"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"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:943
+msgid ""
+"By the way, telnet prints the _Connection closed by foreign host_ message "
+"after our daemon has closed the socket. This shows us that, indeed, using "
+"`fclose(client);` in our code works as advertised."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:945
+#, no-wrap
+msgid "Helper Functions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:951
+msgid ""
+"FreeBSD C library contains many helper functions for sockets programming. "
+"For example, in our sample client we hard coded the `time.nist.gov` IP "
+"address. But we do not always know the IP address. Even if we do, our "
+"software is more flexible if it allows the user to enter the IP address, or "
+"even the domain name."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:953
+#, no-wrap
+msgid "`gethostbyname`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:956
+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 man:gethostbyname[3] and man:"
+"gethostbyname2[3] functions, declared in [.filename]#netdb.h#."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:961
+#, no-wrap
+msgid ""
+"struct hostent * gethostbyname(const char *name);\n"
+"struct hostent * gethostbyname2(const char *name, int af);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:965
+msgid ""
+"Both return a pointer to the `hostent` structure, with much information "
+"about the domain. For our purposes, the `h_addr_list[0]` field of the "
+"structure points at `h_length` bytes of the correct address, already stored "
+"in the _network byte order_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:967
+msgid ""
+"This allows us to create a much more flexible-and much more useful-version "
+"of our daytime program:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:982
+#, no-wrap
+msgid ""
+"/*\n"
+" * daytime.c\n"
+" *\n"
+" * Programmed by G. Adam Stanislav\n"
+" * 19 June 2001\n"
+" */\n"
+"#include <stdio.h>\n"
+"#include <string.h>\n"
+"#include <sys/types.h>\n"
+"#include <sys/socket.h>\n"
+"#include <netinet/in.h>\n"
+"#include <netdb.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:990
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1000
+#, no-wrap
+msgid ""
+" sa.sin_family = AF_INET;\n"
+" sa.sin_port = htons(13);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1002
+#, no-wrap
+msgid " host = (argc > 1) ? (char *)argv[1] : \"time.nist.gov\";\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1007
+#, no-wrap
+msgid ""
+" if ((he = gethostbyname(host)) == NULL) {\n"
+" herror(host);\n"
+" return 2;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1009
+#, no-wrap
+msgid " bcopy(he->h_addr_list[0],&sa.sin_addr, he->h_length);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1014
+#, no-wrap
+msgid ""
+" if (connect(s, (struct sockaddr *)&sa, sizeof sa) < 0) {\n"
+" perror(\"connect\");\n"
+" return 3;\n"
+" }\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1017
+#, no-wrap
+msgid ""
+" while ((bytes = read(s, buf, BUFSIZ)) > 0)\n"
+" write(1, buf, bytes);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1027
+msgid ""
+"We now can type a domain name (or an IP address, it works both ways) on the "
+"command line, and the program will try to connect to its _daytime_ server. "
+"Otherwise, it will still default to `time.nist.gov`. However, even in this "
+"case we will use `gethostbyname` rather than hard coding `192.43.244.18`. "
+"That way, even if its IP address changes in the future, we will still find "
+"it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1031
+msgid ""
+"Since it takes virtually no time to get the time from your local server, you "
+"could run daytime twice in a row: First to get the time from `time.nist."
+"gov`, the second time from your own system. You can then compare the "
+"results and see how exact your system clock is:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1035
+#, no-wrap
+msgid "% daytime ; daytime localhost\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1039
+#, no-wrap
+msgid ""
+"52080 01-06-20 04:02:33 50 0 0 390.2 UTC(NIST) *\n"
+"2001-06-20T04:02:35Z\n"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1042
+msgid "As you can see, my system was two seconds ahead of the NIST time."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1044
+#, no-wrap
+msgid "`getservbyname`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1048
+msgid ""
+"Sometimes you may not be sure what port a certain service uses. The man:"
+"getservbyname[3] function, also declared in [.filename]#netdb.h# comes in "
+"very handy in those cases:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1052
+#, no-wrap
+msgid "struct servent * getservbyname(const char *name, const char *proto);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1055
+msgid ""
+"The `servent` structure contains the `s_port`, which contains the proper "
+"port, already in _network byte order_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1057
+msgid ""
+"Had we not known the correct port for the _daytime_ service, we could have "
+"found it this way:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1067
+#, 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->s_port;\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1074
+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#, which is where `getservbyname` 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#, your software will "
+"find its port without you having to rewrite the code."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1076
+#, no-wrap
+msgid "Concurrent Servers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1080
+msgid ""
+"Unlike a sequential server, a _concurrent server_ has to be able to serve "
+"more than one client at a time. For example, a _chat server_ may be serving "
+"a specific client for hours-it cannot wait till it stops serving a client "
+"before it serves the next one."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1082
+msgid "This requires a significant change in our flowchart:"
+msgstr ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1083
+#, no-wrap
+msgid "Concurrent Server"
+msgstr ""
+
+#. type: Target for macro image
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1084
+#, no-wrap
+msgid "serv2.png"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1088
+msgid ""
+"We moved the _serve_ from the _daemon process_ to its own _server process_. "
+"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 _\"accepted "
+"handle,\"_ i.e., the socket returned by the `accept` call, but also the _top "
+"socket_, i.e., the one opened by the top process right at the beginning."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1091
+msgid ""
+"However, the _server process_ does not need this socket and should `close` "
+"it immediately. Similarly, the _daemon process_ no longer needs the "
+"_accepted socket_, and not only should, but _must_ `close` it-otherwise, it "
+"will run out of available _file descriptors_ sooner or later."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1094
+msgid ""
+"After the _server process_ is done serving, it should close the _accepted "
+"socket_. Instead of returning to `accept`, it now exits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1101
+msgid ""
+"Under UNIX(R), a process does not really _exit_. Instead, it _returns_ to "
+"its parent. Typically, a parent process ``wait``s for its child process, "
+"and obtains a return value. However, our _daemon process_ cannot simply "
+"stop and wait. That would defeat the whole purpose of creating additional "
+"processes. But if it never does `wait`, its children will become _zombies_-"
+"no longer functional but still roaming around."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1104
+msgid ""
+"For that reason, the _daemon process_ needs to set _signal handlers_ in its "
+"_initialize daemon_ phase. At least a SIGCHLD 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/sockets/_index.adoc:1107
+msgid ""
+"That is why our flowchart now contains a _process signals_ box, which is not "
+"connected to any other box. By the way, many servers also process SIGHUP, "
+"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 ""
diff --git a/documentation/content/en/books/developers-handbook/testing/_index.po b/documentation/content/en/books/developers-handbook/testing/_index.po
new file mode 100644
index 0000000000..c1d21ea137
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/testing/_index.po
@@ -0,0 +1,614 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:21-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:14
+#, no-wrap
+msgid "Regression and Performance Testing"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:1
+#, no-wrap
+msgid "Chapter 6. Regression and Performance Testing"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:52
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:54
+msgid ""
+"The FreeBSD regression testing tools can be found in the FreeBSD source tree "
+"in the directory [.filename]#src/tools/regression#."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:56
+#, no-wrap
+msgid "Micro Benchmark Checklist"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:59
+msgid ""
+"This section contains hints for doing proper micro-benchmarking on FreeBSD "
+"or of FreeBSD itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:61
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:63
+msgid "Disable APM and any other kind of clock fiddling (ACPI ?)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:64
+msgid ""
+"Run in single user mode. E.g., man:cron[8], and other daemons only add "
+"noise. The man:sshd[8] daemon can also cause problems. If ssh access is "
+"required during testing either disable the SSHv1 key regeneration, or kill "
+"the parent `sshd` daemon during the tests."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:65
+msgid "Do not run man:ntpd[8]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:66
+msgid ""
+"If man:syslog[3] events are generated, run man:syslogd[8] with an empty [."
+"filename]#/etc/syslogd.conf#, otherwise, do not run it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:67
+msgid "Minimize disk-I/O, avoid it entirely if possible."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:68
+msgid "Do not mount file systems that are not needed."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:69
+msgid ""
+"Mount [.filename]#/#, [.filename]#/usr#, and any other file system as read-"
+"only if possible. This removes atime updates to disk (etc.) from the I/O "
+"picture."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:70
+msgid ""
+"Reinitialize the read/write test file system with man:newfs[8] and populate "
+"it from a man:tar[1] or man:dump[8] 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# "
+"(just reinitialize with `newfs` and mount). To get 100% reproducibility, "
+"populate the file system from a man:dd[1] file (i.e.: `dd if=myimage of=/dev/"
+"ad0s1h bs=1m`)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:71
+msgid "Use malloc backed or preloaded man:md[4] partitions."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:72
+msgid ""
+"Reboot between individual iterations of the test, this gives a more "
+"consistent state."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:73
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:74
+msgid ""
+"Unconfigure hardware that are not in use. Detach disks with man:"
+"atacontrol[8] and man:camcontrol[8] if the disks are not used for the test."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:75
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:77
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:78
+msgid ""
+"Put each file system on its own disk. This minimizes jitter from head-seek "
+"optimizations."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:79
+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 kbd:[space] or kbd:[back-space] "
+"shows up in the numbers."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:80
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:81
+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 {phk} for "
+"more information about this."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:82
+msgid ""
+"Run the test at least 3 times but it is better to run more than 20 times "
+"both for \"before\" and \"after\" 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:85
+msgid ""
+"A good pattern is: `bababa{bbbaaa}*`. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:86
+msgid ""
+"Use man:ministat[1] to see if the numbers are significant. Consider buying "
+"\"Cartoon guide to statistics\" ISBN: 0062731025, highly recommended, if you "
+"have forgotten or never learned about standard deviation and Student's T."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:87
+msgid ""
+"Do not use background man:fsck[8] unless the test is a benchmark of "
+"background `fsck`. Also, disable `background_fsck` in [.filename]#/etc/rc."
+"conf# unless the benchmark is not started at least 60+\"``fsck`` runtime\" "
+"seconds after the boot, as man:rc[8] wakes up and checks if `fsck` needs to "
+"run on any file systems when background `fsck` is enabled. Likewise, make "
+"sure there are no snapshots lying around unless the benchmark is a test with "
+"snapshots."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:88
+msgid ""
+"If the benchmark show unexpected bad performance, check for things like high "
+"interrupt volume from an unexpected source. Some versions of ACPI have been "
+"reported to \"misbehave\" and generate excess interrupts. To help diagnose "
+"odd test results, take a few snapshots of `vmstat -i` and look for anything "
+"unusual."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:89
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:90
+msgid ""
+"Do not ever benchmark with the `WITNESS` and `INVARIANTS` kernel options "
+"enabled unless the test is interested to benchmarking those features. "
+"`WITNESS` can cause 400%+ drops in performance. Likewise, userspace man:"
+"malloc[3] parameters default differently in -CURRENT from the way they ship "
+"in production releases."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:92
+#, no-wrap
+msgid "The FreeBSD Source Tinderbox"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:95
+msgid "The source Tinderbox consists of:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:97
+msgid ""
+"A build script, [.filename]#tinderbox#, that automates checking out a "
+"specific version of the FreeBSD source tree and building it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:98
+msgid ""
+"A supervisor script, [.filename]#tbmaster#, that monitors individual "
+"Tinderbox instances, logs their output, and emails failure notices."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:99
+msgid ""
+"A CGI script named [.filename]#index.cgi# that reads a set of tbmaster logs "
+"and presents an easy-to-read HTML summary of them."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:100
+msgid ""
+"A set of build servers that continually test the tip of the most important "
+"FreeBSD code branches."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:101
+msgid ""
+"A webserver that keeps a complete set of Tinderbox logs and displays an up-"
+"to-date summary."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:104
+msgid ""
+"The scripts are maintained and were developed by {des}, and are now written "
+"in Perl, a move on from their original incarnation as shell scripts. All "
+"scripts and configuration files are kept in https://www.freebsd.org/cgi/"
+"cvsweb.cgi/projects/tinderbox/[/projects/tinderbox/]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:106
+msgid ""
+"For more information about the tinderbox and tbmaster scripts at this stage, "
+"see their respective man pages: tinderbox(1) and tbmaster(1)."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:107
+#, no-wrap
+msgid "The index.cgi Script"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:114
+msgid ""
+"The [.filename]#index.cgi# script generates the HTML summary of tinderbox "
+"and tbmaster logs. Although originally intended to be used as a CGI script, "
+"as indicated by its name, this script can also be run from the command line "
+"or from a man:cron[8] job, in which case it will look for logs in the "
+"directory where the script is located. It will automatically detect "
+"context, generating HTTP headers when it is run as a CGI script. It "
+"conforms to XHTML standards and is styled using CSS."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:117
+msgid ""
+"The script starts in the `main()` 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 URL to the official site is "
+"provided."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:120
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:124
+#, no-wrap
+msgid "tinderbox-$config-$branch-$arch-$machine.{brief,full}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:128
+msgid ""
+"The configurations used on the official Tinderbox build servers are named "
+"for the branches they build. For example, the `releng_8` configuration is "
+"used to build `RELENG_8` as well as all still-supported release branches."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:130
+msgid ""
+"Once all of this startup procedure has been successfully completed, "
+"`do_config()` is called for each configuration."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:132
+msgid ""
+"The `do_config()` function generates HTML for a single Tinderbox "
+"configuration."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:135
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:137
+msgid "For each item:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:139
+msgid "For each machine within that architecture:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:141
+msgid "If a brief log file exists, then:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:143
+msgid "Call `success()` to determine the outcome of the build."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:144
+msgid "Output the modification size."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:145
+msgid ""
+"Output the size of the brief log file with a link to the log file itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:146
+msgid "If a full log file also exists, then:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:148
+msgid ""
+"Output the size of the full log file with a link to the log file itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:150
+msgid "Otherwise:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:152
+msgid "No output."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:154
+msgid ""
+"The `success()` function mentioned above scans a brief log file for the "
+"string \"tinderbox run completed\" in order to determine whether the build "
+"was successful."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:157
+msgid ""
+"Configurations and branches are sorted according to their branch rank. This "
+"is computed as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:159
+msgid "`HEAD` and `CURRENT` have rank 9999."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:160
+msgid "`RELENG_x` has rank __``xx``__99."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:161
+msgid "`RELENG_x_y` has rank _xxyy_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:164
+msgid ""
+"This means that `HEAD` always ranks highest, and `RELENG` branches are "
+"ranked in numerical order, with each `STABLE` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:166
+msgid "`RELENG_8` (branch rank 899)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:167
+msgid "`RELENG_8_3` (branch rank 803)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:168
+msgid "`RELENG_8_2` (branch rank 802)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:169
+msgid "`RELENG_8_1` (branch rank 801)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:170
+msgid "`RELENG_8_0` (branch rank 800)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:174
+msgid ""
+"The colors that Tinderbox uses for each cell in the table are defined by "
+"CSS. 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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:175
+#, no-wrap
+msgid "Official Build Servers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:178
+msgid ""
+"The official Tinderbox build servers are hosted by http://www.sentex."
+"ca[Sentex Data Communications], who also host the FreeBSD Netperf Cluster."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:180
+msgid "Three build servers currently exist:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:182
+msgid "_freebsd-current.sentex.ca_ builds:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:184
+msgid ""
+"`HEAD` for amd64, arm, i386, i386/pc98, ia64, mips, powerpc, powerpc64, and "
+"sparc64."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:185
+msgid ""
+"`RELENG_9` and supported 9._X_ branches for amd64, arm, i386, i386/pc98, "
+"ia64, mips, powerpc, powerpc64, and sparc64."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:187
+msgid "_freebsd-stable.sentex.ca_ builds:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:189
+msgid ""
+"`RELENG_8` and supported 8._X_ branches for amd64, i386, i386/pc98, ia64, "
+"mips, powerpc and sparc64."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:191
+msgid "_freebsd-legacy.sentex.ca_ builds:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:193
+msgid ""
+"`RELENG_7` and supported 7._X_ branches for amd64, i386, i386/pc98, ia64, "
+"powerpc, and sparc64."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:194
+#, no-wrap
+msgid "Official Summary Site"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:197
+msgid ""
+"Summaries and logs from the official build servers are available online at "
+"http://tinderbox.FreeBSD.org[http://tinderbox.FreeBSD.org], hosted by {des} "
+"and set up as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:199
+msgid ""
+"A man:cron[8] job checks the build servers at regular intervals and "
+"downloads any new log files using man:rsync[1]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/testing/_index.adoc:199
+msgid "Apache is set up to use [.filename]#index.cgi# as `DirectoryIndex`."
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/tools/_index.po b/documentation/content/en/books/developers-handbook/tools/_index.po
new file mode 100644
index 0000000000..34236042f9
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/tools/_index.po
@@ -0,0 +1,3377 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-07-07 23:23-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:16
+#, no-wrap
+msgid "Programming Tools"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1
+#, no-wrap
+msgid "Chapter 2. Programming Tools"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:56
+#, no-wrap
+msgid "Synopsis"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:63
+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 UNIX(R). It does _not_ 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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:65
+#, no-wrap
+msgid "Introduction"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:72
+msgid ""
+"FreeBSD offers an excellent development environment. Compilers for C and C+"
+"+ and an assembler come with the basic system, not to mention classic "
+"UNIX(R) tools such as `sed` and `awk`. If that is not enough, there are "
+"many more compilers and interpreters in the Ports collection. The following "
+"section, <<tools-programming,Introduction to Programming>>, lists some of "
+"the available options. FreeBSD is very compatible with standards such as "
+"POSIX(R) and ANSI 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:76
+msgid ""
+"However, all this power can be rather overwhelming at first if you have "
+"never written programs on a UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:78
+msgid ""
+"Most of the document requires little or no knowledge of programming, "
+"although it does assume a basic competence with using UNIX(R) and a "
+"willingness to learn!"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:80
+#, no-wrap
+msgid "Introduction to Programming"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:86
+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 \"commands\" "
+"as they are usually called. One way uses an _interpreter_, the other a "
+"_compiler_. 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:87
+#, no-wrap
+msgid "Interpreters"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:92
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:97
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:102
+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 UNIX(R) shell (`sh`, `csh`) is itself an interpreter, and "
+"many people do in fact write shell \"scripts\" to help with various "
+"\"housekeeping\" tasks on their machine. Indeed, part of the original "
+"UNIX(R) philosophy was to provide lots of small utility programs that could "
+"be linked together in shell scripts to perform useful tasks."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:103
+#, no-wrap
+msgid "Interpreters Available with FreeBSD"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:106
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:108
+msgid ""
+"Instructions on how to get and install applications from the Ports "
+"Collection can be found in the extref:{handbook}[Ports section, ports-using] "
+"of the handbook."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:109
+#, no-wrap
+msgid "BASIC"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:113
+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, BASIC has been the "
+"first programming language for many programmers. It is also the foundation "
+"for Visual Basic."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:115
+msgid ""
+"The Bywater Basic Interpreter can be found in the Ports Collection as "
+"package:lang/bwbasic[] and the Phil Cockroft's Basic Interpreter (formerly "
+"Rabbit Basic) is available as package:lang/pbasic[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:116
+#, no-wrap
+msgid "Lisp"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:120
+msgid ""
+"A language that was developed in the late 1950s as an alternative to the "
+"\"number-crunching\" 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 \"List Processing\". It is very popular in AI (Artificial Intelligence) "
+"circles."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:122
+msgid ""
+"Lisp is an extremely powerful and sophisticated language, but can be rather "
+"large and unwieldy."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:127
+msgid ""
+"Various implementations of Lisp that can run on UNIX(R) systems are "
+"available in the Ports Collection for FreeBSD. GNU Common Lisp can be found "
+"as package:lang/gcl[]. CLISP by Bruno Haible and Michael Stoll is available "
+"as package:lang/clisp[]. 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[] and package:lang/slisp[] are available respectively."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:128
+#, no-wrap
+msgid "Perl"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:130
+msgid ""
+"Very popular with system administrators for writing scripts; also often used "
+"on World Wide Web servers for writing CGI scripts."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:132
+msgid ""
+"Perl is available in the Ports Collection as package:lang/perl5.24[] for all "
+"FreeBSD releases."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:133
+#, no-wrap
+msgid "Scheme"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:137
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:140
+msgid ""
+"Scheme is available from the Ports Collection as package:lang/elk[] for the "
+"Elk Scheme Interpreter. The MIT Scheme Interpreter can be found in package:"
+"lang/mit-scheme[] and the SCM Scheme Interpreter in package:lang/scm[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:141
+#, no-wrap
+msgid "Icon"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:144
+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[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:145
+#, no-wrap
+msgid "Logo"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:148
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:150
+msgid ""
+"The latest version of Logo for FreeBSD is available from the Ports "
+"Collection in package:lang/logo[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:151
+#, no-wrap
+msgid "Python"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:154
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:156
+msgid ""
+"The latest version of Python is available from the Ports Collection in "
+"package:lang/python[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:157
+#, no-wrap
+msgid "Ruby"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:160
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:162
+msgid "Ruby is available from the Ports Collection as package:lang/ruby25[]."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:163
+#, no-wrap
+msgid "Tcl and Tk"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:166
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:169
+msgid ""
+"Various versions of Tcl are available as ports for FreeBSD. The latest "
+"version, Tcl 8.5, can be found in package:lang/tcl87[]."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:170
+#, no-wrap
+msgid "Compilers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:177
+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:"
+"[If you run it in the shell, you may get a core dump.]"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:184
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:188
+msgid ""
+"As the edit-compile-run-debug cycle is rather tedious when using separate "
+"programs, many commercial compiler makers have produced Integrated "
+"Development Environments (IDEs for short). FreeBSD does not include an IDE "
+"in the base system, but package:devel/kdevelop[] is available in the Ports "
+"Collection and many use Emacs for this purpose. Using Emacs as an IDE is "
+"discussed in <<emacs>>."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:190
+#, no-wrap
+msgid "Compiling with `cc`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:195
+msgid ""
+"This section deals with the clang compiler for C and C++, as it's installed "
+"with the FreeBSD base system. Starting with FreeBSD 10.X `clang` is "
+"installed as `cc`; the GNU compiler package:lang/gcc[gcc] is available in "
+"the Ports Collection. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:198
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:201
+msgid ""
+"Pre-process your source code to remove comments and do other tricks like "
+"expanding macros in C."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:202
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:203
+msgid ""
+"Convert the source code into assembly language-this is very close to machine "
+"code, but still understandable by humans. Allegedly."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:204
+msgid ""
+"Convert the assembly language into machine code-yep, we are talking bits and "
+"bytes, ones and zeros here."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:205
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:206
+msgid ""
+"If you are trying to produce an executable from several source code files, "
+"work out how to fit them all together."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:207
+msgid ""
+"Work out how to produce something that the system's run-time loader will be "
+"able to load into memory and run."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:208
+msgid "Finally, write the executable on the filesystem."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:211
+msgid ""
+"The word _compiling_ is often used to refer to just steps 1 to 4-the others "
+"are referred to as _linking_. Sometimes step 1 is referred to as _pre-"
+"processing_ and steps 3-4 as _assembling_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:213
+msgid ""
+"Fortunately, almost all this detail is hidden from you, as `cc` is a front "
+"end that manages calling all these programs with the right arguments for "
+"you; simply typing"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:217
+#, no-wrap
+msgid "% cc foobar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:221
+msgid ""
+"will cause [.filename]#foobar.c# to be compiled by all the steps above. If "
+"you have more than one file to compile, just do something like"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:225
+#, no-wrap
+msgid "% cc foo.c bar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:230
+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:[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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:233
+msgid ""
+"There are lots and lots of options for `cc`, which are all in the manual "
+"page. Here are a few of the most important ones, with examples of how to "
+"use them."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:234
+#, no-wrap
+msgid "`-o _filename_`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:236
+msgid ""
+"The output name of the file. If you do not use this option, `cc` will "
+"produce an executable called [.filename]#a.out#.footnote:[The reasons for "
+"this are buried in the mists of history.]"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:241
+#, no-wrap
+msgid ""
+"% cc foobar.c executable is a.out\n"
+"% cc -o foobar foobar.c executable is foobar\n"
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:243
+#, no-wrap
+msgid "`-c`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:246
+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#."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:250
+#, no-wrap
+msgid "% cc -c foobar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:254
+msgid ""
+"This will produce an _object file_ (not an executable) called [."
+"filename]#foobar.o#. This can be linked together with other object files "
+"into an executable."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:255
+#, no-wrap
+msgid "`-g`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:261
+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 _very_ "
+"useful; the disadvantage is that all this extra information makes the "
+"program much bigger. Normally, you compile with `-g` while you are "
+"developing a program and then compile a \"release version\" without `-g` "
+"when you are satisfied it works properly."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:266
+#, no-wrap
+msgid "% cc -g foobar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:269
+msgid ""
+"This will produce a debug version of the program. footnote:[Note, we did not "
+"use the -o flag to specify the executable name, so we will get an executable "
+"called a.out. Producing a debug version called foobar is left as an exercise "
+"for the reader!]"
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:270
+#, no-wrap
+msgid "`-O`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:274
+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 `-O` to specify a higher level of "
+"optimization, but this often exposes bugs in the compiler's optimizer."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:278
+#, no-wrap
+msgid "% cc -O -o foobar foobar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:281
+msgid "This will produce an optimized version of [.filename]#foobar#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:284
+msgid ""
+"The following three flags will force `cc` to check that your code complies "
+"to the relevant international standard, often referred to as the ANSI "
+"standard, though strictly speaking it is an ISO standard."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:285
+#, no-wrap
+msgid "`-Wall`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:288
+msgid ""
+"Enable all the warnings which the authors of `cc` believe are worthwhile. "
+"Despite the name, it will not enable all the warnings `cc` is capable of."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:289
+#, no-wrap
+msgid "`-ansi`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:292
+msgid ""
+"Turn off most, but not all, of the non-ANSI C features provided by `cc`. "
+"Despite the name, it does not guarantee strictly that your code will comply "
+"to the standard."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:293
+#, no-wrap
+msgid "`-pedantic`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:295
+msgid "Turn off _all_ ``cc``'s non-ANSI C features."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:300
+msgid ""
+"Without these flags, `cc` 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 _portable code_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:303
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:307
+#, no-wrap
+msgid "% cc -Wall -ansi -pedantic -o foobar foobar.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:310
+msgid ""
+"This will produce an executable [.filename]#foobar# after checking [."
+"filename]#foobar.c# for standard compliance."
+msgstr ""
+
+#. type: Labeled list
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:311
+#, no-wrap
+msgid "`-l__library__`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:313
+msgid "Specify a function library to be used at link time."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:316
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:320
+msgid ""
+"The rule is that if the library is called [.filename]#libsomething.a#, you "
+"give `cc` the argument `-l__something__`. For example, the math library is "
+"[.filename]#libm.a#, so you give `cc` the argument `-lm`. A common \"gotcha"
+"\" with the math library is that it has to be the last library on the "
+"command line."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:324
+#, no-wrap
+msgid "% cc -o foobar foobar.c -lm\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:327
+msgid "This will link the math library functions into [.filename]#foobar#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:330
+msgid ""
+"If you are compiling C++ code, use {c-plus-plus-command}. {c-plus-plus-"
+"command} can also be invoked as {clang-plus-plus-command} on FreeBSD."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:334
+#, no-wrap
+msgid "% c++ -o foobar foobar.cc\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:337
+msgid ""
+"This will both produce an executable [.filename]#foobar# from the C++ source "
+"file [.filename]#foobar.cc#."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:338
+#, no-wrap
+msgid "Common `cc` Queries and Problems"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:340
+#, no-wrap
+msgid "I compiled a file called foobar.c and I cannot find an executable called foobar. Where has it gone?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:344
+msgid ""
+"Remember, `cc` will call the executable [.filename]#a.out# unless you tell "
+"it differently. Use the `-o _filename_` option:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:348
+#, no-wrap
+msgid "% cc -o foobar foobar.c\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:350
+#, no-wrap
+msgid "OK, I have an executable called foobar, I can see it when I run ls, but when I type in foobar at the command prompt it tells me there is no such file. Why can it not find it?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:354
+msgid ""
+"Unlike MS-DOS(R), UNIX(R) 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 `./foobar`, which means \"run the file called [.filename]#foobar# "
+"in the current directory.\""
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:355
+#, no-wrap
+msgid "I called my executable test, but nothing happens when I run it. What is going on?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:359
+msgid ""
+"Most UNIX(R) systems have a program called `test` in [.filename]#/usr/bin# "
+"and the shell is picking that one up before it gets to checking the current "
+"directory. Either type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:363
+#, no-wrap
+msgid "% ./test\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:366
+msgid "or choose a better name for your program!"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:367
+#, no-wrap
+msgid "I compiled my program and it seemed to run all right at first, then there was an error and it said something about core dumped. What does that mean?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:371
+msgid ""
+"The name _core dump_ dates back to the very early days of UNIX(R), 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#, which the programmer "
+"could then pore over to find out what went wrong."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:372
+#, no-wrap
+msgid "Fascinating stuff, but what I am supposed to do now?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:375
+msgid "Use a debugger to analyze the core (see <<debugging>>)."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:376
+#, no-wrap
+msgid "When my program dumped core, it said something about a segmentation fault. What is that?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:380
+msgid ""
+"This basically means that your program tried to perform some sort of illegal "
+"operation on memory; UNIX(R) is designed to protect the operating system and "
+"other programs from rogue programs."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:382
+msgid "Common causes for this are:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:384
+msgid "Trying to write to a NULL pointer, eg"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:389
+#, no-wrap
+msgid ""
+"char *foo = NULL;\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:392
+msgid "Using a pointer that has not been initialized, eg"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:397
+#, no-wrap
+msgid ""
+"char *foo;\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:401
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:402
+msgid "Trying to access past the end of an array, eg"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:407
+#, no-wrap
+msgid ""
+"int bar[20];\n"
+"bar[27] = 6;\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:410
+msgid "Trying to store something in read-only memory, eg"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:415
+#, no-wrap
+msgid ""
+"char *foo = \"My string\";\n"
+"strcpy(foo, \"bang!\");\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:418
+msgid ""
+"UNIX(R) compilers often put string literals like `\"My string\"` into read-"
+"only areas of memory."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:419
+msgid "Doing naughty things with `malloc()` and `free()`, eg"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:424
+#, no-wrap
+msgid ""
+"char bar[80];\n"
+"free(bar);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:427
+msgid "or"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:433
+#, no-wrap
+msgid ""
+"char *foo = malloc(27);\n"
+"free(foo);\n"
+"free(foo);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:438
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:439
+#, no-wrap
+msgid "Sometimes when I get a core dump it says bus error. It says in my UNIX(R) book that this means a hardware problem, but the computer still seems to be working. Is this true?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:443
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:444
+#, no-wrap
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:447
+msgid "Yes, just go to another console or xterm, do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:451
+#, no-wrap
+msgid "% ps\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:454
+msgid "to find out the process ID of your program, and do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:458
+#, no-wrap
+msgid "% kill -ABRT pid\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:461
+msgid "where `_pid_` is the process ID you looked up."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:464
+msgid ""
+"This is useful if your program has got stuck in an infinite loop, for "
+"instance. If your program happens to trap SIGABRT, there are several other "
+"signals which have a similar effect."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:467
+msgid ""
+"Alternatively, you can create a core dump from inside your program, by "
+"calling the `abort()` function. See the manual page of man:abort[3] to "
+"learn more."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:470
+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 `gcore` program. See the manual "
+"page of man:gcore[1] for more information."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:472
+#, no-wrap
+msgid "Make"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:474
+#, no-wrap
+msgid "What is `make`?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:477
+msgid ""
+"When you are working on a simple program with only one or two source files, "
+"typing in"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:481
+#, no-wrap
+msgid "% cc file1.c file2.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:484
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:487
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:491
+#, no-wrap
+msgid "% cc file1.o file2.o … file37.c …\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:495
+msgid ""
+"if we had changed [.filename]#file37.c#, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:497
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:499
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:502
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:507
+msgid ""
+"This program is called `make`. It reads in a file, called a _makefile_, "
+"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 \"if [.filename]#fromboz.o# is older than [."
+"filename]#fromboz.c#, that means someone must have changed [."
+"filename]#fromboz.c#, so it needs to be re-compiled.\" The makefile also has "
+"rules telling make _how_ to re-compile the source file, making it a much "
+"more powerful tool."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:510
+msgid ""
+"Makefiles are typically kept in the same directory as the source they apply "
+"to, and can be called [.filename]#makefile#, [.filename]#Makefile# or [."
+"filename]#MAKEFILE#. Most programmers use the name [.filename]#Makefile#, "
+"as this puts it near the top of a directory listing, where it can easily be "
+"seen.footnote:[They do not use the MAKEFILE form as block capitals are often "
+"used for documentation files like README.]"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:511
+#, no-wrap
+msgid "Example of Using `make`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:514
+msgid "Here is a very simple make file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:519
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:545
+#, no-wrap
+msgid ""
+"foo: foo.c\n"
+"\tcc -o foo foo.c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:522
+msgid "It consists of two lines, a dependency line and a creation line."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:529
+msgid ""
+"The dependency line here consists of the name of the program (known as the "
+"_target_), followed by a colon, then whitespace, then the name of the source "
+"file. When `make` reads this line, it looks to see if [.filename]#foo# "
+"exists; if it exists, it compares the time [.filename]#foo# was last "
+"modified to the time [.filename]#foo.c# was last modified. If [."
+"filename]#foo# does not exist, or is older than [.filename]#foo.c#, 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# needs to be re-compiled."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:533
+msgid ""
+"The creation line starts with a tab (press kbd:[tab]) and then the command "
+"you would type to create [.filename]#foo# if you were doing it at a command "
+"prompt. If [.filename]#foo# is out of date, or does not exist, `make` then "
+"executes this command to create it. In other words, this is the rule which "
+"tells make how to re-compile [.filename]#foo.c#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:537
+msgid ""
+"So, when you type `make`, it will make sure that [.filename]#foo# is up to "
+"date with respect to your latest changes to [.filename]#foo.c#. This "
+"principle can be extended to [.filename]#Makefile#'s with hundreds of "
+"targets-in fact, on FreeBSD, it is possible to compile the entire operating "
+"system just by typing `make world` in the appropriate directory!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:540
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:548
+#, no-wrap
+msgid ""
+"install:\n"
+"\tcp foo /home/me\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:551
+msgid "We can tell make which target we want to make by typing:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:555
+#, no-wrap
+msgid "% make target\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:559
+msgid ""
+"`make` will then only look at that target and ignore any others. For "
+"example, if we type `make foo` with the makefile above, make will ignore the "
+"`install` target."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:562
+msgid ""
+"If we just type `make` on its own, make will always look at the first target "
+"and then stop without looking at any others. So if we typed `make` here, it "
+"will just go to the `foo` target, re-compile [.filename]#foo# if necessary, "
+"and then stop without going on to the `install` target."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:566
+msgid ""
+"Notice that the `install` 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 `make install`. In this case, it will copy [."
+"filename]#foo# 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:571
+msgid ""
+"This is a slightly confusing subject to try to explain. If you do not quite "
+"understand how `make` works, the best thing to do is to write a simple "
+"program like \"hello world\" 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. `touch` is very useful here-it changes "
+"the date on a file without you having to edit it."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:572
+#, no-wrap
+msgid "Make and include-files"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:576
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:581
+#, no-wrap
+msgid ""
+"#include <stdio.h>\n"
+"#include \"foo.h\"\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:583
+#, no-wrap
+msgid "int main(....\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:586
+msgid ""
+"To make sure that this file is recompiled the moment [.filename]#foo.h# is "
+"changed, you have to add it in your [.filename]#Makefile#:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:590
+#, no-wrap
+msgid "foo: foo.c foo.h\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:597
+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. `clang` has an option to analyze your files "
+"and to produce a list of include-files and their dependencies: `-MM`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:599
+msgid "If you add this to your Makefile:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:604
+#, no-wrap
+msgid ""
+"depend:\n"
+"\tcc -E -MM *.c > .depend\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:607
+msgid ""
+"and run `make depend`, the file [.filename]#.depend# will appear with a list "
+"of object-files, C-files and the include-files:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:611
+#, no-wrap
+msgid "foo.o: foo.c foo.h\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:614
+msgid ""
+"If you change [.filename]#foo.h#, next time you run `make` all files "
+"depending on [.filename]#foo.h# will be recompiled."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:616
+msgid ""
+"Do not forget to run `make depend` each time you add an include-file to one "
+"of your files."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:617
+#, no-wrap
+msgid "FreeBSD Makefiles"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:623
+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#:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:628
+#, no-wrap
+msgid ""
+"MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/\n"
+"DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:630
+#, no-wrap
+msgid ".include <bsd.port.mk>\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:633
+msgid ""
+"Now, if we go to the directory for this port and type `make`, the following "
+"happens:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:636
+msgid ""
+"A check is made to see if the source code for this port is already on the "
+"system."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:637
+msgid ""
+"If it is not, an FTP connection to the URL in MASTER_SITES is set up to "
+"download the source."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:638
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:639
+msgid ""
+"Any changes required to make the source work on FreeBSD are applied-this is "
+"known as _patching_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:640
+msgid ""
+"Any special configuration needed for the source is done. (Many UNIX(R) "
+"program distributions try to work out which version of UNIX(R) they are "
+"being compiled on and which optional UNIX(R) features are present-this is "
+"where they are given the information in the FreeBSD ports scenario)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:641
+msgid ""
+"The source code for the program is compiled. In effect, we change to the "
+"directory where the source was unpacked and do `make`-the program's own make "
+"file has the necessary information to build the program."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:642
+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 `make install`. "
+"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 `package database`, "
+"so that the port can easily be uninstalled later if we change our mind about "
+"it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:644
+msgid ""
+"Now I think you will agree that is rather impressive for a four line script!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:648
+msgid ""
+"The secret lies in the last line, which tells `make` to look in the system "
+"makefile called [.filename]#bsd.port.mk#. It is easy to overlook this line, "
+"but this is where all the clever stuff comes from-someone has written a "
+"makefile that tells `make` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:652
+msgid ""
+"If you want to have a look at these system makefiles, they are in [."
+"filename]#/usr/share/mk#, 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:653
+#, no-wrap
+msgid "More Advanced Uses of `make`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:658
+msgid ""
+"`Make` is a very powerful tool, and can do much more than the simple example "
+"above shows. Unfortunately, there are several different versions of `make`, "
+"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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:661
+msgid ""
+"The version of make that comes with FreeBSD is the Berkeley make; there is a "
+"tutorial for it in [.filename]#/usr/src/share/doc/psd/12.make#. To view it, "
+"do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:665
+#, no-wrap
+msgid "% zmore paper.ascii.gz\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:668
+msgid "in that directory."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:672
+msgid ""
+"Many applications in the ports use GNU make, which has a very good set of "
+"\"info\" pages. If you have installed any of these ports, GNU make will "
+"automatically have been installed as `gmake`. It is also available as a "
+"port and package in its own right."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:675
+msgid ""
+"To view the info pages for GNU make, you will have to edit [.filename]#dir# "
+"in the [.filename]#/usr/local/info# directory to add an entry for it. This "
+"involves adding a line like"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:679
+#, no-wrap
+msgid " * Make: (make). The GNU Make utility.\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:682
+msgid ""
+"to the file. Once you have done this, you can type `info` and then select [."
+"guimenuitem]#make# from the menu (or in Emacs, do `C-h i`)."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:684
+#, no-wrap
+msgid "Debugging"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:686
+#, no-wrap
+msgid "Introduction to Available Debuggers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:692
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:695
+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 crossref:kerneldebug[kerneldebug,Kernel "
+"Debugging]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:699
+msgid ""
+"The standard debugger supplied with FreeBSD {rel121-current} is called "
+"`lldb` (LLVM debugger). 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 `help` command, as well as https://lldb."
+"llvm.org/[a web tutorial and documentation]."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:704
+msgid ""
+"The `lldb` command is available for FreeBSD {rel113-current} extref:"
+"{handbook}[from ports or packages, ports-using] as package:devel/llvm[]. "
+"This will install the default version of lldb (currently 9.0)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:711
+msgid ""
+"The other debugger available with FreeBSD is called `gdb` (GNU debugger). "
+"Unlike lldb, it is not installed by default on FreeBSD {rel121-current}; to "
+"use it, extref:{handbook}#ports-using/[install] package:devel/gdb[] from "
+"ports or packages. The version installed by default on FreeBSD {rel113-"
+"current} is old; instead, install package:devel/gdb[] there as well. It has "
+"quite good on-line help, as well as a set of info pages."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:716
+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 Emacs will need to use `gdb` as `lldb` is unsupported by Emacs. "
+"Otherwise, try both and see which one you prefer."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:717
+#, no-wrap
+msgid "Using lldb"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:719
+#, no-wrap
+msgid "Starting lldb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:722
+msgid "Start up lldb by typing"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:726
+#, no-wrap
+msgid "% lldb -- progname\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:728
+#, no-wrap
+msgid "Running a Program with lldb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:733
+msgid ""
+"Compile the program with `-g` to get the most out of using `lldb`. 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:737
+#, no-wrap
+msgid "Breakpoint 1: where = temp`main, address = …\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:740
+msgid ""
+"(without an indication of source code filename and line number) when setting "
+"a breakpoint, this means that the program was not compiled with `-g`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:745
+msgid ""
+"Most `lldb` commands have shorter forms that can be used instead. The "
+"longer forms are used here for clarity."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:750
+msgid ""
+"At the `lldb` prompt, type `breakpoint set -n main`. 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 "
+"`process launch` 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 `main()`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:754
+msgid ""
+"To step through the program a line at a time, type `thread step-over`. When "
+"the program gets to a function call, step into it by typing `thread step-"
+"in`. Once in a function call, return from it by typing `thread step-out` or "
+"use `up` and `down` to take a quick look at the caller."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:757
+msgid ""
+"Here is a simple example of how to spot a mistake in a program with `lldb`. "
+"This is our program (with a deliberate mistake):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:761
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1035
+#, no-wrap
+msgid "#include <stdio.h>\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:763
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1037
+#, no-wrap
+msgid "int bazz(int anint);\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:766
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1040
+#, no-wrap
+msgid ""
+"main() {\n"
+"\tint i;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:771
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1045
+#, no-wrap
+msgid ""
+"\tprintf(\"This is my program\\n\");\n"
+"\tbazz(i);\n"
+"\treturn 0;\n"
+"}\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:776
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1050
+#, no-wrap
+msgid ""
+"int bazz(int anint) {\n"
+"\tprintf(\"You gave me %d\\n\", anint);\n"
+"\treturn anint;\n"
+"}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:779
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1053
+msgid ""
+"This program sets i to be `5` and passes it to a function `bazz()` which "
+"prints out the number we gave it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:781
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1055
+msgid "Compiling and running the program displays"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:788
+#, no-wrap
+msgid ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = -5360\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:791
+msgid "That is not what was expected! Time to see what is going on!"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:802
+#, no-wrap
+msgid ""
+"% lldb -- temp\n"
+"(lldb) target create \"temp\"\n"
+"Current executable set to 'temp' (x86_64).\n"
+"(lldb) breakpoint set -n main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef\tlldb puts breakpoint at main()\n"
+"(lldb) process launch\t\t\t\t\tRun as far as main()\n"
+"Process 9992 launching\n"
+"Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64)\tProgram starts running\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:836
+#, no-wrap
+msgid ""
+"Process 9992 stopped\n"
+"* thread #1, name = 'temp', stop reason = breakpoint 1.1\tlldb stops at main()\n"
+" frame #0: 0x00000000002012ef temp`main at temp.c:8:2\n"
+" 5\tmain() {\n"
+" 6\t\tint i;\n"
+" 7\n"
+"-> 8\t\tprintf(\"This is my program\\n\");\t\t\tIndicates the line where it stopped\n"
+" 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+"(lldb) thread step-over\t\t\tGo to next line\n"
+"This is my program\t\t\t\t\t\tProgram prints out\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"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) thread step-in\t\t\tstep into bazz()\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\tlldb displays stack frame\n"
+" 11\t}\n"
+" 12\n"
+" 13\tint bazz(int anint) {\n"
+"-> 14\t\tprintf(\"You gave me %d\\n\", anint);\n"
+" 15\t\treturn anint;\n"
+" 16\t}\n"
+"(lldb)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:839
+msgid ""
+"Hang on a minute! How did anint get to be `-5360`? Was it not set to `5` in "
+"`main()`? Let us move up to `main()` and have a look."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:853
+#, no-wrap
+msgid ""
+"(lldb) up\t\tMove up call stack\n"
+"frame #1: 0x000000000020130b temp`main at temp.c:9:2\t\tlldb displays stack frame\n"
+" 6\t\tint i;\n"
+" 7\n"
+" 8\t\tprintf(\"This is my program\\n\");\n"
+"-> 9\t\tbazz(i);\n"
+" 10\t\treturn 0;\n"
+" 11\t}\n"
+" 12\n"
+"(lldb) frame variable i\t\t\tShow us the value of i\n"
+"(int) i = -5360\t\t\t\t\t\t\tlldb displays -5360\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:857
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1098
+msgid ""
+"Oh dear! Looking at the code, we forgot to initialize i. We meant to put"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:863
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1104
+#, no-wrap
+msgid ""
+"...\n"
+"main() {\n"
+"\tint i;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:867
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1108
+#, no-wrap
+msgid ""
+"\ti = 5;\n"
+"\tprintf(\"This is my program\\n\");\n"
+"...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:872
+msgid ""
+"but we left the `i=5;` line out. As we did not initialize i, it had "
+"whatever number happened to be in that area of memory when the program ran, "
+"which in this case happened to be `-5360`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:878
+msgid ""
+"The `lldb` command displays the stack frame every time we go into or out of "
+"a function, even if we are using `up` and `down` 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:880
+#, no-wrap
+msgid "Examining a Core File with lldb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:885
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1126
+msgid ""
+"A core file is basically a file which contains the complete state of the "
+"process when it crashed. In \"the good old days\", 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]#progname.core# instead of just [."
+"filename]#core#, to make it clearer which program a core file belongs to."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:888
+msgid ""
+"To examine a core file, specify the name of the core file in addition to the "
+"program itself. Instead of starting up `lldb` in the usual way, type `lldb -"
+"c _progname_.core -- _progname_`"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:890
+msgid "The debugger will display something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:897
+#, no-wrap
+msgid ""
+"% lldb -c [.filename]#progname.core# -- [.filename]#progname#\n"
+"(lldb) target create \"[.filename]#progname#\" --core \"[.filename]#progname#.core\"\n"
+"Core file '/home/pauamma/tmp/[.filename]#progname.core#' (x86_64) was loaded.\n"
+"(lldb)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:903
+msgid ""
+"In this case, the program was called [.filename]#progname#, so the core file "
+"is called [.filename]#progname.core#. The debugger does not display why the "
+"program crashed or where. For this, use `thread backtrace all`. This will "
+"also show how the function where the program dumped core was called."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:912
+#, no-wrap
+msgid ""
+"(lldb) thread backtrace all\n"
+"* thread #1, name = 'progname', stop reason = signal SIGSEGV\n"
+" * frame #0: 0x0000000000201347 progname`bazz(anint=5) at temp2.c:17:10\n"
+" frame #1: 0x0000000000201312 progname`main at temp2.c:10:2\n"
+" frame #2: 0x000000000020110f progname`_start(ap=<unavailable>, cleanup=<unavailable>) at crt1.c:76:7\n"
+"(lldb)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:917
+msgid ""
+"`SIGSEGV` 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 `bazz()`. The backtrace also says that in this case, "
+"`bazz()` was called from `main()`."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:918
+#, no-wrap
+msgid "Attaching to a Running Program with lldb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:923
+msgid ""
+"One of the neatest features about `lldb` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:925
+msgid ""
+"To do that, start up another `lldb`, use `ps` to find the process ID for the "
+"child, and do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:929
+#, no-wrap
+msgid "(lldb) process attach -p pid\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:932
+msgid "in `lldb`, and then debug as usual."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:934
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1189
+msgid ""
+"For that to work well, the code that calls `fork` to create the child needs "
+"to do something like the following (courtesy of the `gdb` info pages):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:942
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1197
+#, no-wrap
+msgid ""
+"...\n"
+"if ((pid = fork()) < 0)\t\t/* _Always_ check this */\n"
+"\terror();\n"
+"else if (pid == 0) {\t\t/* child */\n"
+"\tint PauseMode = 1;\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:948
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1203
+#, no-wrap
+msgid ""
+"\twhile (PauseMode)\n"
+"\t\tsleep(10);\t/* Wait until someone attaches to us */\n"
+"\t...\n"
+"} else {\t\t\t/* parent */\n"
+"\t...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:951
+msgid ""
+"Now all that is needed is to attach to the child, set PauseMode to `0` with "
+"`expr PauseMode = 0` and wait for the `sleep()` call to return."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:952
+#, no-wrap
+msgid "Remote Debugging Using LLDB"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:958
+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 extref:{handbook}[ports or packages, ports-using], "
+"as package:devel/llvm-devel[]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:962
+msgid ""
+"Starting with LLDB 12.0.0, remote debugging is supported on FreeBSD. This "
+"means that `lldb-server` can be started to debug a program on one host, "
+"while the interactive `lldb` client connects to it from another one."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:964
+msgid ""
+"To launch a new process to be debugged remotely, run `lldb-server` on the "
+"remote server by typing"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:968
+#, no-wrap
+msgid "% lldb-server g host:port -- progname\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:971
+msgid ""
+"The process will be stopped immediately after launching, and `lldb-server` "
+"will wait for the client to connect."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:973
+msgid ""
+"Start `lldb` locally and type the following command to connect to the remote "
+"server:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:977
+#, no-wrap
+msgid "(lldb) gdb-remote host:port\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:981
+msgid ""
+"`lldb-server` can also attach to a running process. To do that, type the "
+"following on the remote server:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:985
+#, no-wrap
+msgid "% lldb-server g host:port --attach pid-or-name\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:987
+#, no-wrap
+msgid "Using gdb"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:989
+#, no-wrap
+msgid "Starting gdb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:992
+msgid "Start up gdb by typing"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:996
+#, no-wrap
+msgid "% gdb progname\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1000
+msgid "although many people prefer to run it inside Emacs. To do this, type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1004
+#, no-wrap
+msgid " M-x gdb RET progname RET\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1007
+msgid ""
+"Finally, for those finding its text-based command-prompt style off-putting, "
+"there is a graphical front-end for it (package:devel/xxgdb[]) in the Ports "
+"Collection."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1008
+#, no-wrap
+msgid "Running a Program with gdb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1013
+msgid ""
+"Compile the program with `-g` to get the most out of using `gdb`. It will "
+"work without, but will only display the name of the function currently "
+"running, instead of the source code. A line like:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1017
+#, no-wrap
+msgid "... (no debugging symbols found) ...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1020
+msgid "when `gdb` starts up means that the program was not compiled with `-g`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1024
+msgid ""
+"At the `gdb` prompt, type `break main`. 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 `run` 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 `main()`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1028
+msgid ""
+"To step through the program a line at a time, press `n`. When at a function "
+"call, step into it by pressing `s`. Once in a function call, return from it "
+"by pressing `f`, or use `up` and `down` to take a quick look at the caller."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1031
+msgid ""
+"Here is a simple example of how to spot a mistake in a program with `gdb`. "
+"This is our program (with a deliberate mistake):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1062
+#, no-wrap
+msgid ""
+"% cc -g -o temp temp.c\n"
+"% ./temp\n"
+"This is my program\n"
+"anint = 4231\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1065
+msgid "That was not what we expected! Time to see what is going on!"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1077
+#, no-wrap
+msgid ""
+"% gdb temp\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) break main\t\t\t\tSkip the set-up code\n"
+"Breakpoint 1 at 0x160f: file temp.c, line 9.\tgdb puts breakpoint at main()\n"
+"(gdb) run\t\t\t\t\tRun as far as main()\n"
+"Starting program: /home/james/tmp/temp\t\tProgram starts running\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1084
+#, no-wrap
+msgid ""
+"Breakpoint 1, main () at temp.c:9\t\tgdb stops at main()\n"
+"(gdb) n\t\t\t\t\t\tGo to next line\n"
+"This is my program\t\t\t\tProgram prints out\n"
+"(gdb) s\t\t\t\t\t\tstep into bazz()\n"
+"bazz (anint=4231) at temp.c:17\t\t\tgdb displays stack frame\n"
+"(gdb)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1087
+msgid ""
+"Hang on a minute! How did anint get to be `4231`? Was it not set to `5` in "
+"`main()`? Let us move up to `main()` and have a look."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1094
+#, no-wrap
+msgid ""
+"(gdb) up\t\t\t\t\tMove up call stack\n"
+"#1 0x1625 in main () at temp.c:11\t\tgdb displays stack frame\n"
+"(gdb) p i\t\t\t\t\tShow us the value of i\n"
+"$1 = 4231\t\t\t\t\tgdb displays 4231\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1113
+msgid ""
+"but we left the `i=5;` line out. As we did not initialize i, it had "
+"whatever number happened to be in that area of memory when the program ran, "
+"which in this case happened to be `4231`."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1119
+msgid ""
+"The `gdb` command displays the stack frame every time we go into or out of a "
+"function, even if we are using `up` and `down` 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1121
+#, no-wrap
+msgid "Examining a Core File with gdb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1129
+msgid ""
+"To examine a core file, start up `gdb` in the usual way. Instead of typing "
+"`break` or `run`, type"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1133
+#, no-wrap
+msgid "(gdb) core progname.core\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1136
+msgid ""
+"If the core file is not in the current directory, type `dir /path/to/core/"
+"file` first."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1138
+msgid "The debugger should display something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1152
+#, no-wrap
+msgid ""
+"% gdb [.filename]#progname#\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) core [.filename]#progname.core#\n"
+"Core was generated by `[.filename]#progname#'.\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)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1156
+msgid ""
+"In this case, the program was called [.filename]#progname#, so the core file "
+"is called [.filename]#progname.core#. 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 `bazz`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1160
+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. `bt` causes `gdb` to print out a back-trace of the call stack:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1168
+#, no-wrap
+msgid ""
+"(gdb) bt\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)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1172
+msgid ""
+"The `end()` function is called when a program crashes; in this case, the "
+"`bazz()` function was called from `main()`."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1173
+#, no-wrap
+msgid "Attaching to a Running Program with gdb"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1178
+msgid ""
+"One of the neatest features about `gdb` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1180
+msgid ""
+"To do that, start up another `gdb`, use `ps` to find the process ID for the "
+"child, and do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1184
+#, no-wrap
+msgid "(gdb) attach pid\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1187
+msgid "in `gdb`, and then debug as usual."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1206
+msgid ""
+"Now all that is needed is to attach to the child, set PauseMode to `0`, and "
+"wait for the `sleep()` call to return!"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1208
+#, no-wrap
+msgid "Using Emacs as a Development Environment"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1210
+#, no-wrap
+msgid "Emacs"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1214
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1216
+msgid ""
+"It is impossible even to summarize everything Emacs can do here, but here "
+"are some of the features of interest to developers:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1218
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1219
+msgid "Pull-down menus and online help."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1220
+msgid "Language-dependent syntax highlighting and indentation."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1221
+msgid "Completely customizable."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1222
+msgid "You can compile and debug programs within Emacs."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1223
+msgid ""
+"On a compilation error, you can jump to the offending line of source code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1224
+msgid ""
+"Friendly-ish front-end to the `info` program used for reading GNU hypertext "
+"documentation, including the documentation on Emacs itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1225
+msgid ""
+"Friendly front-end to `gdb`, allowing you to look at the source code as you "
+"step through your program."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1227
+msgid "And doubtless many more that have been overlooked."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1229
+msgid ""
+"Emacs can be installed on FreeBSD using the package:editors/emacs[] port."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1232
+msgid ""
+"Once it is installed, start it up and do `C-h t` to read an Emacs tutorial-"
+"that means hold down kbd:[control], press kbd:[h], let go of kbd:[control], "
+"and then press kbd:[t]. (Alternatively, you can use the mouse to select [."
+"guimenuitem]#Emacs Tutorial# from the menu:Help[] menu.)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1237
+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 \"`M-x replace-s RET foo RET bar RET`"
+"\" 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1241
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1244
+msgid ""
+"If you cannot remember what a particular combination of keys does, select [."
+"guimenuitem]#Describe Key# from the menu:Help[] menu and type it in-Emacs "
+"will tell you what it does. You can also use the [.guimenuitem]#Command "
+"Apropos# menu item to find out all the commands which contain a particular "
+"word in them, with the key binding next to it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1247
+msgid ""
+"By the way, the expression above means hold down the kbd:[Meta] key, press "
+"kbd:[x], release the kbd:[Meta] key, type `replace-s` (short for `replace-"
+"string`-another feature of Emacs is that you can abbreviate commands), press "
+"the kbd:[return] key, type `foo` (the string you want replaced), press the "
+"kbd:[return] key, type bar (the string you want to replace `foo` with) and "
+"press kbd:[return] again. Emacs will then do the search-and-replace "
+"operation you have just requested."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1250
+msgid ""
+"If you are wondering what on earth kbd:[Meta] is, it is a special key that "
+"many UNIX(R) workstations have. Unfortunately, PC's do not have one, so it "
+"is usually kbd:[alt] (or if you are unlucky, the kbd:[escape] key)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1254
+msgid ""
+"Oh, and to get out of Emacs, do `C-x C-c` (that means hold down the kbd:"
+"[control] key, press kbd:[x], press kbd:[c] and release the kbd:[control] "
+"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 `C-z` 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1255
+#, no-wrap
+msgid "Configuring Emacs"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1258
+msgid ""
+"Emacs does many wonderful things; some of them are built in, some of them "
+"need to be configured."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1262
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1264
+msgid ""
+"The best way to learn Emacs Lisp is to download the link:ftp://ftp.gnu.org/"
+"old-gnu/emacs/elisp-manual-19-2.4.tar.gz[Emacs Tutorial]"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1269
+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#, 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 ""
+
+#. type: Block title
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1270
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1288
+#, no-wrap
+msgid "A Sample [.filename]#.emacs#"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1273
+msgid ""
+"Unfortunately, there is far too much here to explain it in detail; however "
+"there are one or two points worth mentioning."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1275
+msgid "Everything beginning with a `;` is a comment and is ignored by Emacs."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1276
+msgid ""
+"In the first line, the `-*- Emacs-Lisp -*-` is so that we can edit [."
+"filename]#.emacs# 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#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1277
+msgid ""
+"The kbd:[tab] 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 tab character in whatever you are writing, hold the kbd:[control] "
+"key down while you are pressing the kbd:[tab] key."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1278
+msgid ""
+"This file supports syntax highlighting for C, C++, Perl, Lisp and Scheme, by "
+"guessing the language from the filename."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1279
+msgid ""
+"Emacs already has a pre-defined function called `next-error`. In a "
+"compilation output window, this allows you to move from one compilation "
+"error to the next by doing `M-n`; we define a complementary function, "
+"`previous-error`, that allows you to go to a previous error by doing `M-p`. "
+"The nicest feature of all is that `C-c C-c` will open up the source file in "
+"which the error occurred and jump to the appropriate line."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1280
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1284
+#, no-wrap
+msgid "% emacsclient filename\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1287
+msgid ""
+"and then you can edit the file in your Emacs!footnote:[Many Emacs users set "
+"their EDITOR environment to emacsclient so this happens every time they need "
+"to edit a file.]"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1293
+#, no-wrap
+msgid ";; -*-Emacs-Lisp-*-\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1298
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1306
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1327
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1345
+#, no-wrap
+msgid ""
+";; 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-<\")\n"
+"(global-set-key [C-end] \"\\M->\")\n"
+"(global-set-key [C-prior] \"\\M-<\")\n"
+"(global-set-key [C-next] \"\\M->\")\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1348
+#, no-wrap
+msgid ""
+";; Mouse\n"
+"(global-set-key [mouse-3] 'imenu)\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1352
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1357
+#, no-wrap
+msgid ""
+";; Treat 'y' or <CR> 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1361
+#, no-wrap
+msgid ""
+";; Load packages\n"
+"(require 'desktop)\n"
+"(require 'tar-mode)\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1367
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1376
+#, no-wrap
+msgid ""
+"(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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1381
+#, 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 'lisp-mode 'perl-mode 'scheme-mode)\n"
+" \"List of modes to always start in font-lock-mode\")\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1386
+#, no-wrap
+msgid ""
+"(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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1394
+#, no-wrap
+msgid ""
+"(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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1396
+#, no-wrap
+msgid "(global-set-key [M-f1] 'font-lock-fontify-buffer)\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1413
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1425
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1439
+#, no-wrap
+msgid ""
+"(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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1446
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1450
+#, no-wrap
+msgid ""
+";; Scheme mode...\n"
+"(defun my-scheme-mode-hook ()\n"
+" (define-key scheme-mode-map \"\\C-m\" 'reindent-then-newline-and-indent))\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1456
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1464
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1470
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1483
+#, no-wrap
+msgid ""
+";; 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 (>= emacs-major-version 21)\n"
+"\t(setq show-trailing-whitespace t))\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1489
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1498
+#, no-wrap
+msgid ""
+";; Font lock mode\n"
+"(defun my-make-face (face color &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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1511
+#, no-wrap
+msgid ""
+"(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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1519
+#, no-wrap
+msgid ""
+" (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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1536
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1545
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1551
+#, no-wrap
+msgid ""
+";; Under UNIX\n"
+"(if (not (equal system-type 'ms-dos))\n"
+" (progn\n"
+" (if first-time\n"
+"\t (server-start))))\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1559
+#, no-wrap
+msgid ""
+";; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1565
+#, no-wrap
+msgid ""
+";; Restore the \"desktop\" - do this as late as possible\n"
+"(if first-time\n"
+" (progn\n"
+" (desktop-load-default)\n"
+" (desktop-read)))\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1568
+#, no-wrap
+msgid ""
+";; Indicate that this file has been read at least once\n"
+"(setq first-time nil)\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1570
+#, no-wrap
+msgid ";; No need to debug anything now\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1572
+#, no-wrap
+msgid "(setq debug-on-error nil)\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1575
+#, no-wrap
+msgid ""
+";; All done\n"
+"(message \"All done, %s%s\" (user-login-name) \".\")\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1578
+#, no-wrap
+msgid "Extending the Range of Languages Emacs Understands"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1581
+msgid ""
+"Now, this is all very well if you only want to program in the languages "
+"already catered for in [.filename]#.emacs# (C, C++, Perl, Lisp and Scheme), "
+"but what happens if a new language called \"whizbang\" comes out, full of "
+"exciting features?"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1585
+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#, short for "
+"\"Emacs Lisp\". For example, if whizbang is a FreeBSD port, we can locate "
+"these files by doing"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1589
+#, no-wrap
+msgid "% find /usr/ports/lang/whizbang -name \"*.el\" -print\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1593
+msgid ""
+"and install them by copying them into the Emacs site Lisp directory. On "
+"FreeBSD, this is [.filename]#/usr/local/share/emacs/site-lisp#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1595
+msgid "So for example, if the output from the find command was"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1599
+#, no-wrap
+msgid "/usr/ports/lang/whizbang/work/misc/whizbang.el\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1602
+msgid "we would do"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1606
+#, no-wrap
+msgid "# cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1611
+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#. We "
+"need to add an entry to our [.filename]#.emacs# to make sure Emacs will be "
+"able to use the information in [.filename]#whizbang.el#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1613
+msgid ""
+"Find the auto-mode-alist entry in [.filename]#.emacs# and add a line for "
+"whizbang, such as:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1621
+#, no-wrap
+msgid ""
+"...\n"
+"(\"\\\\.lsp$\" . lisp-mode)\n"
+"(\"\\\\.wiz$\" . whizbang-mode)\n"
+"(\"\\\\.scm$\" . scheme-mode)\n"
+"...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1624
+msgid ""
+"This means that Emacs will automatically go into `whizbang-mode` when you "
+"edit a file ending in [.filename]#.wiz#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1627
+msgid ""
+"Just below this, you will find the font-lock-auto-mode-list entry. Add "
+"`whizbang-mode` to it like so:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1634
+#, 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\")\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1637
+msgid ""
+"This means that Emacs will always enable `font-lock-mode` (ie syntax "
+"highlighting) when editing a [.filename]#.wiz# file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1640
+msgid ""
+"And that is all that is needed. If there is anything else you want done "
+"automatically when you open up [.filename]#.wiz#, you can add a `whizbang-"
+"mode hook` (see `my-scheme-mode-hook` for a simple example that adds `auto-"
+"indent`)."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1642
+#, no-wrap
+msgid "Further Reading"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1645
+msgid ""
+"For information about setting up a development environment for contributing "
+"fixes to FreeBSD itself, please see man:development[7]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1647
+msgid ""
+"Brian Harvey and Matthew Wright _Simply Scheme_ MIT 1994. ISBN 0-262-08226-8"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1648
+msgid "Randall Schwartz _Learning Perl_ O'Reilly 1993 ISBN 1-56592-042-2"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1649
+msgid ""
+"Patrick Henry Winston and Berthold Klaus Paul Horn _Lisp (3rd Edition)_ "
+"Addison-Wesley 1989 ISBN 0-201-08319-1"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1650
+msgid ""
+"Brian W. Kernighan and Rob Pike _The Unix Programming Environment_ Prentice-"
+"Hall 1984 ISBN 0-13-937681-X"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1651
+msgid ""
+"Brian W. Kernighan and Dennis M. Ritchie _The C Programming Language (2nd "
+"Edition)_ Prentice-Hall 1988 ISBN 0-13-110362-8"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1652
+msgid ""
+"Bjarne Stroustrup _The C++ Programming Language_ Addison-Wesley 1991 ISBN "
+"0-201-53992-6"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1653
+msgid ""
+"W. Richard Stevens _Advanced Programming in the Unix Environment_ Addison-"
+"Wesley 1992 ISBN 0-201-56317-7"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/tools/_index.adoc:1653
+msgid ""
+"W. Richard Stevens _Unix Network Programming_ Prentice-Hall 1990 ISBN "
+"0-13-949876-1"
+msgstr ""
diff --git a/documentation/content/en/books/developers-handbook/x86/_index.po b/documentation/content/en/books/developers-handbook/x86/_index.po
new file mode 100644
index 0000000000..357587bc7b
--- /dev/null
+++ b/documentation/content/en/books/developers-handbook/x86/_index.po
@@ -0,0 +1,8103 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2022-02-01 09:20-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: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:14
+#, no-wrap
+msgid "x86 Assembly Language Programming"
+msgstr ""
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1
+#, no-wrap
+msgid "Chapter 11. x86 Assembly Language Programming"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:52
+msgid "_This chapter was written by {stanislav}._"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:54
+#, no-wrap
+msgid "Synopsis"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:58
+msgid ""
+"Assembly language programming under UNIX(R) is highly undocumented. It is "
+"generally assumed that no one would ever want to use it because various "
+"UNIX(R) systems run on different microprocessors, so everything should be "
+"written in C for portability."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:62
+msgid ""
+"In reality, C portability is quite a myth. Even C programs need to be "
+"modified when ported from one UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:64
+msgid ""
+"Even if we believe that all of UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:66
+msgid ""
+"In this chapter I will attempt to show you how you can use assembly language "
+"writing UNIX(R) programs, specifically under FreeBSD."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:71
+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 http://webster.cs.ucr.edu/[Art of Assembly "
+"Language]; 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:73
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4313
+msgid "Copyright (R) 2000-2001 G. Adam Stanislav. All rights reserved."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:75
+#, no-wrap
+msgid "The Tools"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:78
+#, no-wrap
+msgid "The Assembler"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:81
+msgid ""
+"The most important tool for assembly language programming is the assembler, "
+"the software that converts assembly language code into machine language."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:85
+msgid ""
+"Two very different assemblers are available for FreeBSD. One is man:as[1], "
+"which uses the traditional UNIX(R) assembly language syntax. It comes with "
+"the system."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:90
+msgid ""
+"The other is /usr/ports/devel/nasm. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:93
+msgid ""
+"This chapter uses nasm 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:95
+#, no-wrap
+msgid "The Linker"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:98
+msgid ""
+"The output of the assembler, like that of any compiler, needs to be linked "
+"to form an executable file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:101
+msgid ""
+"The standard man:ld[1] linker comes with FreeBSD. It works with the code "
+"assembled with either assembler."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:103
+#, no-wrap
+msgid "System Calls"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:106
+#, no-wrap
+msgid "Default Calling Convention"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:110
+msgid ""
+"By default, the FreeBSD kernel uses the C calling convention. Further, "
+"although the kernel is accessed using `int 80h`, it is assumed the program "
+"will call a function that issues `int 80h`, rather than issuing `int 80h` "
+"directly."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:113
+msgid ""
+"This convention is very convenient, and quite superior to the Microsoft(R) "
+"convention used by MS-DOS(R). Why? Because the UNIX(R) convention allows "
+"any program written in any language to access the kernel."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:116
+msgid ""
+"An assembly language program can do that as well. For example, we could "
+"open a file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:122
+#, no-wrap
+msgid ""
+"kernel:\n"
+"\tint\t80h\t; Call kernel\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:131
+#, no-wrap
+msgid ""
+"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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:135
+msgid ""
+"This is a very clean and portable way of coding. If you need to port the "
+"code to a UNIX(R) system which uses a different interrupt, or a different "
+"way of passing parameters, all you need to change is the kernel procedure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:139
+msgid ""
+"But assembly language programmers like to shave off cycles. The above "
+"example requires a `call/ret` combination. We can eliminate it by "
+"``push``ing an extra dword:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:150
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:153
+msgid ""
+"The `5` that we have placed in `EAX` identifies the kernel function, in this "
+"case `open`."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:155
+#, no-wrap
+msgid "Alternate Calling Convention"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:160
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:165
+msgid ""
+"Linux is a UNIX(R) like system. However, its kernel uses the same system-"
+"call convention of passing parameters in registers MS-DOS(R) does. As with "
+"the UNIX(R) convention, the function number is placed in `EAX`. The "
+"parameters, however, are not passed on the stack but in `EBX, ECX, EDX, ESI, "
+"EDI, EBP`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:174
+#, no-wrap
+msgid ""
+"open:\n"
+"\tmov\teax, 5\n"
+"\tmov\tebx, path\n"
+"\tmov\tecx, flags\n"
+"\tmov\tedx, mode\n"
+"\tint\t80h\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:180
+msgid ""
+"This convention has a great disadvantage over the UNIX(R) way, at least as "
+"far as assembly language programming is concerned: Every time you make a "
+"kernel call you must `push` the registers, then `pop` them later. This "
+"makes your code bulkier and slower. Nevertheless, FreeBSD gives you a "
+"choice."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:183
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:187
+#, no-wrap
+msgid "% brandelf -t Linux filename\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:190
+#, no-wrap
+msgid "Which Convention Should You Use?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:195
+msgid ""
+"If you are coding specifically for FreeBSD, you should always use the "
+"UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:198
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:200
+#, no-wrap
+msgid "Call Numbers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:204
+msgid ""
+"To tell the kernel which system service you are calling, place its number in "
+"`EAX`. Of course, you need to know what the number is."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:206
+#, no-wrap
+msgid "The [.filename]#syscalls# File"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:210
+msgid ""
+"The numbers are listed in [.filename]#syscalls#. `locate syscalls` finds "
+"this file in several different formats, all produced automatically from [."
+"filename]#syscalls.master#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:213
+msgid ""
+"You can find the master file for the default UNIX(R) calling convention in [."
+"filename]#/usr/src/sys/kern/syscalls.master#. If you need to use the other "
+"convention implemented in the Linux emulation mode, read [.filename]#/usr/"
+"src/sys/i386/linux/syscalls.master#."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:217
+msgid ""
+"Not only do FreeBSD and Linux use different calling conventions, they "
+"sometimes use different numbers for the same functions."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:220
+msgid "[.filename]#syscalls.master# describes how the call is to be made:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:231
+#, 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...\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:234
+msgid "It is the leftmost column that tells us the number to place in `EAX`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:237
+msgid ""
+"The rightmost column tells us what parameters to `push`. They are "
+"``push``ed _from right to left_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:239
+msgid ""
+"For example, to `open` a file, we need to `push` the `mode` first, then "
+"`flags`, then the address at which the `path` is stored."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:241
+#, no-wrap
+msgid "Return Values"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:245
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:248
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:250
+#, no-wrap
+msgid "Man Pages"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:254
+msgid ""
+"The traditional place to look for information about various system calls "
+"under UNIX(R) systems are the manual pages. FreeBSD describes its system "
+"calls in section 2, sometimes in section 3."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:256
+msgid "For example, man:open[2] says:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:260
+msgid ""
+"If successful, `open()` returns a non-negative integer, termed a file "
+"descriptor. It returns `-1` on failure, and sets `errno` to indicate the "
+"error."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:262
+msgid ""
+"The assembly language programmer new to UNIX(R) and FreeBSD will immediately "
+"ask the puzzling question: Where is `errno` and how do I get to it?"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:267
+msgid ""
+"The information presented in the manual pages applies to C programs. The "
+"assembly language programmer needs additional information."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:270
+#, no-wrap
+msgid "Where Are the Return Values?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:275
+msgid ""
+"Unfortunately, it depends... For most system calls it is in `EAX`, 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 `EAX`. If it is not there, "
+"you need further research."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:281
+msgid ""
+"I am aware of one system call that returns the value in `EDX`: `SYS_fork`. "
+"All others I have worked with use `EAX`. But I have not worked with them "
+"all yet."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:286
+msgid ""
+"If you cannot find the answer here or anywhere else, study libc source code "
+"and see how it interfaces with the kernel."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:289
+#, no-wrap
+msgid "Where Is `errno`?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:292
+msgid "Actually, nowhere..."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:295
+msgid ""
+"`errno` is part of the C language, not the UNIX(R) kernel. When accessing "
+"kernel services directly, the error code is returned in `EAX`, the same "
+"register the proper return value generally ends up in."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:299
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:301
+#, no-wrap
+msgid "Determining an Error Occurred"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:304
+msgid ""
+"When using the standard FreeBSD calling convention, the `carry flag` is "
+"cleared upon success, set upon failure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:307
+msgid ""
+"When using the Linux emulation mode, the signed value in `EAX` is non-"
+"negative upon success, and contains the return value. In case of an error, "
+"the value is negative, i.e., `-errno`."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:309
+#, no-wrap
+msgid "Creating Portable Code"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:314
+msgid ""
+"Portability is generally not one of the strengths of assembly language. "
+"Yet, writing assembly language programs for different platforms is possible, "
+"especially with nasm. I have written assembly language libraries that can "
+"be assembled for such different operating systems as Windows(R) and FreeBSD."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:316
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:320
+msgid ""
+"For example, FreeBSD is UNIX(R), Linux is UNIX(R) 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:322
+#, no-wrap
+msgid "Dealing with Function Numbers"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:327
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:335
+#, no-wrap
+msgid ""
+"%ifdef\tLINUX\n"
+"%define\tSYS_execve\t11\n"
+"%else\n"
+"%define\tSYS_execve\t59\n"
+"%endif\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:338
+#, no-wrap
+msgid "Dealing with Conventions"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:341
+msgid ""
+"Both, the calling convention, and the return value (the `errno` problem) can "
+"be resolved with macros:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:345
+#, no-wrap
+msgid "%ifdef\tLINUX\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:349
+#, no-wrap
+msgid ""
+"%macro\tsystem\t0\n"
+"\tcall\tkernel\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:358
+#, no-wrap
+msgid ""
+"align 4\n"
+"kernel:\n"
+"\tpush\tebx\n"
+"\tpush\tecx\n"
+"\tpush\tedx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+"\tpush\tebp\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:365
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:372
+#, no-wrap
+msgid ""
+"\tpop\tebp\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tedx\n"
+"\tpop\tecx\n"
+"\tpop\tebx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:377
+#, no-wrap
+msgid ""
+"\tor\teax, eax\n"
+"\tjs\t.errno\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:382
+#, no-wrap
+msgid ""
+".errno:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:384
+#, no-wrap
+msgid "%else\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:388
+#, no-wrap
+msgid ""
+"%macro\tsystem\t0\n"
+"\tint\t80h\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:390
+#, no-wrap
+msgid "%endif\n"
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:393
+#, no-wrap
+msgid "Dealing with Other Portability Issues"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:397
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:400
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:402
+#, no-wrap
+msgid "Using a Library"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:406
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:411
+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 `EAX` 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:419
+#, no-wrap
+msgid ""
+"sys.open:\n"
+"sys.close:\n"
+"[etc...]\n"
+"\tint\t80h\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:423
+msgid ""
+"Your Linux library will require more different functions. But even here you "
+"can group system calls using the same number of parameters:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:434
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:436
+#, no-wrap
+msgid "...\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:442
+#, no-wrap
+msgid ""
+"sys.return:\n"
+"\tor\teax, eax\n"
+"\tjs\tsys.err\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:447
+#, no-wrap
+msgid ""
+"sys.err:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:454
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:456
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:458
+#, no-wrap
+msgid "Using an Include File"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:461
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:464
+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 ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:469
+msgid ""
+"This is the approach we will use throughout this chapter. We will name our "
+"include file [.filename]#system.inc#, and add to it whenever we deal with a "
+"new system call."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:472
+msgid ""
+"We can start our [.filename]#system.inc# by declaring the standard file "
+"descriptors:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:478
+#, no-wrap
+msgid ""
+"%define\tstdin\t0\n"
+"%define\tstdout\t1\n"
+"%define\tstderr\t2\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:481
+msgid "Next, we create a symbolic name for each system call:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:490
+#, 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...]\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:493
+msgid ""
+"We add a short, non-global procedure with a long name, so we do not "
+"accidentally reuse the name in our code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:501
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"access.the.bsd.kernel:\n"
+"\tint\t80h\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:504
+msgid "We create a macro which takes one argument, the syscall number:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:511
+#, no-wrap
+msgid ""
+"%macro\tsystem\t1\n"
+"\tmov\teax, %1\n"
+"\tcall\taccess.the.bsd.kernel\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:515
+msgid ""
+"Finally, we create macros for each syscall. These macros take no arguments."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:521
+#, no-wrap
+msgid ""
+"%macro\tsys.exit\t0\n"
+"\tsystem\tSYS_exit\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:525
+#, no-wrap
+msgid ""
+"%macro\tsys.fork\t0\n"
+"\tsystem\tSYS_fork\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:529
+#, no-wrap
+msgid ""
+"%macro\tsys.read\t0\n"
+"\tsystem\tSYS_read\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:533
+#, no-wrap
+msgid ""
+"%macro\tsys.write\t0\n"
+"\tsystem\tSYS_write\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:535
+#, no-wrap
+msgid "; [etc...]\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:539
+msgid ""
+"Go ahead, enter it into your editor and save it as [.filename]#system.inc#. "
+"We will add more to it as we discuss more syscalls."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:541
+#, no-wrap
+msgid "Our First Program"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:544
+msgid "We are now ready for our first program, the mandatory Hello, World!"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:563
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:566
+msgid ""
+"Here is what it does: Line 1 includes the defines, the macros, and the code "
+"from [.filename]#system.inc#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:570
+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 (`0Ah`). Line "
+"5 creates a constant that contains the length of the string from line 4 in "
+"bytes."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:574
+msgid ""
+"Lines 7-16 contain the code. Note that FreeBSD uses the _elf_ file format "
+"for its executables, which requires every program to start at the point "
+"labeled `_start` (or, more precisely, the linker expects that). This label "
+"has to be global."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:576
+msgid ""
+"Lines 10-13 ask the system to write `hbytes` bytes of the `hello` string to "
+"`stdout`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:579
+msgid ""
+"Lines 15-16 ask the system to end the program with the return value of `0`. "
+"The `SYS_exit` syscall never returns, so the code ends there."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:587
+msgid ""
+"If you have come to UNIX(R) from MS-DOS(R) 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 UNIX(R). As far as "
+"you are concerned, you are writing to a file known as [.filename]#stdout#. "
+"This can be the video screen, or a telnet terminal, or an actual file, or "
+"even the input of another program. Which one it is, is for the system to "
+"figure out."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:590
+#, no-wrap
+msgid "Assembling the Code"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:594
+msgid ""
+"Type the code (except the line numbers) in an editor, and save it in a file "
+"named [.filename]#hello.asm#. You need nasm to assemble it."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:596
+#, no-wrap
+msgid "Installing nasm"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:599
+msgid "If you do not have nasm, type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:608
+#, no-wrap
+msgid ""
+"% su\n"
+"Password:your root password\n"
+"# cd /usr/ports/devel/nasm\n"
+"# make install\n"
+"# exit\n"
+"%\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:611
+msgid ""
+"You may type `make install clean` instead of just `make install` if you do "
+"not want to keep nasm source code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:613
+msgid ""
+"Either way, FreeBSD will automatically download nasm from the Internet, "
+"compile it, and install it on your system."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:618
+msgid ""
+"If your system is not FreeBSD, you need to get nasm from its https://"
+"sourceforge.net/projects/nasm[home page]. You can still use it to assemble "
+"FreeBSD code."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:621
+msgid "Now you can assemble, link, and run the code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:629
+#, no-wrap
+msgid ""
+"% nasm -f elf hello.asm\n"
+"% ld -s -o hello hello.o\n"
+"% ./hello\n"
+"Hello, World!\n"
+"%\n"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:632
+#, no-wrap
+msgid "Writing UNIX(R) Filters"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:635
+msgid ""
+"A common type of UNIX(R) application is a filter-a program that reads data "
+"from the [.filename]#stdin#, processes it somehow, then writes the result to "
+"[.filename]#stdout#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:638
+msgid ""
+"In this chapter, we shall develop a simple filter, and learn how to read "
+"from [.filename]#stdin# and write to [.filename]#stdout#. This filter will "
+"convert each byte of its input into a hexadecimal number followed by a blank "
+"space."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:642
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:736
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:826
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:954
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1221
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2339
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3337
+#, no-wrap
+msgid "%include\t'system.inc'\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:646
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:740
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+"buffer\tdb\t0, 0, ' '\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:658
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:668
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:676
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:680
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:783
+#, no-wrap
+msgid ""
+".done:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:688
+msgid ""
+"In the data section we create an array called `hex`. 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 `0`. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:690
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:696
+msgid ""
+"To read the byte, we ask the system to read one byte from [."
+"filename]#stdin#, and store it in the first byte of the `buffer`. The "
+"system returns the number of bytes read in `EAX`. This will be `1` while "
+"data is coming, or `0`, when no more input data is available. Therefore, we "
+"check the value of `EAX`. If it is `0`, we jump to `.done`, otherwise we "
+"continue."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:700
+msgid ""
+"For simplicity sake, we are ignoring the possibility of an error condition "
+"at this time."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:705
+msgid ""
+"The hexadecimal conversion reads the byte from the `buffer` into `EAX`, or "
+"actually just `AL`, while clearing the remaining bits of `EAX` to zeros. We "
+"also copy the byte to `EDX` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:708
+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#. We then "
+"jump back to the beginning of the program and process the next byte."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:710
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:712
+msgid ""
+"Go ahead, and save the code in a file named [.filename]#hex.asm#, then type "
+"the following (the `^D` means press the control key and type `D` while "
+"holding the control key down):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:721
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A ^D %\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:727
+msgid ""
+"If you are migrating to UNIX(R) from MS-DOS(R), you may be wondering why "
+"each line ends with `0A` instead of `0D 0A`. This is because UNIX(R) does "
+"not use the cr/lf convention, but a \"new line\" convention, which is `0A` "
+"in hexadecimal."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:732
+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 `0A`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:745
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\tmov\tcl, ' '\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:755
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:762
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:771
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:779
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:787
+msgid ""
+"We have stored the space in the `CL` register. We can do this safely "
+"because, unlike Microsoft(R) Windows(R), UNIX(R) system calls do not modify "
+"the value of any register they do not use to return a value in."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:791
+msgid ""
+"That means we only need to set `CL` once. We have, therefore, added a new "
+"label `.loop` and jump to it for the next byte instead of jumping at "
+"`_start`. We have also added the `.hex` label so we can either have a blank "
+"space or a new line as the third byte of the `buffer`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:793
+msgid ""
+"Once you have changed [.filename]#hex.asm# to reflect these changes, type:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:804
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1063
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
+"Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
+"^D %\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:808
+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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:810
+#, no-wrap
+msgid "Buffered Input and Output"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:815
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:818
+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#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:822
+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# 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:828
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:956
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1223
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2341
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3339
+#, no-wrap
+msgid "%define\tBUFSIZE\t2048\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:831
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:959
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:835
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:963
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1232
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2355
+#, no-wrap
+msgid ""
+"section .bss\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:843
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:971
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:847
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:975
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2503
+#, no-wrap
+msgid ""
+".loop:\n"
+"\t; read a byte from stdin\n"
+"\tcall\tgetchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:853
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:981
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1285
+#, no-wrap
+msgid ""
+"\t; convert it to hex\n"
+"\tmov\tdl, al\n"
+"\tshr\tal, 4\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:858
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:986
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1290
+#, no-wrap
+msgid ""
+"\tmov\tal, dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:863
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:991
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1295
+#, no-wrap
+msgid ""
+"\tmov\tal, ' '\n"
+"\tcmp\tdl, 0Ah\n"
+"\tjne\t.put\n"
+"\tmov\tal, dl\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:867
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2514
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:872
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1003
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1307
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2536
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3850
+#, no-wrap
+msgid ""
+"align 4\n"
+"getchar:\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.fetch\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:874
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1005
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1309
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2538
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3852
+#, no-wrap
+msgid "\tcall\tread\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:879
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1010
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1314
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2543
+#, no-wrap
+msgid ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:892
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1023
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:898
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1029
+#, no-wrap
+msgid ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:906
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1037
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1350
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2583
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3889
+#, no-wrap
+msgid ""
+"align 4\n"
+"putchar:\n"
+"\tstosb\n"
+"\tinc\tecx\n"
+"\tcmp\tecx, BUFSIZE\n"
+"\tje\twrite\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:918
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1049
+#, no-wrap
+msgid ""
+"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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:924
+msgid ""
+"We now have a third section in the source code, named `.bss`. This section "
+"is not included in our executable file, and, therefore, cannot be "
+"initialized. We use `resb` instead of `db`. It simply reserves the "
+"requested size of uninitialized memory for our use."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:928
+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 `.data` section. This is also why the UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:932
+msgid ""
+"We use `EDI` and `ESI` as pointers to the next byte to be read from or "
+"written to. We use `EBX` and `ECX` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:934
+msgid "Let us see how it works now:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:945
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"Here I come!\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"
+"^D %\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:950
+msgid ""
+"Not what you expected? The program did not print the output until we pressed "
+"`^D`. That is easy to fix by inserting three lines of code to write the "
+"output every time we have converted a new line to `0A`. I have marked the "
+"three lines with > (do not copy the > in your [.filename]#hex.asm#)."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:998
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+">\tcmp\tal, 0Ah\n"
+">\tjne\t.loop\n"
+">\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1052
+msgid "Now, let us see how it works:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1066
+msgid "Not bad for a 644-byte executable, is it!"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1071
+msgid ""
+"This approach to buffered input/output still contains a hidden danger. I "
+"will discuss-and fix-it later, when I talk about the <<x86-buffered-dark-"
+"side,dark side of buffering>>."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1074
+#, no-wrap
+msgid "How to Unread a Character"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1080
+msgid ""
+"This may be a somewhat advanced topic, mostly of interest to programmers "
+"familiar with the theory of compilers. If you wish, you may <<x86-command-"
+"line,skip to the next section>>, and perhaps read this later."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1086
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1090
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1092
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1096
+msgid ""
+"One possible solution is to store it in a character variable, then set a "
+"flag. We can modify `getchar` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1101
+msgid ""
+"The C language has an `ungetc()` 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 `getchar` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1103
+msgid ""
+"The key to returning a character back to the stream is in how we are getting "
+"the characters to start with:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1106
+msgid ""
+"First we check if the buffer is empty by testing the value of `EBX`. If it "
+"is zero, we call the `read` procedure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1109
+msgid ""
+"If we do have a character available, we use `lodsb`, then decrease the value "
+"of `EBX`. The `lodsb` instruction is effectively identical to:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1114
+#, no-wrap
+msgid ""
+"mov\tal, [esi]\n"
+"\tinc\tesi\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1119
+msgid ""
+"The byte we have fetched remains in the buffer until the next time `read` is "
+"called. We do not know when that happens, but we do know it will not happen "
+"until the next call to `getchar`. Hence, to \"return\" the last-read byte "
+"back to the stream, all we have to do is decrease the value of `ESI` and "
+"increase the value of `EBX`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1126
+#, no-wrap
+msgid ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1130
+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 `ungetc` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1133
+msgid ""
+"Because as long as `getchar` does not have to call `read`, all of the pre-"
+"read bytes are still in the buffer, and our `ungetc` works without a "
+"glitch. But the moment `getchar` calls `read`, the contents of the buffer "
+"change."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1135
+msgid ""
+"We can always rely on `ungetc` working properly on the last character we "
+"have read with `getchar`, but not on anything we have read before that."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1137
+msgid ""
+"If your program reads more than one byte ahead, you have at least two "
+"choices:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1140
+msgid ""
+"If possible, modify the program so it only reads one byte ahead. This is "
+"the simplest solution."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1144
+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 `.bss` section of your code, and "
+"create a small \"spare\" buffer right before your input buffer, something "
+"like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1151
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1154
+msgid ""
+"You also need to modify your `ungetc` to pass the value of the byte to unget "
+"in `AL`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1162
+#, no-wrap
+msgid ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tmov\t[esi], al\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1165
+msgid ""
+"With this modification, you can call `ungetc` 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 ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1167
+#, no-wrap
+msgid "Command Line Arguments"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1171
+msgid ""
+"Our hex 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1175
+msgid ""
+"Before a UNIX(R) system starts a program, it ``push``es some data on the "
+"stack, then jumps at the `_start` label of the program. Yes, I said jumps, "
+"not calls. That means the data can be accessed by reading `[esp+offset]`, "
+"or by simply ``pop``ping it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1178
+msgid ""
+"The value at the top of the stack contains the number of command line "
+"arguments. It is traditionally called `argc`, for \"argument count.\""
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1183
+msgid ""
+"Command line arguments follow next, all `argc` of them. These are typically "
+"referred to as `argv`, for \"argument value(s).\" That is, we get `argv[0]`, "
+"`argv[1]`, `...`, `argv[argc-1]`. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1185
+msgid ""
+"The `argv` list is followed by a NULL pointer, which is simply a `0`. There "
+"is more, but this is enough for our purposes right now."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1190
+msgid ""
+"If you have come from the MS-DOS(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1194
+msgid ""
+"Armed with this knowledge, we are almost ready for the next version of [."
+"filename]#hex.asm#. First, however, we need to add a few lines to [."
+"filename]#system.inc#:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1196
+msgid ""
+"First, we need to add two new entries to our list of system call numbers:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1201
+#, no-wrap
+msgid ""
+"%define\tSYS_open\t5\n"
+"%define\tSYS_close\t6\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1204
+msgid "Then we add two new macros at the end of the file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1210
+#, no-wrap
+msgid ""
+"%macro\tsys.open\t0\n"
+"\tsystem\tSYS_open\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1214
+#, no-wrap
+msgid ""
+"%macro\tsys.close\t0\n"
+"\tsystem\tSYS_close\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1217
+msgid "Here, then, is our modified source code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1228
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1238
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"err:\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1243
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1246
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1258
+#, no-wrap
+msgid ""
+"\tpop\tecx\n"
+"\tjecxz\t.init\t\t; no more arguments\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1252
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1255
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1266
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1269
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1275
+#, no-wrap
+msgid ""
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1279
+#, no-wrap
+msgid ""
+".loop:\n"
+"\t; read a byte from input file or stdin\n"
+"\tcall\tgetchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1302
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tcmp\tal, dl\n"
+"\tjne\t.loop\n"
+"\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1327
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1331
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2564
+#, no-wrap
+msgid ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1335
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2568
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3822
+#, no-wrap
+msgid ""
+"\t; close files\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.close\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1338
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2571
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3825
+#, no-wrap
+msgid ""
+"\tpush\tdword [fd.out]\n"
+"\tsys.close\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1342
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2575
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3831
+#, no-wrap
+msgid ""
+"\t; return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1362
+#, no-wrap
+msgid ""
+"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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1366
+msgid ""
+"In our `.data` section we now have two new variables, `fd.in` and `fd.out`. "
+"We store the input and output file descriptors here."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1368
+msgid ""
+"In the `.text` section we have replaced the references to `stdin` and "
+"`stdout` with `[fd.in]` and `[fd.out]`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1371
+msgid ""
+"The `.text` section now starts with a simple error handler, which does "
+"nothing but exit the program with a return value of `1`. The error handler "
+"is before `_start` so we are within a short distance from where the errors "
+"occur."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1374
+msgid ""
+"Naturally, the program execution still begins at `_start`. First, we remove "
+"`argc` and `argv[0]` from the stack: They are of no interest to us (in this "
+"program, that is)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1380
+msgid ""
+"We pop `argv[1]` to `ECX`. This register is particularly suited for "
+"pointers, as we can handle NULL pointers with `jecxz`. If `argv[1]` is not "
+"NULL, we try to open the file named in the first argument. Otherwise, we "
+"continue the program as before: Reading from `stdin`, writing to `stdout`. "
+"If we fail to open the input file (e.g., it does not exist), we jump to the "
+"error handler and quit."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1385
+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 `stdout`. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1387
+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 `[fd.in]` and `[fd."
+"out]`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1389
+msgid "Our executable is now a whopping 768 bytes long."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1392
+msgid ""
+"Can we still improve it? Of course! Every program can be improved. Here are "
+"a few ideas of what we could do:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1394
+msgid "Have our error handler print a message to `stderr`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1395
+msgid "Add error handlers to the `read` and `write` functions."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1396
+msgid ""
+"Close `stdin` when we open an input file, `stdout` when we open an output "
+"file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1397
+msgid ""
+"Add command line switches, such as `-i` and `-o`, so we can list the input "
+"and output files in any order, or perhaps read from `stdin` and write to a "
+"file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1398
+msgid "Print a usage message if command line arguments are incorrect."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1400
+msgid ""
+"I shall leave these enhancements as an exercise to the reader: You already "
+"know everything you need to know to implement them."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1402
+#, no-wrap
+msgid "UNIX(R) Environment"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1406
+msgid ""
+"An important UNIX(R) concept is the environment, which is defined by "
+"_environment variables_. Some are set by the system, others by you, yet "
+"others by the shell, or any program that loads another program."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1408
+#, no-wrap
+msgid "How to Find Environment Variables"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1413
+msgid ""
+"I said earlier that when a program starts executing, the stack contains "
+"`argc` followed by the NULL-terminated `argv` array, followed by something "
+"else. The \"something else\" is the _environment_, or, to be more precise, "
+"a NULL-terminated array of pointers to _environment variables_. This is "
+"often referred to as `env`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1416
+msgid ""
+"The structure of `env` is the same as that of `argv`, a list of memory "
+"addresses followed by a NULL (`0`). In this case, there is no `\"envc\"`-we "
+"figure out where the array ends by searching for the final NULL."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1419
+msgid ""
+"The variables usually come in the `name=value` format, but sometimes the "
+"`=value` part may be missing. We need to account for that possibility."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1421
+#, no-wrap
+msgid "webvars"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1425
+msgid ""
+"I could just show you some code that prints the environment the same way the "
+"UNIX(R) env command does. But I thought it would be more interesting to "
+"write a simple assembly language CGI utility."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1427
+#, no-wrap
+msgid "CGI: a Quick Overview"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1430
+msgid ""
+"I have a http://www.whizkidtech.redprince.net/cgi-bin/tutorial[detailed CGI "
+"tutorial] on my web site, but here is a very quick overview of CGI:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1432
+msgid ""
+"The web server communicates with the CGI program by setting _environment "
+"variables_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1433
+msgid ""
+"The CGI program sends its output to [.filename]#stdout#. The web server "
+"reads it from there."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1434
+msgid "It must start with an HTTP header followed by two blank lines."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1435
+msgid ""
+"It then prints the HTML code, or whatever other type of data it is producing."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1440
+msgid ""
+"While certain _environment variables_ use standard names, others vary, "
+"depending on the web server. That makes webvars quite a useful diagnostic "
+"tool."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1443
+#, no-wrap
+msgid "The Code"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1447
+msgid ""
+"Our webvars program, then, must send out the HTTP header followed by some "
+"HTML mark-up. It then must read the _environment variables_ one by one and "
+"send them out as part of the HTML page."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1450
+msgid ""
+"The code follows. I placed comments and explanations right inside the code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1487
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1524
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"http\tdb\t'Content-type: text/html', 0Ah, 0Ah\n"
+"\tdb\t'<?xml version=\"1.0\" encoding=\"utf-8\"?>', 0Ah\n"
+"\tdb\t'<!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML Strict//EN\" '\n"
+"\tdb\t'\"DTD/xhtml1-strict.dtd\">', 0Ah\n"
+"\tdb\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" '\n"
+"\tdb\t'xml.lang=\"en\" lang=\"en\">', 0Ah\n"
+"\tdb\t'<head>', 0Ah\n"
+"\tdb\t'<title>Web Environment</title>', 0Ah\n"
+"\tdb\t'<meta name=\"author\" content=\"G. Adam Stanislav\" />', 0Ah\n"
+"\tdb\t'</head>', 0Ah, 0Ah\n"
+"\tdb\t'<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" '\n"
+"\tdb\t'vlink=\"#840084\" alink=\"#0000ff\">', 0Ah\n"
+"\tdb\t'<div class=\"webvars\">', 0Ah\n"
+"\tdb\t'<h1>Web Environment</h1>', 0Ah\n"
+"\tdb\t'<p>The following <b>environment variables</b> are defined '\n"
+"\tdb\t'on this web server:</p>', 0Ah, 0Ah\n"
+"\tdb\t'<table align=\"center\" width=\"80\" border=\"0\" cellpadding=\"10\" '\n"
+"\tdb\t'cellspacing=\"0\" class=\"webvars\">', 0Ah\n"
+"httplen\tequ\t$-http\n"
+"left\tdb\t'<tr>', 0Ah\n"
+"\tdb\t'<td class=\"name\"><tt>'\n"
+"leftlen\tequ\t$-left\n"
+"middle\tdb\t'</tt></td>', 0Ah\n"
+"\tdb\t'<td class=\"value\"><tt><b>'\n"
+"midlen\tequ\t$-middle\n"
+"undef\tdb\t'<i>(undefined)</i>'\n"
+"undeflen\tequ\t$-undef\n"
+"right\tdb\t'</b></tt></td>', 0Ah\n"
+"\tdb\t'</tr>', 0Ah\n"
+"rightlen\tequ\t$-right\n"
+"wrap\tdb\t'</table>', 0Ah\n"
+"\tdb\t'</div>', 0Ah\n"
+"\tdb\t'</body>', 0Ah\n"
+"\tdb\t'</html>', 0Ah, 0Ah\n"
+"wraplen\tequ\t$-wrap\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1534
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1538
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1553
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1559
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1565
+#, no-wrap
+msgid ""
+"\t; Print the left part of HTML\n"
+"\tpush\tdword leftlen\n"
+"\tpush\tdword left\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1576
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1583
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1588
+#, no-wrap
+msgid ""
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1594
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1598
+#, no-wrap
+msgid ""
+"\t; Find the length of the value\n"
+"\tnot\tecx\n"
+"\tlea\tebx, [ebx+ecx-1]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1602
+#, no-wrap
+msgid ""
+"\t; Print \"undefined\" if 0\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.value\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1605
+#, no-wrap
+msgid ""
+"\tmov\tebx, undeflen\n"
+"\tmov\tedi, undef\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1611
+#, no-wrap
+msgid ""
+".value:\n"
+"\tpush\tebx\n"
+"\tpush\tedi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1617
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1620
+#, no-wrap
+msgid ""
+"\t; Get rid of the 60 bytes we have pushed\n"
+"\tadd\tesp, byte 60\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1623
+#, no-wrap
+msgid ""
+"\t; Get the next variable\n"
+"\tjmp\t.loop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1630
+#, no-wrap
+msgid ""
+".wrap:\n"
+"\t; Print the rest of HTML\n"
+"\tpush\tdword wraplen\n"
+"\tpush\tdword wrap\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1634
+#, no-wrap
+msgid ""
+"\t; Return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1638
+msgid ""
+"This code produces a 1,396-byte executable. Most of it is data, i.e., the "
+"HTML mark-up we need to send out."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1640
+msgid "Assemble and link it as usual:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1645
+#, no-wrap
+msgid ""
+"% nasm -f elf webvars.asm\n"
+"% ld -s -o webvars webvars.o\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1649
+msgid ""
+"To use it, you need to upload [.filename]#webvars# 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# directory, or perhaps rename it with a [."
+"filename]#.cgi# extension."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1653
+msgid ""
+"Then you need to use your browser to view its output. To see its output on "
+"my web server, please go to http://www.int80h.org/webvars/[http://www.int80h."
+"org/webvars/]. If curious about the additional environment variables "
+"present in a password protected web directory, go to http://www.int80h.org/"
+"private/[http://www.int80h.org/private/], using the name `asm` and password "
+"`programmer`."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1655
+#, no-wrap
+msgid "Working with Files"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1660
+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 UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1663
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1669
+msgid ""
+"One of the first programs I wrote for UNIX(R) was link:ftp://ftp.int80h.org/"
+"unix/tuc/[tuc], a text-to-UNIX(R) file converter. It converts a text file "
+"from other operating systems to a UNIX(R) text file. In other words, it "
+"changes from different kind of line endings to the newline convention of "
+"UNIX(R). It saves the output in a different file. Optionally, it converts "
+"a UNIX(R) text file to a DOS text file."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1673
+msgid ""
+"I have used tuc extensively, but always only to convert from some other OS "
+"to UNIX(R), 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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1678
+#, no-wrap
+msgid ""
+"% tuc myfile tempfile\n"
+"% mv tempfile myfile\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1681
+msgid ""
+"It would be nice to have a ftuc, i.e., _fast tuc_, and use it like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1685
+#, no-wrap
+msgid "% ftuc myfile\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1688
+msgid ""
+"In this chapter, then, we will write ftuc in assembly language (the original "
+"tuc is in C), and study various file-oriented kernel services in the process."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1690
+msgid ""
+"At first sight, such a file conversion is very simple: All you have to do is "
+"strip the carriage returns, right?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1692
+msgid ""
+"If you answered yes, think again: That approach will work most of the time "
+"(at least with MS DOS text files), but will fail occasionally."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1697
+msgid ""
+"The problem is that not all non UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1699
+msgid ""
+"A text file converter, then, must be able to handle any possible line "
+"endings:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1701
+msgid "carriage return / line feed"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1702
+msgid "carriage return"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1703
+msgid "line feed / carriage return"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1704
+msgid "line feed"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1706
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1708
+#, no-wrap
+msgid "Finite State Machine"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1715
+msgid ""
+"The problem is easily solved by the use of a technique called _finite state "
+"machine_, originally developed by the designers of digital electronic "
+"circuits. A _finite state machine_ 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 _finite state machine_: 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1718
+msgid ""
+"Because of that, all software is essentially a sequence of state "
+"instructions for the microprocessor. Nevertheless, the concept of _finite "
+"state machine_ is useful in software design as well."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1721
+msgid ""
+"Our text file converter can be designer as a _finite state machine_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1723
+msgid "ordinary"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1724
+msgid "cr"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1725
+msgid "lf"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1727
+msgid ""
+"Our program will start in the ordinary state. During this state, the program "
+"action depends on its input as follows:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1730
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1732
+msgid ""
+"If the input is a carriage return, the state is changed to cr. The input is "
+"then discarded, i.e., no output is made."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1734
+msgid ""
+"If the input is a line feed, the state is changed to lf. The input is then "
+"discarded."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1737
+msgid ""
+"Whenever we are in the cr 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1739
+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 ordinary."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1740
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1741
+msgid ""
+"If the input is a line feed, we output the line feed and change the state to "
+"ordinary. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1745
+msgid ""
+"Finally, we are in the lf 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 UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1747
+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 "
+"ordinary. This is exactly the same action as in the cr state upon receiving "
+"the same kind of input."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1748
+msgid ""
+"If the input is a carriage return, we discard the input, we output a line "
+"feed, then change the state to ordinary."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1749
+msgid ""
+"If the input is a line feed, we output the line feed, and leave the state "
+"unchanged."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1751
+#, no-wrap
+msgid "The Final State"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1756
+msgid ""
+"The above _finite state machine_ 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 tuc, just to discover that occasionally "
+"it strips the last line ending."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1759
+msgid ""
+"This problem is easily fixed by checking the state after the entire file was "
+"processed. If the state is not ordinary, we simply need to output one last "
+"line feed."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1765
+msgid ""
+"Now that we have expressed our algorithm as a _finite state machine_, 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1768
+#, no-wrap
+msgid "The Output Counter"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1773
+msgid ""
+"Because our file conversion program may be combining two characters into "
+"one, we need to use an output counter. We initialize it to `0`, 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1775
+#, no-wrap
+msgid "Implementing FSM in Software"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1779
+msgid ""
+"The hardest part of working with a _finite state machine_ is analyzing the "
+"problem and expressing it as a _finite state machine_. That accomplished, "
+"the software almost writes itself."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1782
+msgid ""
+"In a high-level language, such as C, there are several main approaches. One "
+"is to use a `switch` statement which chooses what function should be run. "
+"For example,"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1797
+#, 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}\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1800
+msgid ""
+"Another approach is by using an array of function pointers, something like "
+"this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1804
+#, no-wrap
+msgid "(output[state])(inputchar);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1807
+msgid ""
+"Yet another is to have `state` be a function pointer, set to point at the "
+"appropriate function:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1811
+#, no-wrap
+msgid "(*state)(inputchar);\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1815
+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 `EBX`, and then just issue:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1819
+#, no-wrap
+msgid "call\tebx\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1823
+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 _possibly_ because with the "
+"caching modern microprocessors do, either way may be equally fast."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1825
+#, no-wrap
+msgid "Memory Mapped Files"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1829
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1837
+msgid ""
+"UNIX(R) 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 `mmap` system call to map it into the memory. One nice "
+"thing about `mmap` 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 "
+"`mov`, `lods`, and `stos`. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1840
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1844
+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 tuc "
+"instead."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1850
+msgid ""
+"If you examine your copy of [.filename]#syscalls.master#, you will find two "
+"separate syscalls named `mmap`. This is because of evolution of UNIX(R): "
+"There was the traditional BSD `mmap`, syscall 71. That one was superseded "
+"by the POSIX(R) `mmap`, syscall 197. The FreeBSD system supports both "
+"because older programs were written by using the original BSD version. But "
+"new software uses the POSIX(R) version, which is what we will use."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1852
+msgid "The [.filename]#syscalls.master# lists the POSIX(R) version like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1857
+#, 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); }\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1861
+msgid ""
+"This differs slightly from what man:mmap[2] says. That is because man:"
+"mmap[2] describes the C version."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1865
+msgid ""
+"The difference is in the `long pad` argument, which is not present in the C "
+"version. However, the FreeBSD syscalls add a 32-bit pad after ``push``ing a "
+"64-bit argument. In this case, `off_t` is a 64-bit value."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1867
+msgid ""
+"When we are finished working with a memory-mapped file, we unmap it with the "
+"`munmap` syscall:"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1871
+msgid ""
+"For an in-depth treatment of `mmap`, see W. Richard Stevens' http://www."
+"int80h.org/cgi-bin/isbn?isbn=0130810819[Unix Network Programming, Volume 2, "
+"Chapter 12]."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1874
+#, no-wrap
+msgid "Determining File Size"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1877
+msgid ""
+"Because we need to tell `mmap` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1880
+msgid ""
+"We can use the `fstat` syscall to get all the information about an open file "
+"that the system can give us. That includes the file size."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1883
+msgid ""
+"Again, [.filename]#syscalls.master# lists two versions of `fstat`, a "
+"traditional one (syscall 62), and a POSIX(R) one (syscall 189). Naturally, "
+"we will use the POSIX(R) version:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1887
+#, no-wrap
+msgid "189\tSTD\tPOSIX\t{ int fstat(int fd, struct stat *sb); }\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1891
+msgid ""
+"This is a very straightforward call: We pass to it the address of a `stat` "
+"structure and the descriptor of an open file. It will fill out the contents "
+"of the `stat` structure."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1894
+msgid ""
+"I do, however, have to say that I tried to declare the `stat` structure in "
+"the `.bss` section, and `fstat` 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1896
+#, no-wrap
+msgid "Changing the File Size"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1900
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1903
+msgid ""
+"The `ftruncate` system call allows us to do just that. Despite its somewhat "
+"misleading name, the `ftruncate` system call can be used to both truncate "
+"the file (make it smaller) and to grow it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1906
+msgid ""
+"And yes, we will find two versions of `ftruncate` in [.filename]#syscalls."
+"master#, an older one (130), and a newer one (201). We will use the newer "
+"one:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1910
+#, no-wrap
+msgid "201\tSTD\tBSD\t{ int ftruncate(int fd, int pad, off_t length); }\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1913
+msgid "Please note that this one contains a `int pad` again."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1915
+#, no-wrap
+msgid "ftuc"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1920
+msgid ""
+"We now know everything we need to write ftuc. We start by adding some new "
+"lines in [.filename]#system.inc#. First, we define some constants and "
+"structures, somewhere at or near the beginning of the file:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1927
+#, no-wrap
+msgid ""
+";;;;;;; open flags\n"
+"%define\tO_RDONLY\t0\n"
+"%define\tO_WRONLY\t1\n"
+"%define\tO_RDWR\t2\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1936
+#, no-wrap
+msgid ""
+";;;;;;; 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1960
+#, no-wrap
+msgid ""
+";;;;;;; 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1963
+msgid "We define the new syscalls:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1970
+#, no-wrap
+msgid ""
+"%define\tSYS_mmap\t197\n"
+"%define\tSYS_munmap\t73\n"
+"%define\tSYS_fstat\t189\n"
+"%define\tSYS_ftruncate\t201\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1973
+msgid "We add the macros for their use:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1979
+#, no-wrap
+msgid ""
+"%macro\tsys.mmap\t0\n"
+"\tsystem\tSYS_mmap\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1983
+#, no-wrap
+msgid ""
+"%macro\tsys.munmap\t0\n"
+"\tsystem\tSYS_munmap\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1987
+#, no-wrap
+msgid ""
+"%macro\tsys.ftruncate\t0\n"
+"\tsystem\tSYS_ftruncate\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1991
+#, no-wrap
+msgid ""
+"%macro\tsys.fstat\t0\n"
+"\tsystem\tSYS_fstat\n"
+"%endmacro\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1994
+msgid "And here is our code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2007
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2021
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2023
+#, no-wrap
+msgid "section\t.text\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2029
+#, no-wrap
+msgid ""
+"align 4\n"
+"memerr:\n"
+"\tpush\tdword maelen\n"
+"\tpush\tdword mae\n"
+"\tjmp\tshort error\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2035
+#, no-wrap
+msgid ""
+"align 4\n"
+"toolong:\n"
+"\tpush\tdword ftllen\n"
+"\tpush\tdword ftl\n"
+"\tjmp\tshort error\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2041
+#, no-wrap
+msgid ""
+"align 4\n"
+"facerr:\n"
+"\tpush\tdword faelen\n"
+"\tpush\tdword fae\n"
+"\tjmp\tshort error\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2047
+#, no-wrap
+msgid ""
+"align 4\n"
+"cantopen:\n"
+"\tpush\tdword colen\n"
+"\tpush\tdword co\n"
+"\tjmp\tshort error\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2052
+#, no-wrap
+msgid ""
+"align 4\n"
+"usage:\n"
+"\tpush\tdword usglen\n"
+"\tpush\tdword usg\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2056
+#, no-wrap
+msgid ""
+"error:\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2059
+#, no-wrap
+msgid ""
+"\tpush\tdword 1\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2067
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2071
+#, no-wrap
+msgid ""
+"\tpop\teax\n"
+"\tor\teax, eax\t; Too many arguments?\n"
+"\tjne\tusage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2077
+#, no-wrap
+msgid ""
+"\t; Open the file\n"
+"\tpush\tdword O_RDWR\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tcantopen\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2079
+#, no-wrap
+msgid "\tmov\tebp, eax\t; Save fd\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2082
+#, no-wrap
+msgid ""
+"\tsub\tesp, byte stat_size\n"
+"\tmov\tebx, esp\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2088
+#, no-wrap
+msgid ""
+"\t; Find file size\n"
+"\tpush\tebx\n"
+"\tpush\tebp\t\t; fd\n"
+"\tsys.fstat\n"
+"\tjc\tfacerr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2090
+#, no-wrap
+msgid "\tmov\tedx, [ebx + st_size + 4]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2098
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2101
+#, no-wrap
+msgid ""
+"\t; Do nothing if the file is 0 bytes in size\n"
+"\tjecxz\t.quit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2113
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2118
+#, no-wrap
+msgid ""
+"\tmov\tedi, eax\n"
+"\tmov\tesi, eax\n"
+"\tpush\tecx\t\t; for SYS_munmap\n"
+"\tpush\tedi\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2123
+#, no-wrap
+msgid ""
+"\t; Use EBX for state machine\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tah, 0Ah\n"
+"\tcld\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2128
+#, no-wrap
+msgid ""
+".loop:\n"
+"\tlodsb\n"
+"\tcall\tebx\n"
+"\tloop\t.loop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2131
+#, no-wrap
+msgid ""
+"\tcmp\tebx, ordinary\n"
+"\tje\t.filesize\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2136
+#, no-wrap
+msgid ""
+"\t; Output final lf\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2144
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2147
+#, no-wrap
+msgid ""
+"\t; close it (ebp still pushed)\n"
+"\tsys.close\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2150
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 16\n"
+"\tsys.munmap\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2154
+#, no-wrap
+msgid ""
+".quit:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2159
+#, no-wrap
+msgid ""
+"align 4\n"
+"ordinary:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2162
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2184
+#, no-wrap
+msgid ""
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2166
+#, no-wrap
+msgid ""
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2171
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, cr\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2176
+#, no-wrap
+msgid ""
+"align 4\n"
+".lf:\n"
+"\tmov\tebx, lf\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2181
+#, no-wrap
+msgid ""
+"align 4\n"
+"cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2188
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2216
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2191
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\t; fall through\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2197
+#, no-wrap
+msgid ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2204
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2209
+#, no-wrap
+msgid ""
+"align 4\n"
+"lf:\n"
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2212
+#, no-wrap
+msgid ""
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2222
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2228
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tal, ah\n"
+"\t; fall through\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2233
+#, no-wrap
+msgid ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2240
+msgid ""
+"Do not use this program on files stored on a disk formatted by MS-DOS(R) or "
+"Windows(R). There seems to be a subtle bug in the FreeBSD code when using "
+"`mmap` on these drives mounted under FreeBSD: If the file is over a certain "
+"size, `mmap` will just fill the memory with zeros, and then copy them to the "
+"file overwriting its contents."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2243
+#, no-wrap
+msgid "One-Pointed Mind"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2246
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2249
+msgid ""
+"This, indeed, is very much how UNIX(R) works as well. While a typical "
+"Windows(R) application is attempting to do everything imaginable (and is, "
+"therefore, riddled with bugs), a typical UNIX(R) program does only one "
+"thing, and it does it well."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2251
+msgid ""
+"The typical UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2253
+msgid ""
+"When writing your own UNIX(R) 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2255
+#, no-wrap
+msgid "CSV"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2258
+msgid ""
+"I will illustrate this principle with a specific real-life example I was "
+"faced with recently:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2262
+msgid ""
+"I needed to extract the 11th field of each record from a database I "
+"downloaded from a web site. The database was a CSV file, i.e., a list of "
+"_comma-separated values_. That is quite a standard format for sharing data "
+"among people who may be using different database software."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2265
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2267
+msgid ""
+"I tried awk, using the comma as a separator. But because several lines "
+"contained a quoted comma, awk was extracting the wrong field from those "
+"lines."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2270
+msgid ""
+"Therefore, I needed to write my own software to extract the 11th field from "
+"the CSV file. However, going with the UNIX(R) spirit, I only needed to "
+"write a simple filter that would do the following:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2272
+msgid "Remove the first line from the file;"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2273
+msgid "Change all unquoted commas to a different character;"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2274
+msgid "Remove all quotation marks."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2276
+msgid ""
+"Strictly speaking, I could use sed 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2280
+msgid ""
+"At any rate, writing a program like this took me about 20 minutes. Writing "
+"a program that extracts the 11th field from the CSV file would take a lot "
+"longer, and I could not reuse it to extract some other field from some other "
+"database."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2282
+msgid ""
+"This time I decided to let it do a little more work than a typical tutorial "
+"program would:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2284
+msgid "It parses its command line for options;"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2285
+msgid "It displays proper usage if it finds wrong arguments;"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2286
+msgid "It produces meaningful error messages."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2288
+msgid "Here is its usage message:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2292
+#, no-wrap
+msgid "Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2295
+msgid "All parameters are optional, and can appear in any order."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2299
+msgid ""
+"The `-t` parameter declares what to replace the commas with. The `tab` is "
+"the default here. For example, `-t;` will replace all unquoted commas with "
+"semicolons."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2303
+msgid ""
+"I did not need the `-c` 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, `-c@` will replace all at signs (useful if you "
+"want to split a list of email addresses to their user names and domains)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2306
+msgid ""
+"The `-p` option preserves the first line, i.e., it does not delete it. By "
+"default, we delete the first line because in a CSV file it contains the "
+"field names rather than data."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2309
+msgid ""
+"The `-i` and `-o` options let me specify the input and the output files. "
+"Defaults are [.filename]#stdin# and [.filename]#stdout#, so this is a "
+"regular UNIX(R) filter."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2312
+msgid ""
+"I made sure that both `-i filename` and `-ifilename` are accepted. I also "
+"made sure that only one input and one output files may be specified."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2314
+msgid "To get the 11th field of each record, I can now do:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2318
+#, no-wrap
+msgid "% csv '-t;' data.csv | awk '-F;' '{print $11}'\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2321
+msgid ""
+"The code stores the options (except for the file descriptors) in `EDX`: The "
+"comma in `DH`, the new separator in `DL`, and the flag for the `-p` option "
+"in the highest bit of `EDX`, so a check for its sign will give us a quick "
+"decision what to do."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2323
+msgid "Here is the code:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2337
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2351
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"usg\tdb\t'Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]', 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2365
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2374
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3423
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2383
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3432
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2389
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tmov\tedx, (',' << 8) | 9\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2394
+#, no-wrap
+msgid ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .init\t\t; no more arguments\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2398
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3447
+#, no-wrap
+msgid ""
+"\t; ECX contains the pointer to an argument\n"
+"\tcmp\tbyte [ecx], '-'\n"
+"\tjne\tusage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2401
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2405
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3455
+#, no-wrap
+msgid ""
+".o:\n"
+"\tcmp\tal, 'o'\n"
+"\tjne\t.i\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2409
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3459
+#, no-wrap
+msgid ""
+"\t; Make sure we are not asked for the output file twice\n"
+"\tcmp\tdword [fd.out], stdout\n"
+"\tjne\tusage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2414
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3464
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2420
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2428
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3477
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2432
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3481
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+"\tjmp\tshort .arg\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2436
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3485
+#, no-wrap
+msgid ""
+".i:\n"
+"\tcmp\tal, 'i'\n"
+"\tjne\t.p\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2440
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3489
+#, no-wrap
+msgid ""
+"\t; Make sure we are not asked twice\n"
+"\tcmp\tdword [fd.in], stdin\n"
+"\tjne\tnear usage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2448
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2454
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3502
+#, no-wrap
+msgid ""
+".openinput:\n"
+"\tpush\tdword 0\t\t; O_RDONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tnear ierr\t\t; open failed\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2458
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3506
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+"\tjmp\t.arg\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2466
+#, no-wrap
+msgid ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.t\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tor\tedx, 1 << 31\n"
+"\tjmp\t.arg\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2474
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2482
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2489
+#, no-wrap
+msgid ""
+"align 4\n"
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2493
+#, no-wrap
+msgid ""
+"\t; See if we are to preserve the first line\n"
+"\tor\tedx, edx\n"
+"\tjs\t.loop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2499
+#, no-wrap
+msgid ""
+".firstline:\n"
+"\t; get rid of the first line\n"
+"\tcall\tgetchar\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.firstline\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2507
+#, no-wrap
+msgid ""
+"\t; is it a comma (or whatever the user asked for)?\n"
+"\tcmp\tal, dh\n"
+"\tjne\t.quote\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2510
+#, no-wrap
+msgid ""
+"\t; Replace the comma with a tab (or whatever the user wants)\n"
+"\tmov\tal, dl\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2518
+#, no-wrap
+msgid ""
+".quote:\n"
+"\tcmp\tal, '\"'\n"
+"\tjne\t.put\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2525
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2528
+#, no-wrap
+msgid ""
+"\tcmp\tal, 0Ah\n"
+"\tje\t.put\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2531
+#, no-wrap
+msgid ""
+"\tcall\tputchar\n"
+"\tjmp\tshort .qloop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2547
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3862
+#, no-wrap
+msgid ""
+"read:\n"
+"\tjecxz\t.read\n"
+"\tcall\twrite\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2560
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2597
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3903
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2602
+msgid ""
+"Much of it is taken from [.filename]#hex.asm# above. But there is one "
+"important difference: I no longer call `write` whenever I am outputting a "
+"line feed. Yet, the code can be used interactively."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2606
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2610
+msgid ""
+"The new solution I use now is to call `write` 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2612
+#, no-wrap
+msgid "The Dark Side of Buffering"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2616
+msgid ""
+"This change prevents a mysterious lockup in a very specific case. I refer "
+"to it as the _dark side of buffering_, mostly because it presents a danger "
+"that is not quite obvious."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2620
+msgid ""
+"It is unlikely to happen with a program like the csv 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 _red_, _green_, and _blue_ "
+"intensities of a pixel. Our output will be the negative of our input."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2623
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2631
+#, no-wrap
+msgid ""
+".loop:\n"
+"\tcall\tgetchar\n"
+"\tnot\tal\t\t; Create a negative\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2634
+msgid ""
+"Because this filter works with raw data, it is unlikely to be used "
+"interactively."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2637
+msgid ""
+"But it could be called by image manipulation software. And, unless it calls "
+"`write` before each call to `read`, chances are it will lock up."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2639
+msgid "Here is what might happen:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2642
+msgid "The image editor will load our filter using the C function `popen()`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2643
+msgid "It will read the first row of pixels from a bitmap or pixmap."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2644
+msgid ""
+"It will write the first row of pixels to the _pipe_ leading to the `fd.in` "
+"of our filter."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2645
+msgid ""
+"Our filter will read each pixel from its input, turn it to a negative, and "
+"write it to its output buffer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2646
+msgid "Our filter will call `getchar` to fetch the next pixel."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2647
+msgid "`getchar` will find an empty input buffer, so it will call `read`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2648
+msgid "`read` will call the `SYS_read` system call."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2649
+msgid ""
+"The _kernel_ will suspend our filter until the image editor sends more data "
+"to the pipe."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2650
+msgid ""
+"The image editor will read from the other pipe, connected to the `fd.out` of "
+"our filter so it can set the first row of the output image _before_ it sends "
+"us the second row of the input."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2651
+msgid ""
+"The _kernel_ suspends the image editor until it receives some output from "
+"our filter, so it can pass it on to the image editor."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2655
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2658
+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 "
+"crossref:secure[secure-race-conditions,race condition]."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2660
+msgid ""
+"This problem does not exist if our filter flushes its output buffer _before_ "
+"asking the _kernel_ for more input data."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2662
+#, no-wrap
+msgid "Using the FPU"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2665
+msgid ""
+"Strangely enough, most of assembly language literature does not even mention "
+"the existence of the FPU, or _floating point unit_, let alone discuss "
+"programming it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2667
+msgid ""
+"Yet, never does assembly language shine more than when we create highly "
+"optimized FPU code by doing things that can be done _only_ in assembly "
+"language."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2669
+#, no-wrap
+msgid "Organization of the FPU"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2673
+msgid ""
+"The FPU consists of 8 80-bit floating-point registers. These are organized "
+"in a stack fashion-you can `push` a value on TOS (_top of stack_) and you "
+"can `pop` it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2675
+msgid ""
+"That said, the assembly language op codes are not `push` and `pop` because "
+"those are already taken."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2678
+msgid ""
+"You can `push` a value on TOS by using `fld`, `fild`, and `fbld`. Several "
+"other op codes let you `push` many common _constants_-such as _pi_-on the "
+"TOS."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2681
+msgid ""
+"Similarly, you can `pop` a value by using `fst`, `fstp`, `fist`, `fistp`, "
+"and `fbstp`. Actually, only the op codes that end with a _p_ will literally "
+"`pop` the value, the rest will `store` it somewhere else without removing it "
+"from the TOS."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2683
+msgid ""
+"We can transfer the data between the TOS and the computer memory either as a "
+"32-bit, 64-bit, or 80-bit _real_, a 16-bit, 32-bit, or 64-bit _integer_, or "
+"an 80-bit _packed decimal_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2686
+msgid ""
+"The 80-bit _packed decimal_ is a special case of _binary coded decimal_ "
+"which is very convenient when converting between the ASCII representation of "
+"data and the internal data of the FPU. It allows us to use 18 significant "
+"digits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2688
+msgid ""
+"No matter how we represent data in the memory, the FPU always stores it in "
+"the 80-bit _real_ format in its registers."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2690
+msgid ""
+"Its internal precision is at least 19 decimal digits, so even if we choose "
+"to display results as ASCII in the full 18-digit precision, we are still "
+"showing correct results."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2692
+msgid ""
+"We can perform mathematical operations on the TOS: We can calculate its "
+"_sine_, we can _scale_ it (i.e., we can multiply or divide it by a power of "
+"2), we can calculate its base-2 _logarithm_, and many other things."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2694
+msgid ""
+"We can also _multiply_ or _divide_ it by, _add_ it to, or _subtract_ it "
+"from, any of the FPU registers (including itself)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2697
+msgid ""
+"The official Intel op code for the TOS is `st`, and for the _registers_ "
+"`st(0)`-`st(7)`. `st` and `st(0)`, then, refer to the same register."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2700
+msgid ""
+"For whatever reasons, the original author of nasm has decided to use "
+"different op codes, namely `st0`-`st7`. In other words, there are no "
+"parentheses, and the TOS is always `st0`, never just `st`."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2702
+#, no-wrap
+msgid "The Packed Decimal Format"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2706
+msgid ""
+"The _packed decimal_ format uses 10 bytes (80 bits) of memory to represent "
+"18 digits. The number represented there is always an _integer_."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2710
+msgid ""
+"You can use it to get decimal places by multiplying the TOS by a power of 10 "
+"first."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2714
+msgid ""
+"The highest bit of the highest byte (byte 9) is the _sign bit_: If it is "
+"set, the number is _negative_, otherwise, it is _positive_. The rest of the "
+"bits of this byte are unused/ignored."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2716
+msgid ""
+"The remaining 9 bytes store the 18 digits of the number: 2 digits per byte."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2718
+msgid ""
+"The _more significant digit_ is stored in the high _nibble_ (4 bits), the "
+"_less significant digit_ in the low _nibble_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2720
+msgid ""
+"That said, you might think that `-1234567` would be stored in the memory "
+"like this (using hexadecimal notation):"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2724
+#, no-wrap
+msgid "80 00 00 00 00 00 01 23 45 67\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2727
+msgid ""
+"Alas it is not! As with everything else of Intel make, even the _packed "
+"decimal_ is _little-endian_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2729
+msgid "That means our `-1234567` is stored like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2733
+#, no-wrap
+msgid "67 45 23 01 00 00 00 00 00 80\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2736
+msgid "Remember that, or you will be pulling your hair out in desperation!"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2742
+msgid ""
+"The book to read-if you can find it-is Richard Startz' http://www.amazon.com/"
+"exec/obidos/ASIN/013246604X/whizkidtechnomag[8087/80287/80387 for the IBM PC "
+"& Compatibles]. Though it does seem to take the fact about the little-"
+"endian storage of the _packed decimal_ for granted. I kid you not about the "
+"desperation of trying to figure out what was wrong with the filter I show "
+"below _before_ it occurred to me I should try the little-endian order even "
+"for this type of data."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2745
+#, no-wrap
+msgid "Excursion to Pinhole Photography"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2748
+msgid ""
+"To write meaningful software, we must not only understand our programming "
+"tools, but also the field we are creating software for."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2750
+msgid ""
+"Our next filter will help us whenever we want to build a _pinhole camera_, "
+"so, we need some background in _pinhole photography_ before we can continue."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2752
+#, no-wrap
+msgid "The Camera"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2755
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2760
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2762
+msgid ""
+"If some light sensitive material (such as film) is placed inside the camera, "
+"it can capture the image."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2764
+msgid ""
+"The hole often contains a _lens_, or a lens assembly, often called the "
+"_objective_."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2766
+#, no-wrap
+msgid "The Pinhole"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2770
+msgid ""
+"But, strictly speaking, the lens is not necessary: The original cameras did "
+"not use a lens but a _pinhole_. Even today, _pinholes_ are used, both as a "
+"tool to study how cameras work, and to achieve a special kind of image."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2774
+msgid ""
+"The image produced by the _pinhole_ is all equally sharp. Or _blurred_. "
+"There is an ideal size for a pinhole: If it is either larger or smaller, the "
+"image loses its sharpness."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2776
+#, no-wrap
+msgid "Focal Length"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2779
+msgid ""
+"This ideal pinhole diameter is a function of the square root of _focal "
+"length_, which is the distance of the pinhole from the film."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2783
+#, no-wrap
+msgid "D = PC * sqrt(FL)\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2789
+msgid ""
+"In here, `D` is the ideal diameter of the pinhole, `FL` is the focal length, "
+"and `PC` is a pinhole constant. According to Jay Bender, its value is "
+"`0.04`, while Kenneth Connors has determined it to be `0.037`. 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2791
+#, no-wrap
+msgid "The F-Number"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2795
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2798
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2800
+msgid "The f-number is easy to calculate:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2804
+#, no-wrap
+msgid "F = FL / D\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2809
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2812
+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 `A` as `t`, then "
+"the exposure at f-number `B` is:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2816
+#, no-wrap
+msgid "t * (B / A)²\n"
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2819
+#, no-wrap
+msgid "Normalized F-Number"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2822
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2824
+msgid ""
+"To allow for different f-numbers, cameras typically contained a metal plate "
+"with several holes of different sizes drilled to them."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2827
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2830
+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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2832
+#, no-wrap
+msgid "The F-Stop"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2836
+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 _stop_ "
+"in that position. Because of that, these positions of the dial are called f-"
+"stops."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2840
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2842
+#, no-wrap
+msgid "Designing the Pinhole Software"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2845
+msgid ""
+"We are now ready to decide what exactly we want our pinhole software to do."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2847
+#, no-wrap
+msgid "Processing Program Input"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2851
+msgid ""
+"Since its main purpose is to help us design a working pinhole camera, we "
+"will use the _focal length_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2853
+msgid ""
+"Most of the programs we have written so far worked with individual "
+"characters, or bytes, as their input: The hex program converted individual "
+"bytes into a hexadecimal number, the csv program either let a character "
+"through, or deleted it, or changed it to a different character, etc."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2855
+msgid ""
+"One program, ftuc used the state machine to consider at most two input bytes "
+"at a time."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2857
+msgid ""
+"But our pinhole program cannot just work with individual characters, it has "
+"to deal with larger syntactic units."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2859
+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 `100 mm`, `150 "
+"mm`, and `210 mm`, we may want to enter something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2863
+#, no-wrap
+msgid " 100, 150, 210\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2868
+msgid ""
+"Our program needs to consider more than a single byte of input at a time. "
+"When it sees the first `1`, it must understand it is seeing the first digit "
+"of a decimal number. When it sees the `0` and the other `0`, it must know "
+"it is seeing more digits of the same number."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2873
+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 `100`. And the digits of the second "
+"number into the value of `150`. And, of course, the digits of the third "
+"number into the numeric value of `210`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2875
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2880
+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 "
+"_obvious_ that it is an extra character. Duh!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2882
+msgid ""
+"Plus, it allows me to break up the monotony of computing and type in a query "
+"instead of just a number:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2887
+#, no-wrap
+msgid ""
+"What is the best pinhole diameter for the\n"
+"\t focal length of 150?\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2890
+msgid "There is no reason for the computer to spit out a number of complaints:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2897
+#, no-wrap
+msgid ""
+"Syntax error: What\n"
+"Syntax error: is\n"
+"Syntax error: the\n"
+"Syntax error: best\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2900
+msgid "Et cetera, et cetera, et cetera."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2903
+msgid ""
+"Secondly, I like the `#` 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2905
+msgid ""
+"In our case, we also need to decide what units the input should come in: We "
+"choose _millimeters_ because that is how most photographers measure the "
+"focus length."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2907
+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 _comma_)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2911
+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 `50` and `51`, so allowing the user to input something like "
+"`50.5` 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 ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2913
+#, no-wrap
+msgid "Offering Options"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2918
+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 `PC` constant, we "
+"will need to have the choice."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2920
+msgid ""
+"It is traditional in UNIX(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2922
+msgid "Why have two ways of choosing?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2924
+msgid ""
+"One is to allow a (relatively) _permanent_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2929
+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 _\"rc\"_ is added to the file "
+"name. So, ours could be [.filename]#~/.pinhole# or [.filename]#~/."
+"pinholerc#. (The [.filename]#~/# means current user's home directory.)"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2934
+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 _environment "
+"variable_. In our case, we might look at an environment variable named "
+"`PINHOLE`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2937
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2939
+msgid ""
+"Because we only need to choose _one_ such parameter, we will go with the "
+"second method and search the environment for a variable named `PINHOLE`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2942
+msgid ""
+"The other way allows us to make _ad hoc_ decisions: _\"Though I usually want "
+"you to use 0.039, this time I want 0.03872.\"_ In other words, it allows us "
+"to _override_ the permanent choice."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2944
+msgid "This type of choice is usually done with command line parameters."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2952
+msgid ""
+"Finally, a program _always_ needs a _default_. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2954
+msgid ""
+"Given this system, the program may find conflicting options, and handle them "
+"this way:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2957
+msgid ""
+"If it finds an _ad hoc_ choice (e.g., command line parameter), it should "
+"accept that choice. It must ignore any permanent choice and any default."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2958
+msgid ""
+"_Otherwise_, if it finds a permanent option (e.g., an environment variable), "
+"it should accept it, and ignore the default."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2959
+msgid "_Otherwise_, it should use the default."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2961
+msgid "We also need to decide what _format_ our `PC` option should have."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2963
+msgid ""
+"At first site, it seems obvious to use the `PINHOLE=0.04` format for the "
+"environment variable, and `-p0.04` for the command line."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2967
+msgid ""
+"Allowing that is actually a security risk. The `PC` constant is a very small "
+"number. Naturally, we will test our software using various small values of "
+"`PC`. But what will happen if someone runs the program choosing a huge "
+"value?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2969
+msgid ""
+"It may crash the program because we have not designed it to handle huge "
+"numbers."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2972
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2974
+msgid "Or, we might say, _\"Tough! The user should know better.\"\"_"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2977
+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 _implied 0._ prefix."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2980
+msgid ""
+"In other words, if the user wants `0.04`, we will expect him to type `-p04`, "
+"or set `PINHOLE=04` in his environment. So, if he says `-p9999999`, we will "
+"interpret it as ``0.9999999``-still ridiculous but at least safer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2983
+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 `-b` as "
+"identical to `-p04`, and `-c` as identical to `-p037`."
+msgstr ""
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2985
+#, no-wrap
+msgid "The Output"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2988
+msgid ""
+"We need to decide what we want our software to send to the output, and in "
+"what format."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2990
+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 `tab` character."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2993
+msgid ""
+"Optionally, we should also allow the user to specify the use of the CSV "
+"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 `comma` for the `tab`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2998
+msgid ""
+"We need a command line option for the CSV format. We cannot use `-c` "
+"because that already means _use Connors' constant_. For some strange "
+"reason, many web sites refer to CSV files as _\"Excel spreadsheet\"_ (though "
+"the CSV format predates Excel). We will, therefore, use the `-e` switch to "
+"inform our software we want the output in the CSV format."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3002
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3006
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3008
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3010
+msgid ""
+"So, it makes perfect sense to start each line with the focal length as "
+"entered by the user."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3013
+msgid ""
+"No, wait! Not as entered by the user. What if the user types in something "
+"like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3017
+#, no-wrap
+msgid " 00000000150\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3020
+msgid "Clearly, we need to strip those leading zeros."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3022
+msgid ""
+"So, we might consider reading the user input as is, converting it to binary "
+"inside the FPU, and printing it out from there."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3024
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3209
+msgid "But..."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3026
+msgid "What if the user types something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3030
+#, no-wrap
+msgid " 17459765723452353453534535353530530534563507309676764423\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3035
+msgid ""
+"Ha! The packed decimal FPU format lets us input 18-digit numbers. But the "
+"user has entered more than 18 digits. How do we handle that?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3037
+msgid ""
+"Well, we _could_ modify our code to read the first 18 digits, enter it to "
+"the FPU, then read more, multiply what we already have on the TOS by 10 "
+"raised to the number of additional digits, then `add` to it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3041
+msgid ""
+"Yes, we could do that. But in _this_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3043
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3045
+msgid "What will we do?"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3047
+msgid "We will slap him in the face, in a manner of speaking:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3051
+#, no-wrap
+msgid "17459765723452353453534535353530530534563507309676764423\t???\t???\t???\t???\t???\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3055
+msgid ""
+"To achieve that, we will simply ignore any leading zeros. Once we find a "
+"non-zero digit, we will initialize a counter to `0` and start taking three "
+"steps:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3058
+msgid "Send the digit to the output."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3059
+msgid ""
+"Append the digit to a buffer we will use later to produce the packed decimal "
+"we can send to the FPU."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3060
+msgid "Increase the counter."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3062
+msgid ""
+"Now, while we are taking these three steps, we also need to watch out for "
+"one of two conditions:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3064
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3065
+msgid ""
+"If, or rather _when_, the next input character is not a digit, we are done "
+"inputting for now."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3068
+msgid ""
+"Incidentally, we can simply discard the non-digit, unless it is a `#`, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3070
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3073
+msgid ""
+"We can determine this has happened whenever our counter stays at `0`. In "
+"that case we need to send `0` to the output, and perform another \"slap in "
+"the face\":"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3077
+#, no-wrap
+msgid "0\t???\t???\t???\t???\t???\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3080
+msgid ""
+"Once we have displayed the focal length and determined it is valid (greater "
+"than `0` but not exceeding 18 digits), we can calculate the pinhole diameter."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3083
+msgid ""
+"It is not by coincidence that _pinhole_ contains the word _pin_. Indeed, "
+"many a pinhole literally is a _pin hole_, a hole carefully punched with the "
+"tip of a pin."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3086
+msgid ""
+"That is because a typical pinhole is very small. Our formula gets the result "
+"in millimeters. We will multiply it by `1000`, so we can output the result "
+"in _microns_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3088
+msgid "At this point we have yet another trap to face: _Too much precision._"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3092
+msgid ""
+"Yes, the FPU was designed for high precision mathematics. But we are not "
+"dealing with high precision mathematics. We are dealing with physics "
+"(optics, specifically)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3096
+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 `12` meters long, so we "
+"have the focal length of `12000`. Well, using Bender's constant, it gives "
+"us square root of `12000` multiplied by `0.04`, which is `4.381780460` "
+"millimeters, or `4381.780460` microns."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3101
+msgid ""
+"Put either way, the result is absurdly precise. Our truck is not _exactly_ "
+"`12000` millimeters long. We did not measure its length with such a "
+"precision, so stating we need a pinhole with the diameter of `4.381780460` "
+"millimeters is, well, deceiving. `4.4` millimeters would do just fine."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3106
+msgid ""
+"I \"only\" used ten digits in the above example. Imagine the absurdity of "
+"going for all 18!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3112
+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 `4382` microns. Looking at that number, "
+"we still decide that `4400` microns, or `4.4` millimeters is close enough."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3115
+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 FPU does not offer rounding to a specific number of "
+"digits (after all, it does not view the numbers as decimal but as binary)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3117
+msgid ""
+"We, therefore, must devise an algorithm to reduce the number of significant "
+"digits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3119
+msgid ""
+"Here is mine (I think it is awkward-if you know a better one, _please_, let "
+"me know):"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3122
+msgid "Initialize a counter to `0`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3123
+msgid ""
+"While the number is greater than or equal to `10000`, divide it by `10` and "
+"increase the counter."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3124
+msgid "Output the result."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3125
+msgid ""
+"While the counter is greater than `0`, output `0` and decrease the counter."
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3130
+msgid ""
+"The `10000` is only good if you want _four_ significant digits. For any "
+"other number of significant digits, replace `10000` with `10` raised to the "
+"number of significant digits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3133
+msgid ""
+"We will, then, output the pinhole diameter in microns, rounded off to four "
+"significant digits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3136
+msgid ""
+"At this point, we know the _focal length_ and the _pinhole diameter_. That "
+"means we have enough information to also calculate the _f-number_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3140
+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 _normalized f-number_, i.e., the nearest power of the "
+"square root of 2."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3146
+msgid ""
+"We do that by multiplying the actual f-number by itself, which, of course, "
+"will give us its `square`. 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 FPU gives us a good shortcut to do "
+"that: We can use the `fscale` op code to \"scale\" 1, which is analogous to "
+"``shift``ing an integer left. Finally, we calculate the square root of it "
+"all, and we have the nearest normalized f-number."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3149
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3161
+#, no-wrap
+msgid ""
+"fmul\tst0, st0\n"
+"\tfld1\n"
+"\tfld\tst1\n"
+"\tfyl2x\n"
+"\tfrndint\n"
+"\tfld1\n"
+"\tfscale\n"
+"\tfsqrt\n"
+"\tfstp\tst1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3165
+msgid ""
+"The first line, `fmul st0, st0`, squares the contents of the TOS (top of the "
+"stack, same as `st`, called `st0` by nasm). The `fld1` pushes `1` on the "
+"TOS."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3169
+msgid ""
+"The next line, `fld st1`, pushes the square back to the TOS. At this point "
+"the square is both in `st` and `st(2)` (it will become clear why we leave a "
+"second copy on the stack in a moment). `st(1)` contains `1`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3172
+msgid ""
+"Next, `fyl2x` calculates base-2 logarithm of `st` multiplied by `st(1)`. "
+"That is why we placed `1` on `st(1)` before."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3174
+msgid ""
+"At this point, `st` contains the logarithm we have just calculated, `st(1)` "
+"contains the square of the actual f-number we saved for later."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3178
+msgid ""
+"`frndint` rounds the TOS to the nearest integer. `fld1` pushes a `1`. "
+"`fscale` shifts the `1` we have on the TOS by the value in `st(1)`, "
+"effectively raising 2 to `st(1)`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3180
+msgid ""
+"Finally, `fsqrt` calculates the square root of the result, i.e., the nearest "
+"normalized f-number."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3183
+msgid ""
+"We now have the nearest normalized f-number on the TOS, the base-2 logarithm "
+"rounded to the nearest integer in `st(1)`, and the square of the actual f-"
+"number in `st(2)`. We are saving the value in `st(2)` for later."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3189
+msgid ""
+"But we do not need the contents of `st(1)` anymore. The last line, `fstp "
+"st1`, places the contents of `st` to `st(1)`, and pops. As a result, what "
+"was `st(1)` is now `st`, what was `st(2)` is now `st(1)`, etc. The new `st` "
+"contains the normalized f-number. The new `st(1)` contains the square of "
+"the actual f-number we have stored there for posterity."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3192
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3195
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3197
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3200
+msgid ""
+"Every light meter I have ever seen can determine proper exposure at f5.6. "
+"We will, therefore, calculate an _\"f5.6 multiplier,\"_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3202
+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 `5.6`, and squaring the "
+"result."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3204
+msgid ""
+"Mathematically, dividing the square of our f-number by the square of `5.6` "
+"will give us the same result."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3207
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3215
+msgid ""
+"`5.6` is a _constant_. We do not have to have our FPU waste precious "
+"cycles. We can just tell it to divide the square of the f-number by "
+"whatever `5.6²` equals to. Or we can divide the f-number by `5.6`, and then "
+"square the result. The two ways now seem equal."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3217
+msgid "But, they are not!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3221
+msgid ""
+"Having studied the principles of photography above, we remember that the "
+"`5.6` is actually square root of 2 raised to the fifth power. An "
+"_irrational_ number. The square of this number is _exactly_ `32`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3227
+msgid ""
+"Not only is `32` an integer, it is a power of 2. We do not need to divide "
+"the square of the f-number by `32`. We only need to use `fscale` to shift "
+"it right by five positions. In the FPU lingo it means we will `fscale` it "
+"with `st(1)` equal to `-5`. That is _much faster_ than a division."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3230
+msgid ""
+"So, now it has become clear why we have saved the square of the f-number on "
+"the top of the FPU 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3233
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3236
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3241
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3243
+#, no-wrap
+msgid "FPU Optimizations"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3246
+msgid ""
+"In assembly language we can optimize the FPU code in ways impossible in high "
+"languages, including C."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3250
+msgid ""
+"Whenever a C function needs to calculate a floating-point value, it loads "
+"all necessary variables and constants into FPU 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3254
+msgid ""
+"It \"returns\" the value by leaving the result on the TOS. However, before "
+"it returns, it cleans up. Any variables and constants it used in its "
+"calculation are now gone from the FPU."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3256
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3259
+msgid ""
+"We _knew_ 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3261
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3264
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3266
+msgid ""
+"That means, for one, the value will be changed from the 80-bit precision "
+"used internally by the FPU to a C _double_ (64 bits) or even _single_ (32 "
+"bits)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3269
+msgid ""
+"That also means that the value must be moved from the TOS into the memory, "
+"and then back again. Alas, of all FPU operations, the ones that access the "
+"computer memory are the slowest."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3271
+msgid ""
+"So, whenever programming the FPU in assembly language, look for the ways of "
+"keeping intermediate results on the FPU stack."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3273
+msgid ""
+"We can take that idea even further! In our program we are using a _constant_ "
+"(the one we named `PC`)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3276
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3279
+msgid ""
+"Early on in our program, we are calculating the value of the above "
+"constant. We need to divide our input by `10` for every digit in the "
+"constant."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3282
+msgid ""
+"It is much faster to multiply than to divide. So, at the start of our "
+"program, we divide `10` into `1` to obtain `0.1`, which we then keep on the "
+"stack: Instead of dividing the input by `10` for every digit, we multiply it "
+"by `0.1`."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3286
+msgid ""
+"By the way, we do not input `0.1` directly, even though we could. We have a "
+"reason for that: While `0.1` can be expressed with just one decimal place, "
+"we do not know how many _binary_ places it takes. We, therefore, let the "
+"FPU calculate its binary value to its own high precision."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3291
+msgid ""
+"We are using other constants: We multiply the pinhole diameter by `1000` to "
+"convert it from millimeters to microns. We compare numbers to `10000` when "
+"we are rounding them off to four significant digits. So, we keep both, "
+"`1000` and `10000`, on the stack. And, of course, we reuse the `0.1` when "
+"rounding off numbers to four digits."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3297
+msgid ""
+"Last but not least, we keep `-5` on the stack. We need it to scale the "
+"square of the f-number, instead of dividing it by `32`. 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 `-5` is at `st(1)`, precisely where `fscale` expects it to "
+"be."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3300
+msgid ""
+"It is common to create certain constants from scratch instead of loading "
+"them from the memory. That is what we are doing with `-5`:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3309
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3312
+msgid ""
+"We can generalize all these optimizations into one rule: _Keep repeat values "
+"on the stack!_"
+msgstr ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3317
+msgid ""
+"_PostScript(R)_ is a stack-oriented programming language. There are many "
+"more books available about PostScript(R) than about the FPU assembly "
+"language: Mastering PostScript(R) will help you master the FPU."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3320
+#, no-wrap
+msgid "pinhole-The Code"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3335
+#, 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3370
+#, no-wrap
+msgid ""
+"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 <value>] [-o <outfile>] [-i <infile>]', 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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3376
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3387
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3396
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3405
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3414
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3438
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tsub\tesi, esi\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3443
+#, no-wrap
+msgid ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .getenv\t\t; no more arguments\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3451
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+"\tinc\tecx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3469
+#, no-wrap
+msgid ""
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3496
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3512
+#, no-wrap
+msgid ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.c\n"
+"\tor\tah, ah\n"
+"\tjne\t.pcheck\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3516
+#, no-wrap
+msgid ""
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear usage\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3518
+#, no-wrap
+msgid "\tmov\tah, [ecx]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3526
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3534
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3542
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3555
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3562
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3564
+#, no-wrap
+msgid "\tsub\tecx, ecx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3569
+#, no-wrap
+msgid ""
+".nextenv:\n"
+"\tpop\tesi\n"
+"\tor\tesi, esi\n"
+"\tje\t.default\t; no PINHOLE envar found\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3575
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3583
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3590
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3599
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3608
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3610
+#, no-wrap
+msgid "\tinc\tdl\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3617
+#, no-wrap
+msgid ""
+".processconst:\n"
+"\tinc\tcl\n"
+"\tcmp\tcl, 18\n"
+"\tja\tnear consttoobig\n"
+"\tstosb\n"
+"\tjmp\tshort .constloop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3622
+#, no-wrap
+msgid ""
+"align 4\n"
+".setconst:\n"
+"\tor\tdl, dl\n"
+"\tje\tnear perr\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3625
+#, no-wrap
+msgid ""
+"\tfinit\n"
+"\tfild\tdword [tthou]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3629
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfild\tdword [ten]\n"
+"\tfdivp\tst1, st0\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3632
+#, no-wrap
+msgid ""
+"\tfild\tdword [thousand]\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3635
+#, no-wrap
+msgid ""
+"\tmov\tebp, ecx\n"
+"\tcall\tbcdload\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3639
+#, no-wrap
+msgid ""
+".constdiv:\n"
+"\tfmul\tst0, st2\n"
+"\tloop\t.constdiv\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3646
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfadd\tst0, st0\n"
+"\tfadd\tst0, st0\n"
+"\tfld1\n"
+"\tfaddp\tst1, st0\n"
+"\tfchs\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3651
+#, no-wrap
+msgid ""
+"\t; If we are creating a CSV file,\n"
+"\t; print header\n"
+"\tcmp\tbyte [separ], ','\n"
+"\tjne\t.bigloop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3656
+#, no-wrap
+msgid ""
+"\tpush\tdword headlen\n"
+"\tpush\tdword header\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3660
+#, no-wrap
+msgid ""
+".bigloop:\n"
+"\tcall\tgetchar\n"
+"\tjc\tnear done\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3666
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3673
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3677
+#, no-wrap
+msgid ""
+"\t; Yes, we have a number\n"
+"\tsub\tebp, ebp\n"
+"\tsub\tedx, edx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3682
+#, no-wrap
+msgid ""
+".number:\n"
+"\tcmp\tal, '0'\n"
+"\tje\t.number0\n"
+"\tmov\tdl, 1\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3693
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3704
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3708
+#, no-wrap
+msgid ""
+".ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3713
+#, no-wrap
+msgid ""
+".work:\n"
+"\t; Now, do all the work\n"
+"\tor\tdl, dl\n"
+"\tje\tnear .work0\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3716
+#, no-wrap
+msgid ""
+"\tcmp\tebp, 19\n"
+"\tjae\tnear .toobig\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3718
+#, no-wrap
+msgid "\tcall\tbcdload\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3720
+#, no-wrap
+msgid "\t; Calculate pinhole diameter\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3727
+#, no-wrap
+msgid ""
+"\tfld\tst0\t; save it\n"
+"\tfsqrt\n"
+"\tfmul\tst0, st3\n"
+"\tfld\tst0\n"
+"\tfmul\tst5\n"
+"\tsub\tebp, ebp\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3737
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3740
+#, no-wrap
+msgid ""
+".printdiameter:\n"
+"\tcall\tprintnumber\t; pinhole diameter\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3742
+#, no-wrap
+msgid "\t; Calculate F-number\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3745
+#, no-wrap
+msgid ""
+"\tfdivp\tst1, st0\n"
+"\tfld\tst0\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3747
+#, no-wrap
+msgid "\tsub\tebp, ebp\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3756
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3759
+#, no-wrap
+msgid ""
+".printfnumber:\n"
+"\tcall\tprintnumber\t; F number\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3770
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3773
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3801
+#, no-wrap
+msgid ""
+"\tsub\tebp, ebp\n"
+"\tcall\tprintnumber\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3775
+#, no-wrap
+msgid "\t; Calculate time multiplier from F-5.6\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3778
+#, no-wrap
+msgid ""
+"\tfscale\n"
+"\tfld\tst0\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3784
+#, no-wrap
+msgid ""
+"\t; Round off to 4 significant digits\n"
+".fmul:\n"
+"\tfcom\tst0, st6\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3789
+#, no-wrap
+msgid ""
+"\tjb\t.printfmul\n"
+"\tinc\tebp\n"
+"\tfmul\tst0, st5\n"
+"\tjmp\tshort .fmul\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3792
+#, no-wrap
+msgid ""
+".printfmul:\n"
+"\tcall\tprintnumber\t; F multiplier\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3794
+#, no-wrap
+msgid "\t; Calculate F-stops from 5.6\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3798
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfxch\tst1\n"
+"\tfyl2x\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3805
+#, no-wrap
+msgid ""
+"\tmov\tal, 0Ah\n"
+"\tcall\tputchar\n"
+"\tjmp\t.bigloop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3809
+#, no-wrap
+msgid ""
+".work0:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3814
+#, no-wrap
+msgid ""
+"align 4\n"
+".toobig:\n"
+"\tcall\thuh\n"
+"\tjmp\t.bigloop\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3818
+#, no-wrap
+msgid ""
+"align 4\n"
+"done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3827
+#, no-wrap
+msgid "\tfinit\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3840
+#, no-wrap
+msgid ""
+"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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3845
+#, no-wrap
+msgid ""
+".cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tjne\tskiptoeol\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3858
+#, no-wrap
+msgid ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3875
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3881
+#, no-wrap
+msgid ""
+"align 4\n"
+".empty:\n"
+"\tadd\tesp, byte 4\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3910
+#, no-wrap
+msgid ""
+"align 4\n"
+"bcdload:\n"
+"\t; EBP contains the number of chars in dbuffer\n"
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3914
+#, no-wrap
+msgid ""
+"\tlea\tecx, [ebp+1]\n"
+"\tlea\tesi, [dbuffer+ebp-1]\n"
+"\tshr\tecx, 1\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3916
+#, no-wrap
+msgid "\tstd\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3922
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3931
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3933
+#, no-wrap
+msgid "\tfbld\t[bbuffer]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3940
+#, no-wrap
+msgid ""
+"\tcld\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tecx\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3946
+#, no-wrap
+msgid ""
+"align 4\n"
+"printnumber:\n"
+"\tpush\tebp\n"
+"\tmov\tal, [separ]\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3950
+#, no-wrap
+msgid ""
+"\t; Print the integer at the TOS\n"
+"\tmov\tebp, bbuffer+9\n"
+"\tfbstp\t[bbuffer]\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3956
+#, no-wrap
+msgid ""
+"\t; Check the sign\n"
+"\tmov\tal, [ebp]\n"
+"\tdec\tebp\n"
+"\tor\tal, al\n"
+"\tjns\t.leading\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3960
+#, no-wrap
+msgid ""
+"\t; We got a negative number (should never happen)\n"
+"\tmov\tal, '-'\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3969
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3974
+#, no-wrap
+msgid ""
+"\t; We are here because the result was 0.\n"
+"\t; Print '0' and return\n"
+"\tmov\tal, '0'\n"
+"\tjmp\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3986
+#, no-wrap
+msgid ""
+".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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3990
+#, no-wrap
+msgid ""
+".second:\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3994
+#, no-wrap
+msgid ""
+".next:\n"
+"\tcmp\tebp, bbuffer\n"
+"\tjb\t.done\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4004
+#, no-wrap
+msgid ""
+"\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"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4007
+#, no-wrap
+msgid ""
+"\tdec\tebp\n"
+"\tjmp\tshort .next\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4012
+#, no-wrap
+msgid ""
+".done:\n"
+"\tpop\tebp\n"
+"\tor\tebp, ebp\n"
+"\tje\t.ret\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4018
+#, no-wrap
+msgid ""
+".zeros:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tdec\tebp\n"
+"\tjne\t.zeros\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4021
+#, no-wrap
+msgid ""
+".ret:\n"
+"\tret\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4024
+msgid ""
+"The code follows the same format as all the other filters we have seen "
+"before, with one subtle exception:"
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4027
+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 _character-oriented_ filters."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4029
+msgid ""
+"This filter does not process characters. It processes a _language_ (albeit a "
+"very simple one, consisting only of numbers)."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4031
+msgid "When we have no more input, it can mean one of two things:"
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4033
+msgid "We are done and can quit. This is the same as before."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4034
+msgid ""
+"The last character we have read was a digit. We have stored it at the end of "
+"our ASCII-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 ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4036
+msgid ""
+"For that reason, we have modified our `getchar` and our `read` routines to "
+"return with the `carry flag` _clear_ whenever we are fetching another "
+"character from the input, or the `carry flag` _set_ whenever there is no "
+"more input."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4039
+msgid ""
+"Of course, we are still using assembly language magic to do that! Take a "
+"good look at `getchar`. It _always_ returns with the `carry flag` _clear_."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4041
+msgid ""
+"Yet, our main code relies on the `carry flag` to tell it when to quit-and it "
+"works."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4044
+msgid ""
+"The magic is in `read`. Whenever it receives more input from the system, it "
+"just returns to `getchar`, which fetches a character from the input buffer, "
+"_clears_ the `carry flag` and returns."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4047
+msgid ""
+"But when `read` receives no more input from the system, it does _not_ return "
+"to `getchar` at all. Instead, the `add esp, byte 4` op code adds `4` to "
+"`ESP`, _sets_ the `carry flag`, and returns."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4051
+msgid ""
+"So, where does it return to? Whenever a program uses the `call` op code, the "
+"microprocessor ``push``es the return address, i.e., it stores it on the top "
+"of the stack (not the FPU stack, the system stack, which is in the memory). "
+"When a program uses the `ret` op code, the microprocessor ``pop``s the "
+"return value from the stack, and jumps to the address that was stored there."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4053
+msgid ""
+"But since we added `4` to `ESP` (which is the stack pointer register), we "
+"have effectively given the microprocessor a minor case of _amnesia_: It no "
+"longer remembers it was `getchar` that ``call``ed `read`."
+msgstr ""
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4055
+msgid ""
+"And since `getchar` never ``push``ed anything before ``call``ing `read`, the "
+"top of the stack now contains the return address to whatever or whoever "
+"``call``ed `getchar`. As far as that caller is concerned, he ``call``ed "
+"`getchar`, which ``ret``urned with the `carry flag` set!"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4058
+msgid ""
+"Other than that, the `bcdload` routine is caught up in the middle of a "
+"Lilliputian conflict between the Big-Endians and the Little-Endians."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4060
+msgid ""
+"It is converting the text representation of a number into that number: The "
+"text is stored in the big-endian order, but the _packed decimal_ is little-"
+"endian."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4063
+msgid ""
+"To solve the conflict, we use the `std` op code early on. We cancel it with "
+"`cld` later on: It is quite important we do not `call` anything that may "
+"depend on the default setting of the _direction flag_ while `std` is active."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4065
+msgid ""
+"Everything else in this code should be quit eclear, providing you have read "
+"the entire chapter that precedes it."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4068
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4070
+#, no-wrap
+msgid "Using pinhole"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4074
+msgid ""
+"Because we have decided to make the program _ignore_ any input except for "
+"numbers (and even those inside a comment), we can actually perform _textual "
+"queries_. We do not _have to_, but we _can_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4076
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4082
+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 _fine-tune_ "
+"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 _ask_ a couple of questions."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4084
+msgid "Our session might look like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4088
+#, no-wrap
+msgid "% pinhole\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4090
+#, no-wrap
+msgid "Computer,\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4103
+#, no-wrap
+msgid ""
+"What size pinhole do I need for the focal length of 150?\n"
+"150\t490\t306\t362\t2930\t12\n"
+"Hmmm... How about 160?\n"
+"160\t506\t316\t362\t3125\t12\n"
+"Let's make it 155, please.\n"
+"155\t498\t311\t362\t3027\t12\n"
+"Ah, let's try 157...\n"
+"157\t501\t313\t362\t3066\t12\n"
+"156?\n"
+"156\t500\t312\t362\t3047\t12\n"
+"That's it! Perfect! Thank you very much!\n"
+"^D\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4106
+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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4108
+#, no-wrap
+msgid "Scripting"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4111
+msgid ""
+"Because we have chosen the `#` character to denote the start of a comment, "
+"we can treat our pinhole software as a _scripting language_."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4113
+msgid "You have probably seen shell _scripts_ that start with:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4117
+#, no-wrap
+msgid "#! /bin/sh\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4120
+msgid "...or..."
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4124
+#, no-wrap
+msgid "#!/bin/sh\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4127
+msgid "...because the blank space after the `#!` is optional."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4130
+msgid ""
+"Whenever UNIX(R) is asked to run an executable file which starts with the `#!"
+"`, 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4132
+msgid ""
+"Suppose now that we have installed pinhole in /usr/local/bin/, we can now "
+"write a script to calculate various pinhole diameters suitable for various "
+"focal lengths commonly used with the 120 film."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4134
+msgid "The script might look something like this:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4140
+#, no-wrap
+msgid ""
+"#! /usr/local/bin/pinhole -b -i\n"
+"# Find the best pinhole diameter\n"
+"# for the 120 film\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4143
+#, no-wrap
+msgid ""
+"### Standard\n"
+"80\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4146
+#, no-wrap
+msgid ""
+"### Wide angle\n"
+"30, 40, 50, 60, 70\n"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4149
+#, no-wrap
+msgid ""
+"### Telephoto\n"
+"100, 120, 140\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4152
+msgid "Because 120 is a medium size film, we may name this file medium."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4154
+msgid ""
+"We can set its permissions to execute, and run it as if it were a program:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4159
+#, no-wrap
+msgid ""
+"% chmod 755 medium\n"
+"% ./medium\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4162
+msgid "UNIX(R) will interpret that last command as:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4166
+#, no-wrap
+msgid "% /usr/local/bin/pinhole -b -i ./medium\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4169
+msgid "It will run that command and display:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4181
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4184
+msgid "Now, let us enter:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4188
+#, no-wrap
+msgid "% ./medium -c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4191
+msgid "UNIX(R) will treat that as:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4195
+#, no-wrap
+msgid "% /usr/local/bin/pinhole -b -i ./medium -c\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4199
+msgid ""
+"That gives it two conflicting options: `-b` and `-c` (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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4211
+#, 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\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4215
+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 ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4231
+#, no-wrap
+msgid ""
+"% ./medium -b -e > bender\n"
+"% cat bender\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"
+"%\n"
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4234
+#, no-wrap
+msgid "Caveats"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4238
+msgid ""
+"Assembly language programmers who \"grew up\" under MS-DOS(R) and Windows(R) "
+"often tend to take shortcuts. Reading the keyboard scan codes and writing "
+"directly to video memory are two classical examples of practices which, "
+"under MS-DOS(R) are not frowned upon but considered the right thing to do."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4240
+msgid ""
+"The reason? Both the PC BIOS and MS-DOS(R) are notoriously slow when "
+"performing these operations."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4243
+msgid ""
+"You may be tempted to continue similar practices in the UNIX(R) "
+"environment. For example, I have seen a web site which explains how to "
+"access the keyboard scan codes on a popular UNIX(R) clone."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4245
+msgid ""
+"That is generally a _very bad idea_ in UNIX(R) environment! Let me explain "
+"why."
+msgstr ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4247
+#, no-wrap
+msgid "UNIX(R) Is Protected"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4254
+msgid ""
+"For one thing, it may simply not be possible. UNIX(R) runs in protected "
+"mode. Only the kernel and device drivers are allowed to access hardware "
+"directly. Perhaps a particular UNIX(R) clone will let you read the keyboard "
+"scan codes, but chances are a real UNIX(R) 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 ""
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4256
+#, no-wrap
+msgid "UNIX(R) Is an Abstraction"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4259
+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 "
+"UNIX(R) like systems that let you do it:"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4261
+msgid "_UNIX(R) is an abstraction!_"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4267
+msgid ""
+"There is a major difference in the philosophy of design between MS-DOS(R) "
+"and UNIX(R). MS-DOS(R) 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4270
+msgid ""
+"This is NEVER guaranteed under UNIX(R). It is quite common for a UNIX(R) "
+"user to pipe and redirect program input and output:"
+msgstr ""
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4274
+#, no-wrap
+msgid "% program1 | program2 | program3 > file1\n"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4278
+msgid ""
+"If you have written program2, your input does not come from the keyboard but "
+"from the output of program1. Similarly, your output does not go to the "
+"screen but becomes the input for program3 whose output, in turn, goes to [."
+"filename]#file1#."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4281
+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 PC-style scan codes. It may be a Macintosh(R), or any "
+"other computer."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4283
+msgid ""
+"Now you may be shaking your head: My software is in PC assembly language, "
+"how can it run on a Macintosh(R)? But I did not say your software would be "
+"running on a Macintosh(R), only that its terminal may be a Macintosh(R)."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4287
+msgid ""
+"Under UNIX(R), 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 "
+"Macintosh(R) user in Australia connects to a UNIX(R) system in North America "
+"(or anywhere else) via telnet. 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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4290
+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 ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4293
+msgid ""
+"That is why under UNIX(R) 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 ""
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4301
+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 UNIX(R) form MS-DOS(R). Of course, creative people often break rules, "
+"and it is OK as long as they know they are breaking them and why."
+msgstr ""
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4304
+#, no-wrap
+msgid "Acknowledgements"
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4307
+msgid ""
+"This tutorial would never have been possible without the help of many "
+"experienced FreeBSD programmers from the {freebsd-hackers}, many of whom "
+"have patiently answered my questions, and pointed me in the right direction "
+"in my attempts to explore the inner workings of UNIX(R) system programming "
+"in general and FreeBSD in particular."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4310
+msgid ""
+"Thomas M. Sommers opened the door for me . His https://web.archive.org/"
+"web/20090914064615/http://www.codebreakers-journal.com/content/"
+"view/262/27[How do I write \"Hello, world\" in FreeBSD assembler?] web page "
+"was my first encounter with an example of assembly language programming "
+"under FreeBSD."
+msgstr ""
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4312
+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 ""