<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://homeostasis.scs.carleton.ca/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Soma</id>
	<title>Soma-notes - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://homeostasis.scs.carleton.ca/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Soma"/>
	<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php/Special:Contributions/Soma"/>
	<updated>2026-10-10T11:04:09Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25195</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25195"/>
		<updated>2026-10-09T23:46:22Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Lectures &amp;amp; Exams */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]]&amp;lt;br&amp;gt;&#039;&#039;&#039;No class on Oct 1 ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Midterm Review]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;&#039;&#039;&#039;Midterm Exam (in class)&#039;&#039;&#039;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 17, 9 AM&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25194</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25194"/>
		<updated>2026-10-09T15:00:19Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Video */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in previous classes:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* UNIX accounts&lt;br /&gt;
* password security&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* ssh configuration and usage&lt;br /&gt;
&lt;br /&gt;
==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on October 8th and 9th, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08a-20261008.mp4 Lecture 8A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08b-20261009.mp4 Lecture 8B]&lt;br /&gt;
&lt;br /&gt;
Unfortunately the screen capture got messed up with these, my apologies.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 8A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Wooclap: ALMBSXY&lt;br /&gt;
&lt;br /&gt;
Why tutorials then assignments?&lt;br /&gt;
 - we can grade only so much&lt;br /&gt;
 - but I also want to encourage you to judge whether you understand something or not&lt;br /&gt;
&lt;br /&gt;
How does the Internet work?&lt;br /&gt;
 - postcards going this way and that&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - because they show who they are from and who they are for&lt;br /&gt;
 - limited in size&lt;br /&gt;
 - &amp;quot;public&amp;quot;&lt;br /&gt;
&lt;br /&gt;
What if you wanted to communicate a lot of information via postcards?&lt;br /&gt;
 - break up the message into postcard-sized chunks&lt;br /&gt;
 - number the postcards&lt;br /&gt;
&lt;br /&gt;
But then what if they arrive out of order, get delayed, or get lost?&lt;br /&gt;
 - need some way of checking what information is missing&lt;br /&gt;
&lt;br /&gt;
IP &amp;lt;- postcards (packets)&lt;br /&gt;
TCP &amp;lt;- strategy for getting continuous communication over IP packets,&lt;br /&gt;
       making sure it is reliable&lt;br /&gt;
UDP &amp;lt;- let me manage the postcards myself&lt;br /&gt;
&lt;br /&gt;
So how can we protect these postcards?&lt;br /&gt;
 - cryptography!&lt;br /&gt;
&lt;br /&gt;
Classic cryptography relies on shared secrets&lt;br /&gt;
 - both sides know the &amp;quot;password&amp;quot;&lt;br /&gt;
&lt;br /&gt;
But a shared secret only works if both parties have been previously introduced&lt;br /&gt;
 - not the case on the Internet!&lt;br /&gt;
&lt;br /&gt;
In the 1970&#039;s, cryptographers figured out something much more clever:&lt;br /&gt;
public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography splits the &amp;quot;secret&amp;quot; into two:&lt;br /&gt;
 - a public key that is shared with everyone&lt;br /&gt;
 - a private key that is...private&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With public key cryptography, you can&lt;br /&gt;
 - send a secret message to anyone you have the public key for&lt;br /&gt;
 - verify the authenticity &amp;amp; integrity of a message for anyone you have the public key (check the digital signature)&lt;br /&gt;
&lt;br /&gt;
Now the sharing a secret key problem - we can just send a key as a public key-encrypted message&lt;br /&gt;
 - but how do I know I have the right public key?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To enable passwordless login to an openstack VM&lt;br /&gt;
 - generate an SSH key pair&lt;br /&gt;
 - copy the public key (the .pub  file) to the .ssh/authorized_keys file&lt;br /&gt;
   on the openstack VM&lt;br /&gt;
 - add the key pair to your local ssh agent&lt;br /&gt;
   - this varies depending on your operating system, but is&lt;br /&gt;
     generally &amp;quot;ssh-add&amp;quot; and the private key file&lt;br /&gt;
&lt;br /&gt;
The purpose of ssh-add is to add your unlocked private key to your local ssh agent&lt;br /&gt;
 - the idea is that you don&#039;t want to keep having to unlock your private key, but you want your private key to be protected on disk&lt;br /&gt;
&lt;br /&gt;
PASSWORDS&lt;br /&gt;
 - so passwords are stored locally, but does that mean if someone logs into your computer they automatically know your password?&lt;br /&gt;
 - passwords are stored with secure hashes&lt;br /&gt;
   - the hash of the password is remembered, not the password&lt;br /&gt;
   - if you have the hash you only know the password if you guess it correctly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 8B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8B&lt;br /&gt;
----------&lt;br /&gt;
wooclap: EUJSUZN&lt;br /&gt;
&lt;br /&gt;
There are textbook resources&lt;br /&gt;
 - read them for contextual information&lt;br /&gt;
&lt;br /&gt;
but you need to approach the material intentionally&lt;br /&gt;
 - I can&#039;t build a conceptual model for you&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before explaining SSH, we need to explain why we need it&lt;br /&gt;
So...networking&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - have a sender and a receiver (source and destination)&lt;br /&gt;
 - limited size&lt;br /&gt;
 - &amp;quot;public&amp;quot; - anyone who handles the postcard can read it&lt;br /&gt;
&lt;br /&gt;
packets are basically postcards&lt;br /&gt;
 - and that&#039;s what is sent around on the Internet&lt;br /&gt;
&lt;br /&gt;
If you want to send a lot of information, that means a lot of postcards&lt;br /&gt;
 - what order?&lt;br /&gt;
 - what if one gets lost? Delayed?&lt;br /&gt;
 - privacy?&lt;br /&gt;
 - integrity (no changes)&lt;br /&gt;
 - authenticity (correct sender)?&lt;br /&gt;
&lt;br /&gt;
The Internet was built originally with NO SECURITY&lt;br /&gt;
 - no privacy, integrity, authenticity&lt;br /&gt;
&lt;br /&gt;
Instead it was &amp;quot;best effort&amp;quot;&lt;br /&gt;
 - mistakes will be made&lt;br /&gt;
&lt;br /&gt;
Internet routers - think the post office&lt;br /&gt;
&lt;br /&gt;
So how do we solve the security problem? By using cryptography!&lt;br /&gt;
 - classic cryptography is all about ciphers for encryption&lt;br /&gt;
&lt;br /&gt;
symmetric key cryptography:&lt;br /&gt;
  plaintext + secret key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + secret key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
Old: substitution ciphers, enigma&lt;br /&gt;
Recent: DES&lt;br /&gt;
Current: AES&lt;br /&gt;
&lt;br /&gt;
The challenge of symmetric key cryptography is a chicken &amp;amp; egg problem:&lt;br /&gt;
 - how do you share a key?&lt;br /&gt;
&lt;br /&gt;
Solution: public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography:&lt;br /&gt;
  plaintext + public key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + private key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
public and private key are a matched pair that are generated together&lt;br /&gt;
&lt;br /&gt;
But how do I make sure things haven&#039;t been changed in transit?&lt;br /&gt;
 - integrity, authenticity?&lt;br /&gt;
&lt;br /&gt;
secure hash functions&lt;br /&gt;
 - generating hashes from a document are easy&lt;br /&gt;
 - finding a document with a given hash is hard&lt;br /&gt;
&lt;br /&gt;
So if I have the hash of a document and the hash is correct, I know I got the right document&lt;br /&gt;
&lt;br /&gt;
But then, how do I know I got the right hash?&lt;br /&gt;
&lt;br /&gt;
public key cryptography (digital signature):&lt;br /&gt;
  hash + private key =&amp;gt; signature&lt;br /&gt;
  signature + public key =&amp;gt; hash&lt;br /&gt;
&lt;br /&gt;
To check a signature of a document:&lt;br /&gt;
  compute hash(document)&lt;br /&gt;
  hash(document) ?= hash from signature&lt;br /&gt;
&lt;br /&gt;
If they match, then document is authentic (came from owner of key) and hasn&#039;t been changed&lt;br /&gt;
&lt;br /&gt;
(don&#039;t implement your own cryptography!)&lt;br /&gt;
&lt;br /&gt;
So how do I know I have the right public key for someone?&lt;br /&gt;
 - well, we can just use digital signatures again!&lt;br /&gt;
&lt;br /&gt;
certificate: public key + metadata (name, expiration, etc)&lt;br /&gt;
&lt;br /&gt;
setuid bit&lt;br /&gt;
 - goes with the execute bit&lt;br /&gt;
 - when execve is run, makes the euid of the process the uid of the executable&lt;br /&gt;
&lt;br /&gt;
euid: effective uid, the real uid the kernel uses to decide access&lt;br /&gt;
&lt;br /&gt;
normally uid=euid for a process, but setuid lets this change&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25193</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25193"/>
		<updated>2026-10-09T14:50:32Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Video */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in previous classes:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* UNIX accounts&lt;br /&gt;
* password security&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* ssh configuration and usage&lt;br /&gt;
&lt;br /&gt;
==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on October 8th and 9th, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08a-20261008.mp4 Lecture 8A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08b-20261009.mp4 Lecture 8B]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 8A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Wooclap: ALMBSXY&lt;br /&gt;
&lt;br /&gt;
Why tutorials then assignments?&lt;br /&gt;
 - we can grade only so much&lt;br /&gt;
 - but I also want to encourage you to judge whether you understand something or not&lt;br /&gt;
&lt;br /&gt;
How does the Internet work?&lt;br /&gt;
 - postcards going this way and that&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - because they show who they are from and who they are for&lt;br /&gt;
 - limited in size&lt;br /&gt;
 - &amp;quot;public&amp;quot;&lt;br /&gt;
&lt;br /&gt;
What if you wanted to communicate a lot of information via postcards?&lt;br /&gt;
 - break up the message into postcard-sized chunks&lt;br /&gt;
 - number the postcards&lt;br /&gt;
&lt;br /&gt;
But then what if they arrive out of order, get delayed, or get lost?&lt;br /&gt;
 - need some way of checking what information is missing&lt;br /&gt;
&lt;br /&gt;
IP &amp;lt;- postcards (packets)&lt;br /&gt;
TCP &amp;lt;- strategy for getting continuous communication over IP packets,&lt;br /&gt;
       making sure it is reliable&lt;br /&gt;
UDP &amp;lt;- let me manage the postcards myself&lt;br /&gt;
&lt;br /&gt;
So how can we protect these postcards?&lt;br /&gt;
 - cryptography!&lt;br /&gt;
&lt;br /&gt;
Classic cryptography relies on shared secrets&lt;br /&gt;
 - both sides know the &amp;quot;password&amp;quot;&lt;br /&gt;
&lt;br /&gt;
But a shared secret only works if both parties have been previously introduced&lt;br /&gt;
 - not the case on the Internet!&lt;br /&gt;
&lt;br /&gt;
In the 1970&#039;s, cryptographers figured out something much more clever:&lt;br /&gt;
public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography splits the &amp;quot;secret&amp;quot; into two:&lt;br /&gt;
 - a public key that is shared with everyone&lt;br /&gt;
 - a private key that is...private&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With public key cryptography, you can&lt;br /&gt;
 - send a secret message to anyone you have the public key for&lt;br /&gt;
 - verify the authenticity &amp;amp; integrity of a message for anyone you have the public key (check the digital signature)&lt;br /&gt;
&lt;br /&gt;
Now the sharing a secret key problem - we can just send a key as a public key-encrypted message&lt;br /&gt;
 - but how do I know I have the right public key?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To enable passwordless login to an openstack VM&lt;br /&gt;
 - generate an SSH key pair&lt;br /&gt;
 - copy the public key (the .pub  file) to the .ssh/authorized_keys file&lt;br /&gt;
   on the openstack VM&lt;br /&gt;
 - add the key pair to your local ssh agent&lt;br /&gt;
   - this varies depending on your operating system, but is&lt;br /&gt;
     generally &amp;quot;ssh-add&amp;quot; and the private key file&lt;br /&gt;
&lt;br /&gt;
The purpose of ssh-add is to add your unlocked private key to your local ssh agent&lt;br /&gt;
 - the idea is that you don&#039;t want to keep having to unlock your private key, but you want your private key to be protected on disk&lt;br /&gt;
&lt;br /&gt;
PASSWORDS&lt;br /&gt;
 - so passwords are stored locally, but does that mean if someone logs into your computer they automatically know your password?&lt;br /&gt;
 - passwords are stored with secure hashes&lt;br /&gt;
   - the hash of the password is remembered, not the password&lt;br /&gt;
   - if you have the hash you only know the password if you guess it correctly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 8B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8B&lt;br /&gt;
----------&lt;br /&gt;
wooclap: EUJSUZN&lt;br /&gt;
&lt;br /&gt;
There are textbook resources&lt;br /&gt;
 - read them for contextual information&lt;br /&gt;
&lt;br /&gt;
but you need to approach the material intentionally&lt;br /&gt;
 - I can&#039;t build a conceptual model for you&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before explaining SSH, we need to explain why we need it&lt;br /&gt;
So...networking&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - have a sender and a receiver (source and destination)&lt;br /&gt;
 - limited size&lt;br /&gt;
 - &amp;quot;public&amp;quot; - anyone who handles the postcard can read it&lt;br /&gt;
&lt;br /&gt;
packets are basically postcards&lt;br /&gt;
 - and that&#039;s what is sent around on the Internet&lt;br /&gt;
&lt;br /&gt;
If you want to send a lot of information, that means a lot of postcards&lt;br /&gt;
 - what order?&lt;br /&gt;
 - what if one gets lost? Delayed?&lt;br /&gt;
 - privacy?&lt;br /&gt;
 - integrity (no changes)&lt;br /&gt;
 - authenticity (correct sender)?&lt;br /&gt;
&lt;br /&gt;
The Internet was built originally with NO SECURITY&lt;br /&gt;
 - no privacy, integrity, authenticity&lt;br /&gt;
&lt;br /&gt;
Instead it was &amp;quot;best effort&amp;quot;&lt;br /&gt;
 - mistakes will be made&lt;br /&gt;
&lt;br /&gt;
Internet routers - think the post office&lt;br /&gt;
&lt;br /&gt;
So how do we solve the security problem? By using cryptography!&lt;br /&gt;
 - classic cryptography is all about ciphers for encryption&lt;br /&gt;
&lt;br /&gt;
symmetric key cryptography:&lt;br /&gt;
  plaintext + secret key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + secret key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
Old: substitution ciphers, enigma&lt;br /&gt;
Recent: DES&lt;br /&gt;
Current: AES&lt;br /&gt;
&lt;br /&gt;
The challenge of symmetric key cryptography is a chicken &amp;amp; egg problem:&lt;br /&gt;
 - how do you share a key?&lt;br /&gt;
&lt;br /&gt;
Solution: public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography:&lt;br /&gt;
  plaintext + public key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + private key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
public and private key are a matched pair that are generated together&lt;br /&gt;
&lt;br /&gt;
But how do I make sure things haven&#039;t been changed in transit?&lt;br /&gt;
 - integrity, authenticity?&lt;br /&gt;
&lt;br /&gt;
secure hash functions&lt;br /&gt;
 - generating hashes from a document are easy&lt;br /&gt;
 - finding a document with a given hash is hard&lt;br /&gt;
&lt;br /&gt;
So if I have the hash of a document and the hash is correct, I know I got the right document&lt;br /&gt;
&lt;br /&gt;
But then, how do I know I got the right hash?&lt;br /&gt;
&lt;br /&gt;
public key cryptography (digital signature):&lt;br /&gt;
  hash + private key =&amp;gt; signature&lt;br /&gt;
  signature + public key =&amp;gt; hash&lt;br /&gt;
&lt;br /&gt;
To check a signature of a document:&lt;br /&gt;
  compute hash(document)&lt;br /&gt;
  hash(document) ?= hash from signature&lt;br /&gt;
&lt;br /&gt;
If they match, then document is authentic (came from owner of key) and hasn&#039;t been changed&lt;br /&gt;
&lt;br /&gt;
(don&#039;t implement your own cryptography!)&lt;br /&gt;
&lt;br /&gt;
So how do I know I have the right public key for someone?&lt;br /&gt;
 - well, we can just use digital signatures again!&lt;br /&gt;
&lt;br /&gt;
certificate: public key + metadata (name, expiration, etc)&lt;br /&gt;
&lt;br /&gt;
setuid bit&lt;br /&gt;
 - goes with the execute bit&lt;br /&gt;
 - when execve is run, makes the euid of the process the uid of the executable&lt;br /&gt;
&lt;br /&gt;
euid: effective uid, the real uid the kernel uses to decide access&lt;br /&gt;
&lt;br /&gt;
normally uid=euid for a process, but setuid lets this change&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25192</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25192"/>
		<updated>2026-10-09T14:50:19Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in previous classes:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* UNIX accounts&lt;br /&gt;
* password security&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* ssh configuration and usage&lt;br /&gt;
&lt;br /&gt;
==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on October 8th and 9th, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08a-20261008.mp4 Lecture 7A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec08b-20261009.mp4 Lecture 7B]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 8A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Wooclap: ALMBSXY&lt;br /&gt;
&lt;br /&gt;
Why tutorials then assignments?&lt;br /&gt;
 - we can grade only so much&lt;br /&gt;
 - but I also want to encourage you to judge whether you understand something or not&lt;br /&gt;
&lt;br /&gt;
How does the Internet work?&lt;br /&gt;
 - postcards going this way and that&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - because they show who they are from and who they are for&lt;br /&gt;
 - limited in size&lt;br /&gt;
 - &amp;quot;public&amp;quot;&lt;br /&gt;
&lt;br /&gt;
What if you wanted to communicate a lot of information via postcards?&lt;br /&gt;
 - break up the message into postcard-sized chunks&lt;br /&gt;
 - number the postcards&lt;br /&gt;
&lt;br /&gt;
But then what if they arrive out of order, get delayed, or get lost?&lt;br /&gt;
 - need some way of checking what information is missing&lt;br /&gt;
&lt;br /&gt;
IP &amp;lt;- postcards (packets)&lt;br /&gt;
TCP &amp;lt;- strategy for getting continuous communication over IP packets,&lt;br /&gt;
       making sure it is reliable&lt;br /&gt;
UDP &amp;lt;- let me manage the postcards myself&lt;br /&gt;
&lt;br /&gt;
So how can we protect these postcards?&lt;br /&gt;
 - cryptography!&lt;br /&gt;
&lt;br /&gt;
Classic cryptography relies on shared secrets&lt;br /&gt;
 - both sides know the &amp;quot;password&amp;quot;&lt;br /&gt;
&lt;br /&gt;
But a shared secret only works if both parties have been previously introduced&lt;br /&gt;
 - not the case on the Internet!&lt;br /&gt;
&lt;br /&gt;
In the 1970&#039;s, cryptographers figured out something much more clever:&lt;br /&gt;
public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography splits the &amp;quot;secret&amp;quot; into two:&lt;br /&gt;
 - a public key that is shared with everyone&lt;br /&gt;
 - a private key that is...private&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
With public key cryptography, you can&lt;br /&gt;
 - send a secret message to anyone you have the public key for&lt;br /&gt;
 - verify the authenticity &amp;amp; integrity of a message for anyone you have the public key (check the digital signature)&lt;br /&gt;
&lt;br /&gt;
Now the sharing a secret key problem - we can just send a key as a public key-encrypted message&lt;br /&gt;
 - but how do I know I have the right public key?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To enable passwordless login to an openstack VM&lt;br /&gt;
 - generate an SSH key pair&lt;br /&gt;
 - copy the public key (the .pub  file) to the .ssh/authorized_keys file&lt;br /&gt;
   on the openstack VM&lt;br /&gt;
 - add the key pair to your local ssh agent&lt;br /&gt;
   - this varies depending on your operating system, but is&lt;br /&gt;
     generally &amp;quot;ssh-add&amp;quot; and the private key file&lt;br /&gt;
&lt;br /&gt;
The purpose of ssh-add is to add your unlocked private key to your local ssh agent&lt;br /&gt;
 - the idea is that you don&#039;t want to keep having to unlock your private key, but you want your private key to be protected on disk&lt;br /&gt;
&lt;br /&gt;
PASSWORDS&lt;br /&gt;
 - so passwords are stored locally, but does that mean if someone logs into your computer they automatically know your password?&lt;br /&gt;
 - passwords are stored with secure hashes&lt;br /&gt;
   - the hash of the password is remembered, not the password&lt;br /&gt;
   - if you have the hash you only know the password if you guess it correctly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 8B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 8B&lt;br /&gt;
----------&lt;br /&gt;
wooclap: EUJSUZN&lt;br /&gt;
&lt;br /&gt;
There are textbook resources&lt;br /&gt;
 - read them for contextual information&lt;br /&gt;
&lt;br /&gt;
but you need to approach the material intentionally&lt;br /&gt;
 - I can&#039;t build a conceptual model for you&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before explaining SSH, we need to explain why we need it&lt;br /&gt;
So...networking&lt;br /&gt;
&lt;br /&gt;
Why postcards?&lt;br /&gt;
 - have a sender and a receiver (source and destination)&lt;br /&gt;
 - limited size&lt;br /&gt;
 - &amp;quot;public&amp;quot; - anyone who handles the postcard can read it&lt;br /&gt;
&lt;br /&gt;
packets are basically postcards&lt;br /&gt;
 - and that&#039;s what is sent around on the Internet&lt;br /&gt;
&lt;br /&gt;
If you want to send a lot of information, that means a lot of postcards&lt;br /&gt;
 - what order?&lt;br /&gt;
 - what if one gets lost? Delayed?&lt;br /&gt;
 - privacy?&lt;br /&gt;
 - integrity (no changes)&lt;br /&gt;
 - authenticity (correct sender)?&lt;br /&gt;
&lt;br /&gt;
The Internet was built originally with NO SECURITY&lt;br /&gt;
 - no privacy, integrity, authenticity&lt;br /&gt;
&lt;br /&gt;
Instead it was &amp;quot;best effort&amp;quot;&lt;br /&gt;
 - mistakes will be made&lt;br /&gt;
&lt;br /&gt;
Internet routers - think the post office&lt;br /&gt;
&lt;br /&gt;
So how do we solve the security problem? By using cryptography!&lt;br /&gt;
 - classic cryptography is all about ciphers for encryption&lt;br /&gt;
&lt;br /&gt;
symmetric key cryptography:&lt;br /&gt;
  plaintext + secret key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + secret key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
Old: substitution ciphers, enigma&lt;br /&gt;
Recent: DES&lt;br /&gt;
Current: AES&lt;br /&gt;
&lt;br /&gt;
The challenge of symmetric key cryptography is a chicken &amp;amp; egg problem:&lt;br /&gt;
 - how do you share a key?&lt;br /&gt;
&lt;br /&gt;
Solution: public key cryptography&lt;br /&gt;
&lt;br /&gt;
public key cryptography:&lt;br /&gt;
  plaintext + public key =&amp;gt; ciphertext&lt;br /&gt;
  ciphertex + private key =&amp;gt; plaintext&lt;br /&gt;
&lt;br /&gt;
public and private key are a matched pair that are generated together&lt;br /&gt;
&lt;br /&gt;
But how do I make sure things haven&#039;t been changed in transit?&lt;br /&gt;
 - integrity, authenticity?&lt;br /&gt;
&lt;br /&gt;
secure hash functions&lt;br /&gt;
 - generating hashes from a document are easy&lt;br /&gt;
 - finding a document with a given hash is hard&lt;br /&gt;
&lt;br /&gt;
So if I have the hash of a document and the hash is correct, I know I got the right document&lt;br /&gt;
&lt;br /&gt;
But then, how do I know I got the right hash?&lt;br /&gt;
&lt;br /&gt;
public key cryptography (digital signature):&lt;br /&gt;
  hash + private key =&amp;gt; signature&lt;br /&gt;
  signature + public key =&amp;gt; hash&lt;br /&gt;
&lt;br /&gt;
To check a signature of a document:&lt;br /&gt;
  compute hash(document)&lt;br /&gt;
  hash(document) ?= hash from signature&lt;br /&gt;
&lt;br /&gt;
If they match, then document is authentic (came from owner of key) and hasn&#039;t been changed&lt;br /&gt;
&lt;br /&gt;
(don&#039;t implement your own cryptography!)&lt;br /&gt;
&lt;br /&gt;
So how do I know I have the right public key for someone?&lt;br /&gt;
 - well, we can just use digital signatures again!&lt;br /&gt;
&lt;br /&gt;
certificate: public key + metadata (name, expiration, etc)&lt;br /&gt;
&lt;br /&gt;
setuid bit&lt;br /&gt;
 - goes with the execute bit&lt;br /&gt;
 - when execve is run, makes the euid of the process the uid of the executable&lt;br /&gt;
&lt;br /&gt;
euid: effective uid, the real uid the kernel uses to decide access&lt;br /&gt;
&lt;br /&gt;
normally uid=euid for a process, but setuid lets this change&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25191</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25191"/>
		<updated>2026-10-08T17:49:07Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in previous classes:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* UNIX accounts&lt;br /&gt;
* password security&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* ssh configuration and usage&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25190</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25190"/>
		<updated>2026-10-08T17:48:49Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Topics */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in class:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* UNIX accounts&lt;br /&gt;
* password security&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* ssh configuration and usage&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25189</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25189"/>
		<updated>2026-10-08T17:46:14Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in class:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
* Introduction to networking&lt;br /&gt;
* Public key cryptography&lt;br /&gt;
* password security&lt;br /&gt;
* ssh configuration and usage&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25188</id>
		<title>Operating Systems 2026F Lecture 8</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_8&amp;diff=25188"/>
		<updated>2026-10-08T17:18:01Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;==Readings==  The following readings are supplemental but may help you understand what has been covered in class:  UNIX permissions * &amp;#039;&amp;#039;Operating System Concepts&amp;#039;&amp;#039;, Section 13.4.2, Access control (p. 552-554)  setuid * &amp;#039;&amp;#039;Operating System Concepts&amp;#039;&amp;#039;, Section 17.4.2, Example: UNIX (p. 674-675)  Files and directories * &amp;#039;&amp;#039;Operating Systems: Three Easy Pieces&amp;#039;&amp;#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Readings==&lt;br /&gt;
&lt;br /&gt;
The following readings are supplemental but may help you understand what has been covered in class:&lt;br /&gt;
&lt;br /&gt;
UNIX permissions&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 13.4.2, Access control (p. 552-554)&lt;br /&gt;
&lt;br /&gt;
setuid&lt;br /&gt;
* &#039;&#039;Operating System Concepts&#039;&#039;, Section 17.4.2, Example: UNIX (p. 674-675)&lt;br /&gt;
&lt;br /&gt;
Files and directories&lt;br /&gt;
* &#039;&#039;Operating Systems: Three Easy Pieces&#039;&#039;, [https://pages.cs.wisc.edu/~remzi/OSTEP/file-intro.pdf Chapter 39: Interlude: Files and Directories]&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_7&amp;diff=25187</id>
		<title>Operating Systems 2026F Lecture 7</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_7&amp;diff=25187"/>
		<updated>2026-10-07T17:57:17Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;==Video==  Video from the lectures given on October 6th and 7th, 2026 are now available: * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec07a-20261006.mp4 Lecture 7A] * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec07b-20261007.mp4 Lecture 7B]  ==Notes==  ===Lecture 7A===  &amp;lt;pre&amp;gt; Lecture 7A ----------  Tutorial 4!  Apps ------ Kernel  &amp;lt;--- has more privileges ------- Hardware  Implemented on the CPU through...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on October 6th and 7th, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec07a-20261006.mp4 Lecture 7A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec07b-20261007.mp4 Lecture 7B]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 7A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 7A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Tutorial 4!&lt;br /&gt;
&lt;br /&gt;
Apps&lt;br /&gt;
------&lt;br /&gt;
Kernel  &amp;lt;--- has more privileges&lt;br /&gt;
-------&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
Implemented on the CPU through different modes.&lt;br /&gt;
&lt;br /&gt;
UNIX-like systems expect there to be a supervisor mode and a user mode.&lt;br /&gt;
 - supervisor mode: can access everything&lt;br /&gt;
 - user mode: limited access&lt;br /&gt;
&lt;br /&gt;
processes run in user mode&lt;br /&gt;
the kernel runs in supervisor mode&lt;br /&gt;
&lt;br /&gt;
a &amp;quot;process&amp;quot; is an abstraction over sharing of user mode&lt;br /&gt;
&lt;br /&gt;
the kernel doesn&#039;t share supervisor mode - that&#039;s all that runs&lt;br /&gt;
&lt;br /&gt;
Linux&lt;br /&gt;
 - name of an implementation of a operating system kernel&lt;br /&gt;
 - designed to be basically compatible with POSIX&lt;br /&gt;
&lt;br /&gt;
POSIX&lt;br /&gt;
 - set of standards defining what a UNIX-like system is&lt;br /&gt;
&lt;br /&gt;
UNIX&lt;br /&gt;
 - operating system created by engineers at Bell Labs (AT&amp;amp;T) in the early 1970&#039;s&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
AT&amp;amp;T had been ruled a monopoly so they had lots of rules about what they could and could not do&lt;br /&gt;
 - they weren&#039;t allowed to compete in the commputer market&lt;br /&gt;
 - but their engineers made a nice OS&lt;br /&gt;
 - so, they basically gave away UNIX&lt;br /&gt;
   - very permissive licenses&lt;br /&gt;
   - adopted by a lot of universities, esp ones who were developing the Internet&lt;br /&gt;
&lt;br /&gt;
UNIX is a pun on MULTICS&lt;br /&gt;
&lt;br /&gt;
BSD UNIX - Berkeley variant of UNIX that was where a lot of Internet technologies were prototyped&lt;br /&gt;
&lt;br /&gt;
But then BSD UNIX got big, and so commercial UNIX became a thing in the 1980&#039;s&lt;br /&gt;
 - on scientific workstations and other bigger machines&lt;br /&gt;
&lt;br /&gt;
But every company that made a UNIX workstation made their own proprietary version of UNIX&lt;br /&gt;
 - permissive license from AT&amp;amp;T plus Berkeley giving away their code&lt;br /&gt;
&lt;br /&gt;
These variations got to be such a pain that there came an effort to standardize what a &amp;quot;UNIX-like&amp;quot; system should be&lt;br /&gt;
 - this resulted in POSIX&lt;br /&gt;
&lt;br /&gt;
UNIX is trademarked&lt;br /&gt;
 - not everyone can call their OS UNIX&lt;br /&gt;
&lt;br /&gt;
In the early 1990&#039;s two things happened&lt;br /&gt;
 - The web arrived (1992-1993)&lt;br /&gt;
 - CPUs capable of UNIX became available in PCs&lt;br /&gt;
   - 80386 starting in 1985&lt;br /&gt;
   - 80486 starting in 1989&lt;br /&gt;
&lt;br /&gt;
So a commercial UNIX could have taken over&lt;br /&gt;
 - Microsoft actually sold XENIX for PCs&lt;br /&gt;
&lt;br /&gt;
But really a version of BSD UNIX should have been available for PCs around then and should have been the foundation of the modern Internet&lt;br /&gt;
 - was open source and battle tested&lt;br /&gt;
&lt;br /&gt;
What happened?&lt;br /&gt;
&lt;br /&gt;
AT&amp;amp;T got greedy&lt;br /&gt;
 - was free of antitrust concerns&lt;br /&gt;
 - and UNIX had become valuable&lt;br /&gt;
 - so they went and sued the people who were making BSD UNIX&lt;br /&gt;
&lt;br /&gt;
Linux is the product of three things&lt;br /&gt;
 - AT&amp;amp;T&#039;s lawsuits&lt;br /&gt;
 - the GNU project not making a kernel&lt;br /&gt;
 - a finnish CS undergrad hacking around&lt;br /&gt;
&lt;br /&gt;
The GNU project&lt;br /&gt;
 - project of the Free Software Foundation&lt;br /&gt;
 - stands for GNU&#039;s not UNIX&lt;br /&gt;
 - FSF people (led by Richard Stallman) got tired of proprietary UNIX&lt;br /&gt;
   - wanted THE CODE so they could make their own changes and share&lt;br /&gt;
     them&lt;br /&gt;
   - so they decided to make their own version of a UNIX-like system&lt;br /&gt;
&lt;br /&gt;
 - gcc instead of cc&lt;br /&gt;
 - bash instead of sh&lt;br /&gt;
 - bison instead of lex&lt;br /&gt;
&lt;br /&gt;
All under the GPL&lt;br /&gt;
&lt;br /&gt;
GPL - GNU General Public License&lt;br /&gt;
 - if you distribute, you have to share the source code with binaries&lt;br /&gt;
 - source code should be distributable under same terms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The GNU project did this for essentially all of userspace of a UNIX system by the early 1990&#039;s. But it couldn&#039;t run on bare hardware because they didn&#039;t have a kernel.&lt;br /&gt;
 - GNU Herd was stalled&lt;br /&gt;
&lt;br /&gt;
And then Linus Torvalds came along&lt;br /&gt;
 - got people on the Internet collaborating on making a kernel&lt;br /&gt;
&lt;br /&gt;
People say GNU/Linux because it is the Linux kernel with a GNU userland&lt;br /&gt;
 - but nowadays that isn&#039;t always true (e.g., busybox)&lt;br /&gt;
&lt;br /&gt;
Linux distribution: Linux kernel + some userspace code&lt;br /&gt;
&lt;br /&gt;
So with UNIX, you have code running in supervisor mode (kernelspace) and in user mode (userspace)&lt;br /&gt;
&lt;br /&gt;
We&#039;re now focused on userspace, will talk about kernelspace more after the midterm&lt;br /&gt;
&lt;br /&gt;
So when a process wants to do something with files, it must make system calls&lt;br /&gt;
 - system call is a request to the kernel&lt;br /&gt;
 - kernel can say yes or no&lt;br /&gt;
&lt;br /&gt;
On what basis does the kernel say yes or no?&lt;br /&gt;
&lt;br /&gt;
Wooclap code: AFAGNUX&lt;br /&gt;
&lt;br /&gt;
First, it depends on which process and which file&lt;br /&gt;
&lt;br /&gt;
Some processes can access everything&lt;br /&gt;
Some have limited access&lt;br /&gt;
&lt;br /&gt;
What mainly determines access is the user who owns the process&lt;br /&gt;
 - i.e., the uid associated with the owner field of the process&lt;br /&gt;
&lt;br /&gt;
Files on UNIX have an associated uid and gid (user and group)&lt;br /&gt;
And permissions associated with these.&lt;br /&gt;
&lt;br /&gt;
three groups of read, write, execute bits&lt;br /&gt;
 - yes or no for each&lt;br /&gt;
plus a few other bits&lt;br /&gt;
&lt;br /&gt;
The rwx are for:&lt;br /&gt;
 - the user&lt;br /&gt;
 - the group&lt;br /&gt;
 - other (everyone else)&lt;br /&gt;
&lt;br /&gt;
To read a file, you need read access&lt;br /&gt;
 - first check to see if uid of process equals uid of file&lt;br /&gt;
    - and user read bit enabled&lt;br /&gt;
 - then check gid of process equals gid of file&lt;br /&gt;
    - and group read bit enabled&lt;br /&gt;
 - then check if other read bit enabled&lt;br /&gt;
&lt;br /&gt;
But what about directories?&lt;br /&gt;
 - marked by a &amp;quot;d&amp;quot; bit&lt;br /&gt;
&lt;br /&gt;
When you run ls, you&#039;re reading the contents of the current directory&lt;br /&gt;
 - represented by &amp;quot;.&amp;quot;&lt;br /&gt;
 - &amp;quot;..&amp;quot; is the parent directory&lt;br /&gt;
&lt;br /&gt;
To be able to list&lt;br /&gt;
&lt;br /&gt;
What&#039;s really happening is that the contents of a file is represented as an inode&lt;br /&gt;
 - inodes are numbered per filesystem&lt;br /&gt;
&lt;br /&gt;
A directory is just a mapping of names to inodes&lt;br /&gt;
&lt;br /&gt;
With r permission, you can read the mappings of names to inodes in a directory&lt;br /&gt;
&lt;br /&gt;
With x permission, you can get the inode associated with a name&lt;br /&gt;
&lt;br /&gt;
file permissions are actually inode permission in UNIX&lt;br /&gt;
&lt;br /&gt;
hard links are just name to inode associations&lt;br /&gt;
 (what directories mostly contain)&lt;br /&gt;
&lt;br /&gt;
symbolic links are name to name associations&lt;br /&gt;
&lt;br /&gt;
So what&#039;s special about root (uid=0)?&lt;br /&gt;
 - the kernel treats those processes as being allowed to do almost anything&lt;br /&gt;
&lt;br /&gt;
When you use sudo, you are saying &amp;quot;superuser (root) do this&amp;quot;&lt;br /&gt;
 - better than logging in as root, because it is clear what is being done with elevated privileges&lt;br /&gt;
&lt;br /&gt;
If you just want to be root, run &amp;quot;su&amp;quot; - but you need the root password.&lt;br /&gt;
&lt;br /&gt;
Alternately, run &amp;quot;sudo -i&amp;quot; to login as root if your user has sudo privileges.&lt;br /&gt;
&lt;br /&gt;
setuid bit&lt;br /&gt;
 - goes with the executable bit on a file, but separate&lt;br /&gt;
&lt;br /&gt;
when a process execve&#039;s a program with the setuid bit, the *euid* of the process changes to that of the program file&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 7B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 7B&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Wooclap 1: OEHHFJX&lt;br /&gt;
Be sure to be logged in!&lt;br /&gt;
&lt;br /&gt;
Today is Tutorial 4, plus some history&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Applications (processes)&lt;br /&gt;
-------&lt;br /&gt;
Kernel&lt;br /&gt;
--------&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
kernel and applications take turns on the CPU&lt;br /&gt;
 - key difference is their privilege levels&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So the kernel runs in &amp;quot;supervisor mode&amp;quot;, while&lt;br /&gt;
processes run in &amp;quot;user mode&amp;quot; on the CPU&lt;br /&gt;
 - full access in supervisor mode&lt;br /&gt;
 - limited access in user mode&lt;br /&gt;
&lt;br /&gt;
the process abstraction is a way to multiplex user mode&lt;br /&gt;
&lt;br /&gt;
System calls are how code in user mode invokes code in supervisor mode, i.e., how processes call the kernel&lt;br /&gt;
 - special mechanism because function calls don&#039;t work&lt;br /&gt;
&lt;br /&gt;
So what are permissions for?&lt;br /&gt;
 - tells the kernel what privileges different processes should have, i.e., what resources it should be given access to&lt;br /&gt;
&lt;br /&gt;
We mainly see permissions associated with two things:&lt;br /&gt;
 - processes&lt;br /&gt;
 - files&lt;br /&gt;
&lt;br /&gt;
So when a process accesses a file, the kernel decides whether it is allowed or not based on the permission model&lt;br /&gt;
&lt;br /&gt;
Permissions are generally in some sort of access control matrix&lt;br /&gt;
 - rows are entities&lt;br /&gt;
 - columns are specific permissions&lt;br /&gt;
UNIX uses a simplified access control model for efficiency and usability&lt;br /&gt;
&lt;br /&gt;
I&#039;ve been saying UNIX, Linux, UNIX-like...why?&lt;br /&gt;
&lt;br /&gt;
UNIX is a trademark of AT&amp;amp;T&lt;br /&gt;
 - because it came out of Bell Labs in the early 1970&#039;s&lt;br /&gt;
 - wasn&#039;t really a product at first because was&lt;br /&gt;
   just made by a few engineers for their own use&lt;br /&gt;
 - and AT&amp;amp;T wasn&#039;t allowed to commercialize it really&lt;br /&gt;
    - they were under antitrust restrictions&lt;br /&gt;
 - so they almost gave it away&lt;br /&gt;
    - very open license terms for whomever wanted it&lt;br /&gt;
&lt;br /&gt;
When researchers wanted to create the Internet in the late 1970&#039;s, they mostly built upon UNIX&lt;br /&gt;
 - researchers at Berkeley modified it to make BSD UNIX&lt;br /&gt;
&lt;br /&gt;
So to get on the Internet people wanted to run BSD UNIX, and so it spread&lt;br /&gt;
 - first as itself&lt;br /&gt;
 - then in commercial form from workstation vendors in the 1980&#039;s (e.g., Sun Microsystems)&lt;br /&gt;
&lt;br /&gt;
Because of the licensing terms, workstation manufacturers all could make proprietary versions of UNIX&lt;br /&gt;
 - based on generally available code but with lots of proprietary modifications/additions&lt;br /&gt;
&lt;br /&gt;
Got so bad there was an effort to standardize what &amp;quot;UNIX&amp;quot; should be&lt;br /&gt;
 - resulted in the POSIX standards&lt;br /&gt;
&lt;br /&gt;
So UNIX should have been the basis of the web starting in the early 1990&#039;s, but a few things happened&lt;br /&gt;
 - PCs got powerful enough to run UNIX&lt;br /&gt;
   - Intel 80386 in 1985, 80486 in 1989&lt;br /&gt;
 - there were commercial versions of UNIX for PCs&lt;br /&gt;
   - Microsoft made XENIX&lt;br /&gt;
&lt;br /&gt;
Rather than proprietary UNIX, why couldn&#039;t PCs run a variant of BSD UNIX?&lt;br /&gt;
 - it was still around, had its own variants&lt;br /&gt;
 - but AT&amp;amp;T decided to sue the creators of BSD UNIX&lt;br /&gt;
&lt;br /&gt;
Another piece was the GNU Project&lt;br /&gt;
 - from the Free Software Foundation&lt;br /&gt;
 - HATED proprietary UNIX, so decided to make their own&lt;br /&gt;
&lt;br /&gt;
Started with the foundations&lt;br /&gt;
 - gcc instead of cc&lt;br /&gt;
 - bash rather than sh&lt;br /&gt;
 - bison rather than lex&lt;br /&gt;
&lt;br /&gt;
By the early 1990&#039;s, GNU had implementations of everything in core UNIX...except for the kernel&lt;br /&gt;
 - there was the GNU Herd, but it was VERY delayed&lt;br /&gt;
&lt;br /&gt;
This is where a Finnish CS undergrad steps in&lt;br /&gt;
 - Linus Torvalds posted his own hacked together kernel&lt;br /&gt;
 - with the help of others, he&lt;br /&gt;
   combined it with GNU userland, and now had a&lt;br /&gt;
   UNIX-like system that came to be known as Linux&lt;br /&gt;
&lt;br /&gt;
Strictly speaking, Linux is just the kernel&lt;br /&gt;
 - to get a full UNIX-like system, need to add userspace&lt;br /&gt;
 - Linux + userspace =&amp;gt; Linux distribution&lt;br /&gt;
 - people call Linux GNU/Linux because GNU project code&lt;br /&gt;
   is often part of a Linux distribution&lt;br /&gt;
   - but not always! (e.g., busybox)&lt;br /&gt;
&lt;br /&gt;
One factor in the success of Linux is its license&lt;br /&gt;
 - GNU GPL (General Public License)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;copyleft&amp;quot; license&lt;br /&gt;
 - based on copyright to subvert copyright&lt;br /&gt;
 - says you can distribute code as you like, BUT&lt;br /&gt;
   - you have to give source with binary code&lt;br /&gt;
   - can&#039;t add restrictions&lt;br /&gt;
&lt;br /&gt;
Android has effectively circumvented the GPL of Linux&lt;br /&gt;
 - VERY irritating&lt;br /&gt;
&lt;br /&gt;
Back to permissions&lt;br /&gt;
&lt;br /&gt;
every process has a user and a group&lt;br /&gt;
every file has a user, a group, and permissions&lt;br /&gt;
&lt;br /&gt;
The permissions are&lt;br /&gt;
 - read&lt;br /&gt;
 - write&lt;br /&gt;
 - execute&lt;br /&gt;
And are there for&lt;br /&gt;
 - user&lt;br /&gt;
 - group&lt;br /&gt;
 - other (everyone else)&lt;br /&gt;
plus a few more bits we will discuss&lt;br /&gt;
&lt;br /&gt;
execute for regular files means they can be run as programs&lt;br /&gt;
 - when you compile a program the compiler makes its&lt;br /&gt;
   output executable&lt;br /&gt;
&lt;br /&gt;
Other bits:&lt;br /&gt;
 d: marks a file as a directory&lt;br /&gt;
    - maps filenames to file contents (inodes)&lt;br /&gt;
&lt;br /&gt;
What do permissions mean on a directory?&lt;br /&gt;
 - read lets you list the names in a directory&lt;br /&gt;
 - execute lets you resolve a name to its associated value (i.e., inode)&lt;br /&gt;
&lt;br /&gt;
If a directory is executable but not readable, you can access the contents of files in that directory, but you can&#039;t get a list of files in the directory (try it out!)&lt;br /&gt;
&lt;br /&gt;
But this whole permission model begs a question -&lt;br /&gt;
how do we get around it?&lt;br /&gt;
 - how do we get the right permissions in the first place?&lt;br /&gt;
&lt;br /&gt;
One user is very special in UNIX: root (uid=0)&lt;br /&gt;
 - is allowed to do basically anything by the kernel&lt;br /&gt;
&lt;br /&gt;
So when you first log in, that process is running as root so it can then &amp;quot;become&amp;quot; any user it wants to&lt;br /&gt;
 - called dropping privileges&lt;br /&gt;
&lt;br /&gt;
But then what about sudo?&lt;br /&gt;
 - goes the wrong way, from a less privileged process&lt;br /&gt;
   to one with root capabilities&lt;br /&gt;
 - &amp;quot;superuser (root) do&amp;quot;&lt;br /&gt;
&lt;br /&gt;
s in ls means that the executable and the setuid bit are both set&lt;br /&gt;
 - if just setuid and not executable, you get S&lt;br /&gt;
   (almost never what you want)&lt;br /&gt;
&lt;br /&gt;
With the setuid bit set, the effective uid of a process becomes that of the executable file&lt;br /&gt;
&lt;br /&gt;
The kernel uses the effective uid to decide what is and isn&#039;t allowed&lt;br /&gt;
 - normally uid=euid&lt;br /&gt;
 - but setuid messes with it&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25186</id>
		<title>Operating Systems 2026F: Tutorial 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25186"/>
		<updated>2026-10-05T19:05:06Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have been allocated to the current process.&lt;br /&gt;
&lt;br /&gt;
A process is an abstraction over the limited access of the CPU&#039;s user mode. All processes run in user mode. While kernel code can be doing work on behalf of a specific process, properly speaking no kernel code is in a process. Instead, the kernel implements the process abstraction.&lt;br /&gt;
&lt;br /&gt;
The kernel, however, does not treat all processes the same. The kernel allows some processes to do more than others depending upon the user and group of the process. We can see what access a process has by looking at the permissions associated with files.&lt;br /&gt;
&lt;br /&gt;
Most users have limited access. One user, &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (with user ID of 0), has as much access as is possible from a process. The kernel will even allow the root process to modify how the kernel operates. Processes running as root are still just processes, though, and any access that the kernel gives to such processes is at the discretion of the kernel. (In fact, there are setups which limit the privileges of the root user.)&lt;br /&gt;
&lt;br /&gt;
===File Permissions===&lt;br /&gt;
&lt;br /&gt;
A process&#039; permission to access files in UNIX is determined by the user and group associated with that process. When a person logs in, their initial process is given the user and group associated with their account. All child processes of that initial login process inherit the same user and group.&lt;br /&gt;
&lt;br /&gt;
A user can belong to multiple groups but a process only belongs to one group at a time. (There are ways to change the group associated with a process.) A file is always owned by someone and is always associated with a group.  All files on the UNIX file system (including directories and other special files) have three different sets of permissions:&lt;br /&gt;
* owner permissions&lt;br /&gt;
* group permissions&lt;br /&gt;
* other permissions&lt;br /&gt;
Each of these have read, write, and/or execute permissions along with some other special permissions.&lt;br /&gt;
&lt;br /&gt;
One special permission is the &#039;&#039;setuid&#039;&#039; bit. When an executable has this bit set, the process will run as the user who owns that executable (rather than as the user associated with the process that did the execve). The setuid bit is particularly important when a file is owned by root, as it gives us a way for regular users to escape the bounds of normal permissions. We will see the setuid root bit in action in this tutorial.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ls&amp;lt;/tt&amp;gt; command with the &amp;lt;tt&amp;gt;-l&amp;lt;/tt&amp;gt; option can be used to show both the permissions of a file as well as the owner and group associated with the file.  Permissions are listed first, followed by the owner and the group.&lt;br /&gt;
&lt;br /&gt;
===Logging in to a UNIX system===&lt;br /&gt;
&lt;br /&gt;
In order to log in to a UNIX system (Linux or otherwise), the following steps must occur (potentially not in this order).&lt;br /&gt;
&lt;br /&gt;
# The user must authenticate themselves, proving their identity and that they are allowed to access the system.  By default this is done through a username and password.&lt;br /&gt;
# A new process, U, should be created for the authenticated user.&lt;br /&gt;
# The login program must establish communication with the user via some communications channel.  Normally this channel will be a device.  Standard in, out, and error for U should be connected to this device.&lt;br /&gt;
# U changes uid and gid to that of the new user.&lt;br /&gt;
# U sets up other aspects of the user&#039;s context (mainly setting key environment variables).&lt;br /&gt;
# U does an execve of the user&#039;s chosen shell.&lt;br /&gt;
&lt;br /&gt;
[[#Code|3000userlogin]] is a basic implementation of steps 4-6.   (Steps 2 and 3 are accomplished by running 3000userlogin in a shell, as running an external command means the shell first creates a new process, as we have seen.  We are skipping 1.)&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Secure Shell, or ssh, is the standard method for accessing UNIX and UNIX-like systems remotely. It is a more secure replacement for older technologies such as [https://en.wikipedia.org/wiki/Berkeley_r-commands rsh] and [https://en.wikipedia.org/wiki/Telnet telnet].&lt;br /&gt;
&lt;br /&gt;
The standard implementation of ssh is [http://www.openssh.org openssh], a version of ssh that was originally created for [https://www.openbsd.org/ OpenBSD] but has been ported to other systems. OpenBSD has a reputation for being the most secure UNIX-like system around. It tends to be a bit harder to configure, have less support for current hardware, and have lower overall performance than Linux-based systems; however, it can be very competitive for some workloads.&lt;br /&gt;
&lt;br /&gt;
While ssh support password-based authentication, it is meant to be used with more secure forms of authentication. For example, ssh supports public key authentication, a type of authentication that makes use of [https://en.wikipedia.org/wiki/Public-key_cryptography public key cryptography]. Instead of a shared key (such as a password) that is known to both parties, with public key cryptography, keys come in two parts: a public part and a private part. The public part should be widely distributed, while the private part needs to be carefully secured.&lt;br /&gt;
&lt;br /&gt;
Public key cryptography can be used to send secret messages to anyone you can get the public key for. With digital signatures, public key cryptography can also be used to verify the authenticity and integrity of messages, so long as we know the public key of the originating party.&lt;br /&gt;
&lt;br /&gt;
With public key authentication, we use a key pair to authenticate rather than sending a password.&lt;br /&gt;
&lt;br /&gt;
A cool feature of public key authentication is it is possible to automatically log into a system once the appropriate private key is made available, thus giving us the convenience of passwordless logins with better security than passwords.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
===3000userlogin===&lt;br /&gt;
&lt;br /&gt;
When 3000userlogin is properly compiled and set up, you can run&lt;br /&gt;
&lt;br /&gt;
  ./3000userlogin someuser&lt;br /&gt;
&lt;br /&gt;
and you&#039;ll be logged in as &amp;quot;someuser&amp;quot;, assuming someuser exists.&lt;br /&gt;
&lt;br /&gt;
You can add a user with the adduser command.  For example, to create the user &amp;quot;someuser&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  sudo adduser someuser&lt;br /&gt;
&lt;br /&gt;
Note you&#039;ll have to answer several questions.&lt;br /&gt;
&lt;br /&gt;
If you just compile 3000userlogin normally, you won&#039;t be able to log in as anyone except the current user.  To compile and set up 3000userlogin, do the following:&lt;br /&gt;
&lt;br /&gt;
  gcc -O -Wall 3000userlogin.c -o 3000userlogin&lt;br /&gt;
  sudo chown root:root 3000userlogin&lt;br /&gt;
  sudo chmod u+s 3000userlogin&lt;br /&gt;
&lt;br /&gt;
The chown command makes the binary owned by root, and the chmod command makes it setuid.  Thus, when the program is execve&#039;d it will have an effective user ID of root (euid=0).&lt;br /&gt;
&lt;br /&gt;
Alternately, you can download the code and use the associated makefile to build by doing the following:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/tut4.tar.gz&lt;br /&gt;
  tar xzf tut4.tar.gz&lt;br /&gt;
  cd tut4&lt;br /&gt;
  sudo apt install make    # make isn&#039;t installed on the class VMs oops&lt;br /&gt;
  make&lt;br /&gt;
  make setuid&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Install the openssh-server package (note on openstack it will already be installed, but on a default Ubuntu desktop install it won&#039;t be):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Create a second user in the virtual machine named &amp;quot;other&amp;quot; (or any other name you wish to use):&lt;br /&gt;
&lt;br /&gt;
 sudo adduser other&lt;br /&gt;
&lt;br /&gt;
(Answer the subsequent prompts however you wish, just remember the password.)&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to log in to the &amp;quot;other&amp;quot; account using ssh:&lt;br /&gt;
&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to enter your password.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get a password prompt, password authentication has probably been disabled.  (Password authentication has been disabled on the openstack VMs.)  To enable it, do the following&lt;br /&gt;
&lt;br /&gt;
  sudo nano /etc/ssh/sshd_config    (or vi, or emacs)&lt;br /&gt;
&lt;br /&gt;
In the editor change the line &amp;quot;PasswordAuthentication no&amp;quot; to &amp;quot;PasswordAuthentication yes&amp;quot;.  Then, to restart sshd:&lt;br /&gt;
&lt;br /&gt;
  sudo service sshd restart&lt;br /&gt;
&lt;br /&gt;
Be sure to change it back after you&#039;ve set up public key authentication!&lt;br /&gt;
&lt;br /&gt;
===Public key authentication===&lt;br /&gt;
&lt;br /&gt;
Create a public key file for your account (as user student, ubuntu, or your personal account):&lt;br /&gt;
&lt;br /&gt;
 ssh-keygen&lt;br /&gt;
&lt;br /&gt;
(Accept the default filename and choose at least a simple passphrase.)&lt;br /&gt;
&lt;br /&gt;
You just created a certificate!  (A certificate is just a public key with metadata.)&lt;br /&gt;
&lt;br /&gt;
Copy the key to the other account:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; authorized_keys&lt;br /&gt;
 scp authorized_keys other@localhost:.&lt;br /&gt;
 rm authorized_keys&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
 (as user other)&lt;br /&gt;
 mkdir ~/.ssh (if it doesn&#039;t exist already)&lt;br /&gt;
 chmod 700 ~/.ssh  (make it private)&lt;br /&gt;
 mv ~/authorized_keys ~/.ssh&lt;br /&gt;
 chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
Now you can log in to user other by typing in the passphrase you used to lock the key you generated.&lt;br /&gt;
&lt;br /&gt;
To avoid entering this passphrase every time, you can give it to the authentication agent (generally, ssh-agent) that was started when you logged in:&lt;br /&gt;
&lt;br /&gt;
  ssh-add&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
# Compile and setup 3000userlogin as described above.  Create a new user account.  Verify that you can use 3000userlogin to login as the new user without typing the password of the new user.&lt;br /&gt;
# What is returned as the user&#039;s password by getpwnam()?  Is this what you expected?&lt;br /&gt;
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user, running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set).  Also check to see what happens when you set the setgid bit (with different group IDs on the file).&lt;br /&gt;
# Why does 3000userlogin change its gid before changing its uid?  What happens if you switch the order of these operations?&lt;br /&gt;
# Make 3000userlogin use the shell that is specified in the user&#039;s password entry.  Check by making a new user and setting its shell to a new shell and then see if that new shell runs when you run 3000userlogin.  You should change a user&#039;s shell with the chsh command, run as that user.&lt;br /&gt;
# Can you set 3000shell to be a user&#039;s default shell?  What changes do you have to make for chsh to accept 3000shell?  Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it?&lt;br /&gt;
# Does a user&#039;s default shell have to be a regular shell?  Could it instead be an arbitrary program?  How do you know?&lt;br /&gt;
# How important is each of the environment variables that is set by 3000userlogin?  Are these the only environment variables that are set after you successfully login?&lt;br /&gt;
# Note that 3000userlogin uses environ not envp (as an argument to main) to access environment variables.  Why not use envp?  (Try changing the code to use envp and see what happens.)&lt;br /&gt;
# Setup password-less login to your local system between the student and other account (or any two other accounts), following the above instructions.  Note that the &amp;quot;local&amp;quot; account is the one you are running the ssh command on.&lt;br /&gt;
# Setup password-less login to access.scs.carleton.ca, following the instructions above.&lt;br /&gt;
# Secure shell can be used to directly run a command on another program rather than the default shell.  For example, try &amp;quot;ssh student@localhost bc -l&amp;quot; and see that bc is run.  When you do this, does ssh directly run the specified command or does it first run a shell and have the shell run the command?  Use opensnoop.bt or execsnoop.bt to verify.&lt;br /&gt;
# What files in /etc does bash access when you login via 3000userlogin?  How does this compare to what bash opens when you log in via ssh?&lt;br /&gt;
# &#039;&#039;&#039;(Optional):&#039;&#039;&#039; Prompt for the user&#039;s password before logging the user in.  To do this, you&#039;ll need to get the right password hash and then figure out how to hash the entered password to check if it matches.  See online guides about [https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils how passwords are stored on Linux] for help.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2021f/code/3000userlogin.tar.gz Download code for this tutorial (3000userlogin.c and Makefile)]&lt;br /&gt;
&lt;br /&gt;
===3000userlogin.c===&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/3000userlogin.c Download 3000userlogin.c]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000userlogin.c */&lt;br /&gt;
/* version 0.1 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        char *shell_argv[3];&lt;br /&gt;
        char *username;&lt;br /&gt;
        extern char **environ;&lt;br /&gt;
        struct passwd *pw_entry;&lt;br /&gt;
                &lt;br /&gt;
        if (argc &amp;lt; 2) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Usage: %s &amp;lt;username&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
                exit(-1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;uid=%d, euid=%d, gid=%d, egid=%d\n&amp;quot;,&lt;br /&gt;
               getuid(), geteuid(), getgid(), getegid());&lt;br /&gt;
&lt;br /&gt;
        username = argv[1];&lt;br /&gt;
        &lt;br /&gt;
        pw_entry = getpwnam(username);&lt;br /&gt;
        if (pw_entry == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Could not find user %s.\n&amp;quot;, username);&lt;br /&gt;
                exit(-2);&lt;br /&gt;
        }&lt;br /&gt;
                       &lt;br /&gt;
        result = setgid(pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to gid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
                exit(-3);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = setuid(pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to uid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
                exit(-4);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = chdir(pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to home dir %s\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
                exit(-5);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        shell_argv[0] = &amp;quot;bash&amp;quot;;&lt;br /&gt;
        shell_argv[1] = &amp;quot;--login&amp;quot;;&lt;br /&gt;
        shell_argv[2] = NULL;&lt;br /&gt;
&lt;br /&gt;
        clearenv();&lt;br /&gt;
        setenv(&amp;quot;USERNAME&amp;quot;, pw_entry-&amp;gt;pw_name, 1);&lt;br /&gt;
        setenv(&amp;quot;PATH&amp;quot;, &amp;quot;/usr/bin:/bin&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;SHELL&amp;quot;, &amp;quot;/bin/bash&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;HOME&amp;quot;, pw_entry-&amp;gt;pw_dir, 1);&lt;br /&gt;
        setenv(&amp;quot;COMP3000&amp;quot;, &amp;quot;yes&amp;quot;, 1);&lt;br /&gt;
        &lt;br /&gt;
        execve(&amp;quot;/bin/bash&amp;quot;, shell_argv, environ);&lt;br /&gt;
     &lt;br /&gt;
        fprintf(stderr, &amp;quot;Failed to exec bash\n&amp;quot;);&lt;br /&gt;
        return -6;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Makefile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot; line&amp;gt;&lt;br /&gt;
.PHONY: setuid&lt;br /&gt;
&lt;br /&gt;
3000userlogin: 3000userlogin.c&lt;br /&gt;
	gcc -Wall -O 3000userlogin.c -o 3000userlogin&lt;br /&gt;
&lt;br /&gt;
setuid: 3000userlogin&lt;br /&gt;
	@echo &amp;quot;The following changes ownership to root, group to root, and sets the setuid bit on 3000userlogin:&amp;quot;&lt;br /&gt;
	sudo chown root:root 3000userlogin &amp;amp;&amp;amp; sudo chmod u+s 3000userlogin&lt;br /&gt;
	@echo &amp;quot;3000userlogin is now setuid root!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25185</id>
		<title>Operating Systems 2026F: Tutorial 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25185"/>
		<updated>2026-10-04T19:47:06Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have been allocated to the current process.&lt;br /&gt;
&lt;br /&gt;
A process is an abstraction over the limited access of the CPU&#039;s user mode. All processes run in user mode. While kernel code can be doing work on behalf of a specific process, properly speaking no kernel code is in a process. Instead, the kernel implements the process abstraction.&lt;br /&gt;
&lt;br /&gt;
The kernel, however, does not treat all processes the same. The kernel allows some processes to do more than others depending upon the user and group of the process. We can see what access a process has by looking at the permissions associated with files.&lt;br /&gt;
&lt;br /&gt;
Most users have limited access. One user, &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (with user ID of 0), has as much access as is possible from a process. The kernel will even allow the root process to modify how the kernel operates. Processes running as root are still just processes, though, and any access that the kernel gives to such processes is at the discretion of the kernel. (In fact, there are setups which limit the privileges of the root user.)&lt;br /&gt;
&lt;br /&gt;
===File Permissions===&lt;br /&gt;
&lt;br /&gt;
A process&#039; permission to access files in UNIX is determined by the user and group associated with that process. When a person logs in, their initial process is given the user and group associated with their account. All child processes of that initial login process inherit the same user and group.&lt;br /&gt;
&lt;br /&gt;
A user can belong to multiple groups but a process only belongs to one group at a time. (There are ways to change the group associated with a process.) A file is always owned by someone and is always associated with a group.  All files on the UNIX file system (including directories and other special files) have three different sets of permissions:&lt;br /&gt;
* owner permissions&lt;br /&gt;
* group permissions&lt;br /&gt;
* other permissions&lt;br /&gt;
Each of these have read, write, and/or execute permissions along with some other special permissions.&lt;br /&gt;
&lt;br /&gt;
One special permission is the &#039;&#039;setuid&#039;&#039; bit. When an executable has this bit set, the process will run as the user who owns that executable (rather than as the user associated with the process that did the execve). The setuid bit is particularly important when a file is owned by root, as it gives us a way for regular users to escape the bounds of normal permissions. We will see the setuid root bit in action in this tutorial.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ls&amp;lt;/tt&amp;gt; command with the &amp;lt;tt&amp;gt;-l&amp;lt;/tt&amp;gt; option can be used to show both the permissions of a file as well as the owner and group associated with the file.  Permissions are listed first, followed by the owner and the group.&lt;br /&gt;
&lt;br /&gt;
===Logging in to a UNIX system===&lt;br /&gt;
&lt;br /&gt;
In order to log in to a UNIX system (Linux or otherwise), the following steps must occur (potentially not in this order).&lt;br /&gt;
&lt;br /&gt;
# The user must authenticate themselves, proving their identity and that they are allowed to access the system.  By default this is done through a username and password.&lt;br /&gt;
# A new process, U, should be created for the authenticated user.&lt;br /&gt;
# The login program must establish communication with the user via some communications channel.  Normally this channel will be a device.  Standard in, out, and error for U should be connected to this device.&lt;br /&gt;
# U changes uid and gid to that of the new user.&lt;br /&gt;
# U sets up other aspects of the user&#039;s context (mainly setting key environment variables).&lt;br /&gt;
# U does an execve of the user&#039;s chosen shell.&lt;br /&gt;
&lt;br /&gt;
[[#Code|3000userlogin]] is a basic implementation of steps 4-6.   (Steps 2 and 3 are accomplished by running 3000userlogin in a shell, as running an external command means the shell first creates a new process, as we have seen.  We are skipping 1.)&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Secure Shell, or ssh, is the standard method for accessing UNIX and UNIX-like systems remotely. It is a more secure replacement for older technologies such as [https://en.wikipedia.org/wiki/Berkeley_r-commands rsh] and [https://en.wikipedia.org/wiki/Telnet telnet].&lt;br /&gt;
&lt;br /&gt;
The standard implementation of ssh is [http://www.openssh.org openssh], a version of ssh that was originally created for [https://www.openbsd.org/ OpenBSD] but has been ported to other systems. OpenBSD has a reputation for being the most secure UNIX-like system around. It tends to be a bit harder to configure, have less support for current hardware, and have lower overall performance than Linux-based systems; however, it can be very competitive for some workloads.&lt;br /&gt;
&lt;br /&gt;
While ssh support password-based authentication, it is meant to be used with more secure forms of authentication. For example, ssh supports public key authentication, a type of authentication that makes use of [https://en.wikipedia.org/wiki/Public-key_cryptography public key cryptography]. Instead of a shared key (such as a password) that is known to both parties, with public key cryptography, keys come in two parts: a public part and a private part. The public part should be widely distributed, while the private part needs to be carefully secured.&lt;br /&gt;
&lt;br /&gt;
Public key cryptography can be used to send secret messages to anyone you can get the public key for. With digital signatures, public key cryptography can also be used to verify the authenticity and integrity of messages, so long as we know the public key of the originating party.&lt;br /&gt;
&lt;br /&gt;
With public key authentication, we use a key pair to authenticate rather than sending a password.&lt;br /&gt;
&lt;br /&gt;
A cool feature of public key authentication is it is possible to automatically log into a system once the appropriate private key is made available, thus giving us the convenience of passwordless logins with better security than passwords.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
===3000userlogin===&lt;br /&gt;
&lt;br /&gt;
When 3000userlogin is properly compiled and set up, you can run&lt;br /&gt;
&lt;br /&gt;
  ./3000userlogin someuser&lt;br /&gt;
&lt;br /&gt;
and you&#039;ll be logged in as &amp;quot;someuser&amp;quot;, assuming someuser exists.&lt;br /&gt;
&lt;br /&gt;
You can add a user with the adduser command.  For example, to create the user &amp;quot;someuser&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  sudo adduser someuser&lt;br /&gt;
&lt;br /&gt;
Note you&#039;ll have to answer several questions.&lt;br /&gt;
&lt;br /&gt;
If you just compile 3000userlogin normally, you won&#039;t be able to log in as anyone except the current user.  To compile and set up 3000userlogin, do the following:&lt;br /&gt;
&lt;br /&gt;
  gcc -O -Wall 3000userlogin.c -o 3000userlogin&lt;br /&gt;
  sudo chown root:root 3000userlogin&lt;br /&gt;
  sudo chmod u+s 3000userlogin&lt;br /&gt;
&lt;br /&gt;
The chown command makes the binary owned by root, and the chmod command makes it setuid.  Thus, when the program is execve&#039;d it will have an effective user ID of root (euid=0).&lt;br /&gt;
&lt;br /&gt;
Alternately, you can download the code and use the associated makefile to build by doing the following:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/tut4.tar.gz&lt;br /&gt;
  tar xzf tut4.tar.gz&lt;br /&gt;
  cd tut4&lt;br /&gt;
  sudo apt install make    # make isn&#039;t installed on the class VMs oops&lt;br /&gt;
  make&lt;br /&gt;
  make setuid&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Install the openssh-server package (note on openstack it will already be installed, but on a default Ubuntu desktop install it won&#039;t be):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Create a second user in the virtual machine named &amp;quot;other&amp;quot; (or any other name you wish to use):&lt;br /&gt;
&lt;br /&gt;
 sudo adduser other&lt;br /&gt;
&lt;br /&gt;
(Answer the subsequent prompts however you wish, just remember the password.)&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to log in to the &amp;quot;other&amp;quot; account using ssh:&lt;br /&gt;
&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to enter your password.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get a password prompt, password authentication has probably been disabled.  (Password authentication has been disabled on the openstack VMs.)  To enable it, do the following&lt;br /&gt;
&lt;br /&gt;
  sudo nano /etc/ssh/sshd_config    (or vi, or emacs)&lt;br /&gt;
&lt;br /&gt;
In the editor change the line &amp;quot;PasswordAuthentication no&amp;quot; to &amp;quot;PasswordAuthentication yes&amp;quot;.  Then, to restart sshd:&lt;br /&gt;
&lt;br /&gt;
  sudo service sshd restart&lt;br /&gt;
&lt;br /&gt;
Be sure to change it back after you&#039;ve set up public key authentication!&lt;br /&gt;
&lt;br /&gt;
===Public key authentication===&lt;br /&gt;
&lt;br /&gt;
Create a public key file for your account (as user student, ubuntu, or your personal account):&lt;br /&gt;
&lt;br /&gt;
 ssh-keygen&lt;br /&gt;
&lt;br /&gt;
(Accept the default filename and choose at least a simple passphrase.)&lt;br /&gt;
&lt;br /&gt;
You just created a certificate!  (A certificate is just a public key with metadata.)&lt;br /&gt;
&lt;br /&gt;
Copy the key to the other account:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; authorized_keys&lt;br /&gt;
 scp authorized_keys other@localhost:.&lt;br /&gt;
 rm authorized_keys&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
 (as user other)&lt;br /&gt;
 mkdir ~/.ssh (if it doesn&#039;t exist already)&lt;br /&gt;
 chmod 700 ~/.ssh  (make it private)&lt;br /&gt;
 mv ~/authorized_keys ~/.ssh&lt;br /&gt;
 chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
Now you can log in to user other by typing in the passphrase you used to lock the key you generated.&lt;br /&gt;
&lt;br /&gt;
To avoid entering this passphrase every time, you can give it to the authentication agent (generally, ssh-agent) that was started when you logged in:&lt;br /&gt;
&lt;br /&gt;
  ssh-add&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
# Compile and setup 3000userlogin as described above.  Create a new user account.  Verify that you can use 3000userlogin to login as the new user without typing the password of the new user.&lt;br /&gt;
# What is returned as the user&#039;s password by getpwnam()?  Is this what you expected?&lt;br /&gt;
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user, running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set).  Also check to see what happens when you set the setgid bit (with different group IDs on the file).&lt;br /&gt;
# Why does 3000userlogin change its gid before changing its uid?  What happens if you switch the order of these operations?&lt;br /&gt;
# Make 3000userlogin use the shell that is specified in the user&#039;s password entry.  Check by making a new user and setting its shell to a new shell and then see if that new shell runs when you run 3000userlogin.  You should change a user&#039;s shell with the chsh command, run as that user.&lt;br /&gt;
# Can you set 3000shell to be a user&#039;s default shell?  What changes do you have to make for chsh to accept 3000shell?  Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it?&lt;br /&gt;
# Does a user&#039;s default shell have to be a regular shell?  Could it instead be an arbitrary program?  How do you know?&lt;br /&gt;
# How important is each of the environment variables that is set by 3000userlogin?  Are these the only environment variables that are set after you successfully login?&lt;br /&gt;
# Note that 3000userlogin uses environ not envp (as an argument to main) to access environment variables.  Why not use envp?  (Try changing the code to use envp and see what happens.)&lt;br /&gt;
# Setup password-less login to your local system between the student and other account (or any two other accounts), following the above instructions.  Note that the &amp;quot;local&amp;quot; account is the one you are running the ssh command on.&lt;br /&gt;
# Setup password-less login to access.scs.carleton.ca, following the instructions above.&lt;br /&gt;
# Secure shell can be used to directly run a command on another program rather than the default shell.  For example, try &amp;quot;ssh student@localhost bc -l&amp;quot; and see that bc is run.  When you do this, does ssh directly run the specified command or does it first run a shell and have the shell run the command?  Use opensnoop.bt or execsnoop.bt to verify.&lt;br /&gt;
# What files in /etc does bash access when you login via 3000userlogin?  How does this compare to what bash opens when you log in via ssh?&lt;br /&gt;
# &#039;&#039;&#039;(Optional):&#039;&#039;&#039; Prompt for the user&#039;s password before logging the user in.  To do this, you&#039;ll need to get the right password hash and then figure out how to hash the entered password to check if it matches.  See online guides about [https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils how passwords are stored on Linux] for help.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2021f/code/3000userlogin.tar.gz Download code for this tutorial (3000userlogin.c and Makefile)]&lt;br /&gt;
&lt;br /&gt;
===3000userlogin.c===&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/3000userlogin.c Download 3000userlogin.c]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000userlogin.c */&lt;br /&gt;
/* version 0.1 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        char *shell_argv[3];&lt;br /&gt;
        char *username;&lt;br /&gt;
        extern char **environ;&lt;br /&gt;
        struct passwd *pw_entry;&lt;br /&gt;
                &lt;br /&gt;
        if (argc &amp;lt; 2) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Usage: %s &amp;lt;username&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
                exit(-1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;uid=%d, euid=%d, gid=%d, egid=%d\n&amp;quot;,&lt;br /&gt;
               getuid(), geteuid(), getgid(), getegid());&lt;br /&gt;
&lt;br /&gt;
        username = argv[1];&lt;br /&gt;
        &lt;br /&gt;
        pw_entry = getpwnam(username);&lt;br /&gt;
        if (pw_entry == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Could not find user %s.\n&amp;quot;, username);&lt;br /&gt;
                exit(-2);&lt;br /&gt;
        }&lt;br /&gt;
                       &lt;br /&gt;
        result = setgid(pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to gid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
                exit(-3);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = setuid(pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to uid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
                exit(-4);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = chdir(pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to home dir %s\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
                exit(-5);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        shell_argv[0] = &amp;quot;bash&amp;quot;;&lt;br /&gt;
        shell_argv[1] = &amp;quot;--login&amp;quot;;&lt;br /&gt;
        shell_argv[2] = NULL;&lt;br /&gt;
&lt;br /&gt;
        clearenv();&lt;br /&gt;
        setenv(&amp;quot;USERNAME&amp;quot;, pw_entry-&amp;gt;pw_name, 1);&lt;br /&gt;
        setenv(&amp;quot;PATH&amp;quot;, &amp;quot;/usr/bin:/bin&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;SHELL&amp;quot;, &amp;quot;/bin/bash&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;HOME&amp;quot;, pw_entry-&amp;gt;pw_dir, 1);&lt;br /&gt;
        setenv(&amp;quot;COMP3000&amp;quot;, &amp;quot;yes&amp;quot;, 1);&lt;br /&gt;
        &lt;br /&gt;
        execve(&amp;quot;/bin/bash&amp;quot;, shell_argv, environ);&lt;br /&gt;
     &lt;br /&gt;
        fprintf(stderr, &amp;quot;Failed to exec bash\n&amp;quot;);&lt;br /&gt;
        return -6;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Makefile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot; line&amp;gt;&lt;br /&gt;
.PHONY: setuid&lt;br /&gt;
&lt;br /&gt;
3000userlogin: 3000userlogin.c&lt;br /&gt;
	gcc -Wall -O 3000userlogin.c -o 3000userlogin&lt;br /&gt;
&lt;br /&gt;
setuid: 3000userlogin&lt;br /&gt;
	@echo &amp;quot;The following changes ownership to root, group to root, and sets the setuid bit on 3000userlogin:&amp;quot;&lt;br /&gt;
	sudo chown root:root 3000userlogin &amp;amp;&amp;amp; sudo chmod u+s 3000userlogin&lt;br /&gt;
	@echo &amp;quot;3000userlogin is now setuid root!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25184</id>
		<title>Operating Systems 2026F: Tutorial 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25184"/>
		<updated>2026-10-04T19:07:29Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* File Permissions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have been allocated to the current process.&lt;br /&gt;
&lt;br /&gt;
A process is an abstraction over the limited access of the CPU&#039;s user mode. All processes run in user mode. While kernel code can be doing work on behalf of a specific process, properly speaking no kernel code is in a process. Instead, the kernel implements the process abstraction.&lt;br /&gt;
&lt;br /&gt;
The kernel, however, does not treat all processes the same. The kernel allows some processes to do more than others depending upon the user and group of the process. We can see what access a process has by looking at the permissions associated with files.&lt;br /&gt;
&lt;br /&gt;
Most users have limited access. One user, &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (with user ID of 0), has as much access as is possible from a process. The kernel will even allow the root process to modify how the kernel operates. Processes running as root are still just processes, though, and any access that the kernel gives to such processes is at the discretion of the kernel. (In fact, there are setups which limit the privileges of the root user.)&lt;br /&gt;
&lt;br /&gt;
===File Permissions===&lt;br /&gt;
&lt;br /&gt;
A process&#039; permission to access files in UNIX is determined by the user and group associated with that process. When a person logs in, their initial process is given the user and group associated with their account. All child processes of that initial login process inherit the same user and group.&lt;br /&gt;
&lt;br /&gt;
A user can belong to multiple groups but a process only belongs to one group at a time. (There are ways to change the group associated with a process.) A file is always owned by someone and is always associated with a group.  All files on the UNIX file system (including directories and other special files) have three different sets of permissions:&lt;br /&gt;
* owner permissions&lt;br /&gt;
* group permissions&lt;br /&gt;
* other permissions&lt;br /&gt;
Each of these have read, write, and/or execute permissions along with some other special permissions.&lt;br /&gt;
&lt;br /&gt;
One special permission is the &#039;&#039;setuid&#039;&#039; bit. When an executable has this bit set, the process will run as the user who owns that executable (rather than as the user associated with the process that did the execve). The setuid bit is particularly important when a file is owned by root, as it gives us a way for regular users to escape the bounds of normal permissions. We will see the setuid root bit in action in this tutorial.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ls&amp;lt;/tt&amp;gt; command with the &amp;lt;tt&amp;gt;-l&amp;lt;/tt&amp;gt; option can be used to show both the permissions of a file as well as the owner and group associated with the file.  Permissions are listed first, followed by the owner and the group.&lt;br /&gt;
&lt;br /&gt;
===Logging in to a UNIX system===&lt;br /&gt;
&lt;br /&gt;
In order to log in to a UNIX system (Linux or otherwise), the following steps must occur (potentially not in this order).&lt;br /&gt;
&lt;br /&gt;
# The user must authenticate themselves, proving their identity and that they are allowed to access the system.  By default this is done through a username and password.&lt;br /&gt;
# A new process, U, should be created for the authenticated user.&lt;br /&gt;
# The login program must establish communication with the user via some communications channel.  Normally this channel will be a device.  Standard in, out, and error for U should be connected to this device.&lt;br /&gt;
# U changes uid and gid to that of the new user.&lt;br /&gt;
# U sets up other aspects of the user&#039;s context (mainly setting key environment variables).&lt;br /&gt;
# U does an execve of the user&#039;s chosen shell.&lt;br /&gt;
&lt;br /&gt;
[[#Code|3000userlogin]] is a basic implementation of steps 4-6.   (Steps 2 and 3 are accomplished by running 3000userlogin in a shell, as running an external command means the shell first creates a new process, as we have seen.  We are skipping 1.)&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Secure Shell, or ssh, is the standard method for accessing UNIX and UNIX-like systems remotely. It is a more secure replacement for older technologies such as [https://en.wikipedia.org/wiki/Berkeley_r-commands rsh] and [https://en.wikipedia.org/wiki/Telnet telnet].&lt;br /&gt;
&lt;br /&gt;
The standard implementation of ssh is [http://www.openssh.org openssh], a version of ssh that was originally created for [https://www.openbsd.org/ OpenBSD] but has been ported to other systems. OpenBSD has a reputation for being the most secure UNIX-like system around. It tends to be a bit harder to configure, have less support for current hardware, and have lower overall performance than Linux-based systems; however, it can be very competitive for some workloads.&lt;br /&gt;
&lt;br /&gt;
While ssh support password-based authentication, it is meant to be used with more secure forms of authentication. For example, ssh supports public key authentication, a type of authentication that makes use of [https://en.wikipedia.org/wiki/Public-key_cryptography public key cryptography]. Instead of a shared key (such as a password) that is known to both parties, with public key cryptography, keys come in two parts: a public part and a private part. The public part should be widely distributed, while the private part needs to be carefully secured.&lt;br /&gt;
&lt;br /&gt;
Public key cryptography can be used to send secret messages to anyone you can get the public key for. With digital signatures, public key cryptography can also be used to verify the authenticity and integrity of messages, so long as we know the public key of the originating party.&lt;br /&gt;
&lt;br /&gt;
With public key authentication, we use a key pair to authenticate rather than sending a password.&lt;br /&gt;
&lt;br /&gt;
A cool feature of public key authentication is it is possible to automatically log into a system once the appropriate private key is made available, thus giving us the convenience of passwordless logins with better security than passwords.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
===3000userlogin===&lt;br /&gt;
&lt;br /&gt;
When 3000userlogin is properly compiled and set up, you can run&lt;br /&gt;
&lt;br /&gt;
  ./3000userlogin someuser&lt;br /&gt;
&lt;br /&gt;
and you&#039;ll be logged in as &amp;quot;someuser&amp;quot;, assuming someuser exists.&lt;br /&gt;
&lt;br /&gt;
You can add a user with the adduser command.  For example, to create the user &amp;quot;someuser&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  sudo adduser someuser&lt;br /&gt;
&lt;br /&gt;
Note you&#039;ll have to answer several questions.&lt;br /&gt;
&lt;br /&gt;
If you just compile 3000userlogin normally, you won&#039;t be able to log in as anyone except the current user.  To compile and set up 3000userlogin, do the following:&lt;br /&gt;
&lt;br /&gt;
  gcc -O -Wall 3000userlogin.c -o 3000userlogin&lt;br /&gt;
  sudo chown root:root 3000userlogin&lt;br /&gt;
  sudo chmod u+s 3000userlogin&lt;br /&gt;
&lt;br /&gt;
The chown command makes the binary owned by root, and the chmod command makes it setuid.  Thus, when the program is execve&#039;d it will have an effective user ID of root (euid=0).&lt;br /&gt;
&lt;br /&gt;
Alternately, you can download the code and use the associated makefile to build by doing the following:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/tut4.tar.gz&lt;br /&gt;
  tar xzf tut4.tar.gz&lt;br /&gt;
  cd tut4&lt;br /&gt;
  make&lt;br /&gt;
  make setuid&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Install the openssh-server package (note on openstack it will already be installed, but on a default Ubuntu desktop install it won&#039;t be):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Create a second user in the virtual machine named &amp;quot;other&amp;quot; (or any other name you wish to use):&lt;br /&gt;
&lt;br /&gt;
 sudo adduser other&lt;br /&gt;
&lt;br /&gt;
(Answer the subsequent prompts however you wish, just remember the password.)&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to log in to the &amp;quot;other&amp;quot; account using ssh:&lt;br /&gt;
&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to enter your password.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get a password prompt, password authentication has probably been disabled.  (Password authentication has been disabled on the openstack VMs.)  To enable it, do the following&lt;br /&gt;
&lt;br /&gt;
  sudo nano /etc/ssh/sshd_config    (or vi, or emacs)&lt;br /&gt;
&lt;br /&gt;
In the editor change the line &amp;quot;PasswordAuthentication no&amp;quot; to &amp;quot;PasswordAuthentication yes&amp;quot;.  Then, to restart sshd:&lt;br /&gt;
&lt;br /&gt;
  sudo service sshd restart&lt;br /&gt;
&lt;br /&gt;
Be sure to change it back after you&#039;ve set up public key authentication!&lt;br /&gt;
&lt;br /&gt;
===Public key authentication===&lt;br /&gt;
&lt;br /&gt;
Create a public key file for your account (as user student, ubuntu, or your personal account):&lt;br /&gt;
&lt;br /&gt;
 ssh-keygen&lt;br /&gt;
&lt;br /&gt;
(Accept the default filename and choose at least a simple passphrase.)&lt;br /&gt;
&lt;br /&gt;
You just created a certificate!  (A certificate is just a public key with metadata.)&lt;br /&gt;
&lt;br /&gt;
Copy the key to the other account:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; authorized_keys&lt;br /&gt;
 scp authorized_keys other@localhost:.&lt;br /&gt;
 rm authorized_keys&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
 (as user other)&lt;br /&gt;
 mkdir ~/.ssh (if it doesn&#039;t exist already)&lt;br /&gt;
 chmod 700 ~/.ssh  (make it private)&lt;br /&gt;
 mv ~/authorized_keys ~/.ssh&lt;br /&gt;
 chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
Now you can log in to user other by typing in the passphrase you used to lock the key you generated.&lt;br /&gt;
&lt;br /&gt;
To avoid entering this passphrase every time, you can give it to the authentication agent (generally, ssh-agent) that was started when you logged in:&lt;br /&gt;
&lt;br /&gt;
  ssh-add&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
# Compile and setup 3000userlogin as described above.  Create a new user account.  Verify that you can use 3000userlogin to login as the new user without typing the password of the new user.&lt;br /&gt;
# What is returned as the user&#039;s password by getpwnam()?  Is this what you expected?&lt;br /&gt;
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user, running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set).  Also check to see what happens when you set the setgid bit (with different group IDs on the file).&lt;br /&gt;
# Why does 3000userlogin change its gid before changing its uid?  What happens if you switch the order of these operations?&lt;br /&gt;
# Make 3000userlogin use the shell that is specified in the user&#039;s password entry.  Check by making a new user and setting its shell to a new shell and then see if that new shell runs when you run 3000userlogin.  You should change a user&#039;s shell with the chsh command, run as that user.&lt;br /&gt;
# Can you set 3000shell to be a user&#039;s default shell?  What changes do you have to make for chsh to accept 3000shell?  Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it?&lt;br /&gt;
# Does a user&#039;s default shell have to be a regular shell?  Could it instead be an arbitrary program?  How do you know?&lt;br /&gt;
# How important is each of the environment variables that is set by 3000userlogin?  Are these the only environment variables that are set after you successfully login?&lt;br /&gt;
# Note that 3000userlogin uses environ not envp (as an argument to main) to access environment variables.  Why not use envp?  (Try changing the code to use envp and see what happens.)&lt;br /&gt;
# Setup password-less login to your local system between the student and other account (or any two other accounts), following the above instructions.  Note that the &amp;quot;local&amp;quot; account is the one you are running the ssh command on.&lt;br /&gt;
# Setup password-less login to access.scs.carleton.ca, following the instructions above.&lt;br /&gt;
# Secure shell can be used to directly run a command on another program rather than the default shell.  For example, try &amp;quot;ssh student@localhost bc -l&amp;quot; and see that bc is run.  When you do this, does ssh directly run the specified command or does it first run a shell and have the shell run the command?  Use opensnoop.bt or execsnoop.bt to verify.&lt;br /&gt;
# What files in /etc does bash access when you login via 3000userlogin?  How does this compare to what bash opens when you log in via ssh?&lt;br /&gt;
# &#039;&#039;&#039;(Optional):&#039;&#039;&#039; Prompt for the user&#039;s password before logging the user in.  To do this, you&#039;ll need to get the right password hash and then figure out how to hash the entered password to check if it matches.  See online guides about [https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils how passwords are stored on Linux] for help.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2021f/code/3000userlogin.tar.gz Download code for this tutorial (3000userlogin.c and Makefile)]&lt;br /&gt;
&lt;br /&gt;
===3000userlogin.c===&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/3000userlogin.c Download 3000userlogin.c]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000userlogin.c */&lt;br /&gt;
/* version 0.1 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        char *shell_argv[3];&lt;br /&gt;
        char *username;&lt;br /&gt;
        extern char **environ;&lt;br /&gt;
        struct passwd *pw_entry;&lt;br /&gt;
                &lt;br /&gt;
        if (argc &amp;lt; 2) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Usage: %s &amp;lt;username&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
                exit(-1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;uid=%d, euid=%d, gid=%d, egid=%d\n&amp;quot;,&lt;br /&gt;
               getuid(), geteuid(), getgid(), getegid());&lt;br /&gt;
&lt;br /&gt;
        username = argv[1];&lt;br /&gt;
        &lt;br /&gt;
        pw_entry = getpwnam(username);&lt;br /&gt;
        if (pw_entry == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Could not find user %s.\n&amp;quot;, username);&lt;br /&gt;
                exit(-2);&lt;br /&gt;
        }&lt;br /&gt;
                       &lt;br /&gt;
        result = setgid(pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to gid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
                exit(-3);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = setuid(pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to uid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
                exit(-4);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = chdir(pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to home dir %s\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
                exit(-5);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        shell_argv[0] = &amp;quot;bash&amp;quot;;&lt;br /&gt;
        shell_argv[1] = &amp;quot;--login&amp;quot;;&lt;br /&gt;
        shell_argv[2] = NULL;&lt;br /&gt;
&lt;br /&gt;
        clearenv();&lt;br /&gt;
        setenv(&amp;quot;USERNAME&amp;quot;, pw_entry-&amp;gt;pw_name, 1);&lt;br /&gt;
        setenv(&amp;quot;PATH&amp;quot;, &amp;quot;/usr/bin:/bin&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;SHELL&amp;quot;, &amp;quot;/bin/bash&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;HOME&amp;quot;, pw_entry-&amp;gt;pw_dir, 1);&lt;br /&gt;
        setenv(&amp;quot;COMP3000&amp;quot;, &amp;quot;yes&amp;quot;, 1);&lt;br /&gt;
        &lt;br /&gt;
        execve(&amp;quot;/bin/bash&amp;quot;, shell_argv, environ);&lt;br /&gt;
     &lt;br /&gt;
        fprintf(stderr, &amp;quot;Failed to exec bash\n&amp;quot;);&lt;br /&gt;
        return -6;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Makefile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot; line&amp;gt;&lt;br /&gt;
.PHONY: setuid&lt;br /&gt;
&lt;br /&gt;
3000userlogin: 3000userlogin.c&lt;br /&gt;
	gcc -Wall -O 3000userlogin.c -o 3000userlogin&lt;br /&gt;
&lt;br /&gt;
setuid: 3000userlogin&lt;br /&gt;
	@echo &amp;quot;The following changes ownership to root, group to root, and sets the setuid bit on 3000userlogin:&amp;quot;&lt;br /&gt;
	sudo chown root:root 3000userlogin &amp;amp;&amp;amp; sudo chmod u+s 3000userlogin&lt;br /&gt;
	@echo &amp;quot;3000userlogin is now setuid root!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25183</id>
		<title>Operating Systems 2026F: Tutorial 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25183"/>
		<updated>2026-10-04T19:04:07Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Background */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have been allocated to the current process.&lt;br /&gt;
&lt;br /&gt;
A process is an abstraction over the limited access of the CPU&#039;s user mode. All processes run in user mode. While kernel code can be doing work on behalf of a specific process, properly speaking no kernel code is in a process. Instead, the kernel implements the process abstraction.&lt;br /&gt;
&lt;br /&gt;
The kernel, however, does not treat all processes the same. The kernel allows some processes to do more than others depending upon the user and group of the process. We can see what access a process has by looking at the permissions associated with files.&lt;br /&gt;
&lt;br /&gt;
Most users have limited access. One user, &amp;lt;tt&amp;gt;root&amp;lt;/tt&amp;gt; (with user ID of 0), has as much access as is possible from a process. The kernel will even allow the root process to modify how the kernel operates. Processes running as root are still just processes, though, and any access that the kernel gives to such processes is at the discretion of the kernel. (In fact, there are setups which limit the privileges of the root user.)&lt;br /&gt;
&lt;br /&gt;
===File Permissions===&lt;br /&gt;
&lt;br /&gt;
A process&#039; permission to access files in UNIX is determined by the user and group associated with that process. When a person logs in, their initial process is given the user and group associated with their account. All child processes of that initial login process inherit the same user and group.&lt;br /&gt;
&lt;br /&gt;
A user can belong to multiple groups but a process only belongs to one group at a time. (There are ways to change the group associated with a process.) A file is always owned by someone and is always associated with a group.  All files on the UNIX file system (including directories and other special files) have three different sets of permissions:&lt;br /&gt;
* owner permissions&lt;br /&gt;
* group permissions&lt;br /&gt;
* other permissions&lt;br /&gt;
Each of these have read, write, and/or execute permissions along with some other special permissions we&#039;ll discuss later.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ls&amp;lt;/tt&amp;gt; command with the &amp;lt;tt&amp;gt;-l&amp;lt;/tt&amp;gt; option can be used to show both the permissions of a file as well as the owner and group associated with the file.  Permissions are listed first, followed by the owner and the group.&lt;br /&gt;
&lt;br /&gt;
===Logging in to a UNIX system===&lt;br /&gt;
&lt;br /&gt;
In order to log in to a UNIX system (Linux or otherwise), the following steps must occur (potentially not in this order).&lt;br /&gt;
&lt;br /&gt;
# The user must authenticate themselves, proving their identity and that they are allowed to access the system.  By default this is done through a username and password.&lt;br /&gt;
# A new process, U, should be created for the authenticated user.&lt;br /&gt;
# The login program must establish communication with the user via some communications channel.  Normally this channel will be a device.  Standard in, out, and error for U should be connected to this device.&lt;br /&gt;
# U changes uid and gid to that of the new user.&lt;br /&gt;
# U sets up other aspects of the user&#039;s context (mainly setting key environment variables).&lt;br /&gt;
# U does an execve of the user&#039;s chosen shell.&lt;br /&gt;
&lt;br /&gt;
[[#Code|3000userlogin]] is a basic implementation of steps 4-6.   (Steps 2 and 3 are accomplished by running 3000userlogin in a shell, as running an external command means the shell first creates a new process, as we have seen.  We are skipping 1.)&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Secure Shell, or ssh, is the standard method for accessing UNIX and UNIX-like systems remotely. It is a more secure replacement for older technologies such as [https://en.wikipedia.org/wiki/Berkeley_r-commands rsh] and [https://en.wikipedia.org/wiki/Telnet telnet].&lt;br /&gt;
&lt;br /&gt;
The standard implementation of ssh is [http://www.openssh.org openssh], a version of ssh that was originally created for [https://www.openbsd.org/ OpenBSD] but has been ported to other systems. OpenBSD has a reputation for being the most secure UNIX-like system around. It tends to be a bit harder to configure, have less support for current hardware, and have lower overall performance than Linux-based systems; however, it can be very competitive for some workloads.&lt;br /&gt;
&lt;br /&gt;
While ssh support password-based authentication, it is meant to be used with more secure forms of authentication. For example, ssh supports public key authentication, a type of authentication that makes use of [https://en.wikipedia.org/wiki/Public-key_cryptography public key cryptography]. Instead of a shared key (such as a password) that is known to both parties, with public key cryptography, keys come in two parts: a public part and a private part. The public part should be widely distributed, while the private part needs to be carefully secured.&lt;br /&gt;
&lt;br /&gt;
Public key cryptography can be used to send secret messages to anyone you can get the public key for. With digital signatures, public key cryptography can also be used to verify the authenticity and integrity of messages, so long as we know the public key of the originating party.&lt;br /&gt;
&lt;br /&gt;
With public key authentication, we use a key pair to authenticate rather than sending a password.&lt;br /&gt;
&lt;br /&gt;
A cool feature of public key authentication is it is possible to automatically log into a system once the appropriate private key is made available, thus giving us the convenience of passwordless logins with better security than passwords.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
===3000userlogin===&lt;br /&gt;
&lt;br /&gt;
When 3000userlogin is properly compiled and set up, you can run&lt;br /&gt;
&lt;br /&gt;
  ./3000userlogin someuser&lt;br /&gt;
&lt;br /&gt;
and you&#039;ll be logged in as &amp;quot;someuser&amp;quot;, assuming someuser exists.&lt;br /&gt;
&lt;br /&gt;
You can add a user with the adduser command.  For example, to create the user &amp;quot;someuser&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  sudo adduser someuser&lt;br /&gt;
&lt;br /&gt;
Note you&#039;ll have to answer several questions.&lt;br /&gt;
&lt;br /&gt;
If you just compile 3000userlogin normally, you won&#039;t be able to log in as anyone except the current user.  To compile and set up 3000userlogin, do the following:&lt;br /&gt;
&lt;br /&gt;
  gcc -O -Wall 3000userlogin.c -o 3000userlogin&lt;br /&gt;
  sudo chown root:root 3000userlogin&lt;br /&gt;
  sudo chmod u+s 3000userlogin&lt;br /&gt;
&lt;br /&gt;
The chown command makes the binary owned by root, and the chmod command makes it setuid.  Thus, when the program is execve&#039;d it will have an effective user ID of root (euid=0).&lt;br /&gt;
&lt;br /&gt;
Alternately, you can download the code and use the associated makefile to build by doing the following:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/tut4.tar.gz&lt;br /&gt;
  tar xzf tut4.tar.gz&lt;br /&gt;
  cd tut4&lt;br /&gt;
  make&lt;br /&gt;
  make setuid&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Install the openssh-server package (note on openstack it will already be installed, but on a default Ubuntu desktop install it won&#039;t be):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Create a second user in the virtual machine named &amp;quot;other&amp;quot; (or any other name you wish to use):&lt;br /&gt;
&lt;br /&gt;
 sudo adduser other&lt;br /&gt;
&lt;br /&gt;
(Answer the subsequent prompts however you wish, just remember the password.)&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to log in to the &amp;quot;other&amp;quot; account using ssh:&lt;br /&gt;
&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to enter your password.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get a password prompt, password authentication has probably been disabled.  (Password authentication has been disabled on the openstack VMs.)  To enable it, do the following&lt;br /&gt;
&lt;br /&gt;
  sudo nano /etc/ssh/sshd_config    (or vi, or emacs)&lt;br /&gt;
&lt;br /&gt;
In the editor change the line &amp;quot;PasswordAuthentication no&amp;quot; to &amp;quot;PasswordAuthentication yes&amp;quot;.  Then, to restart sshd:&lt;br /&gt;
&lt;br /&gt;
  sudo service sshd restart&lt;br /&gt;
&lt;br /&gt;
Be sure to change it back after you&#039;ve set up public key authentication!&lt;br /&gt;
&lt;br /&gt;
===Public key authentication===&lt;br /&gt;
&lt;br /&gt;
Create a public key file for your account (as user student, ubuntu, or your personal account):&lt;br /&gt;
&lt;br /&gt;
 ssh-keygen&lt;br /&gt;
&lt;br /&gt;
(Accept the default filename and choose at least a simple passphrase.)&lt;br /&gt;
&lt;br /&gt;
You just created a certificate!  (A certificate is just a public key with metadata.)&lt;br /&gt;
&lt;br /&gt;
Copy the key to the other account:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; authorized_keys&lt;br /&gt;
 scp authorized_keys other@localhost:.&lt;br /&gt;
 rm authorized_keys&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
 (as user other)&lt;br /&gt;
 mkdir ~/.ssh (if it doesn&#039;t exist already)&lt;br /&gt;
 chmod 700 ~/.ssh  (make it private)&lt;br /&gt;
 mv ~/authorized_keys ~/.ssh&lt;br /&gt;
 chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
Now you can log in to user other by typing in the passphrase you used to lock the key you generated.&lt;br /&gt;
&lt;br /&gt;
To avoid entering this passphrase every time, you can give it to the authentication agent (generally, ssh-agent) that was started when you logged in:&lt;br /&gt;
&lt;br /&gt;
  ssh-add&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
# Compile and setup 3000userlogin as described above.  Create a new user account.  Verify that you can use 3000userlogin to login as the new user without typing the password of the new user.&lt;br /&gt;
# What is returned as the user&#039;s password by getpwnam()?  Is this what you expected?&lt;br /&gt;
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user, running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set).  Also check to see what happens when you set the setgid bit (with different group IDs on the file).&lt;br /&gt;
# Why does 3000userlogin change its gid before changing its uid?  What happens if you switch the order of these operations?&lt;br /&gt;
# Make 3000userlogin use the shell that is specified in the user&#039;s password entry.  Check by making a new user and setting its shell to a new shell and then see if that new shell runs when you run 3000userlogin.  You should change a user&#039;s shell with the chsh command, run as that user.&lt;br /&gt;
# Can you set 3000shell to be a user&#039;s default shell?  What changes do you have to make for chsh to accept 3000shell?  Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it?&lt;br /&gt;
# Does a user&#039;s default shell have to be a regular shell?  Could it instead be an arbitrary program?  How do you know?&lt;br /&gt;
# How important is each of the environment variables that is set by 3000userlogin?  Are these the only environment variables that are set after you successfully login?&lt;br /&gt;
# Note that 3000userlogin uses environ not envp (as an argument to main) to access environment variables.  Why not use envp?  (Try changing the code to use envp and see what happens.)&lt;br /&gt;
# Setup password-less login to your local system between the student and other account (or any two other accounts), following the above instructions.  Note that the &amp;quot;local&amp;quot; account is the one you are running the ssh command on.&lt;br /&gt;
# Setup password-less login to access.scs.carleton.ca, following the instructions above.&lt;br /&gt;
# Secure shell can be used to directly run a command on another program rather than the default shell.  For example, try &amp;quot;ssh student@localhost bc -l&amp;quot; and see that bc is run.  When you do this, does ssh directly run the specified command or does it first run a shell and have the shell run the command?  Use opensnoop.bt or execsnoop.bt to verify.&lt;br /&gt;
# What files in /etc does bash access when you login via 3000userlogin?  How does this compare to what bash opens when you log in via ssh?&lt;br /&gt;
# &#039;&#039;&#039;(Optional):&#039;&#039;&#039; Prompt for the user&#039;s password before logging the user in.  To do this, you&#039;ll need to get the right password hash and then figure out how to hash the entered password to check if it matches.  See online guides about [https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils how passwords are stored on Linux] for help.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2021f/code/3000userlogin.tar.gz Download code for this tutorial (3000userlogin.c and Makefile)]&lt;br /&gt;
&lt;br /&gt;
===3000userlogin.c===&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/3000userlogin.c Download 3000userlogin.c]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000userlogin.c */&lt;br /&gt;
/* version 0.1 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        char *shell_argv[3];&lt;br /&gt;
        char *username;&lt;br /&gt;
        extern char **environ;&lt;br /&gt;
        struct passwd *pw_entry;&lt;br /&gt;
                &lt;br /&gt;
        if (argc &amp;lt; 2) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Usage: %s &amp;lt;username&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
                exit(-1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;uid=%d, euid=%d, gid=%d, egid=%d\n&amp;quot;,&lt;br /&gt;
               getuid(), geteuid(), getgid(), getegid());&lt;br /&gt;
&lt;br /&gt;
        username = argv[1];&lt;br /&gt;
        &lt;br /&gt;
        pw_entry = getpwnam(username);&lt;br /&gt;
        if (pw_entry == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Could not find user %s.\n&amp;quot;, username);&lt;br /&gt;
                exit(-2);&lt;br /&gt;
        }&lt;br /&gt;
                       &lt;br /&gt;
        result = setgid(pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to gid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
                exit(-3);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = setuid(pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to uid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
                exit(-4);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = chdir(pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to home dir %s\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
                exit(-5);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        shell_argv[0] = &amp;quot;bash&amp;quot;;&lt;br /&gt;
        shell_argv[1] = &amp;quot;--login&amp;quot;;&lt;br /&gt;
        shell_argv[2] = NULL;&lt;br /&gt;
&lt;br /&gt;
        clearenv();&lt;br /&gt;
        setenv(&amp;quot;USERNAME&amp;quot;, pw_entry-&amp;gt;pw_name, 1);&lt;br /&gt;
        setenv(&amp;quot;PATH&amp;quot;, &amp;quot;/usr/bin:/bin&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;SHELL&amp;quot;, &amp;quot;/bin/bash&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;HOME&amp;quot;, pw_entry-&amp;gt;pw_dir, 1);&lt;br /&gt;
        setenv(&amp;quot;COMP3000&amp;quot;, &amp;quot;yes&amp;quot;, 1);&lt;br /&gt;
        &lt;br /&gt;
        execve(&amp;quot;/bin/bash&amp;quot;, shell_argv, environ);&lt;br /&gt;
     &lt;br /&gt;
        fprintf(stderr, &amp;quot;Failed to exec bash\n&amp;quot;);&lt;br /&gt;
        return -6;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Makefile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot; line&amp;gt;&lt;br /&gt;
.PHONY: setuid&lt;br /&gt;
&lt;br /&gt;
3000userlogin: 3000userlogin.c&lt;br /&gt;
	gcc -Wall -O 3000userlogin.c -o 3000userlogin&lt;br /&gt;
&lt;br /&gt;
setuid: 3000userlogin&lt;br /&gt;
	@echo &amp;quot;The following changes ownership to root, group to root, and sets the setuid bit on 3000userlogin:&amp;quot;&lt;br /&gt;
	sudo chown root:root 3000userlogin &amp;amp;&amp;amp; sudo chmod u+s 3000userlogin&lt;br /&gt;
	@echo &amp;quot;3000userlogin is now setuid root!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25182</id>
		<title>Operating Systems 2026F: Tutorial 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_4&amp;diff=25182"/>
		<updated>2026-10-04T19:01:09Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;&amp;#039;&amp;#039;&amp;#039;This tutorial is not yet finalized.&amp;#039;&amp;#039;&amp;#039;  In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.  ==Background==  In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have be...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial you will learn about permissions, accounts, how logging in works, and ssh.&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
In UNIX and UNIX-like systems like Linux, kernel code runs in supervisor mode (ring 0 on x86-64) and user code runs in user mode (ring 3 on x86-64). When the CPU is in supervisor mode, all system resources can be accessed; when the CPU is in user mode, only a limited set of resources can be used, namely those that have been allocated to the current process.&lt;br /&gt;
&lt;br /&gt;
A process is an abstraction over the limited access of the CPU&#039;s user mode. All processes run in user mode. While kernel code can be doing work on behalf of a specific process, properly speaking no kernel code is in a process. Instead, the kernel implements the process abstraction.&lt;br /&gt;
&lt;br /&gt;
The kernel, however, does not treat all processes the same. The kernel allows some processes to do more than others depending upon the user and group of the process. We can see what access a process has by looking at the permissions associated with files.&lt;br /&gt;
&lt;br /&gt;
===File Permissions===&lt;br /&gt;
&lt;br /&gt;
A process&#039; permission to access files in UNIX is determined by the user and group associated with that process. When a person logs in, their initial process is given the user and group associated with their account. All child processes of that initial login process inherit the same user and group.&lt;br /&gt;
&lt;br /&gt;
A user can belong to multiple groups but a process only belongs to one group at a time. (There are ways to change the group associated with a process.) A file is always owned by someone and is always associated with a group.  All files on the UNIX file system (including directories and other special files) have three different sets of permissions:&lt;br /&gt;
* owner permissions&lt;br /&gt;
* group permissions&lt;br /&gt;
* other permissions&lt;br /&gt;
Each of these have read, write, and/or execute permissions along with some other special permissions we&#039;ll discuss later.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;ls&amp;lt;/tt&amp;gt; command with the &amp;lt;tt&amp;gt;-l&amp;lt;/tt&amp;gt; option can be used to show both the permissions of a file as well as the owner and group associated with the file.  Permissions are listed first, followed by the owner and the group.&lt;br /&gt;
&lt;br /&gt;
===Logging in to a UNIX system===&lt;br /&gt;
&lt;br /&gt;
In order to log in to a UNIX system (Linux or otherwise), the following steps must occur (potentially not in this order).&lt;br /&gt;
&lt;br /&gt;
# The user must authenticate themselves, proving their identity and that they are allowed to access the system.  By default this is done through a username and password.&lt;br /&gt;
# A new process, U, should be created for the authenticated user.&lt;br /&gt;
# The login program must establish communication with the user via some communications channel.  Normally this channel will be a device.  Standard in, out, and error for U should be connected to this device.&lt;br /&gt;
# U changes uid and gid to that of the new user.&lt;br /&gt;
# U sets up other aspects of the user&#039;s context (mainly setting key environment variables).&lt;br /&gt;
# U does an execve of the user&#039;s chosen shell.&lt;br /&gt;
&lt;br /&gt;
[[#Code|3000userlogin]] is a basic implementation of steps 4-6.   (Steps 2 and 3 are accomplished by running 3000userlogin in a shell, as running an external command means the shell first creates a new process, as we have seen.  We are skipping 1.)&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Secure Shell, or ssh, is the standard method for accessing UNIX and UNIX-like systems remotely. It is a more secure replacement for older technologies such as [https://en.wikipedia.org/wiki/Berkeley_r-commands rsh] and [https://en.wikipedia.org/wiki/Telnet telnet].&lt;br /&gt;
&lt;br /&gt;
The standard implementation of ssh is [http://www.openssh.org openssh], a version of ssh that was originally created for [https://www.openbsd.org/ OpenBSD] but has been ported to other systems. OpenBSD has a reputation for being the most secure UNIX-like system around. It tends to be a bit harder to configure, have less support for current hardware, and have lower overall performance than Linux-based systems; however, it can be very competitive for some workloads.&lt;br /&gt;
&lt;br /&gt;
While ssh support password-based authentication, it is meant to be used with more secure forms of authentication. For example, ssh supports public key authentication, a type of authentication that makes use of [https://en.wikipedia.org/wiki/Public-key_cryptography public key cryptography]. Instead of a shared key (such as a password) that is known to both parties, with public key cryptography, keys come in two parts: a public part and a private part. The public part should be widely distributed, while the private part needs to be carefully secured.&lt;br /&gt;
&lt;br /&gt;
Public key cryptography can be used to send secret messages to anyone you can get the public key for. With digital signatures, public key cryptography can also be used to verify the authenticity and integrity of messages, so long as we know the public key of the originating party.&lt;br /&gt;
&lt;br /&gt;
With public key authentication, we use a key pair to authenticate rather than sending a password.&lt;br /&gt;
&lt;br /&gt;
A cool feature of public key authentication is it is possible to automatically log into a system once the appropriate private key is made available, thus giving us the convenience of passwordless logins with better security than passwords.&lt;br /&gt;
&lt;br /&gt;
==Setup==&lt;br /&gt;
&lt;br /&gt;
===3000userlogin===&lt;br /&gt;
&lt;br /&gt;
When 3000userlogin is properly compiled and set up, you can run&lt;br /&gt;
&lt;br /&gt;
  ./3000userlogin someuser&lt;br /&gt;
&lt;br /&gt;
and you&#039;ll be logged in as &amp;quot;someuser&amp;quot;, assuming someuser exists.&lt;br /&gt;
&lt;br /&gt;
You can add a user with the adduser command.  For example, to create the user &amp;quot;someuser&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
  sudo adduser someuser&lt;br /&gt;
&lt;br /&gt;
Note you&#039;ll have to answer several questions.&lt;br /&gt;
&lt;br /&gt;
If you just compile 3000userlogin normally, you won&#039;t be able to log in as anyone except the current user.  To compile and set up 3000userlogin, do the following:&lt;br /&gt;
&lt;br /&gt;
  gcc -O -Wall 3000userlogin.c -o 3000userlogin&lt;br /&gt;
  sudo chown root:root 3000userlogin&lt;br /&gt;
  sudo chmod u+s 3000userlogin&lt;br /&gt;
&lt;br /&gt;
The chown command makes the binary owned by root, and the chmod command makes it setuid.  Thus, when the program is execve&#039;d it will have an effective user ID of root (euid=0).&lt;br /&gt;
&lt;br /&gt;
Alternately, you can download the code and use the associated makefile to build by doing the following:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/tut4.tar.gz&lt;br /&gt;
  tar xzf tut4.tar.gz&lt;br /&gt;
  cd tut4&lt;br /&gt;
  make&lt;br /&gt;
  make setuid&lt;br /&gt;
&lt;br /&gt;
===SSH===&lt;br /&gt;
&lt;br /&gt;
Install the openssh-server package (note on openstack it will already be installed, but on a default Ubuntu desktop install it won&#039;t be):&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install openssh-server&lt;br /&gt;
&lt;br /&gt;
Create a second user in the virtual machine named &amp;quot;other&amp;quot; (or any other name you wish to use):&lt;br /&gt;
&lt;br /&gt;
 sudo adduser other&lt;br /&gt;
&lt;br /&gt;
(Answer the subsequent prompts however you wish, just remember the password.)&lt;br /&gt;
&lt;br /&gt;
At this point you should be able to log in to the &amp;quot;other&amp;quot; account using ssh:&lt;br /&gt;
&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
You&#039;ll have to enter your password.&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t get a password prompt, password authentication has probably been disabled.  (Password authentication has been disabled on the openstack VMs.)  To enable it, do the following&lt;br /&gt;
&lt;br /&gt;
  sudo nano /etc/ssh/sshd_config    (or vi, or emacs)&lt;br /&gt;
&lt;br /&gt;
In the editor change the line &amp;quot;PasswordAuthentication no&amp;quot; to &amp;quot;PasswordAuthentication yes&amp;quot;.  Then, to restart sshd:&lt;br /&gt;
&lt;br /&gt;
  sudo service sshd restart&lt;br /&gt;
&lt;br /&gt;
Be sure to change it back after you&#039;ve set up public key authentication!&lt;br /&gt;
&lt;br /&gt;
===Public key authentication===&lt;br /&gt;
&lt;br /&gt;
Create a public key file for your account (as user student, ubuntu, or your personal account):&lt;br /&gt;
&lt;br /&gt;
 ssh-keygen&lt;br /&gt;
&lt;br /&gt;
(Accept the default filename and choose at least a simple passphrase.)&lt;br /&gt;
&lt;br /&gt;
You just created a certificate!  (A certificate is just a public key with metadata.)&lt;br /&gt;
&lt;br /&gt;
Copy the key to the other account:&lt;br /&gt;
&lt;br /&gt;
 cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; authorized_keys&lt;br /&gt;
 scp authorized_keys other@localhost:.&lt;br /&gt;
 rm authorized_keys&lt;br /&gt;
 ssh other@localhost&lt;br /&gt;
&lt;br /&gt;
 (as user other)&lt;br /&gt;
 mkdir ~/.ssh (if it doesn&#039;t exist already)&lt;br /&gt;
 chmod 700 ~/.ssh  (make it private)&lt;br /&gt;
 mv ~/authorized_keys ~/.ssh&lt;br /&gt;
 chmod 600 ~/.ssh/authorized_keys&lt;br /&gt;
&lt;br /&gt;
Now you can log in to user other by typing in the passphrase you used to lock the key you generated.&lt;br /&gt;
&lt;br /&gt;
To avoid entering this passphrase every time, you can give it to the authentication agent (generally, ssh-agent) that was started when you logged in:&lt;br /&gt;
&lt;br /&gt;
  ssh-add&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
# Compile and setup 3000userlogin as described above.  Create a new user account.  Verify that you can use 3000userlogin to login as the new user without typing the password of the new user.&lt;br /&gt;
# What is returned as the user&#039;s password by getpwnam()?  Is this what you expected?&lt;br /&gt;
# Compare the uid, gid, euid, egid when running 3000userlogin as a regular user, running it setuid root, and running it as root (i.e., running it from a root shell without the setuid bit set).  Also check to see what happens when you set the setgid bit (with different group IDs on the file).&lt;br /&gt;
# Why does 3000userlogin change its gid before changing its uid?  What happens if you switch the order of these operations?&lt;br /&gt;
# Make 3000userlogin use the shell that is specified in the user&#039;s password entry.  Check by making a new user and setting its shell to a new shell and then see if that new shell runs when you run 3000userlogin.  You should change a user&#039;s shell with the chsh command, run as that user.&lt;br /&gt;
# Can you set 3000shell to be a user&#039;s default shell?  What changes do you have to make for chsh to accept 3000shell?  Does anything obvious break when running 3000shell this way, and how can you change 3000userlogin to fix it?&lt;br /&gt;
# Does a user&#039;s default shell have to be a regular shell?  Could it instead be an arbitrary program?  How do you know?&lt;br /&gt;
# How important is each of the environment variables that is set by 3000userlogin?  Are these the only environment variables that are set after you successfully login?&lt;br /&gt;
# Note that 3000userlogin uses environ not envp (as an argument to main) to access environment variables.  Why not use envp?  (Try changing the code to use envp and see what happens.)&lt;br /&gt;
# Setup password-less login to your local system between the student and other account (or any two other accounts), following the above instructions.  Note that the &amp;quot;local&amp;quot; account is the one you are running the ssh command on.&lt;br /&gt;
# Setup password-less login to access.scs.carleton.ca, following the instructions above.&lt;br /&gt;
# Secure shell can be used to directly run a command on another program rather than the default shell.  For example, try &amp;quot;ssh student@localhost bc -l&amp;quot; and see that bc is run.  When you do this, does ssh directly run the specified command or does it first run a shell and have the shell run the command?  Use opensnoop.bt or execsnoop.bt to verify.&lt;br /&gt;
# What files in /etc does bash access when you login via 3000userlogin?  How does this compare to what bash opens when you log in via ssh?&lt;br /&gt;
# &#039;&#039;&#039;(Optional):&#039;&#039;&#039; Prompt for the user&#039;s password before logging the user in.  To do this, you&#039;ll need to get the right password hash and then figure out how to hash the entered password to check if it matches.  See online guides about [https://www.slashroot.in/how-are-passwords-stored-linux-understanding-hashing-shadow-utils how passwords are stored on Linux] for help.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2021f/code/3000userlogin.tar.gz Download code for this tutorial (3000userlogin.c and Makefile)]&lt;br /&gt;
&lt;br /&gt;
===3000userlogin.c===&lt;br /&gt;
&lt;br /&gt;
[https://homeostasis.scs.carleton.ca/~soma/os-2020w/code/3000userlogin.c Download 3000userlogin.c]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000userlogin.c */&lt;br /&gt;
/* version 0.1 */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pwd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        char *shell_argv[3];&lt;br /&gt;
        char *username;&lt;br /&gt;
        extern char **environ;&lt;br /&gt;
        struct passwd *pw_entry;&lt;br /&gt;
                &lt;br /&gt;
        if (argc &amp;lt; 2) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Usage: %s &amp;lt;username&amp;gt;\n&amp;quot;, argv[0]);&lt;br /&gt;
                exit(-1);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;uid=%d, euid=%d, gid=%d, egid=%d\n&amp;quot;,&lt;br /&gt;
               getuid(), geteuid(), getgid(), getegid());&lt;br /&gt;
&lt;br /&gt;
        username = argv[1];&lt;br /&gt;
        &lt;br /&gt;
        pw_entry = getpwnam(username);&lt;br /&gt;
        if (pw_entry == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Could not find user %s.\n&amp;quot;, username);&lt;br /&gt;
                exit(-2);&lt;br /&gt;
        }&lt;br /&gt;
                       &lt;br /&gt;
        result = setgid(pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to gid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_gid);&lt;br /&gt;
                exit(-3);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = setuid(pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to uid %d\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_uid);&lt;br /&gt;
                exit(-4);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        result = chdir(pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Failed to change to home dir %s\n&amp;quot;,&lt;br /&gt;
                        pw_entry-&amp;gt;pw_dir);&lt;br /&gt;
                exit(-5);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        shell_argv[0] = &amp;quot;bash&amp;quot;;&lt;br /&gt;
        shell_argv[1] = &amp;quot;--login&amp;quot;;&lt;br /&gt;
        shell_argv[2] = NULL;&lt;br /&gt;
&lt;br /&gt;
        clearenv();&lt;br /&gt;
        setenv(&amp;quot;USERNAME&amp;quot;, pw_entry-&amp;gt;pw_name, 1);&lt;br /&gt;
        setenv(&amp;quot;PATH&amp;quot;, &amp;quot;/usr/bin:/bin&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;SHELL&amp;quot;, &amp;quot;/bin/bash&amp;quot;, 1);&lt;br /&gt;
        setenv(&amp;quot;HOME&amp;quot;, pw_entry-&amp;gt;pw_dir, 1);&lt;br /&gt;
        setenv(&amp;quot;COMP3000&amp;quot;, &amp;quot;yes&amp;quot;, 1);&lt;br /&gt;
        &lt;br /&gt;
        execve(&amp;quot;/bin/bash&amp;quot;, shell_argv, environ);&lt;br /&gt;
     &lt;br /&gt;
        fprintf(stderr, &amp;quot;Failed to exec bash\n&amp;quot;);&lt;br /&gt;
        return -6;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Makefile===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot; line&amp;gt;&lt;br /&gt;
.PHONY: setuid&lt;br /&gt;
&lt;br /&gt;
3000userlogin: 3000userlogin.c&lt;br /&gt;
	gcc -Wall -O 3000userlogin.c -o 3000userlogin&lt;br /&gt;
&lt;br /&gt;
setuid: 3000userlogin&lt;br /&gt;
	@echo &amp;quot;The following changes ownership to root, group to root, and sets the setuid bit on 3000userlogin:&amp;quot;&lt;br /&gt;
	sudo chown root:root 3000userlogin &amp;amp;&amp;amp; sudo chmod u+s 3000userlogin&lt;br /&gt;
	@echo &amp;quot;3000userlogin is now setuid root!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_6&amp;diff=25181</id>
		<title>Operating Systems 2026F Lecture 6</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_6&amp;diff=25181"/>
		<updated>2026-10-02T14:02:07Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;==Video==  Video from the lecture given on October 2, 2026 is now available: * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec06-20261002.mp4 Lecture 6]  ==Notes==  ===Lecture 6===  &amp;lt;pre&amp;gt; Lecture 6 ---------  Signals  What is a signal?  - message from the kernel to a process  - can originate from the kernel or from another process  Idea: interrupt the process to handle an event  - so a simple form of event handling, or more exception handl...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lecture given on October 2, 2026 is now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec06-20261002.mp4 Lecture 6]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 6===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 6&lt;br /&gt;
---------&lt;br /&gt;
&lt;br /&gt;
Signals&lt;br /&gt;
&lt;br /&gt;
What is a signal?&lt;br /&gt;
 - message from the kernel to a process&lt;br /&gt;
 - can originate from the kernel or from another process&lt;br /&gt;
&lt;br /&gt;
Idea: interrupt the process to handle an event&lt;br /&gt;
 - so a simple form of event handling, or more exception handling&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When a process receives a signal&lt;br /&gt;
 - it stops executing the current code (function)&lt;br /&gt;
 - it instead starts running the appropriate signal handler&lt;br /&gt;
 - when handling is complete, it then returns to where it was, continuing the function&lt;br /&gt;
&lt;br /&gt;
This means signals can interrupt almost ANY part of your program&lt;br /&gt;
 - need to be prepared!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What sort of signals are there?&lt;br /&gt;
 - user defined (SIGUSR1, SIGUSR2)&lt;br /&gt;
 - memory access errors (SIGSEGV, SIGBUS)&lt;br /&gt;
 - some floating point errors&lt;br /&gt;
&lt;br /&gt;
But mainly:&lt;br /&gt;
 - when child processes terminate (SIGCHLD)&lt;br /&gt;
 - when the user wants to terminate the process (SIGTERM)&lt;br /&gt;
   or suspend (SIGSTOP)&lt;br /&gt;
&lt;br /&gt;
And many other conditions&lt;br /&gt;
&lt;br /&gt;
Signal handlers are defined by default by the C library&lt;br /&gt;
&lt;br /&gt;
you can change signals with sigaction()&lt;br /&gt;
 (don&#039;t use signal)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So what bad things can happen to your program because of a signal handler?&lt;br /&gt;
 - could interrupt critical code&lt;br /&gt;
   - can even happen while doing a system call&lt;br /&gt;
 - handler could mess up state of your code&lt;br /&gt;
&lt;br /&gt;
When a process receives a signal while in a system call, we have two choices:&lt;br /&gt;
 - continue the system call after the signal is handled&lt;br /&gt;
    - that doesn&#039;t work because of how the kernel operates&lt;br /&gt;
    - but we can do the system call from the beginning (restart it)&lt;br /&gt;
 - cancel the system call after the signal is handled&lt;br /&gt;
&lt;br /&gt;
Standard I/O file descriptors&lt;br /&gt;
 - when you type &amp;quot;ls&amp;quot;, its output goes to the terminal&lt;br /&gt;
 - but all ls was doing was writing to standard out&lt;br /&gt;
 - how did standard out end up in the terminal?&lt;br /&gt;
&lt;br /&gt;
C standard in    = file descriptor 0 in Linux/UNIX&lt;br /&gt;
C standard out   = file descriptor 1 in Linux/UNIX&lt;br /&gt;
C standard error = file descriptor 2 in Linux/UNIX&lt;br /&gt;
&lt;br /&gt;
What is a file descriptor?&lt;br /&gt;
 - small number&lt;br /&gt;
 - refers to an open file&lt;br /&gt;
&lt;br /&gt;
A file descriptor is what UNIX uses instead of the FILE struct for C.&lt;br /&gt;
&lt;br /&gt;
But what is that small number, really?&lt;br /&gt;
 - index into an array of open files the kernel maintains&lt;br /&gt;
   for the currently running process&lt;br /&gt;
&lt;br /&gt;
When a program starts, 0, 1, and 2 file descriptors are expected to be open and ready to go, with 0 ready for reads and 1 and 2 ready for writes.&lt;br /&gt;
&lt;br /&gt;
Who gets these file descriptors set up? Whomever did the execve!&lt;br /&gt;
 - they could inherit them from who execve&#039;d them, but they are responsible&lt;br /&gt;
&lt;br /&gt;
When you&#039;re using a shell, the shell is responsible for setting up the standard I/O file descriptors.&lt;br /&gt;
&lt;br /&gt;
This is good, because it lets us do I/O redirection&lt;br /&gt;
&lt;br /&gt;
So what does &amp;quot;&amp;gt;&amp;quot; do in most shells?&lt;br /&gt;
 - redirects standard output to the given file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember that &amp;quot;files&amp;quot; in UNIX can be stored on disk, but they can be many other things as well&lt;br /&gt;
 - tty&#039;s/pseudo tty&#039;s&lt;br /&gt;
 - another process (IPC, inter-process communication)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25180</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25180"/>
		<updated>2026-09-30T23:34:26Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please submit the answers to the following questions via Brightspace by October 5, 2026. There are 20 points in eight questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-a1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25179</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25179"/>
		<updated>2026-09-27T20:31:15Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please submit the answers to the following questions via Brightspace by October 5, 2026. There are 20 points in eight questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_3&amp;diff=25178</id>
		<title>Operating Systems 2026F: Tutorial 3</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_3&amp;diff=25178"/>
		<updated>2026-09-26T23:43:18Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;In this tutorial you will be experimenting with and extending [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000shell.c 3000shell.c] (listed below).  &amp;#039;&amp;#039;&amp;#039;Make sure you use the original code from 3000shell for each question.&amp;#039;&amp;#039;&amp;#039;  ==Getting Started==  You should download [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000shell.c 3000shell.c] on your openstack instance (or a Ubuntu Linux 21.04 system or similar).  Compile it using the command  gcc -O -g -...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this tutorial you will be experimenting with and extending [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000shell.c 3000shell.c] (listed below).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Make sure you use the original code from 3000shell for each question.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
You should download [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000shell.c 3000shell.c] on your openstack instance (or a Ubuntu Linux 21.04 system or similar).  Compile it using the command&lt;br /&gt;
 gcc -O -g -Wall 3000shell.c -o 3000shell&lt;br /&gt;
&lt;br /&gt;
==Standard I/O==&lt;br /&gt;
&lt;br /&gt;
Recall that the shell is a command interpreter (program). In comparison, a terminal is a device used to enter data into and display data from a computer. It used to be physical - [https://en.wikipedia.org/wiki/Teleprinter teletypes, or &amp;quot;TTY&amp;quot;&#039;s].  Today they are virtual - pseudoterminals, pseudo teletypes, or pts&#039;s.  /dev/pts/1 is a pts for example.  By themselves, a pts does nothing; however, they allow any program to appear as a virtual teletype to any other program.  (To learn more, &amp;lt;tt&amp;gt;man ptmx&amp;lt;/tt&amp;gt;.  However, this goes into more detail than you need for this tutorial.)&lt;br /&gt;
&lt;br /&gt;
When you ssh to a system interactively, the remote ssh process uses a pseudo tty to connect network I/O with the programs you run at the command line.  In this context you can thus think of ssh (plus a pseudo tty) as an adaptor that converts network traffic into terminal-like I/O.&lt;br /&gt;
&lt;br /&gt;
Standard input, (e.g., /dev/stdin), output (e.g., /dev/stdout) and error (/dev/stderr) are just&lt;br /&gt;
references to file descriptors 0, 1, and 2 for the current process.  They can refer to basically any file.  If a process is run in a terminal, stdin, stdout, and stderr are set to refer to the terminal&#039;s I/O channels via a tty or pts.&lt;br /&gt;
&lt;br /&gt;
Shells provide easy interfaces for changing these file descriptors.  For example:&lt;br /&gt;
&lt;br /&gt;
  ls &amp;gt; ls.log&lt;br /&gt;
&lt;br /&gt;
Will redirect ls&#039;s standard output to the file ls.log.  Similarly, &lt;br /&gt;
&lt;br /&gt;
  bc -l &amp;lt; math.txt&lt;br /&gt;
&lt;br /&gt;
will take math input from /tmp/math.txt and output it to the current terminal.  We can also use the pipe operator to direct the standard output of one program to the standard input of another:&lt;br /&gt;
&lt;br /&gt;
  ls -l | less&lt;br /&gt;
&lt;br /&gt;
(This is really good if you have lots of files in a directory.)&lt;br /&gt;
&lt;br /&gt;
Part of the magic of UNIX is that it allows problems to be solved by combining multiple programs together.  For example, to get a list of unique words in a file, you can do something like the following:&lt;br /&gt;
&lt;br /&gt;
  tr &#039; \t&#039; &#039;\n&#039; &amp;lt; file.txt | tr -d &#039;,.!()?-&#039; | sort | uniq | less  &lt;br /&gt;
&lt;br /&gt;
In summary, shells run in terminals, and the terminal interface is implemented by teletype-like devices, either a &amp;quot;tty&amp;quot; or &amp;quot;pts&amp;quot; device.  Standard in, out, and error are abstractions for interactions with such terminals or, with I/O redirection, other arbitrary files.&lt;br /&gt;
&lt;br /&gt;
==Tasks/Questions==&lt;br /&gt;
&lt;br /&gt;
The purpose of the following questions and tasks is to help you understand how 3000shell works.  At the end of this you should have an understanding of every function and every line of the code.  If you understand 3000shell, then you understand the basics of all UNIX shells.  Your understanding of the code will be tested later, so use this opportunity to dive deep into the code.  These tasks and questions should help you build up a mental model of how 3000shell works.&lt;br /&gt;
&lt;br /&gt;
# Compile and run 3000shell.c&lt;br /&gt;
# Try running programs in the background using &amp;amp; after commands entered in 3000shell.  What happens to the input and output of the program?  Try this for simple programs like ls and bc.  Then, try it for more complex interactive programs such as nano and top.&lt;br /&gt;
# You may have trouble interacting with the shell after running programs in the background.  How can you recover from such a situation?&lt;br /&gt;
# Run 3000shell under gdb and observe all the system calls it makes using &amp;lt;tt&amp;gt;catch syscall&amp;lt;/tt&amp;gt; (after setting a breakpoint on main so you don&#039;t see the syscalls when it starts).  Where does each system call happen?  In what context (source and assembly)?  Consider both parent and child processes (by setting follow-fork-mode to parent and child).  Compare with the output of &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; (e.g., run &amp;lt;tt&amp;gt;strace -fqo 3000shell.log ./3000shell&amp;lt;/tt&amp;gt;).  For info on gdb, see the [[GDB quick start]].&lt;br /&gt;
# 3000shell implements a simple form of output redirection.  What syntax should you use to redirect standard output to a file?&lt;br /&gt;
# Why are lines 207-210 there (the check for pid == -1)?&lt;br /&gt;
# Make find_binary show every attempt to find a binary.&lt;br /&gt;
# Make the shell output &amp;quot;Ouch!&amp;quot; when you send it a SIGUSR1 signal.&lt;br /&gt;
# Delete line 324 (SA_RESTART).  How does the behavior of 3000shell change?&lt;br /&gt;
# Replace the use of find_env() with getenv().  How do their interfaces differ?&lt;br /&gt;
# Make plist output the parent process id for each process, e.g. &amp;quot;5123 ls (5122)&amp;quot;.  Pay attention to the stat and status files in the per-process directories in /proc.&lt;br /&gt;
# Implement redirection of standard error&lt;br /&gt;
# Implement redirection of standard out for plist() (the same as if it was an external command).&lt;br /&gt;
# Implement a built-in 3000kill command that works like the standard kill command.  (What system call/library call is used to send signals?)&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000shell.c 3000shell.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000shell.c */&lt;br /&gt;
/* v2 Sept. 15, 2019 */&lt;br /&gt;
/* v1 Sept. 24, 2017 */&lt;br /&gt;
/* based off of csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html */&lt;br /&gt;
/* Original under &amp;quot;BSD&amp;quot; license */&lt;br /&gt;
/* This version is under GPLv3, copyright 2017, 2019 Anil Somayaji */&lt;br /&gt;
/* You really shouldn&#039;t be incorporating parts of this in any other code,&lt;br /&gt;
   it is meant for teaching, not production */&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/stat.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;dirent.h&amp;gt;&lt;br /&gt;
#include &amp;lt;ctype.h&amp;gt;&lt;br /&gt;
#include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define COMM_SIZE 32&lt;br /&gt;
&lt;br /&gt;
const char *proc_prefix = &amp;quot;/proc&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
        char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
        char **cp, *wbuf;&lt;br /&gt;
        size_t i, j;&lt;br /&gt;
        &lt;br /&gt;
        wbuf=buffer;&lt;br /&gt;
        buf_args[0]=buffer; &lt;br /&gt;
        args[0] =buffer;&lt;br /&gt;
        &lt;br /&gt;
        for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
                if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
                        break;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
                if (strlen(buf_args[i]) &amp;gt; 0)&lt;br /&gt;
                        args[j++]=buf_args[i];&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        *nargs=j;&lt;br /&gt;
        args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* this is kind of like getenv() */&lt;br /&gt;
char *find_env(char *envvar, char *notfound, char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        const int MAXPATTERN = 128;&lt;br /&gt;
        int i, p;&lt;br /&gt;
        char c;&lt;br /&gt;
        char pattern[MAXPATTERN];&lt;br /&gt;
        char *value = NULL;&lt;br /&gt;
&lt;br /&gt;
        p = 0;&lt;br /&gt;
        while ((c = envvar[p])) {&lt;br /&gt;
                pattern[p] = c;&lt;br /&gt;
                p++;&lt;br /&gt;
                if (p == (MAXPATTERN - 2)) {&lt;br /&gt;
                        break;&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        pattern[p] = &#039;=&#039;;&lt;br /&gt;
        p++;&lt;br /&gt;
        pattern[p] = &#039;\0&#039;;&lt;br /&gt;
        &lt;br /&gt;
        i = 0;&lt;br /&gt;
        while (envp[i] != NULL) {&lt;br /&gt;
                if (strncmp(pattern, envp[i], p) == 0) {                        &lt;br /&gt;
                        value = envp[i] + p;&lt;br /&gt;
                }&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        if (value == NULL) {&lt;br /&gt;
                return notfound;&lt;br /&gt;
        } else {&lt;br /&gt;
                return value;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void find_binary(char *name, char *path, char *fn, int fn_size) {&lt;br /&gt;
        char *n, *p;&lt;br /&gt;
        int r, stat_return;&lt;br /&gt;
&lt;br /&gt;
        struct stat file_status;&lt;br /&gt;
&lt;br /&gt;
        if (name[0] == &#039;.&#039; || name[0] == &#039;/&#039;) {&lt;br /&gt;
                strncpy(fn, name, fn_size);&lt;br /&gt;
                return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        p = path;&lt;br /&gt;
        while (*p != &#039;\0&#039;) {       &lt;br /&gt;
                r = 0;&lt;br /&gt;
                while (*p != &#039;\0&#039; &amp;amp;&amp;amp; *p != &#039;:&#039; &amp;amp;&amp;amp; r &amp;lt; fn_size - 1) {&lt;br /&gt;
                        fn[r] = *p;&lt;br /&gt;
                        r++;&lt;br /&gt;
                        p++;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                fn[r] = &#039;/&#039;;&lt;br /&gt;
                r++;&lt;br /&gt;
                &lt;br /&gt;
                n = name;&lt;br /&gt;
                while (*n != &#039;\0&#039; &amp;amp;&amp;amp; r &amp;lt; fn_size) {&lt;br /&gt;
                        fn[r] = *n;&lt;br /&gt;
                        n++;&lt;br /&gt;
                        r++;&lt;br /&gt;
                }&lt;br /&gt;
                fn[r] = &#039;\0&#039;;&lt;br /&gt;
&lt;br /&gt;
                &lt;br /&gt;
                stat_return = stat(fn, &amp;amp;file_status);&lt;br /&gt;
&lt;br /&gt;
                if (stat_return == 0) {&lt;br /&gt;
                        return;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (*p != &#039;\0&#039;) {&lt;br /&gt;
                        p++;&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup_comm_fn(char *pidstr, char *comm_fn)&lt;br /&gt;
{&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        strcpy(comm_fn, proc_prefix);&lt;br /&gt;
        c = comm_fn + strlen(comm_fn);&lt;br /&gt;
        *c = &#039;/&#039;;&lt;br /&gt;
        c++;&lt;br /&gt;
        strcpy(c, pidstr);&lt;br /&gt;
        c = c + strlen(pidstr);&lt;br /&gt;
        strcpy(c, &amp;quot;/comm&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void plist()&lt;br /&gt;
{&lt;br /&gt;
        DIR *proc;&lt;br /&gt;
        struct dirent *e;&lt;br /&gt;
        int result;&lt;br /&gt;
        char comm[COMM_SIZE];  /* seems to just need 16 */        &lt;br /&gt;
        char comm_fn[512];&lt;br /&gt;
        int fd, i, n;&lt;br /&gt;
&lt;br /&gt;
        proc = opendir(proc_prefix);&lt;br /&gt;
&lt;br /&gt;
        if (proc == NULL) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;ERROR: Couldn&#039;t open /proc.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        for (e = readdir(proc); e != NULL; e = readdir(proc)) {&lt;br /&gt;
                if (isdigit(e-&amp;gt;d_name[0])) {&lt;br /&gt;
                        setup_comm_fn(e-&amp;gt;d_name, comm_fn);&lt;br /&gt;
                        fd = open(comm_fn, O_RDONLY);&lt;br /&gt;
                        if (fd &amp;gt; -1) {                                &lt;br /&gt;
                                n = read(fd, comm, COMM_SIZE);&lt;br /&gt;
                                close(fd);&lt;br /&gt;
                                for (i=0; i &amp;lt; n; i++) {&lt;br /&gt;
                                        if (comm[i] == &#039;\n&#039;) {&lt;br /&gt;
                                                comm[i] = &#039;\0&#039;;&lt;br /&gt;
                                                break;&lt;br /&gt;
                                        }&lt;br /&gt;
                                }&lt;br /&gt;
                                printf(&amp;quot;%s: %s\n&amp;quot;, e-&amp;gt;d_name, comm);&lt;br /&gt;
                        } else {&lt;br /&gt;
                                printf(&amp;quot;%s\n&amp;quot;, e-&amp;gt;d_name);&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        result = closedir(proc);&lt;br /&gt;
        if (result) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;ERROR: Couldn&#039;t close /proc.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void signal_handler(int the_signal)&lt;br /&gt;
{&lt;br /&gt;
        int pid, status;&lt;br /&gt;
&lt;br /&gt;
        if (the_signal == SIGHUP) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Received SIGHUP.\n&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (the_signal != SIGCHLD) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Child handler called for signal %d?!\n&amp;quot;,&lt;br /&gt;
                        the_signal);&lt;br /&gt;
                return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        pid = wait(&amp;amp;status);&lt;br /&gt;
&lt;br /&gt;
        if (pid == -1) {&lt;br /&gt;
                /* nothing to wait for */&lt;br /&gt;
                return;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (WIFEXITED(status)) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;\nProcess %d exited with status %d.\n&amp;quot;,&lt;br /&gt;
                        pid, WEXITSTATUS(status));&lt;br /&gt;
        } else {&lt;br /&gt;
                fprintf(stderr, &amp;quot;\nProcess %d aborted.\n&amp;quot;, pid);&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void run_program(char *args[], int background, char *stdout_fn,&lt;br /&gt;
                 char *path, char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        pid_t pid;&lt;br /&gt;
        int fd, *ret_status = NULL;&lt;br /&gt;
        char bin_fn[BUFFER_SIZE];&lt;br /&gt;
&lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid) {&lt;br /&gt;
                if (background) {&lt;br /&gt;
                        fprintf(stderr,&lt;br /&gt;
                                &amp;quot;Process %d running in the background.\n&amp;quot;,&lt;br /&gt;
                                pid);&lt;br /&gt;
                } else {&lt;br /&gt;
                        pid = wait(ret_status);&lt;br /&gt;
                }&lt;br /&gt;
        } else {&lt;br /&gt;
                find_binary(args[0], path, bin_fn, BUFFER_SIZE);&lt;br /&gt;
&lt;br /&gt;
                if (stdout_fn != NULL) {&lt;br /&gt;
                        fd = creat(stdout_fn, 0666);&lt;br /&gt;
                        dup2(fd, 1);&lt;br /&gt;
                        close(fd);&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (execve(bin_fn, args, envp)) {&lt;br /&gt;
                        puts(strerror(errno));&lt;br /&gt;
                        exit(127);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void prompt_loop(char *username, char *path, char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char buffer[BUFFER_SIZE];&lt;br /&gt;
        char *args[ARR_SIZE];&lt;br /&gt;
        &lt;br /&gt;
        int background;&lt;br /&gt;
        size_t nargs;&lt;br /&gt;
        char *s;&lt;br /&gt;
        int i, j;&lt;br /&gt;
        char *stdout_fn;&lt;br /&gt;
        &lt;br /&gt;
        while(1){&lt;br /&gt;
                printf(&amp;quot;%s $ &amp;quot;, username);&lt;br /&gt;
                s = fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
                &lt;br /&gt;
                if (s == NULL) {&lt;br /&gt;
                        /* we reached EOF */&lt;br /&gt;
                        printf(&amp;quot;\n&amp;quot;);&lt;br /&gt;
                        exit(0);&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
                &lt;br /&gt;
                if (nargs==0) continue;&lt;br /&gt;
                &lt;br /&gt;
                if (!strcmp(args[0], &amp;quot;exit&amp;quot;)) {&lt;br /&gt;
                        exit(0);&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (!strcmp(args[0], &amp;quot;plist&amp;quot;)) {&lt;br /&gt;
                        plist();&lt;br /&gt;
                        continue;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                background = 0;            &lt;br /&gt;
                if (strcmp(args[nargs-1], &amp;quot;&amp;amp;&amp;quot;) == 0) {&lt;br /&gt;
                        background = 1;&lt;br /&gt;
                        nargs--;&lt;br /&gt;
                        args[nargs] = NULL;&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                stdout_fn = NULL;&lt;br /&gt;
                for (i = 1; i &amp;lt; nargs; i++) {&lt;br /&gt;
                        if (args[i][0] == &#039;&amp;gt;&#039;) {&lt;br /&gt;
                                stdout_fn = args[i];&lt;br /&gt;
                                stdout_fn++;&lt;br /&gt;
                                printf(&amp;quot;Set stdout to %s\n&amp;quot;, stdout_fn);&lt;br /&gt;
                                for (j = i; j &amp;lt; nargs - 1; j++) {&lt;br /&gt;
                                        args[j] = args[j+1];&lt;br /&gt;
                                }&lt;br /&gt;
                                nargs--;&lt;br /&gt;
                                args[nargs] = NULL;&lt;br /&gt;
                                break;&lt;br /&gt;
                        }&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                run_program(args, background, stdout_fn, path, envp);&lt;br /&gt;
        }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        struct sigaction signal_handler_struct;&lt;br /&gt;
                &lt;br /&gt;
        char *username;&lt;br /&gt;
        char *default_username = &amp;quot;UNKNOWN&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        char *path;&lt;br /&gt;
        char *default_path = &amp;quot;/usr/bin:/bin&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        memset (&amp;amp;signal_handler_struct, 0, sizeof(signal_handler_struct));&lt;br /&gt;
        signal_handler_struct.sa_handler = signal_handler;&lt;br /&gt;
        signal_handler_struct.sa_flags = SA_RESTART;&lt;br /&gt;
        &lt;br /&gt;
        if (sigaction(SIGCHLD, &amp;amp;signal_handler_struct, NULL)) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Couldn&#039;t register SIGCHLD handler.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (sigaction(SIGHUP, &amp;amp;signal_handler_struct, NULL)) {&lt;br /&gt;
                fprintf(stderr, &amp;quot;Couldn&#039;t register SIGHUP handler.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        username = find_env(&amp;quot;USER&amp;quot;, default_username, envp);&lt;br /&gt;
        path = find_env(&amp;quot;PATH&amp;quot;, default_path, envp);&lt;br /&gt;
&lt;br /&gt;
        prompt_loop(username, path, envp);&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25177</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25177"/>
		<updated>2026-09-26T16:50:26Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]]&amp;lt;br&amp;gt;&#039;&#039;&#039;No class on Oct 1 ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Midterm Review]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;&#039;&#039;&#039;Midterm Exam (in class)&#039;&#039;&#039;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25176</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25176"/>
		<updated>2026-09-26T16:48:45Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Assignments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]]&amp;lt;br&amp;gt;&#039;&#039;&#039;No class on Oct 1 ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Midterm Review]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;&#039;&#039;&#039;Midterm Exam (in class)&#039;&#039;&#039;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25175</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25175"/>
		<updated>2026-09-26T16:48:22Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Lectures &amp;amp; Exams */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]]&amp;lt;br&amp;gt;&#039;&#039;&#039;No class on Oct 1 ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Midterm Review]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;&#039;&#039;&#039;Midterm Exam (in class)&#039;&#039;&#039;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)_Course_Outline&amp;diff=25174</id>
		<title>Operating Systems (Fall 2026) Course Outline</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)_Course_Outline&amp;diff=25174"/>
		<updated>2026-09-26T16:47:35Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Grading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Information==&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Course Number:&#039;&#039;&#039; COMP 3000&lt;br /&gt;
*&#039;&#039;&#039;Term:&#039;&#039;&#039; Fall 2026&lt;br /&gt;
*&#039;&#039;&#039;Title:&#039;&#039;&#039; Operating Systems&lt;br /&gt;
*&#039;&#039;&#039;Institution:&#039;&#039;&#039; Carleton University, School of Computer Science&lt;br /&gt;
*&#039;&#039;&#039;Instructor:&#039;&#039;&#039; [https://people.scs.carleton.ca/~soma Anil Somayaji] (he/him, anilsomayaji at cunet.carleton.ca): by appointment in 5137 HP and online&lt;br /&gt;
*&#039;&#039;&#039;Teaching Assistants:&#039;&#039;&#039;&lt;br /&gt;
** TAs will be announced in the first class&lt;br /&gt;
*&#039;&#039;&#039;Lectures:&#039;&#039;&#039;&lt;br /&gt;
** A: Tue. &amp;amp; Thu. 14:35-15:55&lt;br /&gt;
** B: Wed. &amp;amp; Fri. 8:35-9:55&lt;br /&gt;
*&#039;&#039;&#039;Tutorials:&#039;&#039;&#039;&lt;br /&gt;
** A1: Wed. 13:05-14:25&lt;br /&gt;
** A2: Thu. 19:35-20:55&lt;br /&gt;
** A3: Mon. 16:05-17:25&lt;br /&gt;
** B1: Mon. 14:35-15:55&lt;br /&gt;
** B2: Tue. 18:05-19:25&lt;br /&gt;
** B3: Thu. 16:05-17:25&lt;br /&gt;
*&#039;&#039;&#039;Course Website&#039;&#039;&#039;: https://homeostasis.scs.carleton.ca/wiki/index.php/Operating_Systems_%28Fall_2026%29&lt;br /&gt;
&lt;br /&gt;
For information about Carleton&#039;s academic year, including registration and withdrawal dates, see [https://calendar.carleton.ca/academicyear/ Carleton&#039;s The Academic Year].&lt;br /&gt;
&lt;br /&gt;
==Course Calendar Description==&lt;br /&gt;
&lt;br /&gt;
Operating system implementation course stressing fundamental issues in design and how they relate to modern computer architectures. Assignments involve the modification and extension of a multitasking operating system.&lt;br /&gt;
&lt;br /&gt;
Includes: Experiential Learning Activity&lt;br /&gt;
&lt;br /&gt;
Precludes additional credit for SYSC 4001.&amp;lt;br&amp;gt;&lt;br /&gt;
Prerequisites: COMP 2401 with a minimum grade of C- and COMP 2402.&lt;br /&gt;
&lt;br /&gt;
==Learning Outcomes==&lt;br /&gt;
&lt;br /&gt;
By the end of this course, students should:&lt;br /&gt;
* be able to write C code that uses low-level Linux services and should be able to implement simple Linux kernel extensions (modules),&lt;br /&gt;
* have a strong conceptual model of how an operating system works that allows them to determine the relative role of application and operating system code when debugging software, and&lt;br /&gt;
* understand the basic use and architecture of virtual machine-based cloud architectures.&lt;br /&gt;
&lt;br /&gt;
Note that in order to achieve these objectives students should come into this course with a strong background in C programming and general application development.&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
Below is an approximate list of topics the course will cover. Because the concepts of operating systems are highly interconnected, many topics will be covered multiple times at increasing levels of detail. A more detailed list along with associated learning materials will be developed through the term on the [[Operating Systems (Fall 2026)|main course webpage]].&lt;br /&gt;
&lt;br /&gt;
* Processes&lt;br /&gt;
* Computer architecture&lt;br /&gt;
* Filesystems&lt;br /&gt;
* Concurrency&lt;br /&gt;
* CPU Scheduling&lt;br /&gt;
* Virtual Memory&lt;br /&gt;
* Inter-Process Communication&lt;br /&gt;
* Networking&lt;br /&gt;
* High performance I/O&lt;br /&gt;
* Virtual Machines&lt;br /&gt;
* Containers&lt;br /&gt;
* Security&lt;br /&gt;
* Cloud Infrastructure&lt;br /&gt;
&lt;br /&gt;
==Grading==&lt;br /&gt;
&lt;br /&gt;
The marking scheme for this course is:&lt;br /&gt;
&lt;br /&gt;
*  5% for lecture participation.&lt;br /&gt;
* 20% for tutorial participation.&lt;br /&gt;
* 20% for the assignments, if exam average is not too low (see below).&lt;br /&gt;
* 20% for the Midterm Exam, &amp;lt;del&amp;gt;Oct. 15th &amp;amp; 16th&amp;lt;/del&amp;gt; Oct. 20th &amp;amp; 21st during class.&lt;br /&gt;
* 35% for the Final Exam (during the final exam period).&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The midterm and final exams are closed book: no notes, no collaboration, no online resources, no AI. Exams will be written in an exam book based on printed exams, except where accommodations require other forms. I reserve the right to give an oral exam for deferred exams.&lt;br /&gt;
* The lecture and tutorial participation are fundamentally graded on a credit/no credit basis. In other words, if you show up and try you should be able to get full credit. Depending upon class performance the requirements for what is required to get full credit may change over the course of the semester; however, the expectation is that everyone who tries should be able to get 100% of these marks.&lt;br /&gt;
* If your assignment average is more than 25% higher than your weighted exam average (midterm &amp;amp; final), assignment grades are dropped and the weight assigned to the exams. For example, if you get 100% on assignments but only 70% for the exams (weighted average), the assignments would no longer count towards your final grade. (Missed exams count as a zero for grade calculation purposes.)&lt;br /&gt;
* Late assignments are only accepted until solutions are posted, unless extenuating circumstances apply and have been discussed with the course instructor. You have to get your tutorial marked by a TA within 8 days of the tutorial being posted, again unless extenuating circumstances apply.&lt;br /&gt;
&lt;br /&gt;
I also calculate grades using alternative marking schemes at the end of the semester, assigning the highest grade for each student from any of the marking schemes.  Thus your final grade may be higher than might be suggested by strict following of the above scheme.&lt;br /&gt;
&lt;br /&gt;
==Communication, Lectures, and Assignments==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026)|The course website page listed above]] is the canonical source of information on this course.  Please refer to it for updates.  When significant changes are made to this document it will be either announced in lecture and/or posted in the course discussion forum.&lt;br /&gt;
&lt;br /&gt;
Online course announcements and discussions will be on [https://teams.microsoft.com Microsoft Teams].  While you may discuss assignments there, do not post outright answers to them (unless the solutions have been posted).  You may discuss tutorials freely, as they are graded on a participation basis. Note that solutions are never posted for tutorials.&lt;br /&gt;
&lt;br /&gt;
I am best contacted via Teams direct message. I will also respond to email, preferably to my CUNET address. &lt;br /&gt;
&lt;br /&gt;
Assignment and exam submissions will be through [https://brightspace.carleton.ca Brightspace].  Grades will also be posted there.&lt;br /&gt;
&lt;br /&gt;
All lectures will be conducted in person except when announced otherwise, in which case they will take place over Zoom. Note that the Wednesday and Friday lectures will be repeat performances of the Tuesday and Thursday lectures, except for the first week of class when they are reversed.&lt;br /&gt;
&lt;br /&gt;
Lecture recordings will be posted to the course webpage, generally within 48 hours of lecture. One or both of the lectures may be posted, depending on the week.&lt;br /&gt;
&lt;br /&gt;
Lecture participation is based on interactions during lecture, such as questions asked and participation in online polls.  You do not need to participate in every lecture to get full marks for this; the grade is based on the quality and quantity of your interactions.  Note that grades will be calculated so that lecture participation can only improve your grade.&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials are graded based on participation and effort, not correctness.  They are marked out of four points.  The expectation is that if you make a reasonable attempt at all parts of the tutorial, you will get 4/4 points.  Thus for most students tutorials are an easy way to improve your overall grade.  However, if you don&#039;t do the tutorials, you can significantly harm your grade for the course.&lt;br /&gt;
&lt;br /&gt;
To get credit for tutorials, you must demonstrate to your assigned TA that you have made a reasonable attempt at the questions.  This demonstration will typically be through a brief conversation where you show your TA your work, either in person or virtually.  Normally this conversation should happen during your assigned tutorial time but may also take place during TA office hours. If this conversation is not feasible, at your TA&#039;s discretion you may submit written answers.&lt;br /&gt;
&lt;br /&gt;
The scheduled tutorial time is a designated time when you can work with TAs and other students together, in person, on that week&#039;s tutorial.  TAs will generally also be available online during these times as well, so if you aren&#039;t on campus you can still get help and get credit.  You can only get credit for a tutorial within 8 days of the tutorial being made available. (Tutorials are posted generally on Sundays, so you have until the end of the following Monday to get credit.) Partial attempts may be given partial credit; however, you may improve your tutorial mark as long as it is still being accepted.  Exceptions will be made only if there are extenuating circumstances.&lt;br /&gt;
&lt;br /&gt;
Plan to take a 2-5 hours each week to do the assigned tutorial. The Teams tutorial channel is a forum for getting help with tutorials, potentially from other students. While you may collaborate with others and use outside resources (including AI), when asked you should indicate who helped you and and the sources you used.  When submitting written answers, collaborators and sources should be clearly listed.&lt;br /&gt;
&lt;br /&gt;
Your work should be your own.  Please don&#039;t represent the work of others as your own, because if you do, you are subject to being reported to the Dean for plagiarism.&lt;br /&gt;
&lt;br /&gt;
==Collaboration==&lt;br /&gt;
&lt;br /&gt;
Collaboration on all work is allowed except for the midterm and final. Collaboration, however, should be clearly acknowledged.  See below for further details.&lt;br /&gt;
&lt;br /&gt;
For assignments, while you may get help from others and even collaboratively solve technical problems, the code and answers submitted should all be your own work.  For example, you &#039;&#039;may not&#039;&#039; divide an assignment into parts, give a part to another student or anyone else to solve, and then submit that work as your own.  You have to have participated in the creation of every part of your submitted work.  An easy way to make sure this happens is never share files regarding coursework or copy and paste answers into email.  Instead, meet together to work on an assignment and then separate to write up your solutions.&lt;br /&gt;
&lt;br /&gt;
AIs should be treated the same as human collaborators, in that you may use them, but the answers you submit should be your own work, whether it is code or text. Note that artificially boosting your assignment grades may not be helpful if there is too much of a discrepancy between them and your exam grades (see [[#Grading|Grading]] above).&lt;br /&gt;
&lt;br /&gt;
Similarity between submitted assignments and projects that has not been appropriately documented will be treated as plagiarism - the same as copying on a midterm or a final - and will be submitted to the Dean for disciplinary action.&lt;br /&gt;
&lt;br /&gt;
All exams are expected to be completed individually, and without electronic aid; any communication or access of electronic devices (e.g. cellphones) during exams will be considered cheating. Use of Smart Glasses (or other similar assistive technologies) before or during a test is strictly prohibited and is considered an academic integrity violation. Even if you have prescription glasses with assistive technologies, you will not be allowed to use them during the test, so please make sure that you have acceptable prescription glasses. The proctor has the right to ask to inspect your glasses before or during the test. In addition, unless authorized with PMC accommodations, you are NOT allowed to use headphones nor ear buds during a test. Also, during a test, if you choose to wear a baseball cap, sunglasses or anything else that would prevent a proctor from monitoring where your eyes are focused during the test, you will likely be asked by a proctor to move to a different seat. Lastly, you must submit your exam before leaving the classroom or it won&#039;t be graded.&lt;br /&gt;
&lt;br /&gt;
==Course Notes/Multimedia==&lt;br /&gt;
&lt;br /&gt;
Video from lectures will be available via the [[Operating Systems (Fall 2026)|lecture pages on the main course website]] generally within two days after lectures are delivered.  These same pages will also contain code and notes given in class.&lt;br /&gt;
&lt;br /&gt;
Do not rely upon the lectures and notes to cover all material related to this class.  Mastery of the tutorial material is essential for doing well on the assignments and exams.  Textbook and other outside readings should be used as supplements to help you understand concepts covered in lecture and tutorial.&lt;br /&gt;
&lt;br /&gt;
==Required Textbooks==&lt;br /&gt;
&lt;br /&gt;
The course will be using the textbook [https://www.wiley.com/en-us/operating-system-concepts-10th-edition-p-9781119320913 Operating System Concepts, 10th Edition by Silberschatz, Galvin, &amp;amp; Gagne]. You should plan to read the assigned sections BEFORE class, at least briefly, so you are familiar with the context of the lecture; then, read the sections in more detail after lecture.&lt;br /&gt;
&lt;br /&gt;
You may also wish to consult the free online textbook [http://pages.cs.wisc.edu/~remzi/OSTEP/ Operating Systems: Three Easy Pieces]. I used this textbook in previous runs of this class.&lt;br /&gt;
&lt;br /&gt;
This course focuses much more on reading code rather than writing code.  Thus, John Aycock&#039;s book, [http://pages.cpsc.ucalgary.ca/~aycock/reading-and-modifying-code.pdf Reading and Modifying Code], is worth reading to better understand how reading code differs from writing code.&lt;br /&gt;
&lt;br /&gt;
==Course Software==&lt;br /&gt;
&lt;br /&gt;
In this course we will be working with the [http://www.ubuntu.com/ Ubuntu] Linux distribution.  You may use other Linux distributions in the tutorials to complete the assigned work; there will be differences, however, in some aspects (such as installing software), particularly if you use a distribution not based on Ubuntu or Debian.&lt;br /&gt;
&lt;br /&gt;
==Undergraduate Academic Advisor==&lt;br /&gt;
&lt;br /&gt;
The Undergraduate Advisors for the School of Computer Science are available in Room 5302HP; or by email at (scs.ug.advisor at cunet.carleton.ca). The undergraduate advisors can assist with information about prerequisites and preclusions, course substitutions/equivalencies, understanding your academic audit and the remaining requirements for graduation. The undergraduate advisors will also refer students to appropriate resources such as the Science Student Success Centre, Learning Support Services and Writing Tutorial Services.&lt;br /&gt;
&lt;br /&gt;
==SCS Computer Laboratory==&lt;br /&gt;
&lt;br /&gt;
Students taking a COMP course can access the SCS computer labs. The lab schedule and location can be found at: https://carleton.ca/scs/tech-support/computer-laboratories/. All SCS computer lab and technical support information can be found at: https://carleton.ca/scs/tech-support/. Technical support staff may be contacted in-person or virtually, see this page for details: https://carleton.ca/scs/tech-support/contact-it-support/.&lt;br /&gt;
&lt;br /&gt;
==Extenuating Circumstances==&lt;br /&gt;
&lt;br /&gt;
While I expect you to take this course seriously, I do not expect it to be the most important thing in your life. Physical and mental health issues, family responsibilities, natural and personal disasters, and other factors may come up over the semester. I want you to succeed in this course, and to that end I will do what I reasonably can to help you succeed. If your request can be accommodated with not unreasonable effort by me or the TAs, and the accommodation is one that is reasonable to give to anyone in your circumstances, I will do what I can.&lt;br /&gt;
&lt;br /&gt;
Having said this, the main thing I have to give is extra time, but there is only so much time in a semester. Sometimes you&#039;ll need to get extra time by trying again in another semester, and that is okay. Having said that, I will always respect you enough to not pressure you to make a specific choice; you must decide what is best for your circumstances.&lt;br /&gt;
&lt;br /&gt;
Remember that sometimes we all need help. [https://wellness.carleton.ca/ The Carleton Wellness Website] is a good resource if you aren&#039;t sure what to do next.&lt;br /&gt;
&lt;br /&gt;
==Academic Accommodations and Regulations==&lt;br /&gt;
&lt;br /&gt;
===Academic Accommodation===&lt;br /&gt;
&lt;br /&gt;
Carleton is committed to providing academic accessibility for all individuals. You may need special arrangements to meet your academic obligations during the term. The accommodation request processes are outlined on the Academic Accommodations website (https://students.carleton.ca/course-outline/). &lt;br /&gt;
&lt;br /&gt;
===Generative AI Usage===&lt;br /&gt;
&lt;br /&gt;
As our understanding of the uses of AI and its relationship to student work and academic Integrity continue to evolve, students are required to discuss their use of AI in any circumstance not described here with the course instructor to ensure it supports the learning goals for the course.&lt;br /&gt;
 &lt;br /&gt;
===Academic Integrity===&lt;br /&gt;
&lt;br /&gt;
Students are expected to uphold the values of academic integrity, which include fairness, honesty, trust, and responsibility. Examples of actions that compromise these values include but are not limited to plagiarism, accessing unauthorized sites for assignments or tests, unauthorized collaboration on assignments or exams, and using artificial intelligence tools such as ChatGPT when your assessment instructions say it is not permitted.&lt;br /&gt;
&lt;br /&gt;
Misconduct in scholarly activity will not be tolerated and will result in consequences as outlined in [https://carleton.ca/secretariat/wp-content/uploads/Academic-Integrity-Policy-2021.pdf Carleton University’s Academic Integrity Policy]. A list of standard sanctions in the Faculty of Science can be found [https://science.carleton.ca/academic-integrity/ here]. &lt;br /&gt;
&lt;br /&gt;
Additional details about this process can be found on the [https://science.carleton.ca/academic-integrity/ Faculty of Science Academic Integrity website].&lt;br /&gt;
&lt;br /&gt;
Students are expected to familiarize themselves with and abide by [https://carleton.ca/secretariat/wp-content/uploads/Academic-Integrity-Policy-2021.pdf Carleton University’s Academic Integrity Policy]. Claiming ignorance of or confusion about the academic integrity standards as described in the Policy does not excuse a student from responsibility for violations of those standards.&lt;br /&gt;
&lt;br /&gt;
===Student Rights &amp;amp; Responsibilities===&lt;br /&gt;
&lt;br /&gt;
Students are expected to act responsibly and engage respectfully with other students and members of the Carleton and the broader community. See the [https://carleton.ca/studentaffairs/student-rights-and-responsibilities/#sect1.1 7 Rights and Responsibilities Policy] for details regarding the expectations of non-academic behaviour of students. Those who participate with another student in the commission of an infraction of this Policy will also be held liable for their actions.&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)_Course_Outline&amp;diff=25173</id>
		<title>Operating Systems (Fall 2026) Course Outline</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)_Course_Outline&amp;diff=25173"/>
		<updated>2026-09-26T16:47:11Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Grading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Information==&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Course Number:&#039;&#039;&#039; COMP 3000&lt;br /&gt;
*&#039;&#039;&#039;Term:&#039;&#039;&#039; Fall 2026&lt;br /&gt;
*&#039;&#039;&#039;Title:&#039;&#039;&#039; Operating Systems&lt;br /&gt;
*&#039;&#039;&#039;Institution:&#039;&#039;&#039; Carleton University, School of Computer Science&lt;br /&gt;
*&#039;&#039;&#039;Instructor:&#039;&#039;&#039; [https://people.scs.carleton.ca/~soma Anil Somayaji] (he/him, anilsomayaji at cunet.carleton.ca): by appointment in 5137 HP and online&lt;br /&gt;
*&#039;&#039;&#039;Teaching Assistants:&#039;&#039;&#039;&lt;br /&gt;
** TAs will be announced in the first class&lt;br /&gt;
*&#039;&#039;&#039;Lectures:&#039;&#039;&#039;&lt;br /&gt;
** A: Tue. &amp;amp; Thu. 14:35-15:55&lt;br /&gt;
** B: Wed. &amp;amp; Fri. 8:35-9:55&lt;br /&gt;
*&#039;&#039;&#039;Tutorials:&#039;&#039;&#039;&lt;br /&gt;
** A1: Wed. 13:05-14:25&lt;br /&gt;
** A2: Thu. 19:35-20:55&lt;br /&gt;
** A3: Mon. 16:05-17:25&lt;br /&gt;
** B1: Mon. 14:35-15:55&lt;br /&gt;
** B2: Tue. 18:05-19:25&lt;br /&gt;
** B3: Thu. 16:05-17:25&lt;br /&gt;
*&#039;&#039;&#039;Course Website&#039;&#039;&#039;: https://homeostasis.scs.carleton.ca/wiki/index.php/Operating_Systems_%28Fall_2026%29&lt;br /&gt;
&lt;br /&gt;
For information about Carleton&#039;s academic year, including registration and withdrawal dates, see [https://calendar.carleton.ca/academicyear/ Carleton&#039;s The Academic Year].&lt;br /&gt;
&lt;br /&gt;
==Course Calendar Description==&lt;br /&gt;
&lt;br /&gt;
Operating system implementation course stressing fundamental issues in design and how they relate to modern computer architectures. Assignments involve the modification and extension of a multitasking operating system.&lt;br /&gt;
&lt;br /&gt;
Includes: Experiential Learning Activity&lt;br /&gt;
&lt;br /&gt;
Precludes additional credit for SYSC 4001.&amp;lt;br&amp;gt;&lt;br /&gt;
Prerequisites: COMP 2401 with a minimum grade of C- and COMP 2402.&lt;br /&gt;
&lt;br /&gt;
==Learning Outcomes==&lt;br /&gt;
&lt;br /&gt;
By the end of this course, students should:&lt;br /&gt;
* be able to write C code that uses low-level Linux services and should be able to implement simple Linux kernel extensions (modules),&lt;br /&gt;
* have a strong conceptual model of how an operating system works that allows them to determine the relative role of application and operating system code when debugging software, and&lt;br /&gt;
* understand the basic use and architecture of virtual machine-based cloud architectures.&lt;br /&gt;
&lt;br /&gt;
Note that in order to achieve these objectives students should come into this course with a strong background in C programming and general application development.&lt;br /&gt;
&lt;br /&gt;
==Topics==&lt;br /&gt;
&lt;br /&gt;
Below is an approximate list of topics the course will cover. Because the concepts of operating systems are highly interconnected, many topics will be covered multiple times at increasing levels of detail. A more detailed list along with associated learning materials will be developed through the term on the [[Operating Systems (Fall 2026)|main course webpage]].&lt;br /&gt;
&lt;br /&gt;
* Processes&lt;br /&gt;
* Computer architecture&lt;br /&gt;
* Filesystems&lt;br /&gt;
* Concurrency&lt;br /&gt;
* CPU Scheduling&lt;br /&gt;
* Virtual Memory&lt;br /&gt;
* Inter-Process Communication&lt;br /&gt;
* Networking&lt;br /&gt;
* High performance I/O&lt;br /&gt;
* Virtual Machines&lt;br /&gt;
* Containers&lt;br /&gt;
* Security&lt;br /&gt;
* Cloud Infrastructure&lt;br /&gt;
&lt;br /&gt;
==Grading==&lt;br /&gt;
&lt;br /&gt;
The marking scheme for this course is:&lt;br /&gt;
&lt;br /&gt;
*  5% for lecture participation.&lt;br /&gt;
* 20% for tutorial participation.&lt;br /&gt;
* 20% for the assignments, if exam average is not too low (see below).&lt;br /&gt;
* 20% for the Midterm Exam, &amp;lt;del&amp;gt;Oct. 15th &amp;amp; 16th&amp;lt;/del&amp;gt; Oct. 21st &amp;amp; 22nd during class.&lt;br /&gt;
* 35% for the Final Exam (during the final exam period).&lt;br /&gt;
&lt;br /&gt;
Note the following:&lt;br /&gt;
* The midterm and final exams are closed book: no notes, no collaboration, no online resources, no AI. Exams will be written in an exam book based on printed exams, except where accommodations require other forms. I reserve the right to give an oral exam for deferred exams.&lt;br /&gt;
* The lecture and tutorial participation are fundamentally graded on a credit/no credit basis. In other words, if you show up and try you should be able to get full credit. Depending upon class performance the requirements for what is required to get full credit may change over the course of the semester; however, the expectation is that everyone who tries should be able to get 100% of these marks.&lt;br /&gt;
* If your assignment average is more than 25% higher than your weighted exam average (midterm &amp;amp; final), assignment grades are dropped and the weight assigned to the exams. For example, if you get 100% on assignments but only 70% for the exams (weighted average), the assignments would no longer count towards your final grade. (Missed exams count as a zero for grade calculation purposes.)&lt;br /&gt;
* Late assignments are only accepted until solutions are posted, unless extenuating circumstances apply and have been discussed with the course instructor. You have to get your tutorial marked by a TA within 8 days of the tutorial being posted, again unless extenuating circumstances apply.&lt;br /&gt;
&lt;br /&gt;
I also calculate grades using alternative marking schemes at the end of the semester, assigning the highest grade for each student from any of the marking schemes.  Thus your final grade may be higher than might be suggested by strict following of the above scheme.&lt;br /&gt;
&lt;br /&gt;
==Communication, Lectures, and Assignments==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026)|The course website page listed above]] is the canonical source of information on this course.  Please refer to it for updates.  When significant changes are made to this document it will be either announced in lecture and/or posted in the course discussion forum.&lt;br /&gt;
&lt;br /&gt;
Online course announcements and discussions will be on [https://teams.microsoft.com Microsoft Teams].  While you may discuss assignments there, do not post outright answers to them (unless the solutions have been posted).  You may discuss tutorials freely, as they are graded on a participation basis. Note that solutions are never posted for tutorials.&lt;br /&gt;
&lt;br /&gt;
I am best contacted via Teams direct message. I will also respond to email, preferably to my CUNET address. &lt;br /&gt;
&lt;br /&gt;
Assignment and exam submissions will be through [https://brightspace.carleton.ca Brightspace].  Grades will also be posted there.&lt;br /&gt;
&lt;br /&gt;
All lectures will be conducted in person except when announced otherwise, in which case they will take place over Zoom. Note that the Wednesday and Friday lectures will be repeat performances of the Tuesday and Thursday lectures, except for the first week of class when they are reversed.&lt;br /&gt;
&lt;br /&gt;
Lecture recordings will be posted to the course webpage, generally within 48 hours of lecture. One or both of the lectures may be posted, depending on the week.&lt;br /&gt;
&lt;br /&gt;
Lecture participation is based on interactions during lecture, such as questions asked and participation in online polls.  You do not need to participate in every lecture to get full marks for this; the grade is based on the quality and quantity of your interactions.  Note that grades will be calculated so that lecture participation can only improve your grade.&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials are graded based on participation and effort, not correctness.  They are marked out of four points.  The expectation is that if you make a reasonable attempt at all parts of the tutorial, you will get 4/4 points.  Thus for most students tutorials are an easy way to improve your overall grade.  However, if you don&#039;t do the tutorials, you can significantly harm your grade for the course.&lt;br /&gt;
&lt;br /&gt;
To get credit for tutorials, you must demonstrate to your assigned TA that you have made a reasonable attempt at the questions.  This demonstration will typically be through a brief conversation where you show your TA your work, either in person or virtually.  Normally this conversation should happen during your assigned tutorial time but may also take place during TA office hours. If this conversation is not feasible, at your TA&#039;s discretion you may submit written answers.&lt;br /&gt;
&lt;br /&gt;
The scheduled tutorial time is a designated time when you can work with TAs and other students together, in person, on that week&#039;s tutorial.  TAs will generally also be available online during these times as well, so if you aren&#039;t on campus you can still get help and get credit.  You can only get credit for a tutorial within 8 days of the tutorial being made available. (Tutorials are posted generally on Sundays, so you have until the end of the following Monday to get credit.) Partial attempts may be given partial credit; however, you may improve your tutorial mark as long as it is still being accepted.  Exceptions will be made only if there are extenuating circumstances.&lt;br /&gt;
&lt;br /&gt;
Plan to take a 2-5 hours each week to do the assigned tutorial. The Teams tutorial channel is a forum for getting help with tutorials, potentially from other students. While you may collaborate with others and use outside resources (including AI), when asked you should indicate who helped you and and the sources you used.  When submitting written answers, collaborators and sources should be clearly listed.&lt;br /&gt;
&lt;br /&gt;
Your work should be your own.  Please don&#039;t represent the work of others as your own, because if you do, you are subject to being reported to the Dean for plagiarism.&lt;br /&gt;
&lt;br /&gt;
==Collaboration==&lt;br /&gt;
&lt;br /&gt;
Collaboration on all work is allowed except for the midterm and final. Collaboration, however, should be clearly acknowledged.  See below for further details.&lt;br /&gt;
&lt;br /&gt;
For assignments, while you may get help from others and even collaboratively solve technical problems, the code and answers submitted should all be your own work.  For example, you &#039;&#039;may not&#039;&#039; divide an assignment into parts, give a part to another student or anyone else to solve, and then submit that work as your own.  You have to have participated in the creation of every part of your submitted work.  An easy way to make sure this happens is never share files regarding coursework or copy and paste answers into email.  Instead, meet together to work on an assignment and then separate to write up your solutions.&lt;br /&gt;
&lt;br /&gt;
AIs should be treated the same as human collaborators, in that you may use them, but the answers you submit should be your own work, whether it is code or text. Note that artificially boosting your assignment grades may not be helpful if there is too much of a discrepancy between them and your exam grades (see [[#Grading|Grading]] above).&lt;br /&gt;
&lt;br /&gt;
Similarity between submitted assignments and projects that has not been appropriately documented will be treated as plagiarism - the same as copying on a midterm or a final - and will be submitted to the Dean for disciplinary action.&lt;br /&gt;
&lt;br /&gt;
All exams are expected to be completed individually, and without electronic aid; any communication or access of electronic devices (e.g. cellphones) during exams will be considered cheating. Use of Smart Glasses (or other similar assistive technologies) before or during a test is strictly prohibited and is considered an academic integrity violation. Even if you have prescription glasses with assistive technologies, you will not be allowed to use them during the test, so please make sure that you have acceptable prescription glasses. The proctor has the right to ask to inspect your glasses before or during the test. In addition, unless authorized with PMC accommodations, you are NOT allowed to use headphones nor ear buds during a test. Also, during a test, if you choose to wear a baseball cap, sunglasses or anything else that would prevent a proctor from monitoring where your eyes are focused during the test, you will likely be asked by a proctor to move to a different seat. Lastly, you must submit your exam before leaving the classroom or it won&#039;t be graded.&lt;br /&gt;
&lt;br /&gt;
==Course Notes/Multimedia==&lt;br /&gt;
&lt;br /&gt;
Video from lectures will be available via the [[Operating Systems (Fall 2026)|lecture pages on the main course website]] generally within two days after lectures are delivered.  These same pages will also contain code and notes given in class.&lt;br /&gt;
&lt;br /&gt;
Do not rely upon the lectures and notes to cover all material related to this class.  Mastery of the tutorial material is essential for doing well on the assignments and exams.  Textbook and other outside readings should be used as supplements to help you understand concepts covered in lecture and tutorial.&lt;br /&gt;
&lt;br /&gt;
==Required Textbooks==&lt;br /&gt;
&lt;br /&gt;
The course will be using the textbook [https://www.wiley.com/en-us/operating-system-concepts-10th-edition-p-9781119320913 Operating System Concepts, 10th Edition by Silberschatz, Galvin, &amp;amp; Gagne]. You should plan to read the assigned sections BEFORE class, at least briefly, so you are familiar with the context of the lecture; then, read the sections in more detail after lecture.&lt;br /&gt;
&lt;br /&gt;
You may also wish to consult the free online textbook [http://pages.cs.wisc.edu/~remzi/OSTEP/ Operating Systems: Three Easy Pieces]. I used this textbook in previous runs of this class.&lt;br /&gt;
&lt;br /&gt;
This course focuses much more on reading code rather than writing code.  Thus, John Aycock&#039;s book, [http://pages.cpsc.ucalgary.ca/~aycock/reading-and-modifying-code.pdf Reading and Modifying Code], is worth reading to better understand how reading code differs from writing code.&lt;br /&gt;
&lt;br /&gt;
==Course Software==&lt;br /&gt;
&lt;br /&gt;
In this course we will be working with the [http://www.ubuntu.com/ Ubuntu] Linux distribution.  You may use other Linux distributions in the tutorials to complete the assigned work; there will be differences, however, in some aspects (such as installing software), particularly if you use a distribution not based on Ubuntu or Debian.&lt;br /&gt;
&lt;br /&gt;
==Undergraduate Academic Advisor==&lt;br /&gt;
&lt;br /&gt;
The Undergraduate Advisors for the School of Computer Science are available in Room 5302HP; or by email at (scs.ug.advisor at cunet.carleton.ca). The undergraduate advisors can assist with information about prerequisites and preclusions, course substitutions/equivalencies, understanding your academic audit and the remaining requirements for graduation. The undergraduate advisors will also refer students to appropriate resources such as the Science Student Success Centre, Learning Support Services and Writing Tutorial Services.&lt;br /&gt;
&lt;br /&gt;
==SCS Computer Laboratory==&lt;br /&gt;
&lt;br /&gt;
Students taking a COMP course can access the SCS computer labs. The lab schedule and location can be found at: https://carleton.ca/scs/tech-support/computer-laboratories/. All SCS computer lab and technical support information can be found at: https://carleton.ca/scs/tech-support/. Technical support staff may be contacted in-person or virtually, see this page for details: https://carleton.ca/scs/tech-support/contact-it-support/.&lt;br /&gt;
&lt;br /&gt;
==Extenuating Circumstances==&lt;br /&gt;
&lt;br /&gt;
While I expect you to take this course seriously, I do not expect it to be the most important thing in your life. Physical and mental health issues, family responsibilities, natural and personal disasters, and other factors may come up over the semester. I want you to succeed in this course, and to that end I will do what I reasonably can to help you succeed. If your request can be accommodated with not unreasonable effort by me or the TAs, and the accommodation is one that is reasonable to give to anyone in your circumstances, I will do what I can.&lt;br /&gt;
&lt;br /&gt;
Having said this, the main thing I have to give is extra time, but there is only so much time in a semester. Sometimes you&#039;ll need to get extra time by trying again in another semester, and that is okay. Having said that, I will always respect you enough to not pressure you to make a specific choice; you must decide what is best for your circumstances.&lt;br /&gt;
&lt;br /&gt;
Remember that sometimes we all need help. [https://wellness.carleton.ca/ The Carleton Wellness Website] is a good resource if you aren&#039;t sure what to do next.&lt;br /&gt;
&lt;br /&gt;
==Academic Accommodations and Regulations==&lt;br /&gt;
&lt;br /&gt;
===Academic Accommodation===&lt;br /&gt;
&lt;br /&gt;
Carleton is committed to providing academic accessibility for all individuals. You may need special arrangements to meet your academic obligations during the term. The accommodation request processes are outlined on the Academic Accommodations website (https://students.carleton.ca/course-outline/). &lt;br /&gt;
&lt;br /&gt;
===Generative AI Usage===&lt;br /&gt;
&lt;br /&gt;
As our understanding of the uses of AI and its relationship to student work and academic Integrity continue to evolve, students are required to discuss their use of AI in any circumstance not described here with the course instructor to ensure it supports the learning goals for the course.&lt;br /&gt;
 &lt;br /&gt;
===Academic Integrity===&lt;br /&gt;
&lt;br /&gt;
Students are expected to uphold the values of academic integrity, which include fairness, honesty, trust, and responsibility. Examples of actions that compromise these values include but are not limited to plagiarism, accessing unauthorized sites for assignments or tests, unauthorized collaboration on assignments or exams, and using artificial intelligence tools such as ChatGPT when your assessment instructions say it is not permitted.&lt;br /&gt;
&lt;br /&gt;
Misconduct in scholarly activity will not be tolerated and will result in consequences as outlined in [https://carleton.ca/secretariat/wp-content/uploads/Academic-Integrity-Policy-2021.pdf Carleton University’s Academic Integrity Policy]. A list of standard sanctions in the Faculty of Science can be found [https://science.carleton.ca/academic-integrity/ here]. &lt;br /&gt;
&lt;br /&gt;
Additional details about this process can be found on the [https://science.carleton.ca/academic-integrity/ Faculty of Science Academic Integrity website].&lt;br /&gt;
&lt;br /&gt;
Students are expected to familiarize themselves with and abide by [https://carleton.ca/secretariat/wp-content/uploads/Academic-Integrity-Policy-2021.pdf Carleton University’s Academic Integrity Policy]. Claiming ignorance of or confusion about the academic integrity standards as described in the Policy does not excuse a student from responsibility for violations of those standards.&lt;br /&gt;
&lt;br /&gt;
===Student Rights &amp;amp; Responsibilities===&lt;br /&gt;
&lt;br /&gt;
Students are expected to act responsibly and engage respectfully with other students and members of the Carleton and the broader community. See the [https://carleton.ca/studentaffairs/student-rights-and-responsibilities/#sect1.1 7 Rights and Responsibilities Policy] for details regarding the expectations of non-academic behaviour of students. Those who participate with another student in the commission of an infraction of this Policy will also be held liable for their actions.&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25172</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25172"/>
		<updated>2026-09-26T16:34:18Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Lectures &amp;amp; Exams */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]]&amp;lt;br&amp;gt;&#039;&#039;&#039;No class on Oct 1 ([https://www.nspw.org NSPW])&#039;&#039;&#039;&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Midterm Review]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Midterm (in class)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25171</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25171"/>
		<updated>2026-09-26T16:28:08Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Lectures &amp;amp; Exams */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;&#039;&#039;&#039;No class (NSPW)&#039;&#039;&#039;&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]]&amp;lt;br&amp;gt;No class on Oct 1 (NSPW)&amp;lt;/br&amp;gt;&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Lecture 10]]: Midterm Review&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Midterm (in class)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 23|Lecture 23]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25170</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25170"/>
		<updated>2026-09-26T16:15:12Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This assignment is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please submit the answers to the following questions via Brightspace by October 5, 2026. There are 20 points in eight questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25169</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25169"/>
		<updated>2026-09-26T16:14:41Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Assignments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]] (NSPW)&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]] (NSPW)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Lecture 10]]: Midterm Review&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Midterm (in class)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 23|Lecture 23]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25168</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25168"/>
		<updated>2026-09-26T16:12:02Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This assignment is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Please submit the answers to the following questions via Brightspace by ???, 2026. There are 20 points in ?? questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25167</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25167"/>
		<updated>2026-09-26T16:11:41Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please submit the answers to the following questions via Brightspace by ???, 2026. There are 20 points in ?? questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25166</id>
		<title>Operating Systems 2026F: Assignment 1</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Assignment_1&amp;diff=25166"/>
		<updated>2026-09-26T16:11:09Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;Please submit the answers to the following questions via Brightspace by ???, 2026. There are 20 points in ?? questions.  Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be prope...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Please submit the answers to the following questions via Brightspace by ???, 2026. There are 20 points in ?? questions.&lt;br /&gt;
&lt;br /&gt;
Submit your answers as a plain text file following [https://homeostasis.scs.carleton.ca/~soma/os-2026f/templates/comp3000-a1-template.txt this template].  Name your answer file &amp;quot;comp3000-assign1-&amp;lt;username&amp;gt;.txt&amp;quot; (where username is your MyCarletonOne username).  Please make sure to use your correct student ID number otherwise your grades may not be properly recorded.&lt;br /&gt;
&lt;br /&gt;
Your answers will be parsed by a script in order to help with grading so please preserve the format of the template.  No other formats will be accepted.&lt;br /&gt;
&lt;br /&gt;
Note that the file should be a UNIX text file, not a Windows text file (so LF line endings).  See the [https://en.wikipedia.org/wiki/Text_file Wikipedia page on text files] to learn more.  Most modern text editors can convert between different types of text files.  Alternately, install the program &amp;lt;tt&amp;gt;dos2unix&amp;lt;/tt&amp;gt; on the VM to convert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;You may use [https://homeostasis.scs.carleton.ca/~soma/os-2026f/validators/a1-validator.html this validator page] to make sure your answer file is properly named and formatted.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to include what outside resources you used to complete each of your answers, including other students, man pages, and web resources. You do not need to list help from the instructor, TA, or information found in the textbook.&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
In this assignment you will be looking at [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c] and its corresponding assembly language version, [https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s].  You can download the C source, generate the assembly language code, and compile it with the following commands:&lt;br /&gt;
&lt;br /&gt;
  wget https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c&lt;br /&gt;
  gcc -O -S 3000menu.c&lt;br /&gt;
  gcc -O 3000menu.c -o 3000menu&lt;br /&gt;
&lt;br /&gt;
Note that you can also just compile the assembly code directly:&lt;br /&gt;
&lt;br /&gt;
  gcc -O 3000menu.s -o 3000menu  &lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; doesn&#039;t work for you, add the &amp;quot;-z lazy&amp;quot; option when you compile. (This option is not needed on Ubuntu 26.04.)&lt;br /&gt;
&lt;br /&gt;
==Questions==&lt;br /&gt;
Please answer the following questions. When a question asks about how do you know, you need to give empirical evidence. References to documentation are not sufficient as documentation can be incorrect.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] How do you define a custom command for 3000menu without changing its code? What parts 3000menu implement custom command support?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Can menu commands include command line options? Why, or why not?&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What compiler directive (an instruction starting with a period) is present at the start of every function?  What is at the end of the function? Ignore directives that include the name of the function.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Which line(s) in 3000menu.s implement the if/else statements in &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] What line(s) in 3000menu.s implement the call to &amp;lt;tt&amp;gt;getline()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;choose_program()&amp;lt;/tt&amp;gt;? How do you know those are the correct lines?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] &amp;lt;tt&amp;gt;printf&amp;lt;/tt&amp;gt; calls get translated into two different calls in assembly. What are those two calls? And why is each used (rather than the other)?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[2] Does the code in 3000menu.s make any system calls directly? How do you know? Explain briefly.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;[6] How could you modify 3000menu.c so that &amp;lt;tt&amp;gt;run_program()&amp;lt;/tt&amp;gt; no longer used &amp;lt;tt&amp;gt;system()&amp;lt;/tt&amp;gt; and instead used &amp;lt;tt&amp;gt;fork&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;execve&amp;lt;/tt&amp;gt;, and any code from the first two tutorials except for &amp;lt;tt&amp;gt;execvp()&amp;lt;/tt&amp;gt;? You may not use any other external code. Your modified version should have equivalent functionality to the original.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;li&amp;gt;[5] Replace line 29 in 3000menu.s (the assembly code version) with the following two lines:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; mov $57,%eax&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; syscall&amp;lt;/tt&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Create a new binary by compiling the modified assembly language code, calling it 3000menu-q9.  It should run the same as before.&lt;br /&gt;
 &amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;[1] Is 3000menu-q9 statically or dynamically linked?&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;/ol&amp;gt;&lt;br /&gt;
  &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.c 3000menu.c]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
/* 3000menu.c */&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *menu[] = {&lt;br /&gt;
        &amp;quot;/usr/bin/ls&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/ps&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/nano&amp;quot;,&lt;br /&gt;
        &amp;quot;/usr/bin/top&amp;quot;,&lt;br /&gt;
        &amp;quot;CUSTOM&amp;quot;,&lt;br /&gt;
        &amp;quot;QUIT&amp;quot;,&lt;br /&gt;
        NULL&lt;br /&gt;
};&lt;br /&gt;
        &lt;br /&gt;
int quit = 5;&lt;br /&gt;
const int CUSTOM = 4;&lt;br /&gt;
&lt;br /&gt;
void run_program(int choice)&lt;br /&gt;
{&lt;br /&gt;
        int result;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Running %s\n&amp;quot;, menu[choice]);&lt;br /&gt;
        &lt;br /&gt;
        result = system(menu[choice]);&lt;br /&gt;
&lt;br /&gt;
        if (result != 0) {&lt;br /&gt;
                printf(&amp;quot;Command failed.\n&amp;quot;);&lt;br /&gt;
        } else {&lt;br /&gt;
                printf(&amp;quot;Command succeeded.\n&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
                &lt;br /&gt;
        return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int choose_program(void)&lt;br /&gt;
{&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        int choice;&lt;br /&gt;
        char *input = NULL;&lt;br /&gt;
        size_t result, n = 0;&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nChoose a program to run:\n\n&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        while (i &amp;lt;= quit) {&lt;br /&gt;
                printf(&amp;quot;%d. %s\n&amp;quot;, i + 1, menu[i]);&lt;br /&gt;
                i++;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;\nYour choice? &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        result = getline(&amp;amp;input, &amp;amp;n, stdin);&lt;br /&gt;
        choice = atoi(input);&lt;br /&gt;
        free(input);&lt;br /&gt;
&lt;br /&gt;
        if ((result &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;gt; 0) &amp;amp;&amp;amp; (choice &amp;lt;= i)) {&lt;br /&gt;
                return choice - 1;&lt;br /&gt;
        } else {&lt;br /&gt;
                return -1;&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
        int program;&lt;br /&gt;
        char *c;&lt;br /&gt;
&lt;br /&gt;
        c = getenv(&amp;quot;MENUCMD&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        if (c) {&lt;br /&gt;
                menu[CUSTOM] = c;&lt;br /&gt;
        } else {&lt;br /&gt;
                menu[CUSTOM] = menu[quit];&lt;br /&gt;
                quit = CUSTOM;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        while (1) {&lt;br /&gt;
                program = choose_program();&lt;br /&gt;
&lt;br /&gt;
                if (program == quit) {&lt;br /&gt;
                        return 0;&lt;br /&gt;
                }&lt;br /&gt;
                &lt;br /&gt;
                if (program != -1) {&lt;br /&gt;
                        run_program(program);&lt;br /&gt;
                }&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2026f/code/3000menu.s 3000menu.s]===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot; line&amp;gt;&lt;br /&gt;
	.file	&amp;quot;3000menu.c&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.section	.rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
	.string	&amp;quot;Running %s\n&amp;quot;&lt;br /&gt;
.LC1:&lt;br /&gt;
	.string	&amp;quot;Command failed.&amp;quot;&lt;br /&gt;
.LC2:&lt;br /&gt;
	.string	&amp;quot;Command succeeded.&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	run_program&lt;br /&gt;
	.type	run_program, @function&lt;br /&gt;
run_program:&lt;br /&gt;
.LFB51:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 6, -16&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 3, -24&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movslq	%edi, %rbx&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdx&lt;br /&gt;
	leaq	.LC0(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	movq	0(%rbp,%rbx,8), %rdi&lt;br /&gt;
	call	system@PLT&lt;br /&gt;
	testl	%eax, %eax&lt;br /&gt;
	je	.L2&lt;br /&gt;
	leaq	.LC1(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
.L1:&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L2:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	leaq	.LC2(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	jmp	.L1&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE51:&lt;br /&gt;
	.size	run_program, .-run_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC3:&lt;br /&gt;
	.string	&amp;quot;\nChoose a program to run:\n&amp;quot;&lt;br /&gt;
.LC4:&lt;br /&gt;
	.string	&amp;quot;%d. %s\n&amp;quot;&lt;br /&gt;
.LC5:&lt;br /&gt;
	.string	&amp;quot;\nYour choice? &amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	choose_program&lt;br /&gt;
	.type	choose_program, @function&lt;br /&gt;
choose_program:&lt;br /&gt;
.LFB52:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	pushq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	.cfi_offset 12, -16&lt;br /&gt;
	pushq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	.cfi_offset 6, -24&lt;br /&gt;
	pushq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	.cfi_offset 3, -32&lt;br /&gt;
	subq	$32, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 64&lt;br /&gt;
	movq	%fs:40, %rax&lt;br /&gt;
	movq	%rax, 24(%rsp)&lt;br /&gt;
	xorl	%eax, %eax&lt;br /&gt;
	movq	$0, 8(%rsp)&lt;br /&gt;
	movq	$0, 16(%rsp)&lt;br /&gt;
	leaq	.LC3(%rip), %rdi&lt;br /&gt;
	call	puts@PLT&lt;br /&gt;
	cmpl	$0, quit(%rip)&lt;br /&gt;
	js	.L9&lt;br /&gt;
	leaq	menu(%rip), %rbp&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	leaq	.LC4(%rip), %r12&lt;br /&gt;
.L7:&lt;br /&gt;
	addl	$1, %ebx&lt;br /&gt;
	movq	0(%rbp), %rcx&lt;br /&gt;
	movl	%ebx, %edx&lt;br /&gt;
	movq	%r12, %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	addq	$8, %rbp&lt;br /&gt;
	cmpl	quit(%rip), %ebx&lt;br /&gt;
	jle	.L7&lt;br /&gt;
.L6:&lt;br /&gt;
	leaq	.LC5(%rip), %rsi&lt;br /&gt;
	movl	$2, %edi&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	call	__printf_chk@PLT&lt;br /&gt;
	leaq	16(%rsp), %rsi&lt;br /&gt;
	leaq	8(%rsp), %rdi&lt;br /&gt;
	movq	stdin(%rip), %rdx&lt;br /&gt;
	call	getline@PLT&lt;br /&gt;
	movq	%rax, %r12&lt;br /&gt;
	movl	$10, %edx&lt;br /&gt;
	movl	$0, %esi&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	__isoc23_strtol@PLT&lt;br /&gt;
	movq	%rax, %rbp&lt;br /&gt;
	movq	8(%rsp), %rdi&lt;br /&gt;
	call	free@PLT&lt;br /&gt;
	testl	%ebp, %ebp&lt;br /&gt;
	setg	%dl&lt;br /&gt;
	cmpl	%ebx, %ebp&lt;br /&gt;
	setle	%al&lt;br /&gt;
	andl	%eax, %edx&lt;br /&gt;
	testq	%r12, %r12&lt;br /&gt;
	setne	%al&lt;br /&gt;
	movzbl	%al, %eax&lt;br /&gt;
	andl	%edx, %eax&lt;br /&gt;
	negl	%eax&lt;br /&gt;
	andl	%ebp, %eax&lt;br /&gt;
	subl	$1, %eax&lt;br /&gt;
	movq	24(%rsp), %rdx&lt;br /&gt;
	subq	%fs:40, %rdx&lt;br /&gt;
	jne	.L12&lt;br /&gt;
	addq	$32, %rsp&lt;br /&gt;
	.cfi_remember_state&lt;br /&gt;
	.cfi_def_cfa_offset 32&lt;br /&gt;
	popq	%rbx&lt;br /&gt;
	.cfi_def_cfa_offset 24&lt;br /&gt;
	popq	%rbp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	popq	%r12&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
.L9:&lt;br /&gt;
	.cfi_restore_state&lt;br /&gt;
	movl	$0, %ebx&lt;br /&gt;
	jmp	.L6&lt;br /&gt;
.L12:&lt;br /&gt;
	call	__stack_chk_fail@PLT&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE52:&lt;br /&gt;
	.size	choose_program, .-choose_program&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC6:&lt;br /&gt;
	.string	&amp;quot;MENUCMD&amp;quot;&lt;br /&gt;
	.text&lt;br /&gt;
	.globl	main&lt;br /&gt;
	.type	main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB53:&lt;br /&gt;
	.cfi_startproc&lt;br /&gt;
	endbr64&lt;br /&gt;
	subq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 16&lt;br /&gt;
	leaq	.LC6(%rip), %rdi&lt;br /&gt;
	call	getenv@PLT&lt;br /&gt;
	testq	%rax, %rax&lt;br /&gt;
	je	.L14&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
.L18:&lt;br /&gt;
	call	choose_program&lt;br /&gt;
	cmpl	%eax, quit(%rip)&lt;br /&gt;
	je	.L20&lt;br /&gt;
	cmpl	$-1, %eax&lt;br /&gt;
	je	.L18&lt;br /&gt;
	movl	%eax, %edi&lt;br /&gt;
	call	run_program&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L14:&lt;br /&gt;
	movslq	quit(%rip), %rdx&lt;br /&gt;
	leaq	menu(%rip), %rax&lt;br /&gt;
	movq	(%rax,%rdx,8), %rax&lt;br /&gt;
	movq	%rax, 32+menu(%rip)&lt;br /&gt;
	movl	$4, quit(%rip)&lt;br /&gt;
	jmp	.L18&lt;br /&gt;
.L20:&lt;br /&gt;
	movl	$0, %eax&lt;br /&gt;
	addq	$8, %rsp&lt;br /&gt;
	.cfi_def_cfa_offset 8&lt;br /&gt;
	ret&lt;br /&gt;
	.cfi_endproc&lt;br /&gt;
.LFE53:&lt;br /&gt;
	.size	main, .-main&lt;br /&gt;
	.globl	CUSTOM&lt;br /&gt;
	.section	.rodata&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	CUSTOM, @object&lt;br /&gt;
	.size	CUSTOM, 4&lt;br /&gt;
CUSTOM:&lt;br /&gt;
	.long	4&lt;br /&gt;
	.globl	quit&lt;br /&gt;
	.data&lt;br /&gt;
	.align 4&lt;br /&gt;
	.type	quit, @object&lt;br /&gt;
	.size	quit, 4&lt;br /&gt;
quit:&lt;br /&gt;
	.long	5&lt;br /&gt;
	.globl	menu&lt;br /&gt;
	.section	.rodata.str1.1&lt;br /&gt;
.LC7:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ls&amp;quot;&lt;br /&gt;
.LC8:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/ps&amp;quot;&lt;br /&gt;
.LC9:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/nano&amp;quot;&lt;br /&gt;
.LC10:&lt;br /&gt;
	.string	&amp;quot;/usr/bin/top&amp;quot;&lt;br /&gt;
.LC11:&lt;br /&gt;
	.string	&amp;quot;CUSTOM&amp;quot;&lt;br /&gt;
.LC12:&lt;br /&gt;
	.string	&amp;quot;QUIT&amp;quot;&lt;br /&gt;
	.section	.data.rel.local,&amp;quot;aw&amp;quot;&lt;br /&gt;
	.align 32&lt;br /&gt;
	.type	menu, @object&lt;br /&gt;
	.size	menu, 56&lt;br /&gt;
menu:&lt;br /&gt;
	.quad	.LC7&lt;br /&gt;
	.quad	.LC8&lt;br /&gt;
	.quad	.LC9&lt;br /&gt;
	.quad	.LC10&lt;br /&gt;
	.quad	.LC11&lt;br /&gt;
	.quad	.LC12&lt;br /&gt;
	.quad	0&lt;br /&gt;
	.ident	&amp;quot;GCC: (Ubuntu 15.2.0-16ubuntu1) 15.2.0&amp;quot;&lt;br /&gt;
	.section	.note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
	.section	.note.gnu.property,&amp;quot;a&amp;quot;&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	1f - 0f&lt;br /&gt;
	.long	4f - 1f&lt;br /&gt;
	.long	5&lt;br /&gt;
0:&lt;br /&gt;
	.string	&amp;quot;GNU&amp;quot;&lt;br /&gt;
1:&lt;br /&gt;
	.align 8&lt;br /&gt;
	.long	0xc0000002&lt;br /&gt;
	.long	3f - 2f&lt;br /&gt;
2:&lt;br /&gt;
	.long	0x3&lt;br /&gt;
3:&lt;br /&gt;
	.align 8&lt;br /&gt;
4:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_5&amp;diff=25156</id>
		<title>Operating Systems 2026F Lecture 5</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_5&amp;diff=25156"/>
		<updated>2026-09-25T21:10:27Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;==Video==  Video from the lectures given on September 24th and 25th, 2026 are now available: * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec05a-20260924.mp4 Lecture 5A] * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec05b-20260925.mp4 Lecture 5B]  ==Notes==  ===Lecture 5A===  &amp;lt;pre&amp;gt; Lecture 5a ----------  The memory map of a process  - every process has its own view of memory, cannot see the memory of other...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 24th and 25th, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec05a-20260924.mp4 Lecture 5A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec05b-20260925.mp4 Lecture 5B]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 5A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 5a&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
The memory map of a process&lt;br /&gt;
 - every process has its own view of memory, cannot see the memory of other processes&lt;br /&gt;
 - what goes in that address space?&lt;br /&gt;
&lt;br /&gt;
Note that, almost always, the entire address space is NOT VALID MEMORY&lt;br /&gt;
 - if you access most of it, you&#039;ll get an error (segmentation error generally)&lt;br /&gt;
&lt;br /&gt;
So what is a segment?&lt;br /&gt;
&lt;br /&gt;
Well first, consider the address&lt;br /&gt;
 - 64 bit pointer, so 2^64 possible addresses&lt;br /&gt;
&lt;br /&gt;
We can&#039;t have this much RAM, so most of these addresses are invalid.&lt;br /&gt;
 - but which ones are valid?&lt;br /&gt;
 - and on what basis?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First, we should talk about the stack and the heap&lt;br /&gt;
&lt;br /&gt;
The heap is just memory that is allocated in chunks, with each chunk pointed to&lt;br /&gt;
by a pointer&lt;br /&gt;
 - when you call malloc, you&#039;re getting memory from the heap&lt;br /&gt;
 - when you create a new object in most languages other than C, you&#039;re really&lt;br /&gt;
   getting memory from the heap (mostly)&lt;br /&gt;
&lt;br /&gt;
How to manage the heap is a complex problem, solved by memory allocators, garbage collection, etc (beyond the scope of this class)&lt;br /&gt;
&lt;br /&gt;
The stack is memory that is managed in a very simple way: as a stack&lt;br /&gt;
 - LIFO (last in, first out), e.g., a stack of plates&lt;br /&gt;
&lt;br /&gt;
A stack is great because...&lt;br /&gt;
 - no memory leaks!&lt;br /&gt;
 - allocation and de-allocation is trivial&lt;br /&gt;
&lt;br /&gt;
But the discipline of a stack only makes sense in certain contexts&lt;br /&gt;
&lt;br /&gt;
Fortunately, we&#039;ve built our programming languages around those contexts:&lt;br /&gt;
 FUNCTIONS&lt;br /&gt;
&lt;br /&gt;
When a program enters a function, it allocates memory for the function&lt;br /&gt;
When the function exits, that function&#039;s storage needs to be de-allocated&lt;br /&gt;
&lt;br /&gt;
So we need somewhere to put the stack and somewhere to put the heap&lt;br /&gt;
 - could separate, but normally are allocated together&lt;br /&gt;
&lt;br /&gt;
Stack grows from himem (of data segment) down&lt;br /&gt;
heap grows up from the bottom of the data segment&lt;br /&gt;
&lt;br /&gt;
if you put some invalid memory in the middle, you can know when they would potentially overlap (because access to it will generate an error)&lt;br /&gt;
&lt;br /&gt;
a segmentation violation is just an access to memory that hasn&#039;t been allocated&lt;br /&gt;
&lt;br /&gt;
So what&#039;s in memory?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;top&amp;gt;&lt;br /&gt;
  command line args, environment vars&lt;br /&gt;
&lt;br /&gt;
  Data&lt;br /&gt;
 ------ &amp;quot;break&amp;quot;&lt;br /&gt;
  Code&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bottom&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So the command line arguments and environment variables passed to a program&lt;br /&gt;
are at the top of the process&#039;s address space. The kernel put them there when&lt;br /&gt;
the program was launched.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
fork duplicates the current process&lt;br /&gt;
execve replaces the current program with a new one&lt;br /&gt;
 - neither act like normal &amp;quot;functions&amp;quot;, because they are system calls&lt;br /&gt;
&lt;br /&gt;
Windows has &lt;br /&gt;
&lt;br /&gt;
Remember in C we make system calls by calling functions&lt;br /&gt;
 - the functions that make system calls are using compiler-specific ways&lt;br /&gt;
   of making the special CPU instructions for system calls&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
fork &amp;lt;- to make a process&lt;br /&gt;
execve &amp;lt;- to load a program into a process&lt;br /&gt;
exit &amp;lt;- to terminate a process&lt;br /&gt;
wait &amp;lt;- wait for a child to finish&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the parent doesn&#039;t wait for its child, and the child terminates,&lt;br /&gt;
the child sticks around in a zombie state&lt;br /&gt;
 - it is already dead but still around, cannot be further killed&lt;br /&gt;
&lt;br /&gt;
zombies stick around as long as their parent exists&lt;br /&gt;
zombies are &amp;quot;reaped&amp;quot; once the parent dies&lt;br /&gt;
 - init or similar will call wait&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
How do we run programs?&lt;br /&gt;
&lt;br /&gt;
Run fork&lt;br /&gt;
 - duplicates current process, creating a child process&lt;br /&gt;
&lt;br /&gt;
in the parent&lt;br /&gt;
 - wait for the child to finish, or&lt;br /&gt;
 - go do other work and call wait will notified&lt;br /&gt;
   of child termination&lt;br /&gt;
&lt;br /&gt;
in the child&lt;br /&gt;
 - set up things for new program&lt;br /&gt;
   - standard in, out, error, other open files&lt;br /&gt;
     - close any files that SHOULD NOT be accessible&lt;br /&gt;
   - command line arguments&lt;br /&gt;
   - environment variables&lt;br /&gt;
 - execve new program&lt;br /&gt;
&lt;br /&gt;
In practice, you won&#039;t actually see the fork system call nowadays,&lt;br /&gt;
at least on Linux systems. Instead, you&#039;ll see clone&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Containers - have you heard of them?&lt;br /&gt;
&lt;br /&gt;
So containers are all about managing software and dependencies&lt;br /&gt;
 - very poor security isolation properties&lt;br /&gt;
&lt;br /&gt;
Turns out when you create a new process, you can change its view of the world&lt;br /&gt;
 - e.g., give it a different view of the filesystem&lt;br /&gt;
&lt;br /&gt;
namespaces is how you map the following for a process and its children&lt;br /&gt;
&lt;br /&gt;
 /newsystem/bin =&amp;gt; /bin&lt;br /&gt;
 uid 1000 =&amp;gt; uid 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 5B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 5b&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Planning to move midterm to Oct 20, 21&lt;br /&gt;
 - so review will be Oct 15, 16&lt;br /&gt;
 - assignment 2 will be due on the 15th 2:30 PM&lt;br /&gt;
 - a1 will be put off a bit will finalize when posted (you&#039;ll have at least a week)&lt;br /&gt;
 - A1 will be based on T1 and T2&lt;br /&gt;
&lt;br /&gt;
For today, we&#039;re talking memory&lt;br /&gt;
&lt;br /&gt;
With modern OSs, each running process gets its own address space&lt;br /&gt;
 - so 64 bits in size&lt;br /&gt;
 - most of that address space is not allocated, so cannot&lt;br /&gt;
   be used or will generate an error&lt;br /&gt;
 - typically the error is a &amp;quot;segmentation violation&amp;quot;&lt;br /&gt;
   - so what is a segment?&lt;br /&gt;
&lt;br /&gt;
A segment is a unit of memory that has a specific &amp;quot;purpose&amp;quot;&lt;br /&gt;
 - contiguous addresses&lt;br /&gt;
&lt;br /&gt;
What segments are there? You&#039;ll at least have&lt;br /&gt;
 - code (text), read only&lt;br /&gt;
 - data, read write&lt;br /&gt;
   - global variables&lt;br /&gt;
   - dynamically-allocated storage&lt;br /&gt;
&lt;br /&gt;
The data segment has to store two logically distinct types of dynamically allocated memory: the stack and the heap&lt;br /&gt;
&lt;br /&gt;
The heap is used to store dynamically allocated objects/data structures that have indeterminate lifetimes&lt;br /&gt;
 - could be around for a few milliseconds&lt;br /&gt;
 - could exist for most of the run of the program (but aren&#039;t known at compile time)&lt;br /&gt;
 - malloc (C), new (C++), most everything in JavaScript &amp;amp; Python&lt;br /&gt;
&lt;br /&gt;
Now this might sound complicated because IT IS&lt;br /&gt;
 - entire area of memory management techniques&lt;br /&gt;
 - automatic memory management is called &amp;quot;garbage collection&amp;quot;&lt;br /&gt;
   - not only but most general approach&lt;br /&gt;
&lt;br /&gt;
The heap is complex, hard to do right, so traditionally UNIX programs have avoided using the heap as much as possible and instead used the stack&lt;br /&gt;
&lt;br /&gt;
So what&#039;s the stack?&lt;br /&gt;
 - data structure that respects LIFO discipline (last in, first out)&lt;br /&gt;
&lt;br /&gt;
A process normally has one stack that is used for functions&lt;br /&gt;
 - local variables&lt;br /&gt;
 - arguments&lt;br /&gt;
 - return values&lt;br /&gt;
&lt;br /&gt;
heap grows up from bottom of data segment&lt;br /&gt;
stack grows down from the top of the data segment&lt;br /&gt;
&lt;br /&gt;
normally some invalid memory in the middle so you know when the two run into each other&lt;br /&gt;
&lt;br /&gt;
Where do the environment variables and command line variables come from?&lt;br /&gt;
&lt;br /&gt;
Those are both arguments of the execve system call&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Key system calls for running a program in a new process are:&lt;br /&gt;
 - fork&lt;br /&gt;
 - execve&lt;br /&gt;
 - wait&lt;br /&gt;
&lt;br /&gt;
fork: duplicates the current process&lt;br /&gt;
 - new process is called the child, old the parent&lt;br /&gt;
 - except for the PID/PPID and the return value of fork(),&lt;br /&gt;
   code, data, and other state are IDENTICAL&lt;br /&gt;
&lt;br /&gt;
child calls execve&lt;br /&gt;
 - sets up argv, env, open files (standard in/out/error +),&lt;br /&gt;
   signal handlers (will discuss later)&lt;br /&gt;
 - then loads new program binary with execve call, which REPLACES&lt;br /&gt;
   the code in the process&lt;br /&gt;
 - if execve returns, it failed&lt;br /&gt;
&lt;br /&gt;
parent calls wait&lt;br /&gt;
 - either literally waiting for child process to terminate, or&lt;br /&gt;
 - in response to a signal that the child has terminated&lt;br /&gt;
&lt;br /&gt;
Why does the parent care about the child process terminating?&lt;br /&gt;
 - because it has a return status&lt;br /&gt;
&lt;br /&gt;
processes terminate with the exit system call, and exit takes an integer argument that is past via wait to the parent&lt;br /&gt;
&lt;br /&gt;
Modern Linux systems tend not to use the fork system call&lt;br /&gt;
 - fork() actually calls clone&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t use setarch -R to run 3000memview, addresses will be randomized. This is ASLR in action: address space layout randomization&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25155</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25155"/>
		<updated>2026-09-24T21:14:40Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Setting up and connecting a VM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in the SCS documentation. Make sure do the following:&lt;br /&gt;
* Choose the COMP3000-F26.2026-* instance snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Join the class Team if you haven&#039;t already. Link is in brightspace.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25154</id>
		<title>Operating Systems 2026F Lecture 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25154"/>
		<updated>2026-09-24T21:12:19Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Video */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 22nd and 23rd, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 Lecture 4A]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 Lecture 4B]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 4A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 4A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Why is the original LinuxOnTab pretty slow?&lt;br /&gt;
 - load the whole linux distribution over the web, all at once&lt;br /&gt;
 - but also, it is emulating an x86 processor (32 bit)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What is happening when you load a web page? What code is running?&lt;br /&gt;
 - by default, it is HTML, CSS, JavaScript&lt;br /&gt;
 - so how do you run x86 code?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sidebar - what is x86?&lt;br /&gt;
 - refers to the instruction set of Intel (and then AMD) processors&lt;br /&gt;
&lt;br /&gt;
8080 - 8 bit&lt;br /&gt;
8086/8088 - 16 bit&lt;br /&gt;
 - 8088 was in the first IBM PC&lt;br /&gt;
80286&lt;br /&gt;
80386 &amp;lt;-- first 32 bit x86 processor&lt;br /&gt;
80486&lt;br /&gt;
Pentium&lt;br /&gt;
Pentium Pro&lt;br /&gt;
...&lt;br /&gt;
Intel decided to go make the Itanium for its 64 bit processor&lt;br /&gt;
 - not backwards compatible&lt;br /&gt;
&lt;br /&gt;
AMD made x86-64&lt;br /&gt;
 - 64 bit version of x86&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So what&#039;s going on in your web browser?&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v1&lt;br /&gt;
x86 emulator&lt;br /&gt;
Firefox (JavaScript/WebAssembly)&lt;br /&gt;
x86-64 &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v2 (in WebAssembly)&lt;br /&gt;
Firefox (JavaScript/WebAssembly)&lt;br /&gt;
x86-64 &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An operating system can be big or small&lt;br /&gt;
 - a small operating system =&amp;gt; complexity pushed to applications&lt;br /&gt;
 - a big operating system =&amp;gt; applications can be simple, use rich functionality of OS&lt;br /&gt;
&lt;br /&gt;
Again, files are not all &amp;quot;files&amp;quot;&lt;br /&gt;
 - many aren&#039;t real &amp;lt;- /proc, /sys, /dev&lt;br /&gt;
 - many aren&#039;t persistent &amp;lt;- tmpfs filesystems&lt;br /&gt;
&lt;br /&gt;
Shell variables are private to a shell process&lt;br /&gt;
&lt;br /&gt;
Environment variables are passed to any child processes&lt;br /&gt;
 - a child process is created from a parent process&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 4B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 4B&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Why are some operating systems big, and others small?&lt;br /&gt;
 - small because you don&#039;t have room for anything else&lt;br /&gt;
 - large because more functionality -&amp;gt; simpler applications&lt;br /&gt;
   (for the developer)&lt;br /&gt;
&lt;br /&gt;
Intel processors&lt;br /&gt;
8080 &amp;lt;- 8 bit&lt;br /&gt;
8088/8086 &amp;lt;- 16 bit (Original IBM PC)&lt;br /&gt;
80286&lt;br /&gt;
80386 &amp;lt;- 32 bit processor&lt;br /&gt;
80486&lt;br /&gt;
Pentium&lt;br /&gt;
Pentium Pro&lt;br /&gt;
&lt;br /&gt;
Itanium &amp;lt;--- 64 bit processor, NOT backwards compatible&lt;br /&gt;
&lt;br /&gt;
AMD came up with x86-64, and Intel had to adopt it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In LinuxOnTab, we have&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v1&lt;br /&gt;
v86 emulator (in WebAssembly)&lt;br /&gt;
Browser (x86 or ARM) &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v2 (in WebAssembly)&lt;br /&gt;
Browser (x86 or ARM) &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
v1 is slower because&lt;br /&gt;
 - emulates x86-32&lt;br /&gt;
 - loads whole disk image&lt;br /&gt;
&lt;br /&gt;
v2 loads on demand and has native WebAssembly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25153</id>
		<title>Operating Systems 2026F Lecture 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25153"/>
		<updated>2026-09-24T21:11:28Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 22nd and 23rd, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 September 22nd video]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 September 23rd video]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&lt;br /&gt;
===Lecture 4A===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 4A&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Why is the original LinuxOnTab pretty slow?&lt;br /&gt;
 - load the whole linux distribution over the web, all at once&lt;br /&gt;
 - but also, it is emulating an x86 processor (32 bit)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
What is happening when you load a web page? What code is running?&lt;br /&gt;
 - by default, it is HTML, CSS, JavaScript&lt;br /&gt;
 - so how do you run x86 code?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sidebar - what is x86?&lt;br /&gt;
 - refers to the instruction set of Intel (and then AMD) processors&lt;br /&gt;
&lt;br /&gt;
8080 - 8 bit&lt;br /&gt;
8086/8088 - 16 bit&lt;br /&gt;
 - 8088 was in the first IBM PC&lt;br /&gt;
80286&lt;br /&gt;
80386 &amp;lt;-- first 32 bit x86 processor&lt;br /&gt;
80486&lt;br /&gt;
Pentium&lt;br /&gt;
Pentium Pro&lt;br /&gt;
...&lt;br /&gt;
Intel decided to go make the Itanium for its 64 bit processor&lt;br /&gt;
 - not backwards compatible&lt;br /&gt;
&lt;br /&gt;
AMD made x86-64&lt;br /&gt;
 - 64 bit version of x86&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So what&#039;s going on in your web browser?&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v1&lt;br /&gt;
x86 emulator&lt;br /&gt;
Firefox (JavaScript/WebAssembly)&lt;br /&gt;
x86-64 &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v2 (in WebAssembly)&lt;br /&gt;
Firefox (JavaScript/WebAssembly)&lt;br /&gt;
x86-64 &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
An operating system can be big or small&lt;br /&gt;
 - a small operating system =&amp;gt; complexity pushed to applications&lt;br /&gt;
 - a big operating system =&amp;gt; applications can be simple, use rich functionality of OS&lt;br /&gt;
&lt;br /&gt;
Again, files are not all &amp;quot;files&amp;quot;&lt;br /&gt;
 - many aren&#039;t real &amp;lt;- /proc, /sys, /dev&lt;br /&gt;
 - many aren&#039;t persistent &amp;lt;- tmpfs filesystems&lt;br /&gt;
&lt;br /&gt;
Shell variables are private to a shell process&lt;br /&gt;
&lt;br /&gt;
Environment variables are passed to any child processes&lt;br /&gt;
 - a child process is created from a parent process&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Lecture 4B===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Lecture 4B&lt;br /&gt;
----------&lt;br /&gt;
&lt;br /&gt;
Why are some operating systems big, and others small?&lt;br /&gt;
 - small because you don&#039;t have room for anything else&lt;br /&gt;
 - large because more functionality -&amp;gt; simpler applications&lt;br /&gt;
   (for the developer)&lt;br /&gt;
&lt;br /&gt;
Intel processors&lt;br /&gt;
8080 &amp;lt;- 8 bit&lt;br /&gt;
8088/8086 &amp;lt;- 16 bit (Original IBM PC)&lt;br /&gt;
80286&lt;br /&gt;
80386 &amp;lt;- 32 bit processor&lt;br /&gt;
80486&lt;br /&gt;
Pentium&lt;br /&gt;
Pentium Pro&lt;br /&gt;
&lt;br /&gt;
Itanium &amp;lt;--- 64 bit processor, NOT backwards compatible&lt;br /&gt;
&lt;br /&gt;
AMD came up with x86-64, and Intel had to adopt it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In LinuxOnTab, we have&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v1&lt;br /&gt;
v86 emulator (in WebAssembly)&lt;br /&gt;
Browser (x86 or ARM) &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
LinuxOnTab v2 (in WebAssembly)&lt;br /&gt;
Browser (x86 or ARM) &amp;lt;-&amp;gt; Kernel&lt;br /&gt;
Hardware&lt;br /&gt;
&lt;br /&gt;
v1 is slower because&lt;br /&gt;
 - emulates x86-32&lt;br /&gt;
 - loads whole disk image&lt;br /&gt;
&lt;br /&gt;
v2 loads on demand and has native WebAssembly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25152</id>
		<title>Operating Systems 2026F Lecture 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25152"/>
		<updated>2026-09-24T17:49:50Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 22nd and 23rd, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 September 22nd video]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 September 23rd video]&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25151</id>
		<title>Operating Systems 2026F Lecture 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25151"/>
		<updated>2026-09-24T17:45:29Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 22nd and 23rd, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 September 22nd video]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 September 23rd video]&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25150</id>
		<title>Operating Systems 2026F Lecture 4</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F_Lecture_4&amp;diff=25150"/>
		<updated>2026-09-24T17:45:18Z</updated>

		<summary type="html">&lt;p&gt;Soma: Created page with &amp;quot;==Video==  Video from the lectures given on September 22nd and 23rd, 2026 are now available: * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 September 15th video] * [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 September 16th video]&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Video==&lt;br /&gt;
&lt;br /&gt;
Video from the lectures given on September 22nd and 23rd, 2026 are now available:&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04a-20260922.mp4 September 15th video]&lt;br /&gt;
* [https://homeostasis.scs.carleton.ca/~soma/os-2026f/lectures/comp3000-2026f-lec04b-20260923.mp4 September 16th video]&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25145</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25145"/>
		<updated>2026-09-21T19:16:04Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Tutorials */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]] (NSPW)&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]] (NSPW)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Lecture 10]]: Midterm Review&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Midterm (in class)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 23|Lecture 23]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
Tutorials must be marked within 8 days of the tutorial being made available. (For example, T1 must be marked by the end of Sept. 22nd.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25144</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25144"/>
		<updated>2026-09-21T16:18:34Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the COMP3000-F26.2026-* instance snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Join the class Team if you haven&#039;t already. Link is in brightspace.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25143</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25143"/>
		<updated>2026-09-21T14:25:37Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Setting up and connecting a VM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the COMP3000-F26.2026-* instance snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Join the class Team if you haven&#039;t already. Link is in brightspace.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25142</id>
		<title>Operating Systems (Fall 2026)</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_(Fall_2026)&amp;diff=25142"/>
		<updated>2026-09-21T13:33:27Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Assignments */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Course Outline==&lt;br /&gt;
&lt;br /&gt;
[[Operating Systems (Fall 2026) Course Outline|Here]] is the course outline for COMP 3000: Operating Systems.&lt;br /&gt;
&lt;br /&gt;
==Lectures &amp;amp; Exams==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Topic&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 9, 10&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 1|Lecture 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 2|Lecture 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 3|Lecture 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 4|Lecture 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 5|Lecture 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 29, 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 6|Lecture 6]] (NSPW)&amp;lt;br&amp;gt;(Last day to withdraw with fee adjustment: Sep. 30)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 7|Lecture 7]] (NSPW)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 6, 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 8|Lecture 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 9|Lecture 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 10|Lecture 10]]: Midterm Review&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 15, 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Midterm (in class)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 20, 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 11|Lecture 11]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 22, 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 12|Lecture 12]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 13|Lecture 13]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 5, 6&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 14|Lecture 14]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 10, 11&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 15|Lecture 15]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 12, 13&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 16|Lecture 16]]&amp;lt;br&amp;gt;&lt;br /&gt;
	  (Last day to withdraw Nov. 13)&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 17, 18&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
	&amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 17|Lecture 17]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 19, 20&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 18|Lecture 18]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 24, 25&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 19|Lecture 19]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 26, 27&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 20|Lecture 20]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 1, 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 21|Lecture 21]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 3, 4&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 22|Lecture 22]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 8, 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F Lecture 23|Lecture 23]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;TBA&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Final Exam&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tutorials==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Date Available&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Tutorials&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 14&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 1|Tutorial 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 21&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 2|Tutorial 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 28&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 3|Tutorial 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct 5&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 4|Tutorial 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 19&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 5|Tutorial 5]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 2&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 6|Tutorial 6]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 9&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 7|Tutorial 7]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 8|Tutorial 8]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 23&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Tutorial 9|Tutorial 9]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Assignments==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;width: 100%;&amp;quot; border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; cellspacing=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Due Date&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
    &amp;lt;p align=&amp;quot;left&amp;quot;&amp;gt;Assignments&amp;lt;/p&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Sep. 30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 1|Assignment 1]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Oct. 13, 14:30&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 2|Assignment 2]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Nov. 16&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 3|Assignment 3]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;Dec. 7&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;p&amp;gt;[[Operating Systems 2026F: Assignment 4|Assignment 4]]&lt;br /&gt;
      &amp;lt;/p&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25141</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25141"/>
		<updated>2026-09-20T15:02:38Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Join the class Team if you haven&#039;t already. Link is in brightspace.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25140</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25140"/>
		<updated>2026-09-19T19:26:52Z</updated>

		<summary type="html">&lt;p&gt;Soma: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is not yet finalized.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25139</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25139"/>
		<updated>2026-09-19T19:26:15Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Tasks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25138</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25138"/>
		<updated>2026-09-19T19:23:22Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* C: Comparing C and assembly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language (only needed if you want to learn more):&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25137</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25137"/>
		<updated>2026-09-19T19:22:14Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* C: Comparing C and assembly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language:&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25136</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25136"/>
		<updated>2026-09-19T19:22:02Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* C: Comparing C and assembly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language:&lt;br /&gt;
* [https://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf CMU introduction to x86-64]&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25135</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25135"/>
		<updated>2026-09-19T19:20:43Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* B: Function calls, library calls, and system calls */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language:&lt;br /&gt;
* [https://cs61.seas.harvard.edu/site/2018/Asm1/ Eddie Kohler&#039;s assembly language basics (2018)] (also see other notes from this class)&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25134</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25134"/>
		<updated>2026-09-19T19:17:56Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Connecting to Openstack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to [https://carleton.ca/its/vpn-access-to-campus/ VPN in] if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# Use the command &amp;lt;tt&amp;gt;ls -l&amp;lt;/tt&amp;gt; to see the metadata associated with prog.c and prog-dyn, and prog-static.  Who owns these files?  What group are they in?  Do you notice any pattern with the permissions (rwx) associated with each file?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language:&lt;br /&gt;
* [https://cs61.seas.harvard.edu/site/2018/Asm1/ Eddie Kohler&#039;s assembly language basics (2018)] (also see other notes from this class)&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
	<entry>
		<id>https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25133</id>
		<title>Operating Systems 2026F: Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://homeostasis.scs.carleton.ca/wiki/index.php?title=Operating_Systems_2026F:_Tutorial_2&amp;diff=25133"/>
		<updated>2026-09-19T19:17:17Z</updated>

		<summary type="html">&lt;p&gt;Soma: /* Connecting to Openstack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;This tutorial is still in development.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In this tutorial we&#039;re going to look at how processes work at a low level: how they make system calls &amp;amp; library calls, how C and assembly compare, and and how memory is laid out.&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you need to get access to a Linux or UNIX machine, and LinuxOnTab isn&#039;t enough.  We strongly suggest you use an SCS Openstack instance (see below).  You&#039;ll need access to a system for the entire semester, ideally the same one.&lt;br /&gt;
&lt;br /&gt;
The concepts covered below are mostly part of standard UNIX/Linux tutorials.  Feel free to consult one or more of them.  However, remember that you are trying to build a conceptual model of how things work.  Thus, don&#039;t memorize commands; instead, try to understand how things fit together, and ask questions when things don&#039;t work as expected!&lt;br /&gt;
&lt;br /&gt;
If you find yourself searching for the answers to specific questions, you&#039;re probably doing it wrong.&lt;br /&gt;
&lt;br /&gt;
Feel free to discuss this tutorial on Teams in the Tutorials channel.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Again, for emphasis: don&#039;t take snapshots!&#039;&#039;&#039; (see below)&lt;br /&gt;
&lt;br /&gt;
===Connecting to Openstack===&lt;br /&gt;
&lt;br /&gt;
SCS has [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/ lots of documentation on openstack], including a [https://carleton.ca/scs/tech-support/scs-open-stack/openstack-technical-support/openstack-step-by-step-guide/ step-by-step guide].  Start here!&lt;br /&gt;
&lt;br /&gt;
Create a VM on the new SCS openstack cluster at [https://openstack-stein.scs.carleton.ca openstack-stein.scs.carleton.ca] and do your work there.  While you don&#039;t need a persistent VM for this lab, it will be important for future tuturials - and it is nice to have your work stick around when you leave the lab.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To access Openstack&#039;&#039;&#039; you must be on the Carleton network, so make sure to VPN in if you aren&#039;t on the Carleton computer or WiFi network.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;To get added to the COMP 3000 project&#039;&#039;&#039;, you need to [http://www.scs.carleton.ca/webacct change your SCS password] (run newacct) in order to update your account to have the right entitlements.&lt;br /&gt;
&lt;br /&gt;
===Setting up and connecting a VM===&lt;br /&gt;
&lt;br /&gt;
Create a VM on the SCS openstack cluster as shown in lecture. Make sure do the following:&lt;br /&gt;
* Choose the comp3000-2026f-* snapshot image ONLY (others won&#039;t have the right software for later tutorials), use the latest one.&lt;br /&gt;
* Add the ping-ssh-egress security group, and&lt;br /&gt;
* Associating a floating IP address.&lt;br /&gt;
&lt;br /&gt;
The 192.168.X.X IP addresses are private (and cannot be accessed outside of the openstack cluster), the 134.117.X.X floating IP addresses can be accessed from the Carleton network and will allow you to access the wider Internet. You need to &#039;&#039;&#039;ssh to your VM instance&#039;&#039;&#039;. Windows, Ubuntu and MacOS all have SSH clients available from their command lines, just type &amp;quot;ssh student@&amp;lt;IP address&amp;gt;&amp;quot; where the IP address is the floating IP address you assigned to your VM (while connected to the Carleton VPN). Other tools supporting SSH (e.g., PuTTY) also work.&lt;br /&gt;
&lt;br /&gt;
Once you are prompted to log in, the default user is student, default password is student. You&#039;ll have to change your password after you first login.  (If you want to change your password later, use the &amp;lt;tt&amp;gt;passwd&amp;lt;/tt&amp;gt; command.)&lt;br /&gt;
&lt;br /&gt;
You can also connect directly to your instance with ssh -J (proxy), going through access:&lt;br /&gt;
&lt;br /&gt;
  ssh -J &amp;lt;SCS username&amp;gt;@access.scs.carleton.ca student@&amp;lt;Openstack floating IP address&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Don&#039;t use the web console unless it is an emergency, it will be glitchy.  Also, x2go won&#039;t work because the VM doesn&#039;t have a desktop environment installed, on purpose.)&lt;br /&gt;
&lt;br /&gt;
===Backups===&lt;br /&gt;
&lt;br /&gt;
The image provides an &amp;quot;scs-backup&amp;quot; command that will backup the student user&#039;s directory to the SCS linux machines. So if your SCS username is janedoe, you can type:&lt;br /&gt;
 scs-backup janedoe&lt;br /&gt;
and it will create a copy of everything (note: you can customize it) in the student account in a directory called &amp;quot;COMP3000VM-backup&amp;quot; in your home directory. You can ssh/sftp to access.scs.carleton.ca in order to access this copy of your VM&#039;s files.&lt;br /&gt;
&lt;br /&gt;
You should do backups at the end of every session and before you do anything dangerous.  While the cluster is generally stable, you should be ready for everything in it to be erased at a moment&#039;s notice, because it could happen!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note that you cannot take snapshots of your VM, so please don&#039;t try (it will keep trying and never succeed, and you&#039;ll make work for the tech staff who have to cancel what you did).&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Background==&lt;br /&gt;
&lt;br /&gt;
A process on UNIX-like systems are separated from each other: they run in their own address space - pointers can only refer to code and data in that program, not in other programs.  Because programs are separated, they can&#039;t access anything external to them without help.&lt;br /&gt;
&lt;br /&gt;
Here we&#039;re going to talk about libraries and system calls, two ways programs gain access to additional functionality.  Libraries are for external code that is loaded into a process, while system calls allow for code in other processes or the OS kernel to be accessed.&lt;br /&gt;
&lt;br /&gt;
You may want to refer to the background from [[Operating Systems 2026F: Tutorial 1|Tutorial 1]] as well.&lt;br /&gt;
&lt;br /&gt;
===Online Documentation (man pages)===&lt;br /&gt;
&lt;br /&gt;
The man (short for manual) command is one of the primary ways to to access built-in software documentation.  Most software packages that provide command-line programs include man pages.&lt;br /&gt;
&lt;br /&gt;
For almost any commands mentioned in the tutorials, you can use &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; to find the usage.  While you can also find documentation online for these same commands, many have multiple variants that have different functionality.  The man page is guaranteed to document the version installed on your system.&lt;br /&gt;
&lt;br /&gt;
Man pages are divided into multiple sections, with each section having its own purpose, e.g., 1 for general commands, 2 for system calls, and 3 for library functions.  You can specify the section as the first argument to &amp;lt;tt&amp;gt;man&amp;lt;/tt&amp;gt; if there is more than one man page with the same name.  For instance, tee is both a command (&amp;lt;tt&amp;gt;man 1 tee&amp;lt;/tt&amp;gt;) and a system call (&amp;lt;tt&amp;gt;man 2 tee&amp;lt;/tt&amp;gt;).  The lowest number man page will be returned if the section is not specified.&lt;br /&gt;
&lt;br /&gt;
Note that the topics in man pages go beyond just software &amp;amp; command manuals; they also include conventions and abstract concepts (e.g., &amp;lt;tt&amp;gt;man syscalls&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;man man-pages&amp;lt;/tt&amp;gt;).  Thus if you have questions, consider browsing the man pages rather than just going to a search engine.&lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;whatis&amp;lt;/tt&amp;gt; gives you a man summary, and &amp;lt;tt&amp;gt;apropos&amp;lt;/tt&amp;gt; is a quick way to search man pages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Downloading Code &amp;amp; Compiling Programs===&lt;br /&gt;
&lt;br /&gt;
To download C programs to your VM, use &amp;lt;tt&amp;gt;wget&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;curl&amp;lt;/tt&amp;gt; commands:&lt;br /&gt;
&lt;br /&gt;
 wget https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
 curl https://people.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c -o hello.c&lt;br /&gt;
&lt;br /&gt;
To compile, use gcc:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
This compiles it with level 2 optimization and without debugging symbols.&lt;br /&gt;
&lt;br /&gt;
To run, you have to specify where it is:&lt;br /&gt;
&lt;br /&gt;
 ./hello&lt;br /&gt;
&lt;br /&gt;
Remember you can change directories using the &amp;lt;tt&amp;gt;cd&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
By default gcc-produced binaries are dynamically linked (so at runtime they will require dynamic libraries to be present on the system).  To compile a binary that is statically linked (so it has no external runtime library dependencies), instead do this:&lt;br /&gt;
&lt;br /&gt;
 gcc -O2 -static hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
===Assembly Language===&lt;br /&gt;
&lt;br /&gt;
When we write code in C, it has to be compiled to machine code before it can be run.  This compilation step doesn&#039;t happen all at once.  Compilation has distinct phases:&lt;br /&gt;
&lt;br /&gt;
* Compile C code into assembly code (.s files).&lt;br /&gt;
* Assemble assembly code into machine code placed in object code files (.o files).&lt;br /&gt;
* Link object code files together to create a runnable binary.&lt;br /&gt;
&lt;br /&gt;
If you run &amp;lt;tt&amp;gt;gcc -v&amp;lt;/tt&amp;gt;, you&#039;ll see these steps all happen in a very verbose fashion.&lt;br /&gt;
&lt;br /&gt;
===Static &amp;amp; Dynamic Libraries===&lt;br /&gt;
&lt;br /&gt;
Most applications are not self contained; they rely on lots of external code.  In compiled languages such as C, external code can be brought into the process through &#039;&#039;&#039;linking&#039;&#039;&#039;.  There are two basic types of linking, static and dynamic linking:&lt;br /&gt;
* With &#039;&#039;&#039;static linking&#039;&#039;&#039;, code is brought in at compile time (specifically, in the link stage) and added to the executable.  The code is now the same as other application code.  (Static libraries are just collections of .o files.)&lt;br /&gt;
* With &#039;&#039;&#039;dynamic linking&#039;&#039;&#039;, a reference to the library code is added to the binary.  The actual library code has to later be loaded when the program is executed.  This loading will happen before &amp;lt;tt&amp;gt;main()&amp;lt;/tt&amp;gt; is called.&lt;br /&gt;
Static and dynamic libraries are stored in /lib and /usr/lib, traditionally.&lt;br /&gt;
&lt;br /&gt;
The dynamic libraries associated with a program binary can be found using the &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; command.  You can use &amp;lt;tt&amp;gt;ltrace&amp;lt;/tt&amp;gt; to see calls to functions that are dynamically linked.  If a program is statically linked &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; will have nothing to report and will generally produce an error.&lt;br /&gt;
&lt;br /&gt;
Note that code in static and dynamic libraries runs inside of the process loading the code; thus, library code has the same privileges as other application code.  It can do everything regular application code can do (it can access all of your code and data), but it can do no more than your code can do (it has the same restrictions on accessing system resources).&lt;br /&gt;
&lt;br /&gt;
===System Calls===&lt;br /&gt;
&lt;br /&gt;
A process on its own has limited access to the system.  It cannot directly access any external devices or data sources (e.g., files, keyboard, the screen, networks) on its own.  To access these external resources, to allocate memory, or otherwise change its runtime environment, it must make &#039;&#039;&#039;system calls&#039;&#039;&#039;.  Note that system calls run code outside of a process and thus cannot be called like regular function calls.  The standard C library provides function wrappers for most commonly-used system calls so they can be accessed like regular C functions.  Under the hood, however, these functions make use of special compiler directives in order to generate the machine code necessary to invoke system calls.&lt;br /&gt;
&lt;br /&gt;
You can see the system calls produced by a process using the &amp;lt;tt&amp;gt;strace&amp;lt;/tt&amp;gt; command.&lt;br /&gt;
&lt;br /&gt;
In general, the code you call through a system call has more privileges than regular application code.  This is because a system call is a request to the operating system kernel to do something on behalf of the process, and the kernel has full privileges to the system.  (Indeed, it is the part of the system that implements the process abstraction.)  We&#039;re going to talk a lot about system calls this semester, this is just your introduction to the concept.&lt;br /&gt;
&lt;br /&gt;
==Tasks==&lt;br /&gt;
&lt;br /&gt;
===A: Exploring the Openstack VM===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;How does the environment of the Openstack VM compare to the LinuxOnTab one from Tutorial 1? Specifically, how do the following compare?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;ol style=&amp;quot;list-style-type:lower-alpha&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The version of your Linux distribution and the version of your Linux kernel.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The name (binary path) of the current shell, and the shell version.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;RAM, disk space, and CPU.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Using the man command, find out what the following commands do: &amp;lt;tt&amp;gt;which&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;pwd&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;who&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;whoami&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;env&amp;lt;/tt&amp;gt; and&lt;br /&gt;
&amp;lt;tt&amp;gt;whereis&amp;lt;/tt&amp;gt;.  Try using each of them.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Does the Openstack VM run the same or different programs for standard Linux commands? How do you know?&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Making your own commands: the PATH environment variable lists the directories the shell uses to search for external commands. Where can you find documentation on it? How can you add the current directory (whichever directory you are currently in) to PATH? Then, how to make that change permanent? Try to identify multiple ways.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compile and run [http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c &amp;lt;tt&amp;gt;csimpleshell.c&amp;lt;/tt&amp;gt;]. How does its functionality compare to that of bash? List at least 3 differences.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===B: Function calls, library calls, and system calls===&lt;br /&gt;
&lt;br /&gt;
For [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c] and [http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c] do the following (&amp;lt;b&amp;gt;substituting the appropriate source file for prog.c&amp;lt;/b&amp;gt;). For example, for hello.c, you would replace all instances of &amp;quot;prog&amp;quot; in a command with &amp;quot;hello&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
To download programs to your VM, use the wget command, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 wget https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# Compile the program prog.c using &amp;lt;tt&amp;gt;gcc -O2 prog.c -o prog-dyn&amp;lt;/tt&amp;gt; and run prog-dyn.  What does it do?&lt;br /&gt;
# Statically compile and optimize prog.c by running &amp;lt;tt&amp;gt;gcc -O2 -static prog.c -o prog-static&amp;lt;/tt&amp;gt;.  How does the size compare with &amp;lt;tt&amp;gt;prog&amp;lt;/tt&amp;gt;?&lt;br /&gt;
# Run &amp;lt;tt&amp;gt;ldd&amp;lt;/tt&amp;gt; on the static and dynamic versions of the program.  How does the output compare?  Why?&lt;br /&gt;
# See what system calls prog-static produces by running &amp;lt;tt&amp;gt;strace -o syscalls-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more system calls?  &#039;&#039;&#039;Note: system calls are saved in the log file syscalls-static.log.  Feel free to save them in a different file.&#039;&#039;&#039;&lt;br /&gt;
# See what library calls prog-static produces by running &amp;lt;tt&amp;gt;ltrace -x &#039;*&#039; -o library-static.log ./prog-static&amp;lt;/tt&amp;gt;.  Do the same for &amp;lt;tt&amp;gt;prog-dyn&amp;lt;/tt&amp;gt;.  Which version generates more library calls?  (Note: you will have to run &amp;lt;tt&amp;gt;sudo apt install ltrace&amp;lt;/tt&amp;gt; to enable the command.)&lt;br /&gt;
# Compile the program dynamically but with &amp;quot;lazy&amp;quot; linking: &amp;lt;tt&amp;gt;gcc -O2 -z lazy prog.c -o prog-dynlazy&amp;lt;/tt&amp;gt;.  Run &amp;lt;tt&amp;gt;ltrace -o library-lazy.log ./prog-dynlazy&amp;lt;/tt&amp;gt;.  How does the output of this compare to that of the previous ltrace?&lt;br /&gt;
# Use the command &amp;lt;tt&amp;gt;ls -l&amp;lt;/tt&amp;gt; to see the metadata associated with prog.c and prog-dyn, and prog-static.  Who owns these files?  What group are they in?  Do you notice any pattern with the permissions (rwx) associated with each file?&lt;br /&gt;
# (optional) Look up the documentation for each of the system calls made by the static versions of the programs.  You may need to append a 2 or 3 to the manpage invocation, e.g. &amp;quot;man 2 write&amp;quot; gets you the write system call documentation.&lt;br /&gt;
&lt;br /&gt;
===C: Comparing C and assembly===&lt;br /&gt;
&lt;br /&gt;
Do the following with hello.c and syscall-hello.c, as before.&lt;br /&gt;
&lt;br /&gt;
A few tips on x86-64 assembly language:&lt;br /&gt;
* The last letter of many instructions refers to the size of the operand.  For example, callq means call a function using a &amp;quot;quad&amp;quot; value (64 bits).&lt;br /&gt;
* A dollar sign preceding a value means that it is a literal value, a percent sign means it is a register.&lt;br /&gt;
* If a register is in parentheses, then it is being used as a &amp;quot;pointer&amp;quot; (it contains an address, so the CPU goes to that address and interacts with the memory there).  If there is a number before the parentheses, it is an offset to the register&#039;s value.&lt;br /&gt;
&lt;br /&gt;
Resources on x86-64 assembly language:&lt;br /&gt;
* [https://cs61.seas.harvard.edu/site/2018/Asm1/ Eddie Kohler&#039;s assembly language basics (2018)] (also see other notes from this class)&lt;br /&gt;
* [https://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax AT&amp;amp;T/GNU Assembler syntax]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI the Wikipedia article on calling conventions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Using the &amp;lt;tt&amp;gt;nm&amp;lt;/tt&amp;gt; command, see what symbols are defined in prog-static and prog-dyn.  Which defines more symbols?&lt;br /&gt;
# Run the command &amp;lt;tt&amp;gt;gcc -c -O2 prog.c&amp;lt;/tt&amp;gt; to produce an object file.  What file was produced?  What symbols does it define?&lt;br /&gt;
# Look at the assembly code of the program by running &amp;lt;tt&amp;gt;gcc -S -O2 prog.c&amp;lt;/tt&amp;gt;.  What file was produced?  Identify the following in the assembly code (if present):&lt;br /&gt;
#* A function call (call)&lt;br /&gt;
#* A return from a function (ret)&lt;br /&gt;
#* Registers being saved onto the stack (push)&lt;br /&gt;
#* Registers being retrieved from the stack (pop)&lt;br /&gt;
#* Subtraction (sub)&lt;br /&gt;
#* A system call (syscall)&lt;br /&gt;
# Disassemble the object file using &amp;lt;tt&amp;gt;objdump -d&amp;lt;/tt&amp;gt;.  How does this disassembly compare with the output from gcc -S?&lt;br /&gt;
# Examine the headers of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -h&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Examine the contents of object file, dynamically linked executable, and the statically linked executable using &amp;lt;tt&amp;gt;objdump -s&amp;lt;/tt&amp;gt;&lt;br /&gt;
# Re-run all of the previous gcc commands adding the &amp;quot;-v&amp;quot; flag.  What is all of that output?&lt;br /&gt;
&lt;br /&gt;
===D: Examining the runtime memory map===&lt;br /&gt;
&lt;br /&gt;
Compile and run [https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c], then consider the following questions.&lt;br /&gt;
# Why are the addresses inconsistent between runs?  What happens if you run the program with the command &amp;quot;setarch -R ./3000memview&amp;quot;?  (Note this changes how 3000memview is run.) &lt;br /&gt;
# Roughly where does the stack seem to be?  The heap?  Code?  Global variables?&lt;br /&gt;
# Observe how the heap grows (i.e. the value of sbrk changes) in response to malloc calls.  Would you expect the heap to ever run into the stack?  Why or why not?&lt;br /&gt;
# Change each malloc call to allocate more than 128K.  What happens to the values of sbrk?  Why?  (Hint: use strace)&lt;br /&gt;
# Add more code and data to the program, and add more printf&#039;s to see where things are.  Are things where you expect them to be?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/hello.c hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[]) {&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://homeostasis.scs.carleton.ca/~soma/os-2017f/code/tut1/syscall-hello.c syscall-hello.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/syscall.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *buf = &amp;quot;Hello world!\n&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv) {&lt;br /&gt;
        size_t result;&lt;br /&gt;
&lt;br /&gt;
        /* &amp;quot;man 2 write&amp;quot; to see arguments to write syscall */&lt;br /&gt;
        result = syscall(SYS_write, 1, buf, 13);&lt;br /&gt;
&lt;br /&gt;
        return (int) result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[https://homeostasis.scs.carleton.ca/~soma/os-2019f/code/3000memview.c 3000memview.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
char *gmsg = &amp;quot;Global Message&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const int buffer_size = 100;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[])&lt;br /&gt;
{&lt;br /&gt;
        char *lmsg = &amp;quot;Local Message&amp;quot;;&lt;br /&gt;
        char *buf[buffer_size];&lt;br /&gt;
        int i;&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;Memory report\n&amp;quot;);&lt;br /&gt;
        printf(&amp;quot;argv:      %lx\n&amp;quot;, (unsigned long) argv);&lt;br /&gt;
        printf(&amp;quot;argv[0]:   %lx\n&amp;quot;, (unsigned long) argv[0]);&lt;br /&gt;
        printf(&amp;quot;envp:      %lx\n&amp;quot;, (unsigned long) envp);&lt;br /&gt;
        printf(&amp;quot;envp[0]:   %lx\n&amp;quot;, (unsigned long) envp[0]);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;lmsg:      %lx\n&amp;quot;, (unsigned long) lmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;lmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;lmsg);&lt;br /&gt;
        printf(&amp;quot;gmsg:      %lx\n&amp;quot;, (unsigned long) gmsg);&lt;br /&gt;
        printf(&amp;quot;&amp;amp;gmsg:     %lx\n&amp;quot;, (unsigned long) &amp;amp;gmsg);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;main:      %lx\n&amp;quot;, (unsigned long) &amp;amp;main);&lt;br /&gt;
&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        printf(&amp;quot;&amp;amp;buf:      %lx\n&amp;quot;, (unsigned long) &amp;amp;buf);&lt;br /&gt;
&lt;br /&gt;
        for (i = 0; i&amp;lt;buffer_size; i++) {&lt;br /&gt;
                buf[i] = (char *) malloc(4096);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        printf(&amp;quot;buf[0]:    %lx\n&amp;quot;, (unsigned long) buf[0]);&lt;br /&gt;
        printf(&amp;quot;sbrk(0):   %lx\n&amp;quot;, (unsigned long) sbrk(0));&lt;br /&gt;
        &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===[http://people.scs.carleton.ca/~soma/os-2019w/code/csimpleshell.c csimpleshell.c]===&lt;br /&gt;
&amp;lt;syntaxhighlight line lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
/* csimpleshell.c, Enrico Franchi © 2005&lt;br /&gt;
      https://web.archive.org/web/20170223203852/&lt;br /&gt;
      http://rik0.altervista.org/snippets/csimpleshell.html&lt;br /&gt;
      &amp;quot;BSD&amp;quot; license&lt;br /&gt;
&lt;br /&gt;
   January 12, 2019: minor changes to eliminate most compilation warnings&lt;br /&gt;
   (Anil Somayaji, soma@scs.carleton.ca)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;errno.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/wait.h&amp;gt;&lt;br /&gt;
#include &amp;lt;sys/types.h&amp;gt;&lt;br /&gt;
#define BUFFER_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
#define ARR_SIZE 1&amp;lt;&amp;lt;16&lt;br /&gt;
&lt;br /&gt;
void parse_args(char *buffer, char** args, &lt;br /&gt;
                size_t args_size, size_t *nargs)&lt;br /&gt;
{&lt;br /&gt;
    char *buf_args[args_size]; /* You need C99 */&lt;br /&gt;
    char **cp;&lt;br /&gt;
    char *wbuf;&lt;br /&gt;
    size_t i, j;&lt;br /&gt;
    &lt;br /&gt;
    wbuf=buffer;&lt;br /&gt;
    buf_args[0]=buffer; &lt;br /&gt;
    args[0] =buffer;&lt;br /&gt;
    &lt;br /&gt;
    for(cp=buf_args; (*cp=strsep(&amp;amp;wbuf, &amp;quot; \n\t&amp;quot;)) != NULL ;){&lt;br /&gt;
        if ((*cp != NULL) &amp;amp;&amp;amp; (++cp &amp;gt;= &amp;amp;buf_args[args_size]))&lt;br /&gt;
            break;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    for (j=i=0; buf_args[i]!=NULL; i++){&lt;br /&gt;
        if(strlen(buf_args[i])&amp;gt;0)&lt;br /&gt;
            args[j++]=buf_args[i];&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    *nargs=j;&lt;br /&gt;
    args[j]=NULL;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[], char *envp[]){&lt;br /&gt;
    char buffer[BUFFER_SIZE];&lt;br /&gt;
    char *args[ARR_SIZE];&lt;br /&gt;
&lt;br /&gt;
    int ret_status;&lt;br /&gt;
    size_t nargs;&lt;br /&gt;
    pid_t pid;&lt;br /&gt;
    &lt;br /&gt;
    while(1){&lt;br /&gt;
        printf(&amp;quot;$ &amp;quot;);&lt;br /&gt;
        fgets(buffer, BUFFER_SIZE, stdin);&lt;br /&gt;
        parse_args(buffer, args, ARR_SIZE, &amp;amp;nargs); &lt;br /&gt;
&lt;br /&gt;
        if (nargs==0) continue;&lt;br /&gt;
        if (!strcmp(args[0], &amp;quot;exit&amp;quot; )) exit(0);       &lt;br /&gt;
        pid = fork();&lt;br /&gt;
        if (pid){&lt;br /&gt;
            printf(&amp;quot;Waiting for child (%d)\n&amp;quot;, pid);&lt;br /&gt;
            pid = wait(&amp;amp;ret_status);&lt;br /&gt;
            printf(&amp;quot;Child (%d) finished\n&amp;quot;, pid);&lt;br /&gt;
        } else {&lt;br /&gt;
            if( execvp(args[0], args)) {&lt;br /&gt;
                puts(strerror(errno));&lt;br /&gt;
                exit(127);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Soma</name></author>
	</entry>
</feed>