diff options
author | Danilo G. Baio <dbaio@FreeBSD.org> | 2022-08-07 13:50:34 +0000 |
---|---|---|
committer | Danilo G. Baio <dbaio@FreeBSD.org> | 2022-08-07 13:50:34 +0000 |
commit | e5b116889d4d6dc56803b0efc3f4d304ef929c83 (patch) | |
tree | 7f003d7b633ea9e2fb815b09a3ecbbd2fb17785c /documentation/content/en/books/developers-handbook | |
parent | 3e68ca2c7beaeced1a0c52dbb40a1414cce7a72a (diff) |
Diffstat (limited to 'documentation/content/en/books/developers-handbook')
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 "" |