From 5eeadc6d4667a184c5d64bd0252d7dcaa5eaa8f9 Mon Sep 17 00:00:00 2001
From: cyanbird <2534930703@qq.com>
Date: Sat, 3 Nov 2018 00:31:55 +0800
Subject: [PATCH 01/79] =?UTF-8?q?[=E5=AE=8C=E6=88=90=E6=A0=A1=E5=AF=B9]=20?=
=?UTF-8?q?What's=20all=20the=20C=20Plus=20Fuss=3F=20Bjarne=20Stroustrup?=
=?UTF-8?q?=20warns=20of=20dangerous=20future=20plans=20for=20his=20C++?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...rns of dangerous future plans for his C.md | 138 ++++++++----------
1 file changed, 64 insertions(+), 74 deletions(-)
diff --git a/translated/tech/20180618 What-s all the C Plus Fuss- Bjarne Stroustrup warns of dangerous future plans for his C.md b/translated/tech/20180618 What-s all the C Plus Fuss- Bjarne Stroustrup warns of dangerous future plans for his C.md
index 42bd3d3dd9..2f74012741 100644
--- a/translated/tech/20180618 What-s all the C Plus Fuss- Bjarne Stroustrup warns of dangerous future plans for his C.md
+++ b/translated/tech/20180618 What-s all the C Plus Fuss- Bjarne Stroustrup warns of dangerous future plans for his C.md
@@ -1,148 +1,138 @@
-# 关于 C ++ 的所有争论?Bjarne Stroustrup 警告他的 C++ 未来的计划很危险
+# 对 C++ 的忧虑?Bjarne Stroustrup 警告,关于 C++ 的某些未来计划十分危险
![](https://regmedia.co.uk/2018/06/15/shutterstock_38621860.jpg?x=442&y=293&crop=1)
-今年早些时候,我们**访谈**了 Bjarne Stroustrup,他是 C++ 语言的创始人,摩根士丹利技术部门的董事总经理,美国哥伦比亚大学计算机科学的客座教授,他写了[一封信][1]邀请那些关注编程语言演进的人去“想想瓦萨号!”
+今年早些时候,我们对 Bjarne Stroustrup 进行了采访。他是 C++ 语言的创始人,摩根士丹利技术部门的董事总经理,美国哥伦比亚大学计算机科学的客座教授。他写了[一封信][1],请那些关注编程语言进展的人去“想想瓦萨号!”
-毫无疑问,对于丹麦人来说,这句话很容易理解,而那些对于 17 世纪的斯堪的纳维亚历史了解不多的人,还需要展开说一下。瓦萨号是一艘瑞典军舰,由国王 Gustavus Adolphus 委托建造。它是在 1628 年 8 月 10 日首航时,当时波罗的海国家中最强大的军舰,但是它在首航几分钟之后就沉没了。
+这句话对于丹麦人来说,毫无疑问,很容易理解。而那些对于 17 世纪的斯堪的纳维亚历史了解不多的人,还需要详细说明一下。瓦萨号是一艘瑞典军舰,由国王 Gustavus Adolphus 定做。它是当时波罗的海国家中最强大的军舰,但在 1628 年 8 月 10 日首航没几分钟之后,就沉没了。
-巨大的瓦萨号有一个难以解决的设计缺陷:头重脚轻,以至于它被[一阵狂风刮翻了][2]。通过这段翻船历史的回忆,Stroustrup 警示了 C++ 所面临的风险,因为现在越来越多的特性被添加到了 C++ 中。
+巨大的瓦萨号有一个难以解决的设计缺陷:头重脚轻,以至于它被[一阵狂风刮翻了][2]。通过援引这艘沉船的历史,Stroustrup 警示了 C++ 所面临的风险——现在越来越多的特性被添加到了 C++ 中。
-现在已经提议了不少这样的特性。Stroustrup 在他的信中引用了 43 条提议。他认为那些参与 C++ 语言 ISO 标准演进的人(指众所周知的 [WG21][3]),正在努力地让语言更高级,但他们的努力方向却并不一致。
+我们现在已经发现了好些能导致头重脚轻的特性。Stroustrup 在他的信中引用了 43 个提议。他认为那些参与 C++ 语言 ISO 标准演进的人(被称为 [WG21][3]),正在努力推进语言发展,但成员们的努力方向却并不一致。
在他的信中,他写道:
-> 分开来看,许多提议都很有道理。但将它们综合到一起,这些提议是很愚蠢的,将危害 C++ 的未来。
+>分开来看,许多提议都很有道理。但将它们综合到一起,这些提议是很愚蠢的,将危害 C++ 的未来。
-他明确表示,不希望 C++ 重蹈瓦萨号的覆辙,这种渐近式的改进将敲响 C++ 的丧钟。相反,应该吸取瓦萨号的教训,构建一个坚实的基础,吸取经验教训,并做彻底的测试。
+他明确表示,他用瓦萨号作为比喻并不是说他认为不断提升会带来毁灭。我们应该吸取瓦萨号的教训,构建一个坚实的基础,从错误中学习并对新版本做彻底的测试。
-在瑞士拉普斯威尔(Rapperswill)召开的 C++ 标准化委员会会议之后,本月早些时候,Stroustrup 接受了_《The Register》_ 的采访,回答了有关 C++ 语言下一步发展方向方面的几个问题。(最新版是 C++17,它去年刚发布;下一个版本是 C++20,它正在开发中,预计于 2020 年发布。)
+在瑞士拉普斯威尔召开 C++ 标准化委员会会议之后,本月早些时候,Stroustrup 接受了 The Register 的采访,回答了有关 C++ 语言下一步发展方向方面的几个问题。(最新版是 C++17,它去年刚发布;下一个版本是 C++20,它正在开发中,预计于 2020 年发布。)
-**Register:在你的信件《想想瓦萨号!》中,你写道:**
+**Register:在您的信件《想想瓦萨号!》中,您写道:**
-> 在 C++11 开始基础不再完整,而 C++17 中在使基础更加稳固、规范和完整方面几乎没有改善。相反地,却增加了重要接口的复杂度,让人们需要学习的特性数量越来越多。C++ 可能在这种提议的重压之下崩溃 —— 这些提议大多数都不成熟。我们不应该花费大量的时间为专家级用户们(比如我们自己)去创建越来越复杂的东西。~~(还要考虑普通用户的学习曲线,越复杂的东西越不易普及。)~~
+>在 C++11 开始的基础建设尚未完成,而 C++17 基本没有在使基础更加稳固、规范和完整方面做出改善。相反地,却增加了重要接口的复杂度(原文为 surface complexity,直译“表面复杂度”),让人们需要学习的特性数量越来越多。C++ 可能在这种不成熟的提议的重压之下崩溃。我们不应该花费大量的时间为专家级用户们(比如我们自己)去创建越来越复杂的东西。~~(还要考虑普通用户的学习曲线,越复杂的东西越不易普及。)~~
-**对新人来说,C++ 很难吗?如果是这样,你认为怎样的特性让新人更易理解?**
+**对新人来说,C++ 过难了吗?如果是这样,您认为怎样的特性让新人更易理解?**
-**Stroustrup:**C++ 的有些东西对于新人来说确实很难。
+Stroustrup:C++ 的有些东西对于新人来说确实很具有挑战性。
-换句话说,C++ 中有些东西对于新人来说,比起 C 或上世纪九十年代的 C++ 更容易理解了。而难点是让大型社区专注于这些部分,并且帮助新手和普通 C++ 用户去规避那些对高级库实现提供支持的部分。
+另一方面而言,C++ 中有些东西对于新人来说,比起 C 或上世纪九十年代的 C++ 更容易理解了。而难点是让大型社区专注于这些部分,并且帮助新手和非专业的 C++ 用户去规避那些对高级库实现提供支持的部分。
我建议使用 [C++ 核心准则][4] 作为实现上述目标的一个辅助。
-此外,我的 “C++ 教程” 也可以帮助人们在使用现代 C++ 时走上正确的方向,而不会迷失在自上世纪九十年代以来的复杂性中,或困惑于只有专家级的用户才能理解的东西中。第二版的 “C++ 教程” 涵盖了 C++17 和部分 C++20 的内容,这本书即将要出版了。
+此外,我的“C++ 教程”也可以帮助人们在使用现代 C++ 时走上正确的方向,而不会迷失在自上世纪九十年代以来的复杂性中,或困惑于只有专家级的用户才能理解的东西中。这本即将出版的第二版的“ C++ 教程”涵盖了 C++17 和部分 C++20 的内容。
-我和其他人给没有编程经验的大一新生教过 C++,只要你不去深挖编程语言的每个晦涩难懂的角落,把注意力集中到 C++ 中最主流的部分,在三个月内新可以学会 C++。
+我和其他人给没有编程经验的大一新生教过 C++,只要你不去深入编程语言的每个晦涩难懂的角落,把注意力集中到 C++ 中最主流的部分,就可以在三个月内学会 C++。
-“让简单的东西保持简单” 是我长期追求的目标。比如 C++11 的 `range-for` 循环:
+“让简单的东西保持简单”是我长期追求的目标。比如 C++11 的 `range-for` 循环:
```
for (int& x : v) ++x; // increment each element of the container v
-
```
-`v` 的位置可以是任何容器。在 C 和 C 风格的 C++ 中,它可能看到的是这样:
+`v` 的位置可以是任何容器。在 C 和 C 风格的 C++ 中,它可能看起来是这样:
```
for (int i=0; iRegister:您如何看待 C++ 现在的状况?**
-**Stroustrup:** C++11 是 C++ 的最重大的改进版,并且在 C++14 上全面完成了改进工作。C++17 添加了相当多的新特性,但是没有提供对新技术的很多支持。C++20 目前看上去可能会成为一个重大改进版。编译器的状况和标准库实现的非常好,非常接近最新的标准。C++17 已经可用。持续改进了对工具的支持。已经有了许多第三方的库和许多新工具。而不幸的是,这些东西不太好找到。
+Stroustrup:C++11 中作出了许多重大改进,并且我们在 C++14 上全面完成了改进工作。C++17 添加了相当多的新特性,但是没有提供对新技术的很多支持。C++20 目前看上去可能会成为一个重大改进版。编译器的状况非常好,标准库实现得也很优秀,非常接近最新的标准。C++17 现在已经可以使用,对于工具的支持正在逐步推进。已经有了许多第三方的库和好些新工具。然而,不幸的是,这些东西不太好找到。
-我在《想想瓦萨号!》一文中所表达的担忧与标准化过程有关,对新东西的过度热情与完美主义的组合拖延了重大的改进。“追述完美是优秀的敌人”,在六月份拉普斯威尔的会议上有 160 人参与。在这样一个数量庞大和多样化的人群中很难取得一致意见。这就导致了专家们更多地为他们自己去设计,而不是为了整个社区。
+我在《想想瓦萨号!》一文中所表达的担忧与标准化过程有关,对新东西的过度热情与完美主义的组合推迟了重大改进。“追求完美是获得优秀成绩的障碍”。在六月份拉普斯威尔的会议上有 160 人参与;在这样一个数量庞大且多样化的人群中很难取得一致意见。专家们也本来就有只为自己设计语言的倾向,这让他们不会时常在设计时考虑整个社区的需求。
- **Register: C++ 是否有一个期望的状况,或为了期望的适应性而努力简化以满足程序员们在任意时间的需要?**
+**Register:C++ 是否有一个理想的状态,或者与之相反,您只是为了程序员们的期望而努力,随时适应并且努力满足程序员们的需要?**
-**Stroustrup:** 二者都有。我很乐意看到 C++ 支持彻底保证类型安全和资源安全的编程方式。这不应该通过限制适用性或增加成本来实现,而是应该通过改进的表达能力和性能来实现。我认为可以做到这些,通过让程序员使用更好的(更易用的)语言可以实现这一点。
+Stroustrup:二者都有。我很乐意看到 C++ 支持彻底保证类型安全和资源安全的编程方式。这不应该通过限制适用性或增加性能损耗来实现,而是应该通过改进的表达能力和更好的性能来实现。通过让程序员使用更好的(和更易用的)语言工具可以达到这个目标,我们可以做到的。
-终极目标不会马上实现,也不会单靠语言的设计来实现。为了让编程更高效,我们需要通过改进语言特性、最好的库、静态分析、以及规则的组合来实现。C++ 核心准则是我提升 C++ 代码质量的广泛而长远的方法。
+终极目标不会马上实现,也不会单靠语言设计来实现。为了实现这一目标,我们需要改进语言特性、提供更好的库和静态分析,并且设立提升编程效率的规则。C++ 核心准则是我为了提升 C++ 代码质量而实行的广泛而长期的计划的一部分。
-**Register:对于 C++ 是否有明显的风险?如果有,它是如何产生的?(如,改进过于缓慢,新出现的低级语言,等等,从你的信中看,似乎是提议过多。)**
+**Register:目前 C++ 是否面临着可以预见的风险?如果有,它是什么?(如,迭代过于缓慢,新兴低级语言,等等……据您的观点来看,似乎是提出的提议过多。)**
-**Stroustrup:**毫无疑问,今年我们已经收到了 400 个提议。当然,它们并不都是新提议。许多提议都与规范语言和标准库这一必需而乏味的工作相关,但是量大到难以管理。你可以在 WG21 的网站上找到所有这些文章。
+Stroustrup:就是这样。今年我们已经收到了 400 篇文章。当然了,它们并不都是新提议。许多提议都与规范语言和标准库这一必需而乏味的工作相关,但是量大到难以管理。你可以在 WG21 的网站上找到所有这些文章。
-我写了《想想瓦萨号!》这封信作为一个呼吁。我感受到了这种压力,为解决紧急需要和赶时髦而增加语言特性,而不是去加强语言基础(比如,改善静态类型系统)。增加的任何新东西,无论它是多小都会产生成本,比如实现、学习、工具升级。重大的特性是那些改变我们编程思想的特性。那才是我们必须关注的东西。
+我写了《想想瓦萨号!》这封信作为一个呼吁,因为这种为了解决即刻需求(或者赶时髦)而不断增添语言特性,却对巩固语言基础(比如,改善静态类型系统)不管不问的倾向让我感到震惊。增加的任何新东西,无论它多小都会产生成本,比如实现、学习、工具升级。重大的特性改变能够改变我们对编程的想法,而它们才是我们必须关注的东西。
-委员会已经设立了一个”指导小组“,这个小组由在语言、标准库、实现、以及实际使用领域中拥有极强履历的人组成。我是其中的成员之一。我们负责为重点领域写一些关于方向、设计理念和建议方面的东西。
+委员会已经设立了一个”指导小组“,这个小组由在语言、标准库、实现、以及工程实践领域中拥有不错履历的人组成。我是其中的成员之一。我们负责为重点领域写一些关于发展方向、设计理念和建议重点发展领域的东西。
对于 C++20,我们建议去关注:
-```
-概念
-模块(提供适当的模块化和令人称奇的编译时改进)
-Ranges(包括一些无限序列的扩展)
-标准库中的网络概念
-```
+* 概念
+* 模块(适度地模块化并带来编译时的显著改进)
+* Ranges(包括一些无限序列的扩展)
+* 标准库中的网络概念
-在拉普斯威尔会议之后,虽然带来的模块和网络化很显然只是一种延伸,但机会还是有的。我是一个乐观主义者,并且委员会的成员们都非常努力。
+在拉普斯威尔会议之后,这些都有了实现的机会,虽然模块和网络化都不是会议的重点讨论对象。我是一个乐观主义者,并且委员会的成员们都非常努力。
-我并不担心其它语言或新语言会取代它。我喜欢编程语言。如果一个新的语言提供了其它编程语言没有提供的非常有用的东西,那它就是我们从中学习的榜样,当然,每个语言都有它自己的问题。许多 C++ 的问题都与它广泛的应用领域、大量的使用人群和过度的热情有关。大多数语言的社区都喜欢有这样的问题。
+我并不担心其它语言或新语言会取代它。我喜欢编程语言。如果一门新的语言提供了独一无二的、非常有用的东西,那它就是我们的榜样,我们可以向它学习。当然,每门语言本身都有一些问题。 C++ 的许多问题都与它广泛的应用领域、大量的使用人群和过度的热情有关。大多数语言的社区都会有这样的问题。
-**Register:关于 C++ 你是否重新考虑过任何架构方面的决策?**
+**Register:关于 C++ 您是否重新考虑过任何架构方面的决策?**
-**Stroustrup:** 当我使用一些新的编程语言时,我经常思考 C++ 原来的决策和设计。例如,可以看我的《编程的历史》论文第 1、2 部分。
+Stroustrup:当我着手规划新版本时,我经常反思原来的决策和设计。关于这些,可以看我的《编程的历史》论文第 1、2 部分。
-并没有让我觉得很懊悔的重大决策,如果让我重新再做一次决策,几乎不会对现有的特性做任何不同的改变。
+并没有让我觉得很后悔的重大决策。虽然如果我必须重新做一次,我不能保证我不会改变这门语言的特性。
-与以前一样,能够直接处理硬件加上零开销的抽象是设计的指导思想。使用构造函数和析构函数去处理资源是关键(RAII),STL 就是在 C++ 库中能够做什么的一个很好的例子。
+与以前一样,能够直接处理硬件加上零开销的抽象是设计的指导思想。使用构造函数和析构函数去处理资源是关键(RAII);STL 就是解释 C++ 库能够做什么的一个很好的例子。
-**Register:在 2011 年采纳的每三年发布一个标准的节奏是否仍然有效?我之所以这样问是因为 Java 为了更快地迭代,一直在解决需求。**
+**Register:在 2011 年被采纳的,每三年发布一个标准的节奏是否仍然有效?我之所以这样问是因为 Java 已经决定更快地迭代。**
-**Stroustrup:**我认为 C++20 将会按时发布(就像 C++14 和 C++17 那样),并且主要的编译器也会立即遵从它。我也希望 C++20 比起 C++17 能有重大的改进。
+Stroustrup:我认为 C++20 将会按时发布(就像 C++14 和 C++17 那样),并且主流的编译器也会立即采用它。我也希望 C++20 基于 C++17 能有重大的改进。
-对于其它语言如何管理它们的发行版我并不焦虑。C++ 是由一个遵循 ISO 规则的委员会来管理的,并不是由一个大公司或一个”创造它的权威“来管理。这一点不会改变。关于 ISO 标准,C++ 每三年发布一次的周期是一个激动人心的创举。标准的周期是 5 或 10 年。
+对于其它语言如何管理它们的版本,我并不十分关心。C++ 是由一个遵循 ISO 规则的委员会来管理的,而不是由某个大公司或某种“终生的仁慈独裁者”来管理。这一点不会改变。C++ 每三年发布一次的周期在ISO标准中是一个引人注目的创举。通常而言,周期应该是 5 或 10 年。
-**Register:在你的信中你写道:**
+**Register:在您的信中您写道:**
-```
-我们需要一个能够被”普通程序员“使用的条理还算清楚的编程语言,他们主要关心的是能否按时高质量地交付他们的应用程序。
-```
+>我们需要一个能够被”普通程序员“使用的,条理还算清楚的编程语言。他们主要关心的是,能否按时高质量地交付他们的应用程序。
-对语言的改变是否能够去解决这个问题,或者还可能涉及到更多容易获得的工具和教育支持?
+改进语言能够解决这个问题吗?或者,我们还需要更容易获得的工具和教育支持?
-**Stroustrup:**我努力去宣传我的理念 —— C++ 是什么以及如何使用它,并且我鼓励其他人也和我一样去做。
+Stroustrup:我尽力宣传我关于 C++ 的实质和使用方式的理念,并且我鼓励其他人也和我采取相同的行动。
-特别是,我鼓励讲师和作者们向 C++ 程序员们宣扬有用易用的理念,而不是去示范复杂的示例和技术来展示他们自己有多高明。我在 2017 年的 CppCon 大会上的演讲主题就是”学习和教学 C++“,并且也指出 C++ 需要更好的工具。
+特别是,我鼓励讲师和作者们向 C++ 程序员们提出有用的建议,而不是去示范复杂的示例和技术,来展示他们自己有多高明。我在 2017 年的 CppCon 大会上的演讲主题就是“学习和传授 C++”,并且也指出,我们需要更好的工具。
-我在演讲中提到构建支持和包管理器。这些历来都是 C++ 的弱点项。标准化委员会现在有一个工具研究小组,或许不久的将来也会有一个教育研究小组。
+我在演讲中提到了构建技术支持和包管理器,这些历来都是 C++ 的弱点项。标准化委员会现在有一个工具研究小组,或许不久的将来也会组建一个教育研究小组。
-C++ 的社区以前基本上是很乱的,但是在过去的五年里,为了满足社区对新闻和支持的需要,出现了很多会议和博客。CppCon、isocpp.org、以及 Meeting++ 就是这样的例子。
+C++ 的社区以前是十分无组织性的,但是在过去的五年里,为了满足社区对新闻和技术支持的需要,出现了很多集会和博客。CppCon、isocpp.org、以及 Meeting++ 就是一些例子。
-在委员会中做设计是非常困难的。但是,对于所有的大型项目来说,委员会又是必不可少的。我很关注它们,但是为了成功,关注和面对问题是必需的。
+设计一个委员会是非常困难的。但是,对于所有的大型项目来说,委员会又是必不可少的。我很忧虑,但是关注它们并且面对问题是成功的必要条件。
-**Register:你如何看待 C++ 社区的流程?在沟通和决策方面你希望看到哪些变化?**
+**Register:您如何看待 C++ 社区的流程?在沟通和决策方面你希望看到哪些变化?**
-**Stroustrup:**C++ 并没有企业管理的”社区流程“;它有一个 ISO 标准流程。我们不能对 ISO 的角色做重大的改变。理想的情况是,我们设立一个小的全职的”秘书处“来做最终决策和方向管理,但这种理想情况是不会出现的。相反,我们有成百上千的人在线来讨论,大约有 160 人在技术问题上进行投票,大约有 70 组织和 11 个国家在结果提议上正式投票。这样是很混乱的,但是在将来某个时候我们会让它好起来。
+Stroustrup:C++ 并没有企业管理一般的“社区流程”;它所遵循的是 ISO 标准流程。我们不能对 ISO 的条例做大的改变。理想的情况是,我们设立一个小型的、全职的“秘书处”来做最终决策和方向管理,但这种理想情况是不会出现的。相反,我们有成百上千的人在线讨论,大约有 160 人在技术问题上进行投票,大约有 70 组织和 11 个国家的人在最终提议上正式投票。这样很混乱,但是有些时候它的确能发挥作用。
-**Register:最终你认为那些即将推出的 C++ 特性中,对 C++ 用户最有帮助的是哪些?**
+**Register:在最后,您认为那些即将推出的 C++ 特性中,对 C++ 用户最有帮助的是哪些?**
-**Stroustrup:**
+**Stroustrup:**
-```
- 大大地简化了一般编程的概念
- 并行算法 – 没有比使用现代化硬件的并发特性更好的方法了
- 协程,如果委员会能够确定在 C++20 上推出。
- 模块改进了组织源代码的方式,并且大幅改善了编译时间。我希望能有这样的模块,但是它还不能确定能否在 C++20 上推出。
- 一个标准的网络库,但是它还不能确定能否在 C++20 上推出。
-```
+* 那些能让编程显著变简单的概念
+* 并行算法 – 如果要使用现代硬件的并发特性的话,这方法再简单不过了
+* 协程,如果委员会能够确定在 C++20 上推出。
+* 改进了组织源代码方式的,并且大幅改善了编译时间的模块。我希望能有这样的模块,但是还没办法确定我们能不能在 C++20 上推出。
+* 一个标准的网络库,但是还没办法确定我们能否在 C++20 上推出。
此外:
-```
- Contracts(运行时检查的先决条件、后置条件、和断言)可能对许多人都非常重要。
- date 和 time-zone 支持库可能对许多人(行业)非常重要。
-```
+* Contracts(运行时检查的先决条件、后置条件、和断言)可能对许多人都非常重要。
+* date 和 time-zone 支持库可能对许多人(行业)非常重要。
-**Register:最后你还有需要向读者说的话吗?**
+**Register:您还有想对读者们说的话吗?**
-**Stroustrup:**如果 C++ 标准化委员会能够专注于重大问题,去解决重大问题,那么 C++20 将会是非常优秀的。但是在 C++20 推出之前,我们的 C++17 仍然是非常好的,它将改变很多人关于 C++ 已经落伍的旧印象。®
+Stroustrup:如果 C++ 标准化委员会能够专注于重大问题,去解决重大问题,那么 C++20 将会非常优秀。但是在 C++20 推出之前,我们还有 C++17;无论如何,它仍然远超许多人对 C++ 的旧印象。®
------
@@ -151,7 +141,7 @@ via: https://www.theregister.co.uk/2018/06/18/bjarne_stroustrup_c_plus_plus/
作者:[Thomas Claburn][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[qhwdw](https://github.com/qhwdw)
-校对:[校对者ID](https://github.com/校对者ID)
+校对:[thecyanbird](https://github.com/thecyanbird)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
@@ -160,4 +150,4 @@ via: https://www.theregister.co.uk/2018/06/18/bjarne_stroustrup_c_plus_plus/
[2]: https://www.vasamuseet.se/en/vasa-history/disaster
[3]: http://open-std.org/JTC1/SC22/WG21/
[4]: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md
-[5]: https://go.theregister.co.uk/tl/1755/shttps://continuouslifecycle.london/
\ No newline at end of file
+[5]: https://go.theregister.co.uk/tl/1755/shttps://continuouslifecycle.london/
From 5b8dc5d15f5857a1ec83cf1739b330f2bde7f4f4 Mon Sep 17 00:00:00 2001
From: erlinux
Date: Sat, 3 Nov 2018 01:53:30 +0800
Subject: [PATCH 02/79] Translating By erlinux
---
...0180727 How to analyze your system with perf and Python.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sources/tech/20180727 How to analyze your system with perf and Python.md b/sources/tech/20180727 How to analyze your system with perf and Python.md
index c1be98cc0e..4573ed1ee0 100644
--- a/sources/tech/20180727 How to analyze your system with perf and Python.md
+++ b/sources/tech/20180727 How to analyze your system with perf and Python.md
@@ -1,3 +1,7 @@
+**translating by [erlinux](https://github.com/erlinux)**
+**PROJECT MANAGEMENT TOOL called [gn2.sh](https://github.com/lctt/lctt-cli)**
+
+
How to analyze your system with perf and Python
======
From f66dd77e84580dd7f99c9f1ffc99cd3611549ffb Mon Sep 17 00:00:00 2001
From: geekpi
Date: Sat, 3 Nov 2018 09:10:27 +0800
Subject: [PATCH 03/79] translating
---
...- A new tool for gathering Kubernetes resource statistics.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sources/tech/20181101 KRS- A new tool for gathering Kubernetes resource statistics.md b/sources/tech/20181101 KRS- A new tool for gathering Kubernetes resource statistics.md
index 7244e42ab0..50db9d728d 100644
--- a/sources/tech/20181101 KRS- A new tool for gathering Kubernetes resource statistics.md
+++ b/sources/tech/20181101 KRS- A new tool for gathering Kubernetes resource statistics.md
@@ -1,3 +1,5 @@
+translating---geekpi
+
KRS: A new tool for gathering Kubernetes resource statistics
======
Zero-configuration tool simplifies gathering information, such as how many pods are running in a certain namespace.
From 9a1109e5275b6e5b4dbdd5d10823ddac405f029a Mon Sep 17 00:00:00 2001
From: MarineFish <44663096+MarineFish@users.noreply.github.com>
Date: Sat, 3 Nov 2018 11:38:16 +0800
Subject: [PATCH 04/79] Update 20170928 A 3-step process for making more
transparent decisions.md
---
...28 A 3-step process for making more transparent decisions.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sources/tech/20170928 A 3-step process for making more transparent decisions.md b/sources/tech/20170928 A 3-step process for making more transparent decisions.md
index 80e4d294f6..7523b40dd7 100644
--- a/sources/tech/20170928 A 3-step process for making more transparent decisions.md
+++ b/sources/tech/20170928 A 3-step process for making more transparent decisions.md
@@ -1,3 +1,5 @@
+MarineFish translating
+
A 3-step process for making more transparent decisions
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/GOV_Transparency_A.png?itok=2r47nFJB)
From 19515041cd0dd173f653b80d2534a29102292e50 Mon Sep 17 00:00:00 2001
From: qhwdw
Date: Sat, 3 Nov 2018 13:13:58 +0800
Subject: [PATCH 05/79] Translated by qhwdw
---
...016 Lab 5- File system, Spawn and Shell.md | 346 ------------------
...016 Lab 5- File system, Spawn and Shell.md | 339 +++++++++++++++++
2 files changed, 339 insertions(+), 346 deletions(-)
delete mode 100644 sources/tech/20181016 Lab 5- File system, Spawn and Shell.md
create mode 100644 translated/tech/20181016 Lab 5- File system, Spawn and Shell.md
diff --git a/sources/tech/20181016 Lab 5- File system, Spawn and Shell.md b/sources/tech/20181016 Lab 5- File system, Spawn and Shell.md
deleted file mode 100644
index 9250700723..0000000000
--- a/sources/tech/20181016 Lab 5- File system, Spawn and Shell.md
+++ /dev/null
@@ -1,346 +0,0 @@
-Translating by qhwdw
-Lab 5: File system, Spawn and Shell
-======
-
-**Due Thursday, November 15, 2018
-**
-
-### Introduction
-
-In this lab, you will implement `spawn`, a library call that loads and runs on-disk executables. You will then flesh out your kernel and library operating system enough to run a shell on the console. These features need a file system, and this lab introduces a simple read/write file system.
-
-#### Getting Started
-
-Use Git to fetch the latest version of the course repository, and then create a local branch called `lab5` based on our lab5 branch, `origin/lab5`:
-
-```
- athena% cd ~/6.828/lab
- athena% add git
- athena% git pull
- Already up-to-date.
- athena% git checkout -b lab5 origin/lab5
- Branch lab5 set up to track remote branch refs/remotes/origin/lab5.
- Switched to a new branch "lab5"
- athena% git merge lab4
- Merge made by recursive.
- .....
- athena%
-```
-
-The main new component for this part of the lab is the file system environment, located in the new `fs` directory. Scan through all the files in this directory to get a feel for what all is new. Also, there are some new file system-related source files in the `user` and `lib` directories,
-
-| fs/fs.c | Code that mainipulates the file system's on-disk structure. |
-| fs/bc.c | A simple block cache built on top of our user-level page fault handling facility. |
-| fs/ide.c | Minimal PIO-based (non-interrupt-driven) IDE driver code. |
-| fs/serv.c | The file system server that interacts with client environments using file system IPCs. |
-| lib/fd.c | Code that implements the general UNIX-like file descriptor interface. |
-| lib/file.c | The driver for on-disk file type, implemented as a file system IPC client. |
-| lib/console.c | The driver for console input/output file type. |
-| lib/spawn.c | Code skeleton of the spawn library call. |
-
-You should run the pingpong, primes, and forktree test cases from lab 4 again after merging in the new lab 5 code. You will need to comment out the `ENV_CREATE(fs_fs)` line in `kern/init.c` because `fs/fs.c` tries to do some I/O, which JOS does not allow yet. Similarly, temporarily comment out the call to `close_all()` in `lib/exit.c`; this function calls subroutines that you will implement later in the lab, and therefore will panic if called. If your lab 4 code doesn't contain any bugs, the test cases should run fine. Don't proceed until they work. Don't forget to un-comment these lines when you start Exercise 1.
-
-If they don't work, use git diff lab4 to review all the changes, making sure there isn't any code you wrote for lab4 (or before) missing from lab 5. Make sure that lab 4 still works.
-
-#### Lab Requirements
-
-As before, you will need to do all of the regular exercises described in the lab and _at least one_ challenge problem. Additionally, you will need to write up brief answers to the questions posed in the lab and a short (e.g., one or two paragraph) description of what you did to solve your chosen challenge problem. If you implement more than one challenge problem, you only need to describe one of them in the write-up, though of course you are welcome to do more. Place the write-up in a file called `answers-lab5.txt` in the top level of your `lab5` directory before handing in your work.
-
-### File system preliminaries
-
-The file system you will work with is much simpler than most "real" file systems including that of xv6 UNIX, but it is powerful enough to provide the basic features: creating, reading, writing, and deleting files organized in a hierarchical directory structure.
-
-We are (for the moment anyway) developing only a single-user operating system, which provides protection sufficient to catch bugs but not to protect multiple mutually suspicious users from each other. Our file system therefore does not support the UNIX notions of file ownership or permissions. Our file system also currently does not support hard links, symbolic links, time stamps, or special device files like most UNIX file systems do.
-
-### On-Disk File System Structure
-
-Most UNIX file systems divide available disk space into two main types of regions: _inode_ regions and _data_ regions. UNIX file systems assign one _inode_ to each file in the file system; a file's inode holds critical meta-data about the file such as its `stat` attributes and pointers to its data blocks. The data regions are divided into much larger (typically 8KB or more) _data blocks_ , within which the file system stores file data and directory meta-data. Directory entries contain file names and pointers to inodes; a file is said to be _hard-linked_ if multiple directory entries in the file system refer to that file's inode. Since our file system will not support hard links, we do not need this level of indirection and therefore can make a convenient simplification: our file system will not use inodes at all and instead will simply store all of a file's (or sub-directory's) meta-data within the (one and only) directory entry describing that file.
-
-Both files and directories logically consist of a series of data blocks, which may be scattered throughout the disk much like the pages of an environment's virtual address space can be scattered throughout physical memory. The file system environment hides the details of block layout, presenting interfaces for reading and writing sequences of bytes at arbitrary offsets within files. The file system environment handles all modifications to directories internally as a part of performing actions such as file creation and deletion. Our file system does allow user environments to _read_ directory meta-data directly (e.g., with `read`), which means that user environments can perform directory scanning operations themselves (e.g., to implement the `ls` program) rather than having to rely on additional special calls to the file system. The disadvantage of this approach to directory scanning, and the reason most modern UNIX variants discourage it, is that it makes application programs dependent on the format of directory meta-data, making it difficult to change the file system's internal layout without changing or at least recompiling application programs as well.
-
-#### Sectors and Blocks
-
-Most disks cannot perform reads and writes at byte granularity and instead perform reads and writes in units of _sectors_. In JOS, sectors are 512 bytes each. File systems actually allocate and use disk storage in units of _blocks_. Be wary of the distinction between the two terms: _sector size_ is a property of the disk hardware, whereas _block size_ is an aspect of the operating system using the disk. A file system's block size must be a multiple of the sector size of the underlying disk.
-
-The UNIX xv6 file system uses a block size of 512 bytes, the same as the sector size of the underlying disk. Most modern file systems use a larger block size, however, because storage space has gotten much cheaper and it is more efficient to manage storage at larger granularities. Our file system will use a block size of 4096 bytes, conveniently matching the processor's page size.
-
-#### Superblocks
-
-![Disk layout][1]
-
-File systems typically reserve certain disk blocks at "easy-to-find" locations on the disk (such as the very start or the very end) to hold meta-data describing properties of the file system as a whole, such as the block size, disk size, any meta-data required to find the root directory, the time the file system was last mounted, the time the file system was last checked for errors, and so on. These special blocks are called _superblocks_.
-
-Our file system will have exactly one superblock, which will always be at block 1 on the disk. Its layout is defined by `struct Super` in `inc/fs.h`. Block 0 is typically reserved to hold boot loaders and partition tables, so file systems generally do not use the very first disk block. Many "real" file systems maintain multiple superblocks, replicated throughout several widely-spaced regions of the disk, so that if one of them is corrupted or the disk develops a media error in that region, the other superblocks can still be found and used to access the file system.
-
-#### File Meta-data
-
-![File structure][2]
-The layout of the meta-data describing a file in our file system is described by `struct File` in `inc/fs.h`. This meta-data includes the file's name, size, type (regular file or directory), and pointers to the blocks comprising the file. As mentioned above, we do not have inodes, so this meta-data is stored in a directory entry on disk. Unlike in most "real" file systems, for simplicity we will use this one `File` structure to represent file meta-data as it appears _both on disk and in memory_.
-
-The `f_direct` array in `struct File` contains space to store the block numbers of the first 10 (`NDIRECT`) blocks of the file, which we call the file's _direct_ blocks. For small files up to 10*4096 = 40KB in size, this means that the block numbers of all of the file's blocks will fit directly within the `File` structure itself. For larger files, however, we need a place to hold the rest of the file's block numbers. For any file greater than 40KB in size, therefore, we allocate an additional disk block, called the file's _indirect block_ , to hold up to 4096/4 = 1024 additional block numbers. Our file system therefore allows files to be up to 1034 blocks, or just over four megabytes, in size. To support larger files, "real" file systems typically support _double-_ and _triple-indirect blocks_ as well.
-
-#### Directories versus Regular Files
-
-A `File` structure in our file system can represent either a _regular_ file or a directory; these two types of "files" are distinguished by the `type` field in the `File` structure. The file system manages regular files and directory-files in exactly the same way, except that it does not interpret the contents of the data blocks associated with regular files at all, whereas the file system interprets the contents of a directory-file as a series of `File` structures describing the files and subdirectories within the directory.
-
-The superblock in our file system contains a `File` structure (the `root` field in `struct Super`) that holds the meta-data for the file system's root directory. The contents of this directory-file is a sequence of `File` structures describing the files and directories located within the root directory of the file system. Any subdirectories in the root directory may in turn contain more `File` structures representing sub-subdirectories, and so on.
-
-### The File System
-
-The goal for this lab is not to have you implement the entire file system, but for you to implement only certain key components. In particular, you will be responsible for reading blocks into the block cache and flushing them back to disk; allocating disk blocks; mapping file offsets to disk blocks; and implementing read, write, and open in the IPC interface. Because you will not be implementing all of the file system yourself, it is very important that you familiarize yourself with the provided code and the various file system interfaces.
-
-### Disk Access
-
-The file system environment in our operating system needs to be able to access the disk, but we have not yet implemented any disk access functionality in our kernel. Instead of taking the conventional "monolithic" operating system strategy of adding an IDE disk driver to the kernel along with the necessary system calls to allow the file system to access it, we instead implement the IDE disk driver as part of the user-level file system environment. We will still need to modify the kernel slightly, in order to set things up so that the file system environment has the privileges it needs to implement disk access itself.
-
-It is easy to implement disk access in user space this way as long as we rely on polling, "programmed I/O" (PIO)-based disk access and do not use disk interrupts. It is possible to implement interrupt-driven device drivers in user mode as well (the L3 and L4 kernels do this, for example), but it is more difficult since the kernel must field device interrupts and dispatch them to the correct user-mode environment.
-
-The x86 processor uses the IOPL bits in the EFLAGS register to determine whether protected-mode code is allowed to perform special device I/O instructions such as the IN and OUT instructions. Since all of the IDE disk registers we need to access are located in the x86's I/O space rather than being memory-mapped, giving "I/O privilege" to the file system environment is the only thing we need to do in order to allow the file system to access these registers. In effect, the IOPL bits in the EFLAGS register provides the kernel with a simple "all-or-nothing" method of controlling whether user-mode code can access I/O space. In our case, we want the file system environment to be able to access I/O space, but we do not want any other environments to be able to access I/O space at all.
-
-```
-Exercise 1. `i386_init` identifies the file system environment by passing the type `ENV_TYPE_FS` to your environment creation function, `env_create`. Modify `env_create` in `env.c`, so that it gives the file system environment I/O privilege, but never gives that privilege to any other environment.
-
-Make sure you can start the file environment without causing a General Protection fault. You should pass the "fs i/o" test in make grade.
-```
-
-```
-Question
-
- 1. Do you have to do anything else to ensure that this I/O privilege setting is saved and restored properly when you subsequently switch from one environment to another? Why?
-```
-
-
-Note that the `GNUmakefile` file in this lab sets up QEMU to use the file `obj/kern/kernel.img` as the image for disk 0 (typically "Drive C" under DOS/Windows) as before, and to use the (new) file `obj/fs/fs.img` as the image for disk 1 ("Drive D"). In this lab our file system should only ever touch disk 1; disk 0 is used only to boot the kernel. If you manage to corrupt either disk image in some way, you can reset both of them to their original, "pristine" versions simply by typing:
-
-```
- $ rm obj/kern/kernel.img obj/fs/fs.img
- $ make
-```
-
-or by doing:
-
-```
- $ make clean
- $ make
-```
-
-Challenge! Implement interrupt-driven IDE disk access, with or without DMA. You can decide whether to move the device driver into the kernel, keep it in user space along with the file system, or even (if you really want to get into the micro-kernel spirit) move it into a separate environment of its own.
-
-### The Block Cache
-
-In our file system, we will implement a simple "buffer cache" (really just a block cache) with the help of the processor's virtual memory system. The code for the block cache is in `fs/bc.c`.
-
-Our file system will be limited to handling disks of size 3GB or less. We reserve a large, fixed 3GB region of the file system environment's address space, from 0x10000000 (`DISKMAP`) up to 0xD0000000 (`DISKMAP+DISKMAX`), as a "memory mapped" version of the disk. For example, disk block 0 is mapped at virtual address 0x10000000, disk block 1 is mapped at virtual address 0x10001000, and so on. The `diskaddr` function in `fs/bc.c` implements this translation from disk block numbers to virtual addresses (along with some sanity checking).
-
-Since our file system environment has its own virtual address space independent of the virtual address spaces of all other environments in the system, and the only thing the file system environment needs to do is to implement file access, it is reasonable to reserve most of the file system environment's address space in this way. It would be awkward for a real file system implementation on a 32-bit machine to do this since modern disks are larger than 3GB. Such a buffer cache management approach may still be reasonable on a machine with a 64-bit address space.
-
-Of course, it would take a long time to read the entire disk into memory, so instead we'll implement a form of _demand paging_ , wherein we only allocate pages in the disk map region and read the corresponding block from the disk in response to a page fault in this region. This way, we can pretend that the entire disk is in memory.
-
-```
-Exercise 2. Implement the `bc_pgfault` and `flush_block` functions in `fs/bc.c`. `bc_pgfault` is a page fault handler, just like the one your wrote in the previous lab for copy-on-write fork, except that its job is to load pages in from the disk in response to a page fault. When writing this, keep in mind that (1) `addr` may not be aligned to a block boundary and (2) `ide_read` operates in sectors, not blocks.
-
-The `flush_block` function should write a block out to disk _if necessary_. `flush_block` shouldn't do anything if the block isn't even in the block cache (that is, the page isn't mapped) or if it's not dirty. We will use the VM hardware to keep track of whether a disk block has been modified since it was last read from or written to disk. To see whether a block needs writing, we can just look to see if the `PTE_D` "dirty" bit is set in the `uvpt` entry. (The `PTE_D` bit is set by the processor in response to a write to that page; see 5.2.4.3 in [chapter 5][3] of the 386 reference manual.) After writing the block to disk, `flush_block` should clear the `PTE_D` bit using `sys_page_map`.
-
-Use make grade to test your code. Your code should pass "check_bc", "check_super", and "check_bitmap".
-```
-
-`fs_init` function in `fs/fs.c` is a prime example of how to use the block cache. After initializing the block cache, it simply stores pointers into the disk map region in the `super` global variable. After this point, we can simply read from the `super` structure as if they were in memory and our page fault handler will read them from disk as necessary.
-
-```
-Challenge! The block cache has no eviction policy. Once a block gets faulted in to it, it never gets removed and will remain in memory forevermore. Add eviction to the buffer cache. Using the `PTE_A` "accessed" bits in the page tables, which the hardware sets on any access to a page, you can track approximate usage of disk blocks without the need to modify every place in the code that accesses the disk map region. Be careful with dirty blocks.
-```
-
-### The Block Bitmap
-
-After `fs_init` sets the `bitmap` pointer, we can treat `bitmap` as a packed array of bits, one for each block on the disk. See, for example, `block_is_free`, which simply checks whether a given block is marked free in the bitmap.
-
-```
-Exercise 3. Use `free_block` as a model to implement `alloc_block` in `fs/fs.c`, which should find a free disk block in the bitmap, mark it used, and return the number of that block. When you allocate a block, you should immediately flush the changed bitmap block to disk with `flush_block`, to help file system consistency.
-
-Use make grade to test your code. Your code should now pass "alloc_block".
-```
-
-### File Operations
-
-We have provided a variety of functions in `fs/fs.c` to implement the basic facilities you will need to interpret and manage `File` structures, scan and manage the entries of directory-files, and walk the file system from the root to resolve an absolute pathname. Read through _all_ of the code in `fs/fs.c` and make sure you understand what each function does before proceeding.
-
-```
-Exercise 4. Implement `file_block_walk` and `file_get_block`. `file_block_walk` maps from a block offset within a file to the pointer for that block in the `struct File` or the indirect block, very much like what `pgdir_walk` did for page tables. `file_get_block` goes one step further and maps to the actual disk block, allocating a new one if necessary.
-
-Use make grade to test your code. Your code should pass "file_open", "file_get_block", and "file_flush/file_truncated/file rewrite", and "testfile".
-```
-
-`file_block_walk` and `file_get_block` are the workhorses of the file system. For example, `file_read` and `file_write` are little more than the bookkeeping atop `file_get_block` necessary to copy bytes between scattered blocks and a sequential buffer.
-
-```
-Challenge! The file system is likely to be corrupted if it gets interrupted in the middle of an operation (for example, by a crash or a reboot). Implement soft updates or journalling to make the file system crash-resilient and demonstrate some situation where the old file system would get corrupted, but yours doesn't.
-```
-
-### The file system interface
-
-Now that we have the necessary functionality within the file system environment itself, we must make it accessible to other environments that wish to use the file system. Since other environments can't directly call functions in the file system environment, we'll expose access to the file system environment via a _remote procedure call_ , or RPC, abstraction, built atop JOS's IPC mechanism. Graphically, here's what a call to the file system server (say, read) looks like
-
-```
- Regular env FS env
- +---------------+ +---------------+
- | read | | file_read |
- | (lib/fd.c) | | (fs/fs.c) |
-...|.......|.......|...|.......^.......|...............
- | v | | | | RPC mechanism
- | devfile_read | | serve_read |
- | (lib/file.c) | | (fs/serv.c) |
- | | | | ^ |
- | v | | | |
- | fsipc | | serve |
- | (lib/file.c) | | (fs/serv.c) |
- | | | | ^ |
- | v | | | |
- | ipc_send | | ipc_recv |
- | | | | ^ |
- +-------|-------+ +-------|-------+
- | |
- +-------------------+
-
-```
-
-Everything below the dotted line is simply the mechanics of getting a read request from the regular environment to the file system environment. Starting at the beginning, `read` (which we provide) works on any file descriptor and simply dispatches to the appropriate device read function, in this case `devfile_read` (we can have more device types, like pipes). `devfile_read` implements `read` specifically for on-disk files. This and the other `devfile_*` functions in `lib/file.c` implement the client side of the FS operations and all work in roughly the same way, bundling up arguments in a request structure, calling `fsipc` to send the IPC request, and unpacking and returning the results. The `fsipc` function simply handles the common details of sending a request to the server and receiving the reply.
-
-The file system server code can be found in `fs/serv.c`. It loops in the `serve` function, endlessly receiving a request over IPC, dispatching that request to the appropriate handler function, and sending the result back via IPC. In the read example, `serve` will dispatch to `serve_read`, which will take care of the IPC details specific to read requests such as unpacking the request structure and finally call `file_read` to actually perform the file read.
-
-Recall that JOS's IPC mechanism lets an environment send a single 32-bit number and, optionally, share a page. To send a request from the client to the server, we use the 32-bit number for the request type (the file system server RPCs are numbered, just like how syscalls were numbered) and store the arguments to the request in a `union Fsipc` on the page shared via the IPC. On the client side, we always share the page at `fsipcbuf`; on the server side, we map the incoming request page at `fsreq` (`0x0ffff000`).
-
-The server also sends the response back via IPC. We use the 32-bit number for the function's return code. For most RPCs, this is all they return. `FSREQ_READ` and `FSREQ_STAT` also return data, which they simply write to the page that the client sent its request on. There's no need to send this page in the response IPC, since the client shared it with the file system server in the first place. Also, in its response, `FSREQ_OPEN` shares with the client a new "Fd page". We'll return to the file descriptor page shortly.
-
-```
-Exercise 5. Implement `serve_read` in `fs/serv.c`.
-
-`serve_read`'s heavy lifting will be done by the already-implemented `file_read` in `fs/fs.c` (which, in turn, is just a bunch of calls to `file_get_block`). `serve_read` just has to provide the RPC interface for file reading. Look at the comments and code in `serve_set_size` to get a general idea of how the server functions should be structured.
-
-Use make grade to test your code. Your code should pass "serve_open/file_stat/file_close" and "file_read" for a score of 70/150.
-```
-
-```
-Exercise 6. Implement `serve_write` in `fs/serv.c` and `devfile_write` in `lib/file.c`.
-
-Use make grade to test your code. Your code should pass "file_write", "file_read after file_write", "open", and "large file" for a score of 90/150.
-```
-
-### Spawning Processes
-
-We have given you the code for `spawn` (see `lib/spawn.c`) which creates a new environment, loads a program image from the file system into it, and then starts the child environment running this program. The parent process then continues running independently of the child. The `spawn` function effectively acts like a `fork` in UNIX followed by an immediate `exec` in the child process.
-
-We implemented `spawn` rather than a UNIX-style `exec` because `spawn` is easier to implement from user space in "exokernel fashion", without special help from the kernel. Think about what you would have to do in order to implement `exec` in user space, and be sure you understand why it is harder.
-
-```
-Exercise 7. `spawn` relies on the new syscall `sys_env_set_trapframe` to initialize the state of the newly created environment. Implement `sys_env_set_trapframe` in `kern/syscall.c` (don't forget to dispatch the new system call in `syscall()`).
-
-Test your code by running the `user/spawnhello` program from `kern/init.c`, which will attempt to spawn `/hello` from the file system.
-
-Use make grade to test your code.
-```
-
-```
-Challenge! Implement Unix-style `exec`.
-```
-
-```
-Challenge! Implement `mmap`-style memory-mapped files and modify `spawn` to map pages directly from the ELF image when possible.
-```
-
-### Sharing library state across fork and spawn
-
-The UNIX file descriptors are a general notion that also encompasses pipes, console I/O, etc. In JOS, each of these device types has a corresponding `struct Dev`, with pointers to the functions that implement read/write/etc. for that device type. `lib/fd.c` implements the general UNIX-like file descriptor interface on top of this. Each `struct Fd` indicates its device type, and most of the functions in `lib/fd.c` simply dispatch operations to functions in the appropriate `struct Dev`.
-
-`lib/fd.c` also maintains the _file descriptor table_ region in each application environment's address space, starting at `FDTABLE`. This area reserves a page's worth (4KB) of address space for each of the up to `MAXFD` (currently 32) file descriptors the application can have open at once. At any given time, a particular file descriptor table page is mapped if and only if the corresponding file descriptor is in use. Each file descriptor also has an optional "data page" in the region starting at `FILEDATA`, which devices can use if they choose.
-
-We would like to share file descriptor state across `fork` and `spawn`, but file descriptor state is kept in user-space memory. Right now, on `fork`, the memory will be marked copy-on-write, so the state will be duplicated rather than shared. (This means environments won't be able to seek in files they didn't open themselves and that pipes won't work across a fork.) On `spawn`, the memory will be left behind, not copied at all. (Effectively, the spawned environment starts with no open file descriptors.)
-
-We will change `fork` to know that certain regions of memory are used by the "library operating system" and should always be shared. Rather than hard-code a list of regions somewhere, we will set an otherwise-unused bit in the page table entries (just like we did with the `PTE_COW` bit in `fork`).
-
-We have defined a new `PTE_SHARE` bit in `inc/lib.h`. This bit is one of the three PTE bits that are marked "available for software use" in the Intel and AMD manuals. We will establish the convention that if a page table entry has this bit set, the PTE should be copied directly from parent to child in both `fork` and `spawn`. Note that this is different from marking it copy-on-write: as described in the first paragraph, we want to make sure to _share_ updates to the page.
-
-```
-Exercise 8. Change `duppage` in `lib/fork.c` to follow the new convention. If the page table entry has the `PTE_SHARE` bit set, just copy the mapping directly. (You should use `PTE_SYSCALL`, not `0xfff`, to mask out the relevant bits from the page table entry. `0xfff` picks up the accessed and dirty bits as well.)
-
-Likewise, implement `copy_shared_pages` in `lib/spawn.c`. It should loop through all page table entries in the current process (just like `fork` did), copying any page mappings that have the `PTE_SHARE` bit set into the child process.
-```
-
-Use make run-testpteshare to check that your code is behaving properly. You should see lines that say "`fork handles PTE_SHARE right`" and "`spawn handles PTE_SHARE right`".
-
-Use make run-testfdsharing to check that file descriptors are shared properly. You should see lines that say "`read in child succeeded`" and "`read in parent succeeded`".
-
-### The keyboard interface
-
-For the shell to work, we need a way to type at it. QEMU has been displaying output we write to the CGA display and the serial port, but so far we've only taken input while in the kernel monitor. In QEMU, input typed in the graphical window appear as input from the keyboard to JOS, while input typed to the console appear as characters on the serial port. `kern/console.c` already contains the keyboard and serial drivers that have been used by the kernel monitor since lab 1, but now you need to attach these to the rest of the system.
-
-```
-Exercise 9. In your `kern/trap.c`, call `kbd_intr` to handle trap `IRQ_OFFSET+IRQ_KBD` and `serial_intr` to handle trap `IRQ_OFFSET+IRQ_SERIAL`.
-```
-
-We implemented the console input/output file type for you, in `lib/console.c`. `kbd_intr` and `serial_intr` fill a buffer with the recently read input while the console file type drains the buffer (the console file type is used for stdin/stdout by default unless the user redirects them).
-
-Test your code by running make run-testkbd and type a few lines. The system should echo your lines back to you as you finish them. Try typing in both the console and the graphical window, if you have both available.
-
-### The Shell
-
-Run make run-icode or make run-icode-nox. This will run your kernel and start `user/icode`. `icode` execs `init`, which will set up the console as file descriptors 0 and 1 (standard input and standard output). It will then spawn `sh`, the shell. You should be able to run the following commands:
-
-```
- echo hello world | cat
- cat lorem |cat
- cat lorem |num
- cat lorem |num |num |num |num |num
- lsfd
-```
-
-Note that the user library routine `cprintf` prints straight to the console, without using the file descriptor code. This is great for debugging but not great for piping into other programs. To print output to a particular file descriptor (for example, 1, standard output), use `fprintf(1, "...", ...)`. `printf("...", ...)` is a short-cut for printing to FD 1. See `user/lsfd.c` for examples.
-
-```
-Exercise 10.
-
-The shell doesn't support I/O redirection. It would be nice to run sh