<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><id>https://files.stuylinux.org/stuylinux/2024/Systems/atom.xml</id><title>Systems Level Programming</title><updated>2025-02-02T20:30:01.616442+00:00</updated><author><name>Mr. Konstantinovich</name><email>konstans</email></author><generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator><icon>https://files.stuylinux.org/stuylinux/2024/Systems/cestlaz.jpg</icon><logo>https://files.stuylinux.org/stuylinux/2024/Systems/cestlaz.jpg</logo><entry><id>2024-09-05n</id><title>2024-09-05</title><updated>2024-09-05T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-05n"&gt;&lt;!-- --------------------CONTENT BLOCK-------------------- --&gt;
&lt;h5&gt;2024-09-05&lt;/h5&gt;
&lt;h3&gt;Logistics&lt;/h3&gt;
&lt;p&gt;What to expect in this class.&lt;/p&gt;
&lt;p&gt;Discussion of policies and the landing page.&lt;/p&gt;
&lt;h3&gt;&lt;a href="https://konstantinnovation.github.io"&gt;https://konstantinnovation.github.io&lt;/a&gt; &lt;/h3&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;Most of the resources are listed in the summer assignment found on the systems page of my website. (this page)&lt;/p&gt;
&lt;h3 id="2024-09-05h"&gt;Homework 01&lt;/h3&gt;
&lt;h4&gt;1. Forms:&lt;/h4&gt;
&lt;p&gt;Please fill out the &lt;a href="https://forms.gle/qJBUnFZN9kjmegHS8"&gt;start of term survey&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please read and fill out the &lt;a href="https://forms.gle/T9bHX4ffwokLghTu7"&gt;Computer Lab and Resources usage Policy&lt;/a&gt; &lt;/p&gt;
&lt;h4&gt;2. Working environment&lt;/h4&gt;
&lt;p&gt;Please ensure you have a working linux os on your home machine.&lt;/p&gt;
&lt;p&gt;If you have a mac or linux computer, you already have one!&lt;/p&gt;
&lt;h5&gt;Mac&lt;/h5&gt;
&lt;p&gt;
    To work on a Mac computer you must install Xcode from the App Store.
  Run the following in a terminal in install xcode command line tools: &lt;/p&gt;&lt;pre&gt;xcode-select --install&lt;/pre&gt;
&lt;h5&gt;Windows&lt;/h5&gt;
&lt;p&gt;Windows users can install WSL (a linux virtual machine) on your windows computers:&lt;/p&gt;
&lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install"&gt;https://docs.microsoft.com/en-us/windows/wsl/install&lt;/a&gt;
&lt;h5&gt;On all machines:&lt;/h5&gt;
&lt;p&gt;Verify the gcc command runs on your home machine.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;go back to the top of the page&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-05n"/><published>2024-09-05T12:00:00+00:00</published></entry><entry><id>2024-09-06n</id><title>2024-09-06</title><updated>2024-09-06T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-06n"&gt;&lt;!-- --------------------CONTENT BLOCK-------------------- --&gt;
&lt;h5&gt;2024-09-06&lt;/h5&gt;
&lt;h3&gt;Class overview&lt;/h3&gt;
&lt;p&gt;
    In this class you will be learning to write programs for a Unix-like system using the C programming language. You will learn about memory, processes, networking, and as a by product: how to better use a unix-like system (in this case Mint Linux).
  &lt;/p&gt;
&lt;h3&gt;Autonomy in my class&lt;/h3&gt;
&lt;p&gt;
    I treat you as if you were responsible individuals, even if you aren't.
    This means that I will not always check if you are doing what you are supposed to.
    You need to let me know if you are having any issues in class or at home.
  &lt;/p&gt;
&lt;p&gt;
    If you do not understand even a single word, you need to speak up.
    In a technical class context clues are NOT sufficient to convey nuanced
    meaning that is needed. e.g. &lt;em&gt;shibboleth &lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
    You also must read... &lt;b&gt;all&lt;/b&gt; of the directions when trying to solve problems or work
    on assignments. Failure to do so will jeapordize your ability to succeed. A single word
    missed like "not" or "all" could mean you are solving the wrong problem.
  &lt;/p&gt;
&lt;h3&gt;prerequisite terminal skills:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Opening a terminal&lt;/li&gt;
&lt;li&gt;Creating folders and files&lt;/li&gt;
&lt;li&gt;File paths&lt;/li&gt;
&lt;li&gt;Moving and manipulating files&lt;/li&gt;
&lt;li&gt;Using SSH to run commands on other computers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Terminal Refresher tutorial:&lt;/h3&gt;
&lt;p&gt;
    If you feel you do not have these skills at this point, please refresh your memory here:
    &lt;a href="https://ubuntu.com/tutorials/command-line-for-beginners#1-overview"&gt;https://ubuntu.com/tutorials/command-line-for-beginners#1-overview&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Please note that only sections 1-5 are needed.&lt;/p&gt;
&lt;h3 id="2024-09-06h"&gt;Homework 02&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Post a greeting on piazza in the section for your period. You can additionally post if you have questions
      or issues with the summer assignment.&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;&lt;li&gt;Get your ssh-keys working on your personal devices (see the landing page for my website for all classes for instructions).&lt;/li&gt;
&lt;li&gt;Optinally : complete the Terminal Refresher tutorial sections 1-5&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-06n"/><published>2024-09-06T12:00:00+00:00</published></entry><entry><id>2024-09-09n</id><title>2024-09-09</title><updated>2024-09-09T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-09n"&gt;
&lt;h5&gt;2024-09-09&lt;/h5&gt;
&lt;h3&gt;C Quickstart&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;By convention, C source files should have a &lt;code&gt;.c&lt;/code&gt; file extension (i.e. &lt;code&gt;program.c&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The C compiler we will be using is &lt;strong&gt;gcc&lt;/strong&gt; (the Gnu C Compiler)&lt;/li&gt;
&lt;li&gt;
        usage: &lt;code&gt;$ gcc program.c&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;This will create a standalone executable file.&lt;/li&gt;
&lt;li&gt;The default name for the output file is &lt;code&gt;a.out&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;There is no preferred extension for c executable files (think about programs like &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;ssh&lt;/code&gt;, &lt;code&gt;chmod&lt;/code&gt;, these are all C programs, notice the lack of file extension).&lt;/li&gt;
&lt;li&gt;You can provide your own output file name with the &lt;code&gt;-o&lt;/code&gt; flag.
            &lt;ul class="subList"&gt;
&lt;li&gt;usage: &lt;code&gt;$ gcc -o pro program.c&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
        Compiled C programs are natively executable, to run them just type &lt;code&gt;./program&lt;/code&gt;
        (i.e. &lt;code&gt;$ ./a.out&lt;/code&gt; or &lt;code&gt;$ ./pro&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
        C compilers assume you wanted to do what you did, and don't give errors for a variety of things you think should not work.
      &lt;/li&gt;
&lt;li&gt;
        The &lt;code&gt;./&lt;/code&gt; is only needed because you probably compiled the file in a directory(folder)
        outside your PATH environment variable (if that is unclear, you can forget the previous sentence entirely for now).
      &lt;/li&gt;
&lt;li&gt;
        Before moving on, you should write, compile and run the example program provided below.
        I promise it is 100% sytactically correct. (Yes, you may get a compiler warning message, this is the only time you're allowed to ignore it.
        &lt;pre class="codeblock"&gt;&lt;code&gt;int main(){
      printf("Hello world.");&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Addendum:&lt;/strong&gt; Return values&lt;/p&gt;
&lt;p&gt;By default gcc will not tell you if a return statement is missing. Please use the &lt;code&gt;-Wall&lt;/code&gt; flag
          to give you more warnings.
        &lt;/p&gt;
&lt;p&gt;
          Additionally there is a special case in that the main function is to return 0 if control reaches the
          end without an explicit return. This only applies to the main function in C99, and older compilers will
          NOT guarantee this behavior. (This is not likely to be an issue for you.)
        &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;SSH Keys&lt;/h3&gt;
&lt;p&gt; &lt;a href="index.html#sshkeygen"&gt;Create SSH Keys on the lab computers if you haven't done so already.&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="2024-09-13h"&gt;Homework&lt;/h3&gt;
&lt;p&gt;Get your home computer setup to compile and run C programs&lt;/p&gt;
&lt;p&gt;Test your home environment to ensure you can compile.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-09n"/><published>2024-09-09T12:00:00+00:00</published></entry><entry><id>2024-09-10n</id><title>2024-09-10</title><updated>2024-09-10T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-10n"&gt;
&lt;h5&gt;2024-09-10&lt;/h5&gt;
&lt;h3 id="printf"&gt;printf&lt;/h3&gt;
&lt;p&gt; &lt;i&gt;The thinking person's&lt;/i&gt; &lt;code&gt;System.out.println&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;Extensive documentation can be found by using the command: &lt;code&gt;man 3 printf&lt;/code&gt; &lt;/p&gt;
&lt;ol class="mainList"&gt;
&lt;li&gt;&lt;code&gt;printf&lt;/code&gt; is the function normally used in C to print to standard out.&lt;/li&gt;
&lt;li&gt;usage: &lt;code&gt;printf( string, arg0, arg1, ...)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Sends &lt;code&gt;string&lt;/code&gt; to standard out.&lt;/li&gt;
&lt;li&gt;The first argument must be a literal string enclosed by &lt;code&gt;"&lt;/code&gt;, as in the example program above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;string&lt;/code&gt; can contain special placeholder characters that are used to insert other values into the output.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%d&lt;/code&gt; is the placeholder to display a value as an &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%lf&lt;/code&gt; is the placeholder to display a value as a &lt;code&gt;double&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;There are other placeholder characters that we will see later on.&lt;/li&gt;
&lt;li&gt;If placeholder characters are used, then they will be replaced by the arguments following the string when &lt;code&gt;printf&lt;/code&gt; is executed.&lt;/li&gt;
&lt;li&gt;The value arguments can be either variables or literal values.&lt;/li&gt;
&lt;li&gt;example: &lt;code&gt;printf("these are numbers: %d %lf\n", 3, 845.273);&lt;/code&gt; would display: &lt;code&gt;these are numbers: 3 845.273&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Once you get used to it, most people prefer &lt;code&gt;printf&lt;/code&gt;'s value replacement system to Java's string concatenation (+) inside &lt;code&gt;System.out.println&lt;/code&gt;. In fact, Java does have a &lt;code&gt;System.out.printf&lt;/code&gt; because of it.&lt;/li&gt;
&lt;li&gt;The printf command does not add a new line at the end of the output, so you can use multiple printf statements to output on the same line.&lt;/li&gt;
&lt;li&gt;As an exercise, add some &lt;code&gt;printf&lt;/code&gt; statements to your existing example program. Try declaring variables and printing their values. Once you get the hang of it, try using the wrong formatting characters, see what happens…&lt;/li&gt;
&lt;li&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Placeholder&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%d&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%ld&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%f&lt;/code&gt; &lt;sup&gt;*&lt;/sup&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%lf&lt;/code&gt;&lt;sup&gt;*&lt;/sup&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%s&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pointer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%p&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;* &lt;code&gt;%.xf&lt;/code&gt; or &lt;code&gt;%.xlf&lt;/code&gt; will print up to &lt;code&gt;x&lt;/code&gt; significant digits after the floating point&lt;/li&gt;
&lt;li&gt;There are many formatting options, you should look at the man pages of printf for more options using &lt;code&gt;man 3 printf&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-10n"/><published>2024-09-10T12:00:00+00:00</published></entry><entry><id>2024-09-11n</id><title>2024-09-11</title><updated>2024-09-11T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-11n"&gt;
&lt;h5&gt;2024-09-11&lt;/h5&gt;
&lt;h3&gt;Piazza questions are really important today&lt;/h3&gt;
&lt;p&gt;Ask questions about todays notes on piazza. This was meant to have an in person lecture but I was not in school to give a demo + answer questions.&lt;/p&gt;
&lt;h3&gt;Binary&lt;/h3&gt;
&lt;p&gt;Internally to computers numbers are written in binary, which is base 2. The number 111&lt;sub&gt;2&lt;/sub&gt; is actually the decimal number 7, but it is expressed in base 2.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Binary&lt;/th&gt;&lt;th&gt;Decimal&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;1&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;2&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;11&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;3&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;101&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;5&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;1000&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;8&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;1010&lt;sub&gt;2&lt;/sub&gt;&lt;/td&gt; &lt;td&gt;10&lt;sub&gt;10&lt;/sub&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;The way you convert from binary to decimal is the same as how you view the value of a base 10 number,
    you multiply the digit times the column value, e.g. 523 is 5*100 + 2*10 + 3*1. Since binary only has 0 and 1, you just sum the column values of each digit that is &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Incidentally a &lt;code&gt;bit&lt;/code&gt; is a single binary digit. A &lt;code&gt;byte&lt;/code&gt; is 8 bits. &lt;/p&gt;
&lt;p&gt;Take this diagram, which explains how to determine the value of 11100111101&lt;sub&gt;2&lt;/sub&gt; &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="img/base2.gif"/&gt;&lt;/p&gt;
&lt;p&gt;You don't have to be a master of binary, and I won't quiz you on converting, but you should understand the concept, and what a term like &lt;code&gt;32-bit integer&lt;/code&gt; or &lt;code&gt;4-byte integer&lt;/code&gt; means. They both mean a binary number with 32 digits (4 bytes = 4 x 8 bits).&lt;/p&gt;
&lt;p&gt;You should know that the more digits a number has the more numbers you can represent, e.g. a 3 digit number in base 10 can be from 000 up to 999, so 1000 options. The more digits, the bigger the range of values, a 10 digit number has more possible values than a 3 digit number.&lt;/p&gt;
&lt;p&gt;We designate the size of a variables use binary digits, or &lt;code&gt;bits&lt;/code&gt;. The larger the number of bits (or bytes), the larger the range of values.&lt;/p&gt;
&lt;h2 id="primitive-types"&gt;Primitive Types&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
      All C primitives are numeric.
      The only differences are floating point vs. integer and size of variable in memory.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sizeof(type)&lt;/code&gt; can be used to find the size in bytes (&lt;code&gt;stdlib.h&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Size of different types is &lt;em&gt;platform &lt;strong&gt;de&lt;/strong&gt;pendent&lt;/em&gt; , you have to use sizeof to be certain.&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size (bytes)&lt;/th&gt;
&lt;th&gt;Range&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;-128 to 127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;short&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;-32,768 to 32,767&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;-2&lt;sup&gt;31&lt;/sup&gt; to 2&lt;sup&gt;31&lt;/sup&gt;-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;long&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;-2&lt;sup&gt;63&lt;/sup&gt; to 2&lt;sup&gt;63&lt;/sup&gt;-1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;7 digits of precision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;double&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;14 digits of precision&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;char&lt;/code&gt; is an integer type, but can be used to refer to character literals as well.
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;char c = 97;&lt;/code&gt; and &lt;code&gt;char c = 'a';&lt;/code&gt; are both equally valid statements.&lt;/li&gt;
&lt;li&gt;This also means you can perform arithmetic operations on chars natively.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Variables can be declared as &lt;code&gt;unsigned&lt;/code&gt;. Unsigned variables do not use a bit to store the sign of the number, making the lower bound 0 and increasing the upper bound.&lt;/li&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Size (bytes)&lt;/th&gt;
&lt;th&gt;Range&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unsigned char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0 to 255&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unsigned short&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0 to 65,535&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unsigned int&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0 to 2&lt;sup&gt;32&lt;/sup&gt;-1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;li&gt;Note there is no boolean type. In c, any number is a boolean value:
      &lt;ul&gt;
&lt;li&gt;&lt;strong&gt;0 is false&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;All other numeric values are true&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;the expression &lt;code&gt;if(x = 2){}&lt;/code&gt; which has an assignment instead of a comparison does not cause an error. It evaluates the assignment and becomes: &lt;code&gt;if(2){}&lt;/code&gt; This is desired behavior, but does NOT check if x has the same value as 2. &lt;code&gt;x=0&lt;/code&gt; is false while &lt;code&gt;x = non-zero numbers&lt;/code&gt; is true. This is the source of bugs in many programs &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="operator-precedence"&gt;Operator Precedence&lt;/h3&gt;
&lt;p&gt;Operators evaluate from left to right unless otherwise noted&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;() [] -&amp;gt; .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RIGHT TO LEFT ! ~ ++ -- +(unary) -(unary) *(de-reference) &amp;amp;(address of) (type cast) sizeof&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;* / %&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+ -&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&amp;lt; &amp;gt;&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt; &amp;lt;= &amp;gt; &amp;gt;=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;== !=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp; (bitwise and)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;^ (bitwise xor)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;| (bitwise or)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;||&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RIGHT TO LEFT ?:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RIGHT TO LEFT = += -= *= /= %= ^= |= &amp;amp;= &amp;lt;&amp;lt;= &amp;gt;&amp;gt;=&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Experiment!&lt;/h3&gt;
&lt;p&gt;Please experiment with some things.&lt;/p&gt;
&lt;p&gt;Write the example and explanation in your notes.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create some expressions using opeators and print the results. Many of the operators are the same as in java. Do not worry about dereferencing, address of, bit shifts (&amp;gt;&amp;gt;) and bitwise operators.&lt;/li&gt;
&lt;li&gt;Make an example of using multiple assignment operators "=" evaluating from right to left.&lt;/li&gt;
&lt;li&gt;How does the &lt;code&gt;?:&lt;/code&gt; (ternary operator) work, create an example.&lt;/li&gt;
&lt;li&gt;The ternary operators in the same expression are right to left, what does this allow a programmer to do that would not work it it were left to right?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-11n"/><published>2024-09-11T12:00:00+00:00</published></entry><entry><id>2024-09-12n</id><title>2024-09-12</title><updated>2024-09-12T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-12n"&gt;
&lt;h5&gt;2024-09-12&lt;/h5&gt;
&lt;h2 id="variables"&gt;Variables&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;C is statically typed, meaning every variable must be given a type.&lt;/li&gt;
&lt;li&gt;Variables must be declared before they are used &lt;code&gt;TYPE IDENTIFIER;&lt;/code&gt; e.g. &lt;code&gt;int x;&lt;/code&gt;.
      &lt;ul&gt;
&lt;li&gt;You can assign a variable a value at declaration (i.e. &lt;code&gt;int x = 10;&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;THERE IS NO DEFAULT VALUE FOR VARIABLES&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;In Java, instance variables got initialized to 0, arrays were also zeroed out. That’s a thing of the past.&lt;/li&gt;
&lt;li&gt;
          Remember that declaring a variable means requesting a piece of memory to be used by your program of the
          corresponding variable size. (&lt;code&gt;int&lt;/code&gt; means you are asking for 4 bytes of memory.)
        &lt;/li&gt;
&lt;li&gt;
          If you do not initialize (provide a value for) a variable, its initial value will be whatever happens
            to be in the piece of memory that was assigned to your variable. Sometimes, that’s 0, sometimes it’s 2167354.
            You cannot predict this reliably.
        &lt;/li&gt;
&lt;li&gt;
          This is cause for one of the most frustrating kind of programming errors in C. Normally,
            if you run the same function with the same input twice, you will get the same result.
            If you don’t initialize a variable, you could run the same program twice and get two different
            results, because you’re not guranteed that variable will have had the same value twice
            (common occurance: you run your program and get lucky, a variable is initialized to 0. Then
            I run your work  and the program crashes or does not give the required result because the
            variable is initialized to some junk value).

        &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Variables can be declared as &lt;code&gt;unsigned&lt;/code&gt; (i.e. &lt;code&gt;unsigned int u;&lt;/code&gt;).
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;unsigned&lt;/code&gt; variables have a lower bound of 0 and a higher upper bound than their signed counterparts.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unsigned char uc;&lt;/code&gt; declares a 1 byte integer type that can hold any number in the range [0, 255] otherwise known as [0, 2^8 - 1], as in there are 8 bits used for the number.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unsigned&lt;/code&gt; variables don’t need to set aside a bit for the sign of the value, hence the larger upper bound.&lt;/li&gt;
&lt;li&gt;There is an additional u in the printf placeholder string for unsigned types. &lt;code&gt;"%d"&lt;/code&gt; becomes &lt;code&gt;"%ud"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Functions&lt;/h3&gt;
&lt;p&gt;Function and variable names are both examples or identifiers.&lt;/p&gt;
&lt;p&gt;All identifiers must be declared before they can be used.&lt;/p&gt;
&lt;p&gt;A function declaration provides its return type, name and parameters.&lt;/p&gt;
&lt;p&gt;This is also known as a function header: &lt;code&gt;double foo(int bar)&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;A function body is almost always attached to the header to make a complete function:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;double foo(int bar){
    return 1.23;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="loopsandconditionals"&gt;Loops and conditionals have the same syntax as java!&lt;/h2&gt;
&lt;p&gt;Since java and c have the same syntax for &lt;code&gt;if/while/for&lt;/code&gt; you can experiement with them to make sure you can use them with real problems.&lt;/p&gt;
&lt;h2 id="2024-09-12h"&gt;Lab01&lt;/h2&gt;
&lt;a href="https://classroom.github.com/a/gh4en8wj"&gt;Assignment01 repo&lt;/a&gt;
&lt;p&gt;Select your name the first time you use our github classroom page. Please click on your name only.&lt;/p&gt;
&lt;p&gt;Look at the problems here: &lt;a href="http://projecteuler.net/index.php?section=problems"&gt;http://projecteuler.net/index.php?section=problems&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;    They are all math problems of some sort, you will be writing a program with several functions to solve them&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep the file names provided in the repo.&lt;/li&gt;
&lt;li&gt;Write a function for each problem you solve. &lt;em&gt;You may wish to have auxiliary functions.&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;Each of your problem functions should return the numerical solution.&lt;/li&gt;
&lt;li&gt;In your main(), call and print the results of each function in numerical order(problem number, not result) one per line as seen in the example below.&lt;/li&gt;
&lt;li&gt;Please do the following: 1,5,6 after that try 14 and 2.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample output (not correct values):&lt;/p&gt;
&lt;pre class="codeblock"&gt;
  Euler01,1023
  Euler05,92381
  Euler15,31821.123
  etc.&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-12n"/><published>2024-09-12T12:00:00+00:00</published></entry><entry><id>2024-09-14n</id><title>2024-09-13</title><updated>2024-09-13T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-14n"&gt;
&lt;h5&gt;2024-09-13&lt;/h5&gt;
&lt;h3 id="compiling-and-linking"&gt;Compiling and Linking&lt;/h3&gt;
&lt;p&gt;Compilers are more complex than straightforward source code -&amp;gt; executable code translators, and have multiple components.&lt;/p&gt;
&lt;p&gt;To start, we'll look at three major pieces of gcc, the &lt;strong&gt;preprocessor&lt;/strong&gt; &lt;strong&gt;compiler&lt;/strong&gt; and the &lt;strong&gt;linker&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Preprocessor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The preprocessor is, at it's simplest interpretation, a text replacement system.&lt;/li&gt;
&lt;li&gt;Modifies source code file with text, as opposed to binary data.&lt;/li&gt;
&lt;li&gt;All preprocessor commands start with &lt;code&gt;#&lt;/code&gt; (i.e. &lt;code&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Note that preprocessor directives do not end in &lt;code&gt;;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;A few basic preprocessor directives&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;#include&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Adds the entire text of the included file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#define&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Usage: &lt;code&gt;#define TEXT REPLACEMENT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Will replace every instance of &lt;code&gt;TEXT&lt;/code&gt; with the provided &lt;code&gt;REPLACEMENT&lt;/code&gt;.&lt;/li&gt;
&lt;li class="subList"&gt;Examples:
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;#define PI 3.14159&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#define MESSAGE "Hello!"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;printf("%s, %f\n", MESSAGE, PI);&lt;/code&gt; would turn into &lt;code&gt;printf("%s, %f\n", "Hello!", 3.14159);&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Note that define does not use &lt;code&gt;=&lt;/code&gt;, becuase this is not an assignment.&lt;/li&gt;
&lt;li&gt;You can also use &lt;code&gt;#define&lt;/code&gt; to declare function-like macros.
          &lt;ul class="subList"&gt;
&lt;li&gt;&lt;code&gt;#define MAX(a, b) a &amp;gt; b ? a : b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MAX(x, y)&lt;/code&gt; would turn into &lt;code&gt;x &amp;gt; y ? x : y&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Note that this would be a direct copy/paste, so if x were a command that gives different results each time (random(), next(), x++, etc.), it would be pasted twice and likely evaluate to two different results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;#ifndef IDENTIFIER ... #endif&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Conditional preprocessor statement.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;IDENTIFIER&lt;/code&gt; is not defined (for the preprocessor), then include all the lines of code up to the &lt;code&gt;#endif&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;IDENTIFIER&lt;/code&gt; is defined, skip everything up to the &lt;code&gt;#endif&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example of #ifndef
    &lt;/p&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;#ifndef PI
#define PI 3.14159
#endif&lt;/code&gt;&lt;/pre&gt;
&lt;li&gt;&lt;strong&gt;Compiler&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Turns C source code into binary code.&lt;/li&gt;
&lt;li&gt;The result is &lt;strong&gt;not&lt;/strong&gt; an executable program.&lt;/li&gt;
&lt;li&gt;Only one C file is compiled at a time.&lt;/li&gt;
&lt;li&gt;The compiler checks called functions against their declared hearders, but if a function is defined in a separate file, its code is &lt;strong&gt;not added&lt;/strong&gt; at this step.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ gcc -c &amp;lt;FILE&amp;gt;&lt;/code&gt; will run the preprocessor and compile stages only, creating a non executable binary object file. The resulting file will have an extension of &lt;strong&gt;.o&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Since an executable is &lt;em&gt;not&lt;/em&gt; created, you can successfully compile, via &lt;code&gt;$ gcc -c&lt;/code&gt;, a C file that does not have a &lt;code&gt;main&lt;/code&gt; function.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linker&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Combines compiled binary code from multiple files into a single executable program.&lt;/li&gt;
&lt;li&gt;Will automatically look for standard library source code, or anything that can be included using &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If multiple definitions for any identifier is found, the linker will fail.&lt;/li&gt;
&lt;li&gt;Must find &lt;strong&gt;one&lt;/strong&gt; definition for &lt;code&gt;main&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you provide gcc multiple c files, it will compile each one individual and then run the linker on them together.&lt;/li&gt;
&lt;li&gt;If you provide gcc any .o files, it will skip the compilation step for those files and then use them during linking.&lt;/li&gt;
&lt;li&gt;You can mix and match .c and .o files for gcc, but it is not encouraged.&lt;/li&gt;
&lt;li&gt;For example these would be good ways to compile a program, if you had files &lt;code&gt;foo.c goo.c boo.c&lt;/code&gt;:
        &lt;ul&gt;
&lt;li&gt;&lt;code&gt;$ gcc -o program foo.c goo.c boo.c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or compile the files separately: (If you only changed one of the c files, you can recompile that one file but not the rest.)
            &lt;pre class="codeblock"&gt;&lt;code&gt;$ gcc -c foo.c
$ gcc -c goo.c
$ gcc -c boo.c
$ gcc foo.o goo.o boo.o
            &lt;/code&gt;&lt;/pre&gt;
	    The output would be the default &lt;code&gt;a.out&lt;/code&gt; but you could optionally use the -o flag to change it.
          &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;h3&gt;Homework:&lt;/h3&gt;
&lt;p&gt;Monday you will modify your lab, so make sure you have it working.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-14n"/><published>2024-09-13T12:00:00+00:00</published></entry><entry><id>2024-09-16n</id><title>2024-09-16</title><updated>2024-09-16T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-16n"&gt;
&lt;h5&gt;2024-09-16&lt;/h5&gt;
&lt;h2&gt;Makefiles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Make is a command line tool to help automate building programs with multiple files and dependencies.&lt;/li&gt;
&lt;li&gt;It is designed such that you can compile only the files that have been modified, or that rely on modified files.&lt;/li&gt;
&lt;li&gt;Compiling instructions and file dependencies are put into a file called &lt;em&gt;makefile&lt;/em&gt; or &lt;em&gt;Makefile&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Running &lt;code&gt;make&lt;/code&gt;, will look for a file with one of the default names but (you can specify a different file with the &lt;code&gt;make -f FILENAME&lt;/code&gt; argument).&lt;/li&gt;
&lt;li&gt;The main parts of makesfiles are:
      &lt;ol&gt;
&lt;li&gt;Targets: Things to make (usually executables or .o files)&lt;/li&gt;
&lt;li&gt;Dependencies: Files or other targets needed to create a target.&lt;/li&gt;
&lt;li&gt;Rules: The steps to create the target.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Make will always run the first target if none is specified.&lt;/li&gt;
&lt;li&gt;Make recursively goes through dependencies.&lt;/li&gt;
&lt;li&gt;Make will check the modification timestamps for &lt;strong&gt;targets&lt;/strong&gt; and &lt;strong&gt;dependencies&lt;/strong&gt; and will only run the &lt;strong&gt;rules&lt;/strong&gt; if the target is older than one or more of its dependencies.&lt;/li&gt;
&lt;li&gt;Makefile Syntax: (&amp;lt;TAB&amp;gt; is the tab character)
      &lt;pre class="codeblock"&gt;&lt;code&gt;target: dependency0 dependency1 dependency2 ...
&amp;lt;TAB&amp;gt;rule&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There should be a newline between the dependency list and the rules, and the &lt;strong&gt;TAB&lt;/strong&gt; is necessary, there should not be any space between it and the rule.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;You can try to copy/paste this makefile, but replace the leading spaces (margine only) with tabs.
      &lt;pre class="codeblock"&gt;&lt;code&gt;default:
    echo "'make' will run this line"
compile:
    @echo "'make compile' will run this line, but the @ suppresses the echo command on the terminal!"
run:
    @echo "'make run' will run this line, but the @ suppresses the echo command on the terminal!"&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Here is a makefile for a program made from three .c files: main.c, foo.c and goo.c.&lt;/li&gt;
&lt;li&gt;main.c calls functions from foo.c&lt;/li&gt;
&lt;li&gt;foo.c calls functions from goo.c
    &lt;p&gt;Note: copy/paste from a website does not preserve tab characters! &lt;strong&gt;DO NOT COPY PASTE, write it yourself with tabs&lt;/strong&gt; &lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;all: main.o foo.o goo.o
  gcc -o program main.o foo.o goo.o

main.o: main.c foo.h
  gcc -c main.c

foo.o: foo.c goo.h
  gcc -c foo.c

goo.o: goo.c goo.h
  gcc -c goo.c
      &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;This makefile creates the executable file &lt;strong&gt;program&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Since &lt;em&gt;all&lt;/em&gt; is not a file and it is the first target, it will always run.
      &lt;ul&gt;
&lt;li&gt;If instead, the first target was called &lt;strong&gt;program&lt;/strong&gt;, then make would check the modification timestamp of that file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main.o&lt;/strong&gt; is the first dependency, so make will go to that target.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main.o&lt;/strong&gt; depends on main.c and foo.h&lt;/li&gt;
&lt;li&gt;
      The rest of the dependencies will go through in a similar way. Running &lt;code&gt;$ make&lt;/code&gt;
      the first time would do the following:
      &lt;pre class="codeblock"&gt;&lt;code&gt;gcc -c main.c
gcc -c foo.c
gcc -c goo.c
gcc -o porgram main.o foo.o goo.o
      &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Notice the order of compilation and trace it through the makefile.&lt;/li&gt;
&lt;li&gt;If goo.h is modified, the following would happen:
      &lt;pre class="codeblock"&gt;&lt;code&gt;gcc -c foo.c
gcc -c goo.c
gcc -o porgram main.o foo.o goo.o
      &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Actual Example:&lt;/h2&gt;
&lt;h3&gt;main.c&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include "foo.h"
int main(){
  printf("fu(5) is: %d\n",fu(5));
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;foo.h&lt;/h3&gt;
&lt;p&gt;Any .h file only contains headers and an include guard:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#ifndef FOO_H //include guard
#define FOO_H
int fu(int x);
//more function headers can go here
#endif&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;foo.c&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;int fu(int x){
  return x+1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;makefile&lt;/h3&gt;
&lt;p&gt;This file should be named makefile or Makefile&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please Note:&lt;/strong&gt; the clean target will remove any compiled files and executables, so that you can test your compilation from scratch. This is very important.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Also Note&lt;/strong&gt; the compile target also has a target "runme" so that it is called EITHER when you use make compile, OR when the file runme needs to be created.&lt;/p&gt;
&lt;p&gt;The first target is the default, no matter what you name it.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;notDefault:
  @echo "No arguments runs the first recipe no matter what you call it."
compile runme:  main.o foo.o
  @gcc -o runme foo.o main.o
main.o: main.c foo.h
  @gcc -c main.c
foo.o: foo.c
  @gcc -c foo.c
run: runme
  @./runme
clean:
  rm *.o
  rm runme&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="2024-09-13h"&gt;Update Lab01&lt;/h2&gt;
&lt;p&gt;Big goal: Set up a makefile for your lab01 and link it as described below&lt;/p&gt;
&lt;p&gt;I will ONLY compile and run using make. You will lose credit for having invalid makfiles.&lt;/p&gt;
&lt;p&gt;Modify your euler assignment such that you have the following files:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;euler.c&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Your euler assignment, modified to only contain the euler problem functions.&lt;/li&gt;
&lt;li&gt;Get rid of &lt;code&gt;main()&lt;/code&gt; by moving it to &lt;strong&gt;main.c&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Do not put separate functions headers here (function definitions will have the header line still of course).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;euler.h&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The function headers for the functions in &lt;strong&gt;euler.c&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;They should be no argument functions that return a single int. This includes if the intermediary results exceed integer range.&lt;/li&gt;
&lt;li&gt;Name them using the format: &lt;code&gt;int euler01()&lt;/code&gt;, &lt;code&gt;int euler01()&lt;/code&gt;, etc. Just the problem numbers you were assigned.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;main.c&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;#include "euler.h"&lt;/code&gt; at the top.&lt;/li&gt;
&lt;li&gt;Has a main function that correctly runs all the functions in &lt;strong&gt;euler.c&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;makefile&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Appropriately compile &lt;strong&gt;euler.c&lt;/strong&gt; and &lt;strong&gt;main.c&lt;/strong&gt; separately.&lt;/li&gt;
&lt;li&gt;Generates an executable file called &lt;strong&gt;euler&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The compile target should be to compile the entire program.&lt;/li&gt;
&lt;li&gt;The run target will run your program. Both make run, and &lt;code&gt;./euler&lt;/code&gt; should run your program.&lt;/li&gt;
&lt;li&gt;I will ONLY test working makefiles. Test with &lt;code&gt;make compile&lt;/code&gt; and &lt;code&gt;make run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;For my labs, you MUST use the @ operator before each command of your makefile to suppress the command text, and only see the output.&lt;/li&gt;
&lt;li&gt;If running &lt;code&gt;make run&lt;/code&gt; on a clean clone of your lab01 repo works on the lab machines, then you are good to go. You should make a clean target to test this on your non-clean repo that has the extra files.
          &lt;p&gt;output format after using &lt;code&gt;make run&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="codeblock"&gt;Euler01,1023
Euler02,55552
Euler05,92381
Euler15,31821.123
etc.&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-16n"/><published>2024-09-16T12:00:00+00:00</published></entry><entry><id>2024-09-17n</id><title>2024-09-17</title><updated>2024-09-17T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-17n"&gt;
&lt;h5&gt;2024-09-17&lt;/h5&gt;
&lt;h1 id="memory"&gt;Memory&lt;/h1&gt;
&lt;h2&gt;Bits &amp;amp; Bytes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;All digital data is &lt;em&gt;binary&lt;/em&gt;, broken up into series of 1s and 0s.&lt;/li&gt;
&lt;li&gt;Physically, this data can take many forms, electronic (high voltage | low voltage), optical (light on | light off), magnetic (+ | - magnetic charge) and so on.&lt;/li&gt;
&lt;li&gt;A single 1 or 0 is a &lt;strong&gt;bit&lt;/strong&gt;, a unit of digital data.&lt;/li&gt;
&lt;li&gt;8 bits make a &lt;strong&gt;byte&lt;/strong&gt;.
      &lt;ul&gt;
&lt;li&gt;Why 8? - Some people thought that was a good number. It used to be 4.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If you have a music file that is 5 MB (megabytes) large, that means it takes 5 million bytes, or 40 million bits to be represented digitally. That's 40 million individual 1s and 0s in whatever physical form it may be.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Computer Memory 101&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;In order to get all this pointer stuff down, we have to be cool with understanding computer memory. So let's do that.&lt;/li&gt;
&lt;li&gt;In general, memory is the term used to describe the computer part that contains any active data. Active data includes things like:
      &lt;ul&gt;
&lt;li&gt;All open applications, even ones running in the background.&lt;/li&gt;
&lt;li&gt;All open files.&lt;/li&gt;
&lt;li&gt;Operating system.&lt;/li&gt;
&lt;li&gt;Background processes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Let us say a computer has 4 gigabytes of memory, that means it can handle 4 billion bytes of data open at once.&lt;/li&gt;
&lt;li&gt;The important distinction to be made is between &lt;em&gt;memory&lt;/em&gt; and &lt;em&gt;storage&lt;/em&gt;.
      &lt;ul&gt;
&lt;li&gt;&lt;em&gt;Storage&lt;/em&gt; refers to data stored on disk (Hard Drive, SSD, Flash Drive, Floppy Disk…).&lt;/li&gt;
&lt;li&gt;Storage is where data gets saved for the long term. At any given time, most computers will have a lot more data in storage than in memory.&lt;/li&gt;
&lt;li&gt;For example, you might have the entire &lt;a href="https://en.wikipedia.org/wiki/Pearl_Jam"&gt;Pearl Jam&lt;/a&gt; discography stored on your hard drive, but you can only listen to one song at a time, so the song you-re currenlty listening to would be the only data in memory out of all the other songs in storage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Memory is much faster to access than storage, which is why it is used. THe downside is that memory is &lt;em&gt;volitile&lt;/em&gt;, meaning it requires power to retain data (imagine losing everything when you shut your compuer off), and it's much more expensive than storage.&lt;/li&gt;
&lt;li&gt;The most common form of memory is RAM (Random Access Memory). The more RAM you have, the more data you can hape open at once.
      &lt;ul&gt;
&lt;li&gt;Computers can use a concept called &lt;em&gt;virtual memory&lt;/em&gt;, which will allocate unused disk space for memory purposes in the event that your RAM is full.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When you open a program/file (in the *nix world, everthing is a file), the file is &lt;strong&gt;copied&lt;/strong&gt; from storage into memory. Saving a file reverses this process, taking the changes you-ve made from memory and copying them into storage.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Interacting with Memory in your Programs&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Just like any other program, when a program you write is run, it takes up memory space.&lt;/li&gt;
&lt;li&gt;Every variable and function you write gets turned into bits which takes up memory space when run.&lt;/li&gt;
&lt;li&gt;In this class, when we talk about the memory usage of a program, we will mostly be talking about variables.&lt;/li&gt;
&lt;li&gt;For example, when you declare an &lt;code&gt;int&lt;/code&gt;, that means your program will request 4 bytes of memory to store a value. See prior notes for the chart of types and sizes.&lt;/li&gt;
&lt;li&gt;Some more detail on &lt;a href="https://en.wikipedia.org/wiki/Endianness"&gt;endianness&lt;/a&gt;:
      &lt;ul&gt;
&lt;li&gt;Forgetting about computer data for a moment, think aboput normal decimal numbers. In the number 2,354 we would say 2 is the most significant digit, because that 2 represents 2 thousand, the largest value of any digit in that number.&lt;/li&gt;
&lt;li&gt;Generally, we write decimal numbers left-&amp;gt;right from most-&amp;gt;least significant.&lt;/li&gt;
&lt;li&gt;Endianness is a similar concept, except instead of thinking of the significance of digits, we look at the significance of &lt;strong&gt;bytes&lt;/strong&gt;.
          &lt;ol&gt;
&lt;li&gt;Consider the value &lt;code&gt;261&lt;/code&gt;. In binary, that would be: &lt;code&gt;100000101&lt;/code&gt;, which is a 9 bit number.&lt;/li&gt;
&lt;li&gt;To store &lt;code&gt;261&lt;/code&gt; in an &lt;code&gt;int&lt;/code&gt;, C will use 4 bytes, so it would really look more like this:
              &lt;ul&gt;
&lt;li&gt;&lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000001&lt;/code&gt; &lt;code&gt;00000101&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Think about the significance of bytes in the same way you think about the significance of digits. In the above representation, the most significant byte comes first. Since we only need 9 bits (which is spread over 2 bytes) to represent &lt;code&gt;261&lt;/code&gt;, the first two bytes are all &lt;code&gt;0&lt;/code&gt;. The third byte, &lt;code&gt;00000001&lt;/code&gt;, represents the number &lt;code&gt;256&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Systems that use this representation are called &lt;strong&gt;big endian&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Other systems use the reverse order, going from least significant to most significant byte. These are called &lt;strong&gt;little endian&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;261&lt;/code&gt; in &lt;strong&gt;little endian&lt;/strong&gt; format would be:
              &lt;ul&gt;
&lt;li&gt;&lt;code&gt;00000101&lt;/code&gt; &lt;code&gt;00000001&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Notice that the indicidual bytes are in most-&amp;gt;least significant bit order, but the order of the bytes is reversed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Another example, &lt;code&gt;2,151,686,160&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Big endian: &lt;code&gt;10000000&lt;/code&gt; &lt;code&gt;01000000&lt;/code&gt; &lt;code&gt;00100000&lt;/code&gt; &lt;code&gt;00010000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Little endian: &lt;code&gt;00010000&lt;/code&gt; &lt;code&gt;00100000&lt;/code&gt; &lt;code&gt;01000000&lt;/code&gt; &lt;code&gt;10000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="" src="img/Big-endian-and-Little-endian.png" width="800"/&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-17n"/><published>2024-09-17T12:00:00+00:00</published></entry><entry><id>2024-09-17n</id><title>2024-09-17</title><updated>2024-09-17T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-17n"&gt;
&lt;h5&gt;2024-09-17&lt;/h5&gt;
&lt;h3 id="memory-addresses"&gt;Memory Addresses&lt;/h3&gt;
&lt;p&gt;In order to understand pointers, we need to take a closer look at what a variable is&lt;/p&gt;
&lt;p&gt;There are three key features to any variable in your code:
    &lt;/p&gt;&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;identifier&lt;/strong&gt;: Name you use in code to refer to the variable.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;value&lt;/strong&gt;: Data that you store.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;address&lt;/strong&gt;: The location of data in memory.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let's focus on the &lt;strong&gt;address&lt;/strong&gt; (the following explanation is somewhat simplified, the nitty gritty details are not necessary to understand the concept)&lt;/p&gt;
&lt;p&gt;Memory is addressed by starting at the first byte block (1), going up until the last accessible byte.
    &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;For example, if your computer has 4GB of RAM, then in theory memory addresses would go from 1 to ~4,000,000,000.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The amount of potential memory addresses is limited by the processor, since a processor must be able to read an entire memory address within a single cycle. For modern, 64-bit computers, this means you could theorhetically have 2^64 bytes of memory, though this number is practically limited by hardware.&lt;/p&gt;
&lt;p&gt;The address space of a program is determined by the operating system (OS), when the program is run. Therefore it can be different each time.&lt;/p&gt;
&lt;h3&gt;Get an address of a variable:&lt;/h3&gt;
&lt;p&gt;You can get the address of any variable using the &lt;strong&gt;address of operator&lt;/strong&gt; : &lt;code&gt;&amp;amp;&lt;/code&gt;;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;%p&lt;/code&gt; placeholder character will print out a memory address in hexadecimal format: &lt;code&gt;printf("x: %d, address of x: %p\n", x, &amp;amp;x);&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you would prefer to see the address in decimal, you can use the placeholder for an &lt;code&gt;unsigned long&lt;/code&gt; on a 64 bit. (This will most likely result in a warning from gcc): &lt;code&gt;printf("x: %d, address of x: %lu\n", x, &amp;amp;x);&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Store an address&lt;/h3&gt;
&lt;p&gt;In order to set a pointer to an existing variable you use the &lt;code&gt;&amp;amp;&lt;/code&gt; operator&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;int x = 97;
int* ptr;//declar a pointer to an int type.
ptr = &amp;amp;x;//set the value of ptr to the address of x (make ptr point to x)&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Get the value at an address:&lt;/h3&gt;
&lt;p&gt;In order to follow a pointer to where it points, you must de-reference it.&lt;/p&gt;
&lt;p&gt;
    Dereference by using the * operator. This means &lt;code&gt;ptr&lt;/code&gt; is the address of x,
    but &lt;code&gt;*ptr&lt;/code&gt; is the contents of x which happens to be 97 in this example.&lt;/p&gt;
&lt;h3&gt;Modify an address:&lt;/h3&gt;
&lt;p&gt;You can modify what address the pointer ptr contains by assigning as follows: &lt;code&gt;ptr = NEWER_ADDRESS;&lt;/code&gt; or equivalent expressions. &lt;/p&gt;
&lt;h3&gt;Modify the contents of the address:&lt;/h3&gt;
&lt;p&gt;You can modify the value contained in the memory slot ptr points to using the assignment: &lt;code&gt;*ptr = NEWER_VALUE;&lt;/code&gt; or equivalent expressions. &lt;/p&gt;
&lt;h3 id="2024-09-21h"&gt;Lab02&lt;/h3&gt;
&lt;h2&gt;Do the following in a C program.&lt;/h2&gt;
&lt;p&gt;Clone the repo from here to do your work:&lt;/p&gt;
&lt;a href="https://classroom.github.com/a/qB71UL4A"&gt;https://classroom.github.com/a/qB71UL4A&lt;/a&gt;
&lt;h4&gt;It will get a little tricky, so do things one step at a time, compile, run and test frequently.&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Declare and initialize variables of types &lt;code&gt;char&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;, and &lt;code&gt;long&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Print out the addresses of each variable in hex and decimal.
      &lt;ul&gt;
&lt;li&gt;What do you notice anything about the addresses?
          &lt;/li&gt;
&lt;li&gt;What about when you run the program more than once?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Declare and initialize pointers for each of your variables.&lt;/li&gt;
&lt;li&gt;Print out the value of what each of the pointers are referencing. (this should be the same value from step 1.).&lt;/li&gt;
&lt;li&gt;Use the pointers to modify the values of the original variables and print out the new values.&lt;/li&gt;
&lt;li&gt;
      Declare and initialize an &lt;code&gt;unsigned int&lt;/code&gt; variable and 2 pointers that point to it, one should
      be an &lt;code&gt;int*&lt;/code&gt; and the other should be a &lt;code&gt;char *&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Print out the value of each pointer (this should be the memory address), and de-reference each pointer to print out the value each points to.
      &lt;ul&gt;
&lt;li&gt;The output should look something like: &lt;code&gt;p: 0x7ffee3dbd938 p points to: 133&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Print out your &lt;code&gt;unsigned int&lt;/code&gt; in decimal and hex.
      &lt;ul&gt;
&lt;li&gt;The &lt;code&gt;printf&lt;/code&gt; formatting character for a hexadecimal int is: &lt;code&gt;%x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;printf&lt;/code&gt; formatting character for an unsigned int is: &lt;code&gt;%u&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;char*&lt;/code&gt; to print out each individual byte of your &lt;code&gt;unsigned int&lt;/code&gt;.
      &lt;ul&gt;
&lt;li&gt;The &lt;code&gt;printf&lt;/code&gt; formatting character for a single byte in hex is &lt;code&gt;%hhu&lt;/code&gt; for unsigned decimal integer and &lt;code&gt;hhx&lt;/code&gt; for an unsigned hex, (that is half of half of an integer).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Super helpful option:&lt;/strong&gt; Try setting the value of your unsigned int to:  &lt;code&gt;1 + 2 + 4 + 256 + 512 + 1024&lt;/code&gt; and then print out the bytes again. &lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;char*&lt;/code&gt; to increment &lt;em&gt;each byte&lt;/em&gt; of the &lt;code&gt;unsigned int&lt;/code&gt; by 1.
      Print out the &lt;code&gt;unsigned int&lt;/code&gt; in both hex and decimal after each modification.
      When done, print out each byte like in step 9. You may need to reset the &lt;code&gt;char *&lt;/code&gt; so
      that it points to the &lt;code&gt;unsigned int&lt;/code&gt;, depending on how you wrote step 4 out.&lt;/li&gt;
&lt;li&gt;Perform the same operation as in step 11, except add 16 to each byte.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;As you go through this, look at what's happening to each byte, and think about the level of control you have over the memory space used by your program. What values did you see for each individual byte? Can you make sense of them? Does the order make sense?&lt;/li&gt;
&lt;li&gt;If you want to test things further try doing all the above with different kinds of values:&lt;/li&gt;
&lt;li&gt;Try an &lt;code&gt;unsigned int&lt;/code&gt; with a value greater that 2.1 billion.&lt;/li&gt;
&lt;li&gt;Try a regular &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-17n"/><published>2024-09-17T12:00:00+00:00</published></entry><entry><id>2024-09-18n</id><title>2024-09-18</title><updated>2024-09-18T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-18n"&gt;&lt;!-- ------------------------------------------ --&gt;
&lt;h5&gt;2024-09-18&lt;/h5&gt;
&lt;h3&gt;SSH&lt;/h3&gt;
&lt;p&gt;The documentation for SSH on my site has been updated to incldue multiple ssh targets in case one is non-functional ( &lt;em&gt;We are looking at you marge...&lt;/em&gt; )&lt;/p&gt;
&lt;p&gt; &lt;a href="https://konstantinnovation.github.io/index.html#ssh"&gt;https://konstantinnovation.github.io/index.html#ssh&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;the -fu suffix:&lt;/h3&gt;
&lt;p&gt;-fu : (slang) Used to form nouns indicating expertise or mastery of specified skill or area of knowledge.&lt;/p&gt;
&lt;ul&gt;
    ‎&lt;li&gt;Google + ‎-fu → ‎Google-fu
    ‎&lt;/li&gt;&lt;li&gt;script + ‎-fu → ‎script-fu
    &lt;/li&gt;&lt;li&gt;My Google-fu is weak!
    &lt;/li&gt;&lt;li&gt;Aragorn uses Ranger-fu to figure out that Sam and Frodo have taken a boat.
  &lt;/li&gt;&lt;/ul&gt;
&lt;h4&gt;Etymology&lt;/h4&gt;
&lt;p&gt;From kung-fu.&lt;/p&gt;
&lt;h3&gt;More &lt;code&gt;printf&lt;/code&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;printf&lt;/code&gt; provides different ways of printing out values.&lt;/li&gt;
&lt;li&gt;Remember that no matter how you write a number in your code, it is stored in memory in binary, so as far as &lt;code&gt;printf&lt;/code&gt; is concerned, even printing out a value in decimal (base 10), requires translating the stored data.&lt;/li&gt;
&lt;li&gt;There is no such thing as a “native” hexidecimal or decimal number. You write them in your code in some way, and they turn into binary when the program is compiled.&lt;/li&gt;
&lt;li&gt;So &lt;code&gt;printf&lt;/code&gt; takes the binary data, and displays it in a particular way based on the formatting character(s) provided.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%d&lt;/code&gt; : print a value as a signed decimal &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%u&lt;/code&gt; : print a value as a decimal &lt;code&gt;unsigned int&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%o&lt;/code&gt; : print a value as an octal number.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%x&lt;/code&gt; : print a value as a hexidecimal number.
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;%o&lt;/code&gt; and &lt;code&gt;%x&lt;/code&gt; will always treat the value as if it were unsigned.&lt;/li&gt;
&lt;li&gt;You can print a value out with &lt;code&gt;%u&lt;/code&gt; or &lt;code&gt;%d&lt;/code&gt; regardless of how it is declared, that doesn-t mean it will make sense, just that &lt;code&gt;printf&lt;/code&gt; will convert the value accordingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h&lt;/code&gt; : modify the printed value to look at 2 bytes instead of 4.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hh&lt;/code&gt; : modify the printed value to look at 1 byte.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;h&lt;/code&gt; and &lt;code&gt;hh&lt;/code&gt; can modify &lt;code&gt;u&lt;/code&gt;, &lt;code&gt;d&lt;/code&gt;, &lt;code&gt;o&lt;/code&gt; or &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The code snippet below displays these options: (note %% prints a % symbol.)
      &lt;pre class="codeblock"&gt;&lt;code&gt;unsigned int q = 2151686160;
printf("%%d: %d\n", q);
printf("%%u: %u\n", q);
printf("%%o: %o\n", q);
printf("%%x: %x\n", q);
printf("%%hhx: %hhx\n", q);
printf("%%hhu: %hhu\n", q);
  &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Note: 2151686160 is &lt;code&gt;80402010&lt;/code&gt; in hex, and &lt;code&gt;1000 0000 0100 0000 0010 0000 0001 0000&lt;/code&gt; in binary.&lt;/li&gt;
&lt;li&gt;When run, this prints (on my computer):
      &lt;div&gt;&lt;div&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;%d: -2143281136
%u: 2151686160
%o: 20020020020
%x: 80402010
%hhx: 10
%hhu: 16
  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Things to notice:
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;%d&lt;/code&gt; is not the actual value we used, this has to do with how negative numbers are represented.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%hhx&lt;/code&gt; and &lt;code&gt;%hhu&lt;/code&gt; print the first byte of the value. Based on that, you can tell the endianness of the system the program is run on (it is possible you get a different result from my example).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Bash Scripts&lt;/h3&gt;
&lt;p&gt;Quick discussion on the reasons to use a bash script vs make.&lt;/p&gt;
&lt;h4&gt;Make&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Make is specialized in compiling source code and building projects&lt;/li&gt;
&lt;li&gt;bash scripts are a general purpose tool&lt;/li&gt;
&lt;li&gt;The ability to have dependencies compiled automatically&lt;/li&gt;
&lt;li&gt;only compile files that are older than their depenencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Bash scripts&lt;/h4&gt;
&lt;p&gt;Bash scripts are just files that run a predetermined set of terminal commands.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a file myScript.sh&lt;/li&gt;
&lt;li&gt;Add the following code:
      &lt;pre&gt;&lt;code&gt;#!/usr/bin/bash
S="Ding"
for i in {1..9}
do
	S=$S" ding"
done
cowsay -f fox $S&lt;/code&gt; &lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Chmod the file to be executable: &lt;code&gt;chmod +x myScript.sh&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Run the script using &lt;code&gt;./myScript.sh&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first line of the script says to use bash and not zsh to run your script. This is optional, but suggested if you use loops which differ in bash/zsh&lt;/p&gt;
&lt;h2 id="2024-09-19h"&gt;Classwork + Homework&lt;/h2&gt;
&lt;p&gt;Write a bash script that is intended to be executed in the main directory of your repo. The script (minimally) does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Get the link remote repo from the current repo (use git remote -v)&lt;/p&gt;
&lt;p&gt;Here is a command to help you put it into a variable: &lt;code&gt;cloneurl=`git remote -v | cut -d ' ' -f 1 | cut -d $'\t' -f 2 | head -n 1`&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Clone that repo in the parent directory of the already cloned repo.
      Specify a name that is not going to conflict with your other repositores using:
      &lt;code&gt;git clone GIT_SSH_LINK NAME_OF_FOLDER&lt;/code&gt; . &lt;/li&gt;
&lt;li&gt;Change into that newly cloned repo.&lt;/li&gt;
&lt;li&gt;Compile and run the code using &lt;pre&gt;make compile &amp;amp;&amp;amp; make run&lt;/pre&gt; &lt;/li&gt;
&lt;li&gt;You can visually determine if the output is as expected. &lt;/li&gt;
&lt;li&gt;Remove the freshly cloned repo.&lt;/li&gt;
&lt;li&gt;After that works try to use a bash if statement to look at the returned value of &lt;code&gt;make compile&lt;/code&gt;
      You should run the program if it compiles, or print out "failed to compile" when it doesn't compile.&lt;/li&gt;
&lt;li&gt;Extra: You can try to do more interesting things by looking at stdout  &lt;code&gt;&amp;amp;gt&lt;/code&gt;  and stderr &lt;code&gt;2&amp;amp;gt&lt;/code&gt; terminal redirectionand  and verifying that there are no errors automatically! I am not providing notes on this but google a few things and see if you can hack together a bash script!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You are permitted to use your google-fu, and share ideas/resources with others!&lt;/p&gt;
&lt;p&gt;Note a bash conditional has the following syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if command ; then
    echo "Command succeeded"
else
    echo "Command failed"
fi
&lt;/code&gt; &lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-18n"/><published>2024-09-18T12:00:00+00:00</published></entry><entry><id>2024-09-19n</id><title>2024-09-19</title><updated>2024-09-19T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-19n"&gt;
&lt;h5&gt;2024-09-19&lt;/h5&gt;
&lt;h3&gt;Lab02 deadline&lt;/h3&gt;
&lt;p&gt;The lab is due Monday. You will have the majority of the period to work on it today.&lt;/p&gt;
&lt;h3&gt;Math&lt;/h3&gt;
&lt;p&gt;The math library in &lt;code&gt;math.h&lt;/code&gt; has a bunch of useful functions such as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;double sqrt(double x)&lt;/code&gt; : Returns the square root of x.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;double log10(double x)&lt;/code&gt; : Returns the common logarithm (base-10 logarithm) of x.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;double pow(double x, double y)&lt;/code&gt; : Returns x raised to the power of y.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The only problem is that when you &lt;code&gt;#include &amp;amp;ltmath.h&amp;gt;&lt;/code&gt; you must compile with the &lt;code&gt;-lm&lt;/code&gt; flag. (Both compile and linking steps)&lt;/p&gt;
&lt;h3&gt;Makefile tweaks&lt;/h3&gt;
&lt;p&gt;Don't use make run as a command like this:&lt;/p&gt;
&lt;pre&gt;
    &lt;code&gt;default:
      make run&lt;/code&gt;
    &lt;/pre&gt;
&lt;p&gt;Instead here is a better way to have make run be default, but easily change it later. It also gives you an idea of how to suppress rm having no target files.&lt;/p&gt;
&lt;p&gt;Note the -lm flag on gcc when compiling files that use the math.h library.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;.PHONY: clean run compile
run: prog
  @./prog
clean:
  rm -f *.o prog
compile prog: tester.o fun.o
  @gcc -o prog tester.o fun.o -lm
tester.o: tester.c fun.h
  @gcc -c tester.c
fun.o: fun.c
  @gcc -c fun.c -lm&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In order for the run command to automatically compile: The output filename &lt;code&gt;prog&lt;/code&gt; is also a target. (next to compile) This allows the compiled file to be a dependency.&lt;/li&gt;
&lt;li&gt;The .PHONY targets are NOT files. This is important if you have &lt;/li&gt;
&lt;li&gt;The clean command is not @ suppressed. This is my preference so I see the rm command on the terminal. All other things should be suppressed unless you are debugging.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-19n"/><published>2024-09-19T12:00:00+00:00</published></entry><entry><id>2024-09-23n</id><title>2024-09-23</title><updated>2024-09-23T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-23n"&gt;
&lt;h5&gt;2024-09-23&lt;/h5&gt;
&lt;h3&gt;Why make a script&lt;/h3&gt;
&lt;p&gt;What are some of the advantages of making a script to complete a task?&lt;/p&gt;
&lt;p&gt;Where sholud scripts that you write be stored?&lt;/p&gt;
&lt;p&gt;A quick bash scripting reference can be found here: &lt;a href="https://devhints.io/bash"&gt;https://devhints.io/bash&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Control your environment&lt;/h3&gt;
&lt;p&gt;
    Everyone should be comfortable tweaking and configuring their working environment on a computer.
    Today you will learn to make your scripts more accessible when you are working in the terminal,
    so that you don't have to remember where you place them in order to call them.
  &lt;/p&gt;
&lt;p&gt;
    The tool you created yesterday is a perfect example of something you want to use in multiple places (each of your lab folders).
    It does not make sense to copy this script to each lab folder however!
  &lt;/p&gt;
&lt;p&gt;You can just evoke the script by typing &lt;code&gt;/PATH/TO/SCRIPT/ScriptName.sh &lt;/code&gt; e.g. &lt;code&gt;~/scripts/ScriptName.sh &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here is a super simple version of the script:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#!/usr/bin/bash
cloneurl=`git remote -v | cut -d ' ' -f 1 | cut -d $'\t' -f 2 | head -n 1`
cd ..
git clone $cloneurl temprepo
cd temprepo
make compile
make run
cd ..
rm -rf temprepo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: &lt;code&gt;#!/usr/bin/bash&lt;/code&gt; is required if your shell is not bash and you want to use the script by name. Otherwise you need to type &lt;code&gt;bash scriptname.sh&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;If this fails to find bash, type &lt;code&gt;which bash&lt;/code&gt; to get the correct location. &lt;/p&gt;
&lt;h3&gt;Updating your path variable&lt;/h3&gt;
&lt;p&gt;You may have noticed: you cannot just type the name of your script to trigger the script.&lt;/p&gt;
&lt;p&gt;All programs and scripts you make require a &lt;code&gt;./&lt;/code&gt; before the script/program name because they are not located in any of your PATH directories.&lt;/p&gt;
&lt;p&gt;In the lab, you cannot put your programs in a pre-designated PATH directory, so you can just set a local directory to hold all of your programs and scripts.&lt;/p&gt;
&lt;h3&gt;Make a direcotry for your binaries/scripts&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Make a directory &lt;code&gt;~/bin&lt;/code&gt; &lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;mkdir ~/bin&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now you can make this directory part of your path using the command:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;export PATH=$PATH:~/bin&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Suggested: add this command to your &lt;code&gt;~/.profile&lt;/code&gt; so that you don't have to type it every time you use the computer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Place your script &lt;code&gt;clonetest.sh&lt;/code&gt; (or whatever you want to call it) from yesterday into your ~/bin directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now the moment you have been waiting for: you can now use your script from ANY directory just by typing &lt;code&gt;clonetest.sh&lt;/code&gt;, AND you can auto complete the command name with the tab key! &lt;/p&gt;
&lt;p&gt;Any scripts and programs you place in this folder can be called by name much like ls, pwd and all those useful commands you use already.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Not sure which profile is executing?&lt;/h3&gt;
&lt;p&gt;It is possible you are editing the wrong profile since there are several. Between &lt;code&gt;.profile&lt;/code&gt;, &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.bash_profile&lt;/code&gt;, or even &lt;code&gt;.zshrc&lt;/code&gt; it can be confusing!&lt;/p&gt;
&lt;p&gt;If you ever need to check what is running, just place an echo command inside your profiles so you can test which is actually being executed.&lt;/p&gt;
&lt;h3&gt;Tweak your script from yesterday&lt;/h3&gt;
&lt;p&gt;The git clone command can be a large wall of text you don't want to see.&lt;/p&gt;
&lt;p&gt;You can silence this command by redirecting the stderr (error text) to /dev/null.&lt;/p&gt;
&lt;p&gt;Try this to make the clone quiet: &lt;code&gt;git clone URL NAME 2&amp;amp;gt /dev/null&lt;/code&gt; &lt;/p&gt;
&lt;h2&gt;Open a remote repo in a browser using the CLI including scripts:&lt;/h2&gt;
&lt;p&gt;Like this: &lt;code&gt;firefox "https://`(git config remote.origin.url | cut -f2 -d@ | tr ':' /)`"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Change the explorer.exe to some other application... like &lt;code&gt;opera&lt;/code&gt; on mac, you can use the &lt;code&gt;open&lt;/code&gt; command , or &lt;code&gt;explorer.exe&lt;/code&gt; on windows&lt;/p&gt;
&lt;h3&gt;Make it a shortcut:&lt;/h3&gt;
&lt;code&gt;alias gh='explorer.exe https://$(git config remote.origin.url | cut -f2 -d@ | tr ':' /)'&lt;/code&gt;
&lt;h3&gt;WSL&lt;/h3&gt;
&lt;p&gt;Demo utility of WSL.&lt;/p&gt;
&lt;h2 id="2024-09-27h"&gt;Homework&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;There is a perusall assignment on academic dishonesty. Please Read it and ask any questions about it by tomorrow. Do not worry about the auto scoring.&lt;/li&gt;
&lt;li&gt;Use your google-fu to learn some terminal-fu. (Specifically about the bash shell or scripts). &lt;/li&gt;
&lt;li&gt;Make a post on piazza in the terminal-fu section. Either share something useful/cool/surprising about the shell, or add on to someone else's post with related cool stuff.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-23n"/><published>2024-09-23T12:00:00+00:00</published></entry><entry><id>2024-09-24n</id><title>2024-09-24</title><updated>2024-09-24T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-24n"&gt;
&lt;h5&gt;2024-09-24&lt;/h5&gt;
&lt;h3&gt;Goals&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Clarify issues with poiners and pointer arithmetic.&lt;/li&gt;
&lt;li&gt;Talk about wsl features.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="pointers"&gt;Pointers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Regular variables are designed to store &lt;em&gt;values&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Pointers are variables designed to store &lt;em&gt;memory addresses&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
      Pointers are variables, meaning they are an identifier for a value stored in
      memory at a particular address (see above for detail), the only difference is
      that a pointer is designed to store an address.
    &lt;/li&gt;
&lt;li&gt;
      Pointers must be able to store the value of any potential memory address.
      On 64 bit computers, this means pointers have to be able to represent 64 bits, or 8 bytes.&lt;/li&gt;
&lt;li&gt;Pointers are designed for addresses, which means they are natively &lt;code&gt;unsigned&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Even though all pointers are the same size, we declare them using the type of the value pointed to.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Syntax&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; is used to declare a pointer variable.&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;int x = 5;
int *p = &amp;amp;x;&lt;/code&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Here &lt;code&gt;p&lt;/code&gt; is a pointer variable that stores the address of the variable &lt;code&gt;x&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Notice that p is a normal variable, and has its own, different, memory address.&lt;/li&gt;
&lt;li&gt;If you-re thinking, “hey, this looks familiar… like object variables in java”. You-re right! Object variables, or references, are java's pointers. You just don-t have as much control over them as we do in C. In fact, think about the error you get when you try to use an uninitialized object variable in java… &lt;em&gt;null pointer&lt;/em&gt;, meaning the reference stored is 0 (null), which is an invlaid memory address.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; is also used as the &lt;strong&gt;de-reference operator&lt;/strong&gt;. This will return the value stored at the memory address pointed to by the pointer.&lt;/li&gt;
&lt;li&gt;Given the definitions of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt; above:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int y = *p + 10;&lt;/code&gt; would set &lt;code&gt;y&lt;/code&gt; to the value &lt;code&gt;15&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*p = y;&lt;/code&gt; would set the value at the memory address stored in &lt;code&gt;p&lt;/code&gt;, to whatever the value stored in &lt;code&gt;y&lt;/code&gt; is.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pointer Arithmetic&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Consider the following C snippet:
      &lt;pre class="codeblock"&gt;&lt;code&gt;  unsigned int i = 2151686160;
  int *ip = &amp;amp;i;
  char *cp = &amp;amp;i;
  &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ip&lt;/code&gt; and &lt;code&gt;cp&lt;/code&gt; will store the address of the first byte used to store &lt;code&gt;i&lt;/code&gt;. Depending on the &lt;a href="https://en.wikipedia.org/wiki/Endianness"&gt;endianness&lt;/a&gt; of the system, that byte will either be &lt;code&gt;10000000&lt;/code&gt; (big) or &lt;code&gt;00010000&lt;/code&gt; (little).&lt;/li&gt;
&lt;li&gt;Let's just say that the first byte is located at memory address &lt;code&gt;3000&lt;/code&gt; (using small number for ease of discussion)&lt;/li&gt;
&lt;li&gt;Due to pointer arithmetic: If you perform &lt;code&gt;ip++&lt;/code&gt; and &lt;code&gt;cp++&lt;/code&gt;, each pointer will be incremented by &lt;code&gt;1 * sizeof(type)&lt;/code&gt; ,  &lt;code&gt;ip&lt;/code&gt; will increase to &lt;code&gt;3004&lt;/code&gt; and &lt;code&gt;cp&lt;/code&gt; will increase to &lt;code&gt;3001&lt;/code&gt;. In essence, &lt;code&gt;ip&lt;/code&gt; would move one &lt;code&gt;int&lt;/code&gt; forward in memory, while &lt;code&gt;cp&lt;/code&gt; only moves one &lt;code&gt;char&lt;/code&gt; (byte) forward.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Looking ahead&lt;/h3&gt;
&lt;p&gt;Using pointer arithmetic is needed to make use of arrays. An array[0] points to the start of a block of memory, while array[1] points 1 * sizeof(type) from the start. This is the elegance of arrays in c.&lt;/p&gt;
&lt;h3 id="endianness"&gt;Endianness&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Some more detail on &lt;a href="https://en.wikipedia.org/wiki/Endianness"&gt;endianness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Forgetting about computer data for a moment, think aboput normal decimal numbers. In the number 2,354 we would say 2 is the most significant digit, because that 2 represents 2 thousand, the largest value of any digit in that number.&lt;/li&gt;
&lt;li&gt;Generally, we write decimal numbers left-&amp;gt;right from most-&amp;gt;least significant.&lt;/li&gt;
&lt;li&gt;Endianness is a similar concept, except instead of thinking of the significance of digits, we look at the significance of &lt;strong&gt;bytes&lt;/strong&gt;.
      &lt;ul&gt;
&lt;li&gt;Consider the value &lt;code&gt;261&lt;/code&gt;. In binary, that would be: &lt;code&gt;100000101&lt;/code&gt;, which is a 9 bit number.&lt;/li&gt;
&lt;li&gt;To store &lt;code&gt;261&lt;/code&gt; in an &lt;code&gt;int&lt;/code&gt;, C will use 4 bytes, so it would really look more like this:
          &lt;ul class="subList"&gt;
&lt;li&gt;&lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000001&lt;/code&gt; &lt;code&gt;00000101&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Think about the significance of bytes in the same way you think about the significance of digits. In the above representation, the most significant byte comes first. Since we only need 9 bits (which is spread over 2 bytes) to represent &lt;code&gt;261&lt;/code&gt;, the first two bytes are all &lt;code&gt;0&lt;/code&gt;. The third byte, &lt;code&gt;00000001&lt;/code&gt;, represents the number &lt;code&gt;256&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Systems that use this representation are called &lt;strong&gt;big endian&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Other systems use the reverse order, going from least significant to most significant byte. These are called &lt;strong&gt;little endian&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;261&lt;/code&gt; in &lt;strong&gt;little endian&lt;/strong&gt; format would be:
          &lt;ul class="subList"&gt;
&lt;li&gt;&lt;code&gt;00000101&lt;/code&gt; &lt;code&gt;00000001&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt; &lt;code&gt;00000000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Notice that the indicidual bytes are in most-&amp;gt;least significant bit order, but the order of the bytes is reversed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Another example, &lt;code&gt;2,151,686,160&lt;/code&gt;
&lt;ul class="subList"&gt;
&lt;li&gt;Big endian: &lt;code&gt;10000000&lt;/code&gt; &lt;code&gt;01000000&lt;/code&gt; &lt;code&gt;00100000&lt;/code&gt; &lt;code&gt;00010000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Little endian: &lt;code&gt;00010000&lt;/code&gt; &lt;code&gt;00100000&lt;/code&gt; &lt;code&gt;01000000&lt;/code&gt; &lt;code&gt;10000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;WSL demo.&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;You can open your current directory in windows explorer by typing the command &lt;code&gt;explorer.exe .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Your wsl can see your windows drive in &lt;code&gt;/mnt/c/&lt;/code&gt; , and your windows install can see your wsl drive.&lt;/li&gt;
&lt;li&gt;You can open windows programs on your linux filesystem as well! try it with a program installed like: &lt;code&gt;/mnt/c/Program\ Files/Notepad++/notepad++.exe&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Alias any windows programs in your config file with something like: &lt;code&gt;alias notepad="/mnt/c/Program\ Files/Notepad++/notepad++.exe"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;You can make a bash script to run pulsar or notepad++ really easily. Create a file called npp in your ~/bin directory of wsl. Then add the script: &lt;pre&gt;#!/bin/bash
/mnt/c/Program\ Files/Notepad++/notepad++.exe $1&lt;/pre&gt;
    The $1 means the 1st argument of the script. If you then typed &lt;code&gt;npp hello.txt&lt;/code&gt; it would replace $1 with hello.txt &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-24n"/><published>2024-09-24T12:00:00+00:00</published></entry><entry><id>2024-09-25n</id><title>2024-09-25</title><updated>2024-09-25T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-25n"&gt;
&lt;h5&gt;2024-09-25&lt;/h5&gt;
&lt;h1 id="random-numbers"&gt;Random Numbers&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Note: On some systems, you may be able to use other functions than the ones described below, but they are not standard for linux, so you should stay away from them for now.&lt;/li&gt;
&lt;li&gt;Generating a random number in C requires 2 steps
    &lt;ol&gt;
&lt;li&gt;Seeding the random number generator&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;srand( time(NULL) );&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;srand(&amp;lt;SEED&amp;gt;)&lt;/code&gt; seeds the random number generator with the provided argument.&lt;/li&gt;
&lt;li&gt;If you use the same argument to &lt;code&gt;srand()&lt;/code&gt; multiple times, you will get the exact same sequence of random numbers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time(NULL)&lt;/code&gt; will return the current &lt;a href="https://www.epochconverter.com"&gt;EPOCH&lt;/a&gt; time, it is commonly used with &lt;code&gt;srand()&lt;/code&gt; to get new random sequences.
            &lt;ol&gt;
&lt;li&gt;Getting a random number&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;int x = rand();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Returns the next random number in the sequence seeded by &lt;code&gt;srand()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Returns an &lt;code&gt;int&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;srand()&lt;/code&gt; and &lt;code&gt;rand()&lt;/code&gt; are both in &lt;code&gt;&amp;lt;stdlib.h&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time()&lt;/code&gt; is in &lt;code&gt;&amp;lt;time.h&amp;gt;&lt;/code&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Here is a script to repeat your make command 30 times to test random:&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt; for i in {1..30}; do make; done&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Here is a 'random' script:&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;S="Ding"
for i in {1..9}
do
        S=$S" ding"
done
cowsay -f fox $S&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Arrays&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;An array is an allocated block of memory meant to hold multiple pieces of data of the same type.&lt;/li&gt;
&lt;li&gt;C arrays do not have a length attribute/function.&lt;/li&gt;
&lt;li&gt;We will use &lt;code&gt;[]&lt;/code&gt; to access array elements.&lt;/li&gt;
&lt;li&gt;The size of an array must be set at declaration and cannot be changed.&lt;/li&gt;
&lt;li&gt;The size of an array cannot be dyanmic.&lt;/li&gt;
&lt;li&gt;There is no boundry checking (much more on this later).&lt;/li&gt;
&lt;li&gt;Array declaraion/access syntax:
    &lt;pre class="codeblock"&gt;float ray[5];
ray[2] = 8.22;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;The above code requests a block of memory large enough for 5 &lt;code&gt;floats&lt;/code&gt; (20 bytes), which then can be accessed using 0-based &lt;code&gt;[]&lt;/code&gt; notation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Array Variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Array &lt;em&gt;varibles&lt;/em&gt; (not the arrays themselves) are pointers to the allocated array block.&lt;/li&gt;
&lt;li&gt;Unlike standard pointers, array variables are &lt;strong&gt;immutable&lt;/strong&gt;, meaning that you can never change the memory address an array variable points to.&lt;/li&gt;
&lt;li&gt;In the previous example, &lt;code&gt;ray&lt;/code&gt; is a variable that points to the beginning of the 20 bytes allocated to that array of floats.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;sizeof&lt;/code&gt; function can be used to find the size of a given type (like &lt;code&gt;float&lt;/code&gt; or &lt;code&gt;char *&lt;/code&gt;), or _the amount of memory associated with a given variable.
    &lt;ul&gt;
&lt;li&gt;&lt;code&gt;sizeof(ray)&lt;/code&gt; would return &lt;code&gt;20&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sizeof(ray) / sizeof(float)&lt;/code&gt; would return &lt;code&gt;5&lt;/code&gt;. It is more standard in C &lt;em&gt;not&lt;/em&gt; to use this, instead using other constants/variables to keep track of array sizes. Since array sizes must be set at compile time, you-re more likely to see something like this:
        &lt;pre class="codeblock"&gt;&lt;code&gt;int ARR_SIZE = 10;
double trouble[ ARR_SIZE ];
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Array Variables &amp;amp; Pointers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Since array variables are pointers, we can assign normal pointers to array variables.
      &lt;pre class="codeblock"&gt;&lt;code&gt;float ray[5];
float *rp = ray;
  &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ray&lt;/code&gt;, is immutable, so we &lt;strong&gt;could not&lt;/strong&gt; do soemthing like &lt;code&gt;ray++&lt;/code&gt;, but &lt;code&gt;rp&lt;/code&gt; is a normal pointer, so we could do &lt;code&gt;rp++&lt;/code&gt;. Due to &lt;em&gt;pointer arithmetic&lt;/em&gt;, &lt;code&gt;rp++&lt;/code&gt; would actually add &lt;code&gt;4&lt;/code&gt; to &lt;code&gt;rp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sizeof(ray)&lt;/code&gt; would return &lt;code&gt;20&lt;/code&gt;, while &lt;code&gt;sizeof(rp)&lt;/code&gt; would return &lt;code&gt;8&lt;/code&gt;, since &lt;code&gt;rp&lt;/code&gt; is a pointer and only holds an 8 byte (on most systems) memory address.&lt;/li&gt;
&lt;li&gt;This is commonly done, and because of pointer arithmetic, you can iterate through an array by using a pointer and incrementing it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Array Indexing and &lt;code&gt;[]&lt;/code&gt; Notation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
      The following two pieces of code perform the same task:
      &lt;code&gt;ray[3]&lt;/code&gt; and &lt;code&gt;*(rp + 3)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the second example, we add &lt;code&gt;3&lt;/code&gt; to &lt;code&gt;rp&lt;/code&gt;, which is the same address as the location for &lt;code&gt;ray[3]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The de-reference operator (&lt;code&gt;*&lt;/code&gt;), is then used to retrieve the value.&lt;/li&gt;
&lt;li&gt;You can think of the standard &lt;code&gt;[]&lt;/code&gt; notation in terms of specifying an offset from the beginning memory address of an array.&lt;/li&gt;
&lt;li&gt;Arrays are 0-indexed because the first element is stored at the starting address, so you need not add to get to the correct memory address.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;a[i]&lt;/code&gt; notation is actually shorthand for:
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;*(a + i)&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This means that you can use &lt;code&gt;[]&lt;/code&gt; with pointer variables as well.
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;rp[3]&lt;/code&gt; is valid code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can write &lt;code&gt;ray[-1]&lt;/code&gt; or &lt;code&gt;rp[-1]&lt;/code&gt;, which would go to the value 4  bytes (one float size) before the beginning of your array.&lt;/li&gt;
&lt;li&gt;If you use an index past the end of an array allocation, you will be attempting to access the memory addresses past the end of the array.&lt;/li&gt;
&lt;li&gt;In either case, going past an array allocation on either end is not advised. Your code will compile, but when run, at best you-ll access other variables within the program, at worst, you-ll crash.&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;WARNING: HORRIBLE SYNTAX AHEAD&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Once again, &lt;code&gt;*(a + i)&lt;/code&gt; is the same as &lt;code&gt;a[i]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt; is a commutative operations, meaning &lt;code&gt;a + i&lt;/code&gt; == &lt;code&gt;i + a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;… some of you may see where this is going&lt;/li&gt;
&lt;li&gt;Since: &lt;code&gt;*(a + i)&lt;/code&gt; == &lt;code&gt;*(i + a)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;It follows that: &lt;code&gt;a[i]&lt;/code&gt; == &lt;code&gt;i[a]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;So &lt;code&gt;ray[2]&lt;/code&gt; can also be written as &lt;code&gt;2[ray]&lt;/code&gt;. Try it once, then NEVER DO IT AGAIN!&lt;/li&gt;
&lt;li&gt;Use this knowledge wisely.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2024-09-25h"&gt;Lab03 Arrays&lt;/h3&gt;
&lt;h4&gt;Due: Monday 09/30 8:00am&lt;/h4&gt;
&lt;p&gt;You will have today + 1 full class day + home time for this.&lt;/p&gt;
&lt;p&gt;You SHOULD be done with this by Friday.&lt;/p&gt;
&lt;p&gt;Clone link: &lt;a href="https://classroom.github.com/a/9lGpCz-A"&gt;https://classroom.github.com/a/9lGpCz-A&lt;/a&gt; &lt;/p&gt;
&lt;h4&gt;Do the following in a C program.&lt;/h4&gt;
&lt;p&gt;
    For this assignment, &lt;em&gt;do not create helper functions, put everything inside main&lt;/em&gt; (it won't be too long).
    We will talk about passing arrays and pointers are function arguments next week.
  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create an array large enough to store 10 ints.&lt;/li&gt;
&lt;li&gt;Set the first value in the array to 0.&lt;/li&gt;
&lt;li&gt;Populate the rest of the array with random values in the range -128 to 127.(you can make a function to generate )&lt;/li&gt;
&lt;li&gt;Print out the values in this array in the format "[1, -3, 4, 7....,9]" that is: ", " between values with [] around the whole set.&lt;/li&gt;
&lt;li&gt;Create a second array of the same size.&lt;/li&gt;
&lt;li&gt;Create pointer variables that will point to each array.&lt;/li&gt;
&lt;li&gt;USING ONLY POINTER VARIABLES (that is, do not use the array variables) do the following:
      &lt;ul&gt;
&lt;li&gt;Populate the second array with the values in the first but in reverse order&lt;/li&gt;
&lt;li&gt;Print out the values in the second array using pointer notation &lt;code&gt;*&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Do this last step again using array notation (try the array variable and the pointer variable with the &lt;code&gt;[]&lt;/code&gt; ).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;a href="#TOP"&gt;go back to the top of the page&lt;/a&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-25n"/><published>2024-09-25T12:00:00+00:00</published></entry><entry><id>2024-09-27n</id><title>2024-09-27</title><updated>2024-09-27T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-27n"&gt;
&lt;h5&gt;2024-09-27&lt;/h5&gt;
&lt;h3&gt;Remember your #ifndef&lt;/h3&gt;
&lt;p&gt;In your header files remember to use the ifndef operator to not re-include things. This won't break now, but it will later and you won't know why.&lt;/p&gt;
&lt;p&gt;A good naming convention for filename.h is to use filename_h as your ifndef identifier&lt;/p&gt;
&lt;pre&gt;#ifndef filename_h
#define filename_h
int foo();
void bar(int x);
#endif&lt;/pre&gt;
&lt;h3&gt;C Functions&lt;/h3&gt;
&lt;h4&gt;pass by value&lt;/h4&gt;
&lt;p&gt;All functions in C are &lt;em&gt;pass by value&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;This means that the arguments are &lt;strong&gt;copied&lt;/strong&gt; into new variables when the function is called.&lt;/li&gt;
&lt;li&gt;As a result, normal values are not modified when passed into a funtion. Consider this function to swap two values:
    &lt;pre class="codeblock"&gt;&lt;code&gt;void swap(int x, int y) {
  int temp = x;
  x = y;
  y = temp;
}
int main(){
  int a = 10;
  int b = 20;
  swap(a, b);
  //what happened to a and b?
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;img alt="" src="img/PassByValueSwap.png"/&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;In this example, when &lt;code&gt;swap&lt;/code&gt; is run on &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are created. The function swaps the values of &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, but once the function finishes, it is popped off the call stack, and &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; are gone. &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are left unchanged.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Power of Pointers!&lt;/h3&gt;
&lt;p&gt;This is where pointers come in handy. If you pass a pointer to a memory address, then you can modify the value it points to. Look at this modified version of swap.&lt;/p&gt;&lt;p&gt;
&lt;/p&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;void swap(int *x, int *y) {
  int temp = *x;
  *x = *y;
  *y = temp;
}

int main(){
  int a = 10;
  int b = 20;
  swap(&amp;amp;a, &amp;amp;b);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;img alt="PassByReferencePointerSwap.png" src="img/PassByReferencePointerSwap.png"/&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Now that &lt;code&gt;swap&lt;/code&gt; takes pointers, we can de-reference the parameters to get at the values pointed to. When the function is colled, &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; become copies of the &lt;em&gt;addresses&lt;/em&gt; of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, so when &lt;code&gt;swap&lt;/code&gt; finishes, the values will actaully be swapped.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pointer paramters&lt;/h3&gt;
&lt;p&gt;Passing pointers as arguments is actually what happens in java when object variables are used!
  You may recall the phrase &lt;em&gt;pass by reference&lt;/em&gt;, all that means is pass by value, but the
  value being passed is a memory address.
  &lt;/p&gt;
&lt;p&gt;
  When you pass an array as a argument to a function, the entire array is &lt;em&gt;not&lt;/em&gt; copied.
  Since array variables are pointers, all arrays are treated as regular pointers when passed
  into a function.&lt;/p&gt;
&lt;p&gt; The following function headers are equivalent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;void arr_func( int arr[]);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void point_func( int *arr);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;It is generally preferred to use the second option, since it makes clear that the parameter
      is a normal pointer. It is possible to use the first option and think that something special
       is going on due to the array notation (but nothing is).&lt;/li&gt;
&lt;li&gt;The sizeof() function will always evaluate to the sizeof a pointer in both cases (8 on 64-bit systems) and &lt;strong&gt;not&lt;/strong&gt; the array size, as was the case when used on the immutable pointer variable you created originally.(see demo below)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Array parameter Example:&lt;/h3&gt;
&lt;pre&gt; &lt;code&gt;#include &amp;amp;ltstdlib.h&amp;gt;
#include &amp;amp;ltstdio.h&amp;gt;

//n should be int*
void passArray(int n[]){
  printf("  size of n: %lu\n",sizeof(n));
  printf("&amp;amp;n %p\n",&amp;amp;n);
  printf("n %p\n",n);
}
int main(){
  int ARR_SIZE = 10;
  int nums[ ARR_SIZE ];
  nums[0]= 0;
  printf("size of nums: %lu\n",sizeof(nums));
  printf("&amp;amp;nums %p\n",&amp;amp;nums);
  printf("nums %p\n",nums);
  passArray(nums);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Warning:&lt;/strong&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;array.c: In function ‘passArray-:
array.c:4:35: warning: ‘sizeof- on array function parameter ‘n-
          will return size of ‘int *- [-Wsizeof-array-argument]
4 |   printf("size of n: %lu\n",sizeof(n));
  |&lt;/code&gt;&lt;/pre&gt;
&lt;strong&gt;Output:&lt;/strong&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;size of nums: 40
&amp;amp;nums 0x7ffda2ebcf30
nums 0x7ffda2ebcf30
size of n: 8
&amp;amp;n 0x7ffda2ebcf18
n 0x7ffda2ebcf30&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-27n"/><published>2024-09-27T12:00:00+00:00</published></entry><entry><id>2024-09-30n</id><title>2024-09-30</title><updated>2024-09-30T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-09-30n"&gt;
&lt;h5&gt;2024-09-30&lt;/h5&gt;
&lt;h2&gt;Stack and Heap Memory&lt;/h2&gt;
&lt;p&gt;Every program has memory for both the stack and heap.&lt;/p&gt;
&lt;h3&gt;Stack memory&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Stores all normally declared variables (including pointers and structs), arrays and function calls.&lt;/li&gt;
&lt;li&gt;Functions are pushed onto the stack in the order they are called, and popped off when completed.&lt;/li&gt;
&lt;li&gt;When a function is popped off the stack, the stack memory associated with it is released.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Heap memory&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Stores dynamically allocated memory.&lt;/li&gt;
&lt;li&gt;Data will remain in the heap until it is manually released. (or the program terminates)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Dynamic memory allocation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;void* malloc(size_t x)&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;Allocates x bytes of heap memory.&lt;/li&gt;
&lt;li&gt;Returns the address at the beginning of the allocation&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns a &lt;code&gt;void *&lt;/code&gt; so you should typecast:&lt;/p&gt;
&lt;code&gt;(type*) malloc(number-of-bytes);&lt;/code&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;int *ptr;
ptr = (int*) malloc(100 * sizeof(int));&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;free(void * p)&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;Releases dynamically allocated memory.&lt;/li&gt;
&lt;li&gt;Has one parameter, a pointer to the beginning of a dynamically allocated block of memory.&lt;/li&gt;
&lt;li&gt;Every call to malloc/calloc should have a corresponding call to free.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;void* calloc(size_t n, size_t x)&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;Allocates n * x bytes of memory, ensuring every bit is 0.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Works like malloc in all other ways, including your need to typecast to the pointer type from void*&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;int *p;
p = (int*)calloc( 5, sizeof(int) );
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;void* realloc(void *p, size_t x)&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;Changes the amount of memory allocated for a block to x bytes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;p&lt;/code&gt; must point to the beginning of a block.&lt;/li&gt;
&lt;li&gt;Returns a pointer to the beginning of the block (this is not always the same as &lt;code&gt;p&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;x&lt;/code&gt; is smaller than the original size of the allocation, the extra bytes will be released.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;x&lt;/code&gt; is larger than the original size then either:
          &lt;ul&gt;
&lt;li&gt;If there is enough space at the end of the original allocation, the original allocation will be updated.&lt;/li&gt;
&lt;li&gt;If there is not enough space, a new allocation will be created, containing all the original values. The original allocation will be freed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Visualizer is possibly helpful for the differences:&lt;/h3&gt;
&lt;a href="https://pythontutor.com/visualize.html#code=%23include%20%3Cstdio.h%3E%0A%23include%20%3Cstdlib.h%3E%0Avoid%20foo%28int%20*arr,%20int%20size%29%7B%0A%20%20%20%0A%20%20%20for%28int%20i%20%3D%200%3B%20i%20%3C%20size%3B%20i%2B%2B%29%7B%0A%20%20%20%20printf%28%22%25d%20%22,*%28arr%2Bi%29%29%3B%0A%20%20%20%7D%0A%20%20%20printf%28%22%5Cn%22%29%3B%0A%7D%0A%0Aint%20main%28%29%20%7B%0A%20%20int%20nums%5B%5D%20%3D%20%7B10,%2020,%2030%7D%3B%0A%20%20%0A%20%20int%20size%20%3D%204%3B%0A%20%20int%20*nums2%20%3D%20%28int%20*%20%29%20malloc%28size*sizeof%28int%29%29%3B%0A%20%20%0A%20%20for%28int%20i%20%3D%200%3B%20i%20%3C%20size%3B%20i%2B%2B%29%7B%0A%20%20%20%20nums2%5Bi%5D%20%3D%20size-i%3B%0A%20%20%7D%0A%20%20foo%28nums2,%20size%29%3B%0A%20%20return%200%3B%0A%7D&amp;amp;cppShowMemAddrs=true&amp;amp;cumulative=false&amp;amp;heapPrimitives=nevernest&amp;amp;mode=edit&amp;amp;origin=opt-frontend.js&amp;amp;py=c_gcc9.3.0&amp;amp;rawInputLstJSON=%5B%5D&amp;amp;textReferences=false"&gt;C Visualizer with array example.&lt;/a&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-09-30n"/><published>2024-09-30T12:00:00+00:00</published></entry><entry><id>2024-10-02n</id><title>2024-10-02</title><updated>2024-10-02T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-02n"&gt;
&lt;h5&gt;2024-10-02&lt;/h5&gt;
&lt;h2&gt;Checking for prime numbers&lt;/h2&gt;
&lt;p&gt;A naive way to check if an integer k is prime, is to check divisibility of all integers [2,k-1].&lt;/p&gt;
&lt;p&gt;Slightly less naive is to check divisibility of all integers [2,x], and figure out how small an x you need.&lt;/p&gt;
&lt;p&gt;Since all factors are paired around the sqrt, you can use the range [2,(int)sqrt(k)]&lt;/p&gt;
&lt;p&gt;This is very slow as we don't need to check divisibility by all of those numbers. It would be faster to just check the prime ones.&lt;/p&gt;
&lt;h2&gt;Sieve of Eratosthenes&lt;/h2&gt;
&lt;p&gt;Here is a much better method to find prime numbers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Assume all numbers are prime except 0 and 1.
      &lt;p&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 0 &lt;/s&gt;&lt;/span&gt; &lt;span style="color:gray"&gt;&lt;s&gt; 1 &lt;/s&gt;&lt;/span&gt; 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Start with the first prime number (2) Iterate through all prime numbers and cross them out because they are composite (not prime). &lt;/p&gt;
&lt;p&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 0 &lt;/s&gt;&lt;/span&gt; &lt;span style="color:gray"&gt;&lt;s&gt; 1 &lt;/s&gt;&lt;/span&gt; 2 3 &lt;span style="color:gray"&gt;&lt;s&gt; 4 &lt;/s&gt;&lt;/span&gt; 5 &lt;span style="color:gray"&gt;&lt;s&gt; 6 &lt;/s&gt;&lt;/span&gt; 7 &lt;span style="color:gray"&gt;&lt;s&gt; 8 &lt;/s&gt;&lt;/span&gt; 9 &lt;span style="color:gray"&gt;&lt;s&gt;10&lt;/s&gt;&lt;/span&gt; 11 &lt;span style="color:gray"&gt;&lt;s&gt;12&lt;/s&gt;&lt;/span&gt; 13 &lt;span style="color:gray"&gt;&lt;s&gt;14&lt;/s&gt;&lt;/span&gt; 15 &lt;span style="color:gray"&gt;&lt;s&gt;16&lt;/s&gt;&lt;/span&gt; 17 &lt;span style="color:gray"&gt;&lt;s&gt;18&lt;/s&gt;&lt;/span&gt; 19 &lt;span style="color:gray"&gt;&lt;s&gt;20&lt;/s&gt;&lt;/span&gt; 21 &lt;span style="color:gray"&gt;&lt;s&gt;22&lt;/s&gt;&lt;/span&gt; 23 &lt;span style="color:gray"&gt;&lt;s&gt;24&lt;/s&gt;&lt;/span&gt; 25 &lt;span style="color:gray"&gt;&lt;s&gt;26&lt;/s&gt;&lt;/span&gt; 27 &lt;span style="color:gray"&gt;&lt;s&gt;28&lt;/s&gt;&lt;/span&gt; 29 &lt;span style="color:gray"&gt;&lt;s&gt;30&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Look at the next number that is not yet crossed out (3) which will be the 2nd prime, and repeat the process for that number.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 0 &lt;/s&gt;&lt;/span&gt; &lt;span style="color:gray"&gt;&lt;s&gt; 1 &lt;/s&gt;&lt;/span&gt; 2 3&lt;span style="color:gray"&gt;&lt;s&gt; 4 &lt;/s&gt;&lt;/span&gt; 5 &lt;span style="color:gray"&gt;&lt;s&gt; 6 &lt;/s&gt;&lt;/span&gt; 7 &lt;span style="color:gray"&gt;&lt;s&gt; 8 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 9 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;10&lt;/s&gt;&lt;/span&gt; 11 &lt;span style="color:gray"&gt;&lt;s&gt;12&lt;/s&gt;&lt;/span&gt; 13 &lt;span style="color:gray"&gt;&lt;s&gt;14 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;15 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;16&lt;/s&gt;&lt;/span&gt; 17 &lt;span style="color:gray"&gt;&lt;s&gt;18&lt;/s&gt;&lt;/span&gt; 19 &lt;span style="color:gray"&gt;&lt;s&gt;20 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;21 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;22&lt;/s&gt;&lt;/span&gt; 23 &lt;span style="color:gray"&gt;&lt;s&gt;24&lt;/s&gt;&lt;/span&gt; 25 &lt;span style="color:gray"&gt;&lt;s&gt;26 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;27 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;28&lt;/s&gt;&lt;/span&gt; 29 &lt;span style="color:gray"&gt;&lt;s&gt;30&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
      Look at the next number that is not yet crossed out (5) which will be the 3rd prime, and repeat the process for that number.
      &lt;p&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 0 &lt;/s&gt;&lt;/span&gt; &lt;span style="color:gray"&gt;&lt;s&gt; 1 &lt;/s&gt;&lt;/span&gt; 2 3&lt;span style="color:gray"&gt;&lt;s&gt; 4 &lt;/s&gt;&lt;/span&gt; 5 &lt;span style="color:gray"&gt;&lt;s&gt; 6 &lt;/s&gt;&lt;/span&gt; 7 &lt;span style="color:gray"&gt;&lt;s&gt; 8 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt; 9 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;10&lt;/s&gt;&lt;/span&gt; 11 &lt;span style="color:gray"&gt;&lt;s&gt;12&lt;/s&gt;&lt;/span&gt; 13 &lt;span style="color:gray"&gt;&lt;s&gt;14 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;15 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;16&lt;/s&gt;&lt;/span&gt; 17 &lt;span style="color:gray"&gt;&lt;s&gt;18&lt;/s&gt;&lt;/span&gt; 19 &lt;span style="color:gray"&gt;&lt;s&gt;20 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;21 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;22&lt;/s&gt;&lt;/span&gt; 23 &lt;span style="color:gray"&gt;&lt;s&gt;24 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;25 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;26 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;27 &lt;/s&gt;&lt;/span&gt;&lt;span style="color:gray"&gt;&lt;s&gt;28&lt;/s&gt;&lt;/span&gt; 29 &lt;span style="color:gray"&gt;&lt;s&gt;30&lt;/s&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Repeat until you find the k&lt;sup&gt;th&lt;/sup&gt; prime.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The algorithm in code&lt;/h2&gt;
&lt;p&gt;The first 25 primes are: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, and 97.&lt;/p&gt;
&lt;p&gt;Let us see how we would find them using the sieve of eratosthenes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; First, choose a SIZE greater than or equal to the largest prime you want. Choosing a SIZE too big means your algorithm will run slower. Choosing a SIZE too small means you won't find the n&lt;sup&gt;th&lt;/sup&gt; prime.
      This means you will need to know approximately how big the n&lt;sup&gt;th&lt;/sup&gt; prime is to make an array large enough. This is a problem to think about later however,  let us use 100 for this example. &lt;/li&gt;
&lt;li&gt; Now we can treat each index of the array as the value we are testing, and store a value to indicate prime or not.&lt;/li&gt;
&lt;li&gt; Mark all of the  numbers up to that SIZE. (you could do counting numbers instead if you like)&lt;/li&gt;
&lt;li&gt; Initialize the array so all values are prime, then mark 0 and 1 as composite.
      &lt;p&gt;&lt;img alt="" src="img/ArraySieve.png" width="600px"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt; Find the next index that is prime, Now flag all indices that are the multiples of that as not prime.
      &lt;p&gt;&lt;img alt="" src="img/ArraySieveNext.png" width="600px"/&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt; Continue the process until you get a stopping condition. Either you got to the end of the array, or you found the n&lt;sup&gt;th&lt;/sup&gt; prime.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="2024-10-05h"&gt;Lab04 Requirements&lt;/h3&gt;
&lt;p&gt;  Clone the repo: &lt;a href="https://classroom.github.com/a/SBdHcF-w"&gt;https://classroom.github.com/a/SBdHcF-w&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;  You will need to worry about sieve.c and sieve.h. &lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Critical:&lt;/strong&gt; You will put a main in some other c file, not in sieve.c . I will test your sieve.c with my own tester.&lt;/p&gt;
&lt;p&gt;  Suggestion: have your sieve() function call a different function with all the work in it. This makes it easy to update to whichever version you made that works fastests.&lt;/p&gt;
&lt;p&gt;  In sieve.c have a function &lt;code&gt;int sieve(int n);&lt;/code&gt; that returns the nth prime.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;sieve(1) returns 2&lt;/li&gt;
&lt;li&gt;sieve(2) returns 3&lt;/li&gt;
&lt;li&gt;sieve(25) returns 97&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Optimizations:&lt;/h3&gt;
&lt;p&gt;Please make sure you make new versions as you try to add new features. Always keep your fastest working version around.&lt;/p&gt;
&lt;p&gt;Note: When crossing out the multiples of eac prime, you MUST increment by that primes in the loop, not by 1. e.g. increment by 5 to cross out multiples of 5. This is not an optimization.&lt;/p&gt;
&lt;p&gt;Here is a possible progression of optimizations.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No Optimizations, just malloc/calloc the array and get large primes. (Just make it work)&lt;/li&gt;
&lt;li&gt;Estimate the size of your array using math (see prime approximation below)&lt;/li&gt;
&lt;li&gt;Use char array instead of int&lt;/li&gt;
&lt;li&gt;Only cross out multiples of primes IF the prime is less than the sqrt of the SIZE. This makes the entire process stop when you reach a high enough prime. &lt;/li&gt;
&lt;li&gt;Try to cut down on your extra variables and extra function calls&lt;/li&gt;
&lt;li&gt;Store only odd values in your array, this cuts down array traversal and memory allocation quite a bit. e.g. index 0 is 1, index 1 is 3, index 2 is 5 etc.&lt;/li&gt;
&lt;li&gt;Try using bitwise operations and store bits (exploration of this topic is optional)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Everyone should be able to do all of the non-bitwise optimizations!&lt;/p&gt;
&lt;h2&gt;Prime approximations&lt;/h2&gt;
&lt;p&gt;
    The prime number is approximately &lt;code&gt;n * ln(n)&lt;/code&gt; by the prime number theorem. However this is not always &amp;gt;= the n'th prime. You will need to add a coefficient or offset.
  &lt;/p&gt;
&lt;h3&gt;Versions&lt;/h3&gt;
&lt;p&gt;You will need to make multiple versions of this method!&lt;/p&gt;
&lt;p&gt;Make sieveV1(n) and comment what optimizations you added.&lt;/p&gt;
&lt;p&gt;Make sieve(n) call your fastest working sieveVx() command.&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;int sieve(int n){
   return sieveV5(n);
}

//basic version
int sieveV1(int n){
  //code
}

//stopped early when checking primes
int sieveV2(int n){
  //code
}
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;You need to test for both speed and correctness. You only have to account for sieve(n) where 1 &amp;lt;= n &amp;lt;= 2,000,000&lt;/p&gt;
&lt;p&gt;Here is a quick test script to see how fast your version is:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include "sieve.h"
int main(){
  //This quickly checks a variety of sizes and values
  //Do not try to exploit the fact that these function calls are in the same main. I run multiple tests.
  int input[] = {1, 2, 3, 4,  5,  6,  7,  8,  9, 10, 25,
      100, 1000, 2350, 2945, 9822,  10000,  50000, 73234,  100000,
      500000, 1000003,1510041,1932457, 2000000};
  int ans[] =   {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 97,
      541, 7919, 20897, 26849, 102563, 104729, 611953, 926623,1299709,
      7368787, 15485927, 24049567, 31285333 ,32452843};

  for(int i = 0; i &amp;lt; sizeof(input)/sizeof(int); i++){
      int guess = sieve(input[i]);
      //printf("Test sieve(%7d)\t%s, your guess : %8d \n",input[i],(guess==ans[i])?"PASS":"FAIL",guess);
      if(guess!=ans[i]){
          //exit at first failed case.
          printf("ERROR: sieve(%7d) your guess : %8d \n", input[i], guess);
          return 1;
      }

  }
  printf("Pass all cases.");
  return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Test results: (on same computer) &lt;/h3&gt;
&lt;p&gt;8.9 sec : Unoptimized (array always 32452844) &lt;/p&gt;
&lt;p&gt;2.5 sec : Tight array bounds.&lt;/p&gt;
&lt;p&gt;1.6 sec : Tight array bounds /w char array.&lt;/p&gt;
&lt;p&gt;0.6 sec : Tight array bounds /w char array only storing odd values in the array.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-02n"/><published>2024-10-02T12:00:00+00:00</published></entry><entry><id>2024-10-09n</id><title>2024-10-09</title><updated>2024-10-09T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-09n"&gt;
&lt;h5&gt;2024-10-09&lt;/h5&gt;
&lt;h2&gt;Strings in C&lt;/h2&gt;
&lt;p&gt;In c, strings are character arrays.&lt;/p&gt;
&lt;p&gt;There is nothing special about the way character arrays work.
    Because strings are so useful, there are a few features of C that make working with them simpler.&lt;/p&gt;
&lt;p&gt;
    By &lt;strong&gt;convention&lt;/strong&gt; the last entry in a string character array is the NULL character
    (either &lt;code&gt;0&lt;/code&gt; (the number), or &lt;code&gt;'\0'&lt;/code&gt; (the character).
    This is not something that is guaranteed, if you want to create a string, you will
    need to make sure that there is a terminating NULL, if not, a number of string related functions will not work.
  &lt;/p&gt;
&lt;h3&gt; When you use &lt;code&gt;""&lt;/code&gt; to make a string &lt;em&gt;literal&lt;/em&gt; :&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;A character array large enough to store the string, including a terminating NULL, is created in memory.&lt;/li&gt;
&lt;li&gt;The characters of the string are stored in that array, and a terminating NULL is added.&lt;/li&gt;
&lt;li&gt;String literals are &lt;em&gt;immutable&lt;/em&gt; &lt;/li&gt;
&lt;li&gt;
      If a string literal is exactly repeated in code, a new character array is not created,
      instead, the orginal array is used. This means all references to the same immutable
      string literal refer to the same piece of memory.
    &lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Declaring Strings&lt;/h3&gt;
&lt;p&gt;There are 4 ways to declare strings in C (in eaxch example, the numbers and strings used are randomly chosen, none have special meaning in C).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;char s[256];&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Declares a mutable array of 256 bytes.&lt;/li&gt;
&lt;li&gt;No speciic characters are saved to memory.&lt;/li&gt;
&lt;li&gt;No guarantee of a NULL character at any position.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;char s[256] = "Imagine"&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Creates the immutable string literal &lt;code&gt;"Imagine"&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;Declares a mutable array of 256 bytes.&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Copies&lt;/em&gt; the string &lt;code&gt;"Imagine"&lt;/code&gt; , including a terminating NULL, into the first 8 bytes of the array &lt;code&gt;s&lt;/code&gt; .&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;char s[] = "Tuesday"; &lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Creates the immutable string literal &lt;code&gt;"Tuesday"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Creates an 8 bytes array, large enough for &lt;code&gt;"Tuesday"&lt;/code&gt; and a terminating NULL for the variable &lt;code&gt;s&lt;/code&gt; &lt;/li&gt;
&lt;li&gt; &lt;em&gt;Copies&lt;/em&gt; the string &lt;code&gt;"Tuesday"&lt;/code&gt; , including a terminating NULL, into the array &lt;code&gt;s&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;char *s = "Mankind"; &lt;/code&gt;
&lt;ul&gt;
&lt;li&gt; Creates the immutable string literal &lt;code&gt;"Mankind"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt; &lt;code&gt;s&lt;/code&gt; becomes a pointer to that immutable string. &lt;/li&gt;
&lt;li&gt;  It is important to note that in the last example, an array is not created. In that case &lt;code&gt;s&lt;/code&gt; is just a pointer to the memory location with the immutable string lives. If you want a mutable string, you cannot declare it this way. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#include &lt;stdio.h&gt;
int main() {
  char s[16];
  char s2[16] = "Imagine";
  char s3[] = "Fish";
  char *s4 = "Imagine";
  char *s5 = "Imagine";

  //printf("%s\n",s);//DO NOT PRINT UNINITIALIZED MEMORY!
  printf("%s\n",s2);
  printf("%s\n",s3);
  printf("%s\n",s4);
  return 0;
}&lt;/stdio.h&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;img alt="" src="img/cStrings.png" width="600px"/&gt;
&lt;h2&gt;Working With String Variables&lt;/h2&gt;
&lt;p&gt;Everything we've covered about pointers and arrays still holds true, string variables are pointers, either array pointers or normal pointers.&lt;/p&gt;
&lt;p&gt;It is important to keep track of &lt;em&gt;variables&lt;/em&gt; vs. &lt;em&gt;values&lt;/em&gt; .&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; &lt;code&gt;char s[10] = "Trogdor!!";&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;In this example, &lt;code&gt;s&lt;/code&gt; is an array variable that points to the 10 byte array allocation. &lt;code&gt;s&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s&lt;/code&gt; is immutable, it cannot point to any other memory location. e.g. &lt;code&gt;s = "is a dragon";&lt;/code&gt; &lt;strong&gt;is an error&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The values in the array &lt;code&gt;s&lt;/code&gt; points to are &lt;strong&gt;not&lt;/strong&gt; immutable. You can change the value of the string at any point. &lt;code&gt;s[0] = 'M';&lt;/code&gt; is perfectly good.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;char *s = "No sports references";&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Here, &lt;code&gt;s&lt;/code&gt; is a pointer.&lt;/li&gt;
&lt;li&gt;As a pointer, you can change the value &lt;code&gt;s&lt;/code&gt; points to. &lt;code&gt;s = "The Best";&lt;/code&gt; is valid.&lt;/li&gt;
&lt;li&gt;
          Since &lt;code&gt;s&lt;/code&gt; points to an immutable string literal, you cannot change the value of the string.
          &lt;code&gt;s[0] = 'N';&lt;/code&gt; &lt;strong&gt;is an error&lt;/strong&gt; .
        &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;String library&lt;/h2&gt;
&lt;p&gt;You can find built in functions for handling strings in &lt;code&gt;string.h&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;man 3 string&lt;/code&gt; to get a summary of methods, or use a&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-09n"/><published>2024-10-09T12:00:00+00:00</published></entry><entry><id>2024-10-10n</id><title>2024-10-10</title><updated>2024-10-10T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-10n"&gt;
&lt;h5&gt;2024-10-10&lt;/h5&gt;
&lt;h2 id="2024-10-10h"&gt; Lab05&lt;/h2&gt;
&lt;h5&gt;Deadline October 16th 8am&lt;/h5&gt;
&lt;p&gt;You will have 3 lab days + homework time for this lab.&lt;/p&gt;
&lt;p&gt;First, acquaint yourself with the basic string functions: strlen, strcpy, strcat, strncat and strncpy. You can look at the man pages for each if you are unclear as to their uses. I encourage you to play around with each so you are comfortable with how to use them.&lt;/p&gt;
&lt;p&gt;Then write your own versions of the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;strlen: &lt;code&gt;int mystrlen( char *s ) &lt;/code&gt; &lt;/li&gt;
&lt;li&gt;strcpy/strncpy: &lt;code&gt;char * mystrcpy( char *dest, char *source )&lt;/code&gt;
                                 and &lt;code&gt;char * mystrncpy( char *dest, char *source, int n)&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;strcat/strncat: &lt;code&gt;char * mystrcat( char *dest, char *source )&lt;/code&gt;
                                 and &lt;code&gt; char * mystrncat( char *dest, char *source, int n)&lt;/code&gt; ]&lt;/li&gt;
&lt;li&gt;strcmp: &lt;code&gt; int mystrcmp( char *s1, char *s2 )&lt;/code&gt;.
      Your version does not need to return the same exact value as the system version, as long as it returns -, + or 0 when it should. &lt;/li&gt;
&lt;li&gt;strchr: &lt;code&gt;char * mystrchr( char *s, char c )&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;strong&gt;Required&lt;/strong&gt; use the function headers provided above, they may differ from the standard headers.&lt;/p&gt;
&lt;p&gt;You must test every function you write, you will not get full credit for an untested functions.&lt;/p&gt;
&lt;p&gt;Your program should consist of:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the &lt;code&gt;main.c&lt;/code&gt; file that I have prepared for you, available in the github classroom lab05 repo&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;mystring.c&lt;/code&gt; &lt;code&gt;mystring.h&lt;/code&gt; pair of files for your string functions.&lt;/li&gt;
&lt;li&gt;a makefile with a compile target as the default, and a run target.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When you test your functions, run them alongside the regular ones so you can see if they behave the same way or not. Remember you should call them my+originalName.&lt;/p&gt;
&lt;p&gt;You must look at documentation to determine the behavior of the functions, in particular the n vs non-n versions!&lt;/p&gt;
&lt;h3&gt;Use this repository for the work:&lt;/h3&gt;
&lt;a href="https://classroom.github.com/a/MMknZczF"&gt;
    https://classroom.github.com/a/MMknZczF
  &lt;/a&gt;
&lt;h3&gt;When you are done, you should look at the following two functions:&lt;/h3&gt;
&lt;p&gt;1. strstr : returns a pointer to the first index of a specified substring in another string. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;char * mystrstr( char *s1, char * s2 )&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;2. mysplit&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;char * mysplit(char *s, char d)&lt;/code&gt;
    This is not quite a built in string function, but similar to strsep.
    This function should go through s, replacing one instance of c with
    a NULL byte. It returns a pointer to the byte after the null &lt;/p&gt;
&lt;p&gt;Why is this useful? How can it be used?&lt;/p&gt;
&lt;p&gt;Attempt to write these functions. &lt;/p&gt;
&lt;h3&gt;Here's an example of what your code might look like when run:&lt;/h3&gt;
&lt;pre&gt;start strings:
s1: []
s2: [hello]
s3: [goodbye]

Testing strlen(s1):
[standard]:     0
[mine]:         0

Testing strlen(s2):
[standard]:     5
[mine]:         5

Testing strcpy(s1, s2):
[standard]:     [hello]
[mine]:         [hello]

Testing strncpy(s1, s3, 3):
[standard]:     [goo______________________________________________]
[mine]:         [goo______________________________________________]

Testing strcat(s1, s3):
[standard]:     [hellogoodbye]
[mine]:         [hellogoodbye]

Testing strncat(s1, s2, 3):
[standard]:     [hellohel]
[mine]:         [hellohel]

Testing strchr(s1, 'l'):
[standard]:     [0x7ffff3e10112]
[mine]:         [0x7ffff3e10112]

Testing strchr(s1, 0):
[standard]:     [0x7ffff3e10115]
[mine]:         [0x7ffff3e10115]

Testing strchr(s1, 'z'):
[standard]:     [(nil)]
[mine]:         [(nil)]

Testing strcmp
Comparting ab to abc:
        [standard]:     [-1]
        [mine]:         [-99]
Comparting abc to ab:
        [standard]:     [1]
        [mine]:         [99]
Comparting abc to abc:
        [standard]:     [0]
        [mine]:         [0]&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-10n"/><published>2024-10-10T12:00:00+00:00</published></entry><entry><id>2024-10-15n</id><title>2024-10-15</title><updated>2024-10-15T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-15n"&gt;
&lt;h5&gt;2024-10-15&lt;/h5&gt;
&lt;h2&gt;Results of Sieve&lt;/h2&gt;
&lt;p&gt;Here are the top 3 student times relative to mine:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt; &lt;th&gt;Name&lt;/th&gt; &lt;th&gt;Time&lt;/th&gt; &lt;th&gt;% of K&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;09.Chen.Matthew&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;1.73&lt;/td&gt; &lt;td&gt;.81&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;10,Yu.Kellen&lt;/strong&gt; &lt;/td&gt; &lt;td&gt;1.9&lt;/td&gt; &lt;td&gt;.89&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;K &lt;/td&gt; &lt;td&gt;2.12&lt;/td&gt; &lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;09.Liang.Edmund &lt;/td&gt; &lt;td&gt;2.5&lt;/td&gt; &lt;td&gt;1.17&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10.Chen.Alan&lt;/td&gt; &lt;td&gt;3.09&lt;/td&gt; &lt;td&gt;1.45&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;09.Goihman.Benjamin&lt;/td&gt; &lt;td&gt;3.125&lt;/td&gt; &lt;td&gt;1.47&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;09.Hasan.Tanzeem&lt;/td&gt; &lt;td&gt;3.189&lt;/td&gt; &lt;td&gt;1.50&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Compared to 2023's top 3 students:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt; &lt;th&gt;Name&lt;/th&gt; &lt;th&gt;Time&lt;/th&gt; &lt;th&gt;% of K&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;K&lt;/strong&gt; &lt;/td&gt; &lt;td&gt;0.185&lt;/td&gt; &lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;10.rahman.naowal/&lt;/strong&gt; &lt;/td&gt; &lt;td&gt;0.209&lt;/td&gt; &lt;td&gt;1.13&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;08.li.andrew/&lt;/td&gt; &lt;td&gt;0.332&lt;/td&gt; &lt;td&gt;1.79&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;09.winer.charlie/&lt;/td&gt; &lt;td&gt;0.333&lt;/td&gt; &lt;td&gt;1.8&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Compared to the 2022's top 4 students:&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt; &lt;th&gt;Name&lt;/th&gt; &lt;th&gt;Time&lt;/th&gt; &lt;th&gt;% of K&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;&lt;strong&gt;3.dewan.zawad&lt;/strong&gt; &lt;/td&gt; &lt;td&gt;0.532&lt;/td&gt; &lt;td&gt;0.89&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;&lt;strong&gt;K&lt;/strong&gt;&lt;/td&gt; &lt;td&gt;0.599&lt;/td&gt; &lt;td&gt;1&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;hughes.vernon&lt;/td&gt; &lt;td&gt;0.686&lt;/td&gt; &lt;td&gt;1.15&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;eisenberg.lee&lt;/td&gt; &lt;td&gt;0.701&lt;/td&gt; &lt;td&gt;1.17&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;paltrowitz.jacob&lt;/td&gt; &lt;td&gt;0.706&lt;/td&gt; &lt;td&gt;1.18&lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;C can do some funky things:&lt;/h2&gt;
&lt;p&gt;If your strcpy looks like this:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char* mystrcpy(char* d, char* s){
  char* orig = dest;
  while(*src){
    *dest=*src;
    dest++;
    src++;
  }
  *dest=*src;
  return orig;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consider instead how this would work:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char* mystrcpy(char* d, char* s){
  char* orig = d;
  while(*d++ = *s++);
  return orig;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or the ghastly:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char* mystrcpy(char* d, char* s){
	return (*d=*s) ? mystrcpy(d+1,s+1) - 1 : d;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;struct&lt;/h2&gt;
&lt;p&gt;A &lt;code&gt;struct&lt;/code&gt; is a custom data type that is a collection of values.&lt;/p&gt;
&lt;h3&gt;Declaring&lt;/h3&gt;
&lt;p&gt;
  The following line creates a variable, &lt;code&gt;s&lt;/code&gt;, who's type is an anonymous struct:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;struct { int a; char x; } s;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;code&gt;struct { int a; char x; }&lt;/code&gt; is the full type of &lt;code&gt;s&lt;/code&gt;,
  it is syntactically identical to &lt;code&gt;int&lt;/code&gt; or &lt;code&gt;float&lt;/code&gt;
&lt;/p&gt;
&lt;h3&gt;Utilization&lt;/h3&gt;
&lt;p&gt;We use the &lt;code&gt;.&lt;/code&gt; operator to access a value inside a struct&lt;/p&gt;
&lt;p&gt;&lt;code&gt;s.a = 10;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;s.x = '@';&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here is an example of creating and using a struct:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt; int main() {
  struct {int a; char x;} s0;

  s0.a = 51;
  s0.x = '%';

  printf("s0: %d\t%c\n", s0.a, s0.x);

  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Creating prototypes&lt;/h3&gt;
&lt;p&gt;It is preferable to &lt;strong&gt;prototype&lt;/strong&gt; your structs, which will make it easier to create and work with multiple variables of the same struct type.
    &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;struct foo { int a; char x; };&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Note that since we are not creating a variable, there is no name between the &lt;code&gt;}&lt;/code&gt; and the &lt;code&gt;;&lt;/code&gt; at the end.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After creating a prototye for a struct, you can declare new variables of that type like so:
    &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;struct foo s;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You still must include the word &lt;code&gt;struct&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is typically better practice to prototype structs outside of any particular function.
    &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Struct prototypes are most commonly found in .h files.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;Here is an example of creating and using a struct with a prototype:
    &lt;/p&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;struct foo {int a; char x;};
int main() {
   struct foo s0;
   struct foo s1;

   s0.a = 51;
   s0.x = '%';

   s1 = s0;
   printf("s0: %d\t%c\n", s0.a, s0.x);
   printf("s1: %d\t%c\n", s1.a, s1.x);

   return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Pointers and Structs&lt;/h3&gt;
&lt;p&gt;You can make pointers to structs like pointers to primitaves.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;struct foo *p = &amp;amp;s;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DANGER!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One very important note, &lt;code&gt;.&lt;/code&gt; takes precedence over &lt;code&gt;*&lt;/code&gt;.
  &lt;/p&gt;&lt;p&gt;
    This means that &lt;code&gt;*p.x&lt;/code&gt; is the same as &lt;code&gt;*(p.x)&lt;/code&gt;
    which is almost certainly &lt;strong&gt;NOT&lt;/strong&gt; what you want. (This will look for x inside p and de-reference that result).
  &lt;/p&gt;
&lt;p&gt;To access a value in a struct via a pointer you need to do: &lt;code&gt;(*p).x&lt;/code&gt;, that is, de-reference first, then get x.&lt;/p&gt;
&lt;h3&gt;Shortcut:&lt;/h3&gt;
&lt;p&gt;In C, &lt;code&gt;p-&amp;gt;x&lt;/code&gt; is syntactic shorthand for &lt;code&gt;(*p).x&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-15n"/><published>2024-10-15T12:00:00+00:00</published></entry><entry><id>2024-10-16n</id><title>2024-10-16</title><updated>2024-10-16T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-16n"&gt;
&lt;h5&gt;2024-10-16&lt;/h5&gt;
&lt;h3&gt;Struct lab&lt;/h3&gt;
&lt;p&gt;This is a small part of the lab that doesn't need that much time. (It is intended to be rather basic,
    if you have trouble let me know.)&lt;/p&gt;
&lt;p&gt;Due: Tomorrow 10/17 In class! (Just this much, you will expand on it in class this is just the basics.&lt;/p&gt;
&lt;h2 id="2024-10-16h"&gt;lab06&lt;/h2&gt;
&lt;p&gt;GitHub Submission Link: &lt;a href="https://classroom.github.com/a/nlVP82jI"&gt;https://classroom.github.com/a/nlVP82jI&lt;/a&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a makefile with compile and run targets.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;mystruct.c&lt;/code&gt; and &lt;code&gt;mystruct.h&lt;/code&gt; file for your struct methods, and a separate &lt;code&gt;main.c&lt;/code&gt; file for your main. (This should be default style behavior for all of your projects).&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;struct movie&lt;/code&gt; that has 3 data members, int, float, and a string.
      (Use a char[] NOT char* for this string.)
    &lt;/li&gt;
&lt;li&gt;Let us put in Strings that are the names of movies. The int can be the year released, double can be the average rating of that movie out of 10.&lt;/li&gt;
&lt;li&gt;Write a function that print(struct movie m) that prints your struct in a single line.&lt;/li&gt;
&lt;li&gt;Write a function that createmovie(...) creates a new struct in heap memory and returns its address. It should have paramaters appropriate to your struct.&lt;/li&gt;
&lt;li&gt;
      Write your main function that:
      &lt;ul&gt;
&lt;li&gt;Create an array of 4 pointers to your struct.&lt;/li&gt;
&lt;li&gt;Populate it with randomized data using your creating method.&lt;/li&gt;
&lt;li&gt;Print your data in a reasonable way (one element per line)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;hint: You may need to make an array of strings so you can choose one randomly see note below.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char arr[3][10] = {"abc", "abcd", "abcde"};
printf("String array Elements are:\n");
for (int i = 0; i &amp;lt; 3; i++)
{
  printf("%s\n", arr[i]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-16n"/><published>2024-10-16T12:00:00+00:00</published></entry><entry><id>2024-10-18n</id><title>2024-10-18</title><updated>2024-10-18T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-18n"&gt;
&lt;h3 id="2024-10-18h"&gt;Lab06-structs is really linked-lists&lt;/h3&gt;
&lt;h4&gt; Due: Monday 10/21 8:00 am&lt;/h4&gt;
&lt;h4&gt;New Things to add to the lab&lt;/h4&gt;
&lt;p&gt;Write a simple linked list library + program.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your labs should always be compileable via &lt;code&gt;compile&lt;/code&gt; and &lt;code&gt;run&lt;/code&gt; targets of your makefile&lt;/li&gt;
&lt;li&gt;Rename your  &lt;code&gt;myStruct.c/.h&lt;/code&gt;  from the previous instructions to &lt;code&gt;node.c/.h&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Change your struct name to &lt;code&gt;struct node&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add a new element to the struct: A pointer to a struct of the same type (the next node).&lt;/li&gt;
&lt;li&gt;Write several list functions outlined below. They should be in a &lt;code&gt;list.c/.h&lt;/code&gt; library. You must have a separate c file used for your main function and testing.&lt;/li&gt;
&lt;li&gt;Your main should print a series of tests for these various functions. This should be enough to convince yourself (and me) that the functions work correctly*. I would advise you to test removing first, last and middle elements, multiple times in case one of these cases breaks future functionality. &lt;/li&gt;
&lt;li&gt;*Correctly does not include: warnings or segementation faults.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's an example of how a struct could have a pointer to the same type inside of it:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;struct user_node {
  int id;
  char name[200];
  struct user_node *next;
  };&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Teacher Testing&lt;/h3&gt;
&lt;p&gt;I will create a driver main program, that includes your &lt;code&gt;list.h&lt;/code&gt;  and &lt;code&gt;node.h&lt;/code&gt; then uses the functions. If this does not work, you will not recieve credit.&lt;/p&gt;
&lt;h3&gt;Create the following functions:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;void print_list(struct node * list)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Should take a pointer to a node struct and print out all of the data in the list, one element per newline.
          Prefix each line with the index of the element e.g.
        &lt;pre class="codeblock"&gt;[0]Star Wars: Episode IV - A New Hope (1977) 8.6
[1]Alien (1979) 8.5
[2]The Matrix (1999) 8.7
[3]Inception (2010) 8.8
[4]Interstellar (2014) 8.7&lt;/pre&gt; &lt;/li&gt;
&lt;li&gt;You should call your print() function from your node class. Modify it a little so that the formatting is the same as the example:  &lt;code&gt;"The Matrix (1999) 8.7"&lt;/code&gt; or  &lt;code&gt;"TITLE (YEAR) SCORE"&lt;/code&gt; with spaces between them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct node * insert_front(struct node * list, char* title, int year, double rating)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Should take a pointer to the existing list and create a new node and put it at the beginning of the list.&lt;/li&gt;
&lt;li&gt;The second argument will be an char* that contains a string that should be copied into your node.&lt;/li&gt;
&lt;li&gt;The numerical parameters should also be copied into your node.&lt;/li&gt;
&lt;li&gt;Returns a pointer to the beginning of the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct node * free_list(struct node * list)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Should take a pointer to a list as a parameter and then go through the entire list freeing each node and return a pointer to the beginning of the list (which should be NULL by then).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct node * remove_node_by_index(struct node * list, int index)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Remove the node in the index position, from the list pointed to by &lt;code&gt;front&lt;/code&gt;. Assume this list starts at index zero.&lt;/li&gt;
&lt;li&gt;A node that is removed must be free'd&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;index&lt;/code&gt; is negative or &lt;code&gt;index &amp;gt;=&lt;/code&gt; the length of the list, nothing is changed. (This includes when the list is empty)&lt;/li&gt;
&lt;li&gt;Returns a pointer to the beginning of the list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Sample Usage&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;struct node * movies = NULL;
movies = insert_front(movies, "Pulp Fiction", 1994, 9.0);
movies = insert_front(movies, "Battlefield Earth", 2000, 2.5);
print_list(movies);
movies = free_list(movies);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should recognize that functions that return a pointer to the beginning of the list should be assigned to the list, like insert, or even free!&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-18n"/><published>2024-10-18T12:00:00+00:00</published></entry><entry><id>2024-10-21n</id><title>2024-10-21</title><updated>2024-10-21T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-21n"&gt;
&lt;h5&gt;2024-10-21&lt;/h5&gt;
&lt;h3 id="file-functions"&gt;File functions&lt;/h3&gt;
&lt;code&gt;open - &amp;lt;fcntl.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Add a file to the file table and returns its file descriptor.&lt;/li&gt;
&lt;li&gt;This will make the file accessible within a program via the returned file descriptor.&lt;/li&gt;
&lt;li&gt;If open fails, -1 is returned, extra error information can be found in &lt;code&gt;errno&lt;/code&gt;.
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;errno&lt;/code&gt; is an int variable that can be found in &lt;code&gt;&amp;lt;errno.h&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;strerror&lt;/code&gt; (in &lt;code&gt;string.h&lt;/code&gt;) on errno to return a string description of the error&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;open( path, flags, mode )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mode&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Only used when creating a file. Set the new file's permissions using a 3 digit octal #&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flags&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Determine what you plan to do with the file, use the following constants and combine with &lt;code&gt;|&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_RDONLY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_WRONLY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_RDWR&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_APPEND&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_TRUNC&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_CREAT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O_EXCL&lt;/code&gt;: when combined with &lt;code&gt;O_CREAT&lt;/code&gt;, will return an error if the file exists&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;examples:
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;open(foo.txt, O_RDONLY, 0)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;open(goo.txt, O_WRONLY | O_APPEND | O_CREAT, 0644)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;code&gt;read - &amp;lt;unistd.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Read data from a file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read( fd, buff, n )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Read &lt;code&gt;n&lt;/code&gt; bytes from &lt;code&gt;fd&lt;/code&gt;'s file into &lt;code&gt;buff&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Returns the number of bytes actually read. Returns -1 and sets &lt;code&gt;errno&lt;/code&gt;	if unsuccessful.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buff&lt;/code&gt; must be a memory address (pointer or array), but can be to any type of data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;code&gt;write - &amp;lt;unistd.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Write data to a file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;write( fd, buff, n )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Write &lt;code&gt;n&lt;/code&gt; bytes to the &lt;code&gt;fd&lt;/code&gt;'s file from &lt;code&gt;buff&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Returns the number of bytes actually written. Returns -1 and sets &lt;code&gt;errno&lt;/code&gt;	if unsuccessful.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buff&lt;/code&gt; must be a memory address (pointer or array), but can be to any type of data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lseek - &amp;lt;unistd.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Set the current position in an open file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lseek( file_descriptor, offset, whence )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;offset&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Number of bytes to move the position by, Can be negative.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;whence&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Where to measure the offset from&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SEEK_SET&lt;/code&gt;: offset is evaluated from the beginning of the file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SEEK_CUR&lt;/code&gt;: offset is relative to the current position in the file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SEEK_END&lt;/code&gt;: offset is evaluated from the end of the file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Returns the number of bytes the current position is from the beginning of the file, or -1 (&lt;code&gt;errno&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;code&gt;stat - &amp;lt;sys/stat.h&amp;gt;	&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Get information about a file (metadata)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stat( path, stat_buffer )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;stat_buffer&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Must be a pointer to a &lt;code&gt;struct stat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;All the file information gets put into the stat buffer.&lt;/li&gt;
&lt;li&gt;Some of the fields in struct stat:
              &lt;ul&gt;
&lt;li&gt;&lt;code&gt;st_size&lt;/code&gt;: file size in bytes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;st_uid, st_gid&lt;/code&gt;: user id, group id&lt;/li&gt;
&lt;li&gt;&lt;code&gt;st_mode&lt;/code&gt;: file permissions&lt;/li&gt;
&lt;li&gt;&lt;code&gt;st_atime, st_mtime&lt;/code&gt;: last access, last modification
                  &lt;ul&gt;
&lt;li&gt;These are &lt;code&gt;time_t&lt;/code&gt; variables. We can use functions in &lt;code&gt;time.h&lt;/code&gt; to make sense of them&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctime( time )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Returns the time as a string&lt;/li&gt;
&lt;li&gt;&lt;code&gt;time&lt;/code&gt; is type &lt;code&gt;time_t *&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;code&gt;opendir - &amp;lt;dirent.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Open a directory file&lt;/li&gt;
&lt;li&gt;This will not change the current working directory (cwd), it only allows your program to read the contents of the directory file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;opendir( path )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Returns a pointer to a directory stream (&lt;code&gt;DIR *&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;closedir - &amp;lt;dirent.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Closes the directory stream and frees the pointer associated with it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;closedir( dir_stream )&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;readdir - &amp;lt;dirent.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;readdir( dir_stream )&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Returns a pointer to the next entry in a directory stream, or &lt;code&gt;NULL&lt;/code&gt; if all entries have already been returned.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct dirent - &amp;lt;sys/types.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Directory struct that contains the information stored in a directory file. Some of the data members&lt;/li&gt;
&lt;li&gt;&lt;code&gt;d_name&lt;/code&gt;: Name of a file&lt;/li&gt;
&lt;li&gt;&lt;code&gt;d_type&lt;/code&gt;: File type as an int&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;man readdir&lt;/code&gt; to list the different components.&lt;/li&gt;
&lt;li&gt;
          Example usage:
          &lt;pre&gt;&lt;code&gt;DIR * d;
d = opendir( "somedir" );
struct dirent *entry;
entry = readdir( d );
closedir(d);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rewinddir - &amp;lt;dirent.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rewinddir(d)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;d&lt;/code&gt; must be a &lt;code&gt;DIR *&lt;/code&gt; returned from &lt;code&gt;opendir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Resets the directory stream of &lt;code&gt;d&lt;/code&gt; to the beginning.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-21n"/><published>2024-10-21T12:00:00+00:00</published></entry><entry><id>2024-10-22n</id><title>2024-10-22</title><updated>2024-10-22T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-22n"&gt;
&lt;h5&gt;2024-10-22&lt;/h5&gt;
&lt;h3&gt;Demo Code To Be Discussed:&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;fcntl.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;sys/stat.h&amp;gt;
#include &amp;lt;errno.h&amp;gt;
#include &amp;lt;time.h&amp;gt;
#include &amp;lt;sys/types.h&amp;gt;
#include &amp;lt;dirent.h&amp;gt;
int err(){
    printf("errno %d\n",errno);
    printf("%s\n",strerror(errno));
    exit(1);
}

#define BUFFER_SIZE 128

int main(){
  int r_file,w_file;
  char buff[BUFFER_SIZE+1];
  buff[BUFFER_SIZE]=0; // for printf purposes.

  /////////////////////////////////////
  //Fail to open:
  //Either don't have the file, or grant no read access
  r_file = open("./cantouchthis", O_RDONLY , 0);
  printf("open(./canttouchthis) : %s\n",strerror(errno));

  ////////////////////////////////////
  //Open for read
  r_file = open("./text.book", O_RDONLY , 0);
  if(r_file == -1) err();
  printf("r_file: %u\n",r_file);

  ////////////////////////////////////
  //Open for write
  w_file = open("./copy",
      O_WRONLY | O_APPEND | O_CREAT, 0611);
  if(w_file==-1)err();
  printf("w_file: %u\n",w_file);


  ////////////////////////////////////////
  //READ and WRITE
  int bytes;
  //putting the assignment in the while boolean
  //eliminates the need to check for 0 bytes read
  while(bytes = read(r_file, buff, BUFFER_SIZE)){
    if(bytes == -1)err();//all non 0 are true

    printf("Bytes read: %u",bytes);
    printf("'''%s'''\n",buff);

    //write the bytes
    int wbytes = write(w_file , buff, bytes);
    if(wbytes == -1)err();;


  }


  /////////////////////////////
  //WRITE NUMBERS!
  int x = 97;
  //write the 4 bytes of the int, 97,0,0, and 0.
  write(w_file,&amp;amp;x,4);

  x= 65+25;//Z
  //Write the 1st byte of x (least significant)
  write(w_file,&amp;amp;x,1);

  double y = 1234.5678;
  //Write a double... this will end poorly.
  write(w_file,&amp;amp;y,8);//write a double

  ///////////////////////////////////////
  //STAT!
  struct stat * stat_buffer;
  struct stat s_buff;//not used in the example

  //malloc sizeof the struct, not the pointer!
  stat_buffer = malloc(sizeof(struct stat)*1);

  stat( "./copy", stat_buffer);//or use &amp;amp;s_buff
  printf("size: %ld \n", stat_buffer-&amp;gt;st_size);
  printf("mode : %o \n", stat_buffer-&amp;gt;st_mode);

  time_t t = stat_buffer-&amp;gt;st_mtime;
  printf("%s\n",ctime(&amp;amp;t));
  free(stat_buffer);


  //////////////////////////////////////
  //DIRENT
  DIR * d;
  char* PATH = ".";
  d = opendir( PATH );
  struct dirent *entry;

  //Can use as a while boolean
  //since null is the end of the dirent list.
  while(entry = readdir( d )){
    printf("filename: %s\n",entry-&amp;gt;d_name);
    printf("--type: %d\n",entry-&amp;gt;d_type);
    //You can use the PATH + filename to get stat data!
  }
  closedir(d);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-22n"/><published>2024-10-22T12:00:00+00:00</published></entry><entry><id>2024-10-23n</id><title>2024-10-23</title><updated>2024-10-23T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-23n"&gt;
&lt;h2&gt;Pair Project:&lt;/h2&gt;
&lt;p&gt;Choose a partner for the first project (music playlist manager using linked lists)&lt;/p&gt;
&lt;p&gt;We will start the project on Monday.&lt;/p&gt;
&lt;p&gt;You should check if both you and your partner know how to handle:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Branching.&lt;/li&gt;
&lt;li&gt;Merging.&lt;/li&gt;
&lt;li&gt;Merge conflicts.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;/dev/random&lt;/h2&gt;
&lt;p&gt;Your computer measures temperatures and voltages and generates an 'entropy pool' to create truly random numbers.&lt;/p&gt;
&lt;p&gt;You can read bytes from &lt;code&gt;/dev/random&lt;/code&gt; to return random bytes from the 'entropy pool'. &lt;/p&gt;
&lt;p&gt;When the entropy pool is empty (you read too many values), reads from /dev/random will block until additional environmental noise is gathered.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/dev/random &lt;/code&gt; is be suitable for uses that need very high quality randomness such as one-time pad or key generation.&lt;/p&gt;
&lt;h2&gt;/dev/urandom&lt;/h2&gt;
&lt;p&gt;When you do NOT need totally cryptographically secure values, or you cannot have your program block we read from &lt;code&gt;/dev/urandom&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;A read from the &lt;code&gt;/dev/urandom&lt;/code&gt; device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values a&lt;/p&gt;
&lt;h2&gt;Lab07-Files&lt;/h2&gt;
&lt;h4&gt;dev[ise a]/random plan&lt;/h4&gt;
&lt;p&gt;Check the File Functions section of the notes page for reference.&lt;/p&gt;
&lt;p&gt;Repo Link: &lt;a href="https://classroom.github.com/a/aQupXEVS"&gt;
    https://classroom.github.com/a/aQupXEVS&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Read or write&lt;/h3&gt;
&lt;p&gt;Your goal for this lab is to create a program that can either write to or read from a file. You can do this by using command line arguments or making two separate main programs. You would need to look up command line parsing in c, so making 2 main programs is acceptable.&lt;/p&gt;
&lt;p&gt;Your makefile will have 2 run targets. If you have 2 main files, your compile target can compile both at the same time.&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A function that generates and returns a random int by reading in the correct number of bytes from &lt;code&gt;/dev/random&lt;/code&gt; . Please note that this is a file for purposes of reading. This should be in a separate c/h library!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A main function (or two) that can either WRITE values to a file, or READ values from a file.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;make write&lt;/strong&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Declare two int variables and an int array of size 8&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Populate the two variables and an array with random numbers generated by your random function. &lt;/p&gt;
&lt;p&gt;If your program seems to stall at this step, it's possible that your computer doesn't have enough entropy and is waiting, you can read from /dev/urandom instead.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
          Prints out the contents of the two variables and array.
          &lt;ul&gt;
&lt;li&gt;Write the two variables to the file.&lt;/li&gt;
&lt;li&gt;After testing the two variables, also write the array to a file called &lt;code&gt;arraydata.dat&lt;/code&gt;. Just use a single write command (DO NOT use a loop).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;make read&lt;/strong&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Declare two int variables and an int array of size 8&lt;/li&gt;
&lt;li&gt;
          Reads the data from the file into your program.
          &lt;ul&gt;
&lt;li&gt;Read the two random values from the file into two new variables.&lt;/li&gt;
&lt;li&gt;Read the whole array from the file into a different array using a single read command. (DO NOT use a loop!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prints the contents of the two variables/array.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Urgent:&lt;/strong&gt; This program should work if there isn't already a &lt;code&gt;arraydata.dat&lt;/code&gt;,
        so it should be able to create the file when it doesn't exist. I will be &lt;code&gt;rm -f arraydata.dat&lt;/code&gt; in my grading script, so I know your code works when the file isn't already created.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember to use good practices, like checking return values for errors&lt;/p&gt;
&lt;p&gt;Also remember to include a makefile that includes separate &lt;code&gt;compile&lt;/code&gt; + &lt;code&gt;read&lt;/code&gt; + &lt;code&gt;write&lt;/code&gt; targets&lt;/p&gt;
&lt;h3&gt;Sample output (yours will vary)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;make write
    Generating random numbers:
    x : 12875823
    y : 40258233
    ary[0]: 198116400
    ary[1]: 259268753
    ary[2]: 283364368
    ary[3]: 327370590
    ary[4]: 354867368
    ary[5]: 387688898
    ary[6]: 261733183
    ary[7]: 172096907
  Writing numbers to file...&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;make read
  Reading numbers from file...
    x : 12875823
    y : 40258233
    ary[0]: 198116400
    ary[1]: 259268753
    ary[2]: 283364368
    ary[3]: 327370590
    ary[4]: 354867368
    ary[5]: 387688898
    ary[6]: 261733183
    ary[7]: 172096907&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-23n"/><published>2024-10-23T12:00:00+00:00</published></entry><entry><id>2024-10-28n</id><title>2024-10-28</title><updated>2024-10-28T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-28n"&gt;
&lt;h5&gt;2024-10-28&lt;/h5&gt;
&lt;h2 id="2024-10-28h"&gt;MyTunez™&lt;/h2&gt;
&lt;h3&gt;Logistics&lt;/h3&gt;
&lt;h4&gt;Partner&lt;/h4&gt;
&lt;p&gt;You may work with a partner on this assignment. They must be in the same class period as you.&lt;/p&gt;
&lt;p&gt;Working in a group requires the use of branching, see the tutorial here: &lt;a href="index.html#gitbranch"&gt;Git Branching Tutorial&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Repo&lt;/h4&gt;
&lt;p&gt;The github classrooms link works differently with groups. The first partner in a group should create a new team when accepting the assignment, then the 2nd person should join that team.&lt;/p&gt;
&lt;p&gt;Only join a team if the other person agreed, otherwise your teacher must manually change the teams.&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;DO NOT JOIN UNTIL CLASS DISCUSSION&lt;/strong&gt;
    assignment repo:
    &lt;a href="https://classroom.github.com/a/osoZpCnK"&gt;https://classroom.github.com/a/osoZpCnK&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Team name should be PERIOD-LastnameFirstInitial-LastName2FirstInitial2&lt;/p&gt;
&lt;p&gt;E.g. this group of 3 students in period 5: &lt;code&gt;5-WrightG-WongL-WongJ&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can put a creative group name in your readme, e.g. &lt;code&gt;Two Wongs Don't Make A Wright&lt;/code&gt; &lt;/p&gt;
&lt;h2&gt;Music Library Overview&lt;/h2&gt;
&lt;p&gt;Write a program in C that implements a music library organizer.&lt;/p&gt;
&lt;p&gt;This will consist of 2 data structures:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A linked list of songs in &lt;code&gt;node.c/h&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Your nodes/links should be able to hold a song's title and artist. You should use structures like the following:&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;
              &lt;code&gt;struct song_node{
  char artist[100];
  char title[100];
  struct song_node *next;
};&lt;/code&gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;The actual library in &lt;code&gt;library.c/h&lt;/code&gt;. This should be an array of 27 linked lists (one for each letter from 'a' to 'z', and another for symbols).
      &lt;ul&gt;
&lt;li&gt;Each slot will contain a linked list of all the artists that have names that start with the corresponding letter.&lt;/li&gt;
&lt;li&gt;When you add a song, it should go on to a linked list at the appropriate array slot, and then determine the correct position alphabetically, first by artist, then by song. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Linked List Part:&lt;/h3&gt;
&lt;p&gt;You should start by making your linked lists work with the following functionality:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;insert song at the front (this is just for testing)&lt;/li&gt;
&lt;li&gt;
        insert song in alphabetical order (this is the primary way to insert for later)
          &lt;ul&gt;
&lt;li&gt;Alphabetical is by Artist then by Song, so all ACDC songs come before all of the Black Sabbath songs&lt;/li&gt;
&lt;li&gt;You must make a &lt;code&gt;int compare(struct song_node * a, struct song_node * b)&lt;/code&gt; functions to easily compare song nodes effectively. These comparisons should be case &lt;strong&gt;INSENSITIVE&lt;/strong&gt;, so:
                A &amp;amp;lt Abba &amp;amp;lt ACDC &amp;amp;lt Aerosmith. Abba and abba would be considered equal. You can make a lowercase version of the strings before you compare, or convert the numbers as you compare them. (anything from 97(a) to 122(z) inclusive is counted as 65(A) to 90(Z). )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void print_song_list(struct song_node *)&lt;/code&gt; print the entire list, see format in examples.&lt;/li&gt;
&lt;li&gt;find and return a pointer to a node based on artist and song name&lt;/li&gt;
&lt;li&gt;find and return a pointer to the first song of an artist based on artist name&lt;/li&gt;
&lt;li&gt;Return a pointer to random element in the list.&lt;/li&gt;
&lt;li&gt;
        remove a single specified node from the list
        &lt;ul&gt;
&lt;li&gt;specified by both artist and song name.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;free the entire list, anything that was malloc'ed must be freed&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Library Part&lt;/h3&gt;
&lt;h4&gt;DO NOT WORK ON THIS PART UNTIL YOUR LINKED LIST IS COMPLETE&lt;/h4&gt;
&lt;p&gt;Then create your array of linked lists (suggested type: struct song_node ** for the full program to have the following functions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;struct song_node ** init();&lt;/code&gt;
        initialize a new library: Allocate enough memory for 27 linked lists, make sure each entry is an empty list.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void add(struct song_node ** library, char* artist, char* title)&lt;/code&gt;
        Add song alphabetically to the correct slot in the library.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct song_node * search_song(struct song_node ** library, char* artist, char* title )&lt;/code&gt;
        Search for a song given song title and artist (return a pointer, or NULL if it isn't found).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;struct song_node * search_artist(struct song_node ** library, char* artist )&lt;/code&gt;
        Search for the first song that is by the provided artist (return a pointer, or NULL if it isn't found).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_letter(struct song_node ** library, char letter)&lt;/code&gt;
         Print out all the entries under a certain letter. The letter var shoudl use capital 'A' through'Z', or '0' for non-letter artists.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_artist(struct song_node ** library, char* artist)&lt;/code&gt;
        Print out all the songs of a the provided artist, use the same format as a print_song_list. This may print nothing if no matching artist is found.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_library(struct song_node ** library)&lt;/code&gt;
        Print out the entire library , see format in examples.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void shuffle (struct song_node ** library, int n)&lt;/code&gt;
        Shuffle - &lt;strong&gt;prints&lt;/strong&gt; out a series of &lt;code&gt;n&lt;/code&gt; randomly chosen songs. (can have duplicates) Please make sure the distribution of random is equal per song. If you have 100 ABBA songs, and 2 Beoncé songs, the ABBA songs should print 50x more frequently than Beoncé. &lt;/li&gt;
&lt;li&gt;&lt;code&gt;int delete_song(struct song_node ** library, char* artist, char* title )&lt;/code&gt;
        Delete a song from the library, make sure the memory is free'd.
        &lt;ul&gt;
&lt;li&gt;specified by both artist and song name.&lt;/li&gt;
&lt;li&gt;Return 0 if the song was deleted, 1 if the song was not found.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void reset(struct song_node ** library) &lt;/code&gt;
         Clear out all the linked lists in the library. This must free() all memory malloc'ed. (Originally it had an int return, that was an error.)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Putting it all together&lt;/h3&gt;
&lt;p&gt;Files you should have:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
          A .c file that contains the main function you use to test all your work. You must test all the functions in your main function in order to receive full credit!!!
      &lt;/li&gt;
&lt;li&gt;
        Two sets of .h/.c files. There are 2 separate structures being worked on, the linked list &lt;em&gt;(node.c/h)&lt;/em&gt; and the library &lt;em&gt;(library.c/h)&lt;/em&gt;.
      &lt;/li&gt;
&lt;li&gt;A makefile with a (default) compile target that generates a single executable program, as well as a run target.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Example testing&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;LINKED LIST TESTS
====================================

Testing print_list:
	[ {ac/dc, thunderstruck} | {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {radiohead, paranoid android} | {radiohead, street spirit (fade out)} | ]
====================================

Testing print_node:
	{ac/dc, thunderstruck}
====================================

Testing find_node:
looking for [pearl jam: even flow]
	node found! {pearl jam, even flow}
looking for [pearl jam: daughter]
	node not found
====================================

Testing find_artist:
looking for [pink floyd]
	artist found! [ {pink floyd, time} | {radiohead, paranoid android} | {radiohead, street spirit (fade out)} | ]
looking for [pearl jam]
	artist found! [ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {radiohead, paranoid android} | {radiohead, street spirit (fade out)} | ]
looking for [presidents of the united states of america]
	artist not found
====================================

Testing songcmp (helper function):
Comparing [pearl jam: even flow] to [pearl jam: even flow]
	0
Comparing [pearl jam: even flow] to [pearl jam: alive]
	4
Comparing [pearl jam: alive] to [pearl jam: even flow]
	-4
Comparing [pearl jam: even flow] to [pink floyd: time]
	-4
====================================

Testing random:
{pink floyd, time}
{radiohead, paranoid android}
{radiohead, street spirit (fade out)}
{pearl jam, alive}
====================================

Testing remove:
Removing [ac/dc: thunderstruck]
	[ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {radiohead, paranoid android} | {radiohead, street spirit (fade out)} ]
Removing [radiohead: street spirit (fade out)]
	[ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {radiohead, paranoid android} ]
Removing [pearl jam: yellow ledbetter]
	[ {pearl jam, alive} | {pearl jam, even flow} | {pink floyd, time} | {radiohead, paranoid android} ]
Removing [pearl jam: yellow ledbetter]
	{pearl jam: yellow ledbetter} not found
[ {pearl jam, alive} | {pearl jam, even flow} | {pink floyd, time} | {radiohead, paranoid android} ]
====================================

Testing free_list
	freeing_node: {pearl jam, alive}
	freeing_node: {pearl jam, even flow}
	freeing_node: {pink floyd, time}
	freeing_node: {radiohead, paranoid android}
list after free_list:
[ ]
====================================

MUSIC LIBRARY TESTS
====================================

Testing print_letter
[ ]
====================================

Testing print_library
====================================

Testing print_letter
[ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {presidents of the united states of america, peaches} ]
====================================

Testing print_library
a: [ {ac/dc, thunderstruck} ]
p: [ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {presidents of the united states of america, peaches} ]
r: [ {radiohead, paranoid android} | {radiohead, street spirit (fade out)} ]
====================================

Testing find:
looking for [pearl jam: alive]
	song found! {pearl jam, alive}
looking for [pearl jam: time]
	song not found
====================================

Testing find artist:
looking for [pearl jam]
	artist found! [ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {presidents of the united states of america, peaches} ]
looking for [pink floyd]
	artist found! [ {pink floyd, time} | {presidents of the united states of america, peaches} ]
looking for [bob dylan]
	artist not found
====================================

Testing remove_song
removing: [pearl jam: alive]
a: [ {ac/dc, thunderstruck} ]
p: [ {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} | {presidents of the united states of america, peaches} ]
r: [ {radiohead, paranoid android} | {radiohead, street spirit (fade out)} | ]

removing: [pearl jam: yellow ledbetter]
a: [ {ac/dc, thunderstruck} ]
p: [ {pearl jam, even flow} | {pink floyd, time} | {presidents of the united states of america, peaches} ]
r: [ {radiohead, paranoid android} | {radiohead, street spirit (fade out)} ]
====================================

Testing clear_library:
	freeing_node: {ac/dc, thunderstruck}
	freeing_node: {pearl jam, even flow}
	freeing_node: {pink floyd, time}
	freeing_node: {presidents of the united states of america, peaches}
	freeing_node: {radiohead, paranoid android}
	freeing_node: {radiohead, street spirit (fade out)}

Library after clear:
====================================

Adding songs to empty library
a: [ {ac/dc, thunderstruck} ]
p: [ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} | {pink floyd, time} ]
====================================

Testing print_artist:
Printing [pearl jam]
pearl jam: [ {pearl jam, alive} | {pearl jam, even flow} | {pearl jam, yellow ledbetter} ]

Printing [ac/dc]
ac/dc: [ {ac/dc, thunderstruck} ]
====================================


Printing [radiohead]
radiohead:
====================================

Testing shuffle
{pink floyd, time}
{pearl jam, yellow ledbetter}
{pearl jam, alive}
====================================&lt;/code&gt; &lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-28n"/><published>2024-10-28T12:00:00+00:00</published></entry><entry><id>2024-10-30n</id><title>2024-10-30</title><updated>2024-10-30T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-10-30n"&gt;
&lt;h5&gt;2024-10-30&lt;/h5&gt;
&lt;h3&gt;Pclassic&lt;/h3&gt;
&lt;p&gt;PClassic's 2024 Fall competition is on Nov. 23, 2024. You can familiarize yourselves with the competition questions of previous years here : &lt;a href="https://www.pclassic.org/problems"&gt;https://www.pclassic.org/problems&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you are interested you should make a team and practice solving the problems. You shoudl also actually practice together on a single computer if you are serious.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.google.com/document/d/10T0p5LjNASS48tAnAZO0Gj67IoQOyTB4A6BIir0sseQ"&gt;Information Document&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
    StuyCCC has compiled a document of relevant information, including important dates and how to sign up for the in-person trip:
  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; &lt;a href="https://forms.gle/fGEoeJiSERp39F8a9"&gt;Sign up form&lt;/a&gt; (also on the document above)&lt;/li&gt;
&lt;li&gt;Don't forget to join our Discord server and Epsilon for further details:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://discord.gg/Wd2FxeE"&gt;https://discord.gg/Wd2FxeE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://epsilon.stuysu.org/stuyccc"&gt;  https://epsilon.stuysu.org/stuyccc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-10-30n"/><published>2024-10-30T12:00:00+00:00</published></entry><entry><id>2024-11-04n</id><title>2024-11-04</title><updated>2024-11-04T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-04n"&gt;
&lt;h5&gt;2024-11-04&lt;/h5&gt;
&lt;h2&gt;Input&lt;/h2&gt;
&lt;h3&gt;Command Line Arguments:&lt;/h3&gt;
&lt;code&gt;int main( int argc, char *argv[] )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Program name is considered the first command line argument&lt;/li&gt;
&lt;li&gt; &lt;code&gt;argc&lt;/code&gt; is the number of command line arguments&lt;/li&gt;
&lt;li&gt;&lt;code&gt;argv&lt;/code&gt; is the array of command line arguments as strings&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;stdin input&lt;/h3&gt;
&lt;p&gt; &lt;code&gt;fgets&lt;/code&gt; is in &lt;code&gt;&amp;amp;ltstdio.h&amp;gt;&lt;/code&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;fgets&lt;/code&gt; will read in data from a file stream (I/O stream) and store it in a string. This is how we can read from &lt;code&gt;stdin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fgets( char * buffer, int n, FILE * f );&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FILE *&lt;/code&gt; is the file stream type, more complex than a file descriptor, allows for buffered input.&lt;/li&gt;
&lt;li&gt;Reads at most n-1 characters from file stream f and stores it in s, appends NULL to the end.&lt;/li&gt;
&lt;li&gt;Stops at newline, end of file, or the byte limit.&lt;/li&gt;
&lt;li&gt;Returns a pointer to the buffer, or null if no bytes were read.&lt;/li&gt;
&lt;li&gt;stdin is a FILE * variable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Example: &lt;code&gt;fgets(s, 100, stdin)&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Other file streams&lt;/h3&gt;
  The &lt;code&gt;fopen()&lt;/code&gt; function is a higher level wrapper for the system call &lt;code&gt;open()&lt;/code&gt; that returns a file stream. We can open files using &lt;code&gt; fopen()&lt;/code&gt; to enable using &lt;code&gt;fgets()&lt;/code&gt; on regular files.
  &lt;ul&gt;
&lt;li&gt;&lt;code&gt;fopen()&lt;/code&gt; returns &lt;code&gt;FILE *&lt;/code&gt; (a file stream) attached to the specified file/device. If the function fails, it returns a null pointer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fopen(char *path, char *mode)&lt;/code&gt; path is the same as open, but mode is now a string, and it supports: "r", "w", "a", "w+" (read, write, append, write but the file must exist). More mode combinations can be found in the documentation. (see man 3 fopen) &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Pulling data from strings&lt;/h3&gt;
&lt;code&gt;sscanf&lt;/code&gt; in &lt;code&gt;&amp;amp;ltstdio.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Reads in data from a string using a format string to determine types.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sscanf( char *s, char * format, void * var0, void * var1, ... )&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Copies the data into each variable.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;char* s = "103 1.23 0.042311234";
int x; float f; double d;
sscanf(s, "%d %f %lf", &amp;amp;x, &amp;amp;f, &amp;amp;d);
    &lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;char dtm[32];
strcpy( dtm, "Saturday March 25 1989" );
sscanf( dtm, "%s %s %d  %d", weekday, month, &amp;amp;day, &amp;amp;year );
printf("%s %d, %d = %s\n", month, day, year, weekday );&lt;/code&gt; &lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Use your skills!&lt;/h2&gt;
&lt;p&gt;Write a program to help determine if triangles are valid.&lt;/p&gt;
&lt;p&gt;The program will either take user input or parses a file named '&lt;code&gt;input&lt;/code&gt;' wtih the following file format : any plain text file with 3 integers on each line, that contains a multiple of 3 lines inside of it (but not 0).&lt;/p&gt;
&lt;p&gt;After compiling, when you run your program, there are 2 calculations to make.&lt;/p&gt;
&lt;p&gt;Determine how many triangles are valid. We will assume that valid just means you can make a triangle with the given side lengths.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./a.out user&lt;/code&gt; will read 3 ints from &lt;code&gt;stdin&lt;/code&gt; and print either valid or invalid.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./a.out horizontal&lt;/code&gt; will treat each line of input as a triangle, and print the total number of valid triangles  in the set.&lt;/p&gt;
&lt;p&gt;(OPTIONAL CHALLENGE)&lt;code&gt;./a.out vertical&lt;/code&gt; will treat each set of 3 lines as 3 vertically aligned triangles, and print the total number of valid triangles in the set. (This is more challenging but only because it gets ugly dealing with the 9 values in a 3 line set.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./a.out&lt;/code&gt; with no argumetns, or with invalid arguments will print directions.&lt;/p&gt;
&lt;p&gt;Note that given:&lt;/p&gt;
&lt;pre&gt;330  143  338
769  547   83
930  625  317&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;horizontal&lt;/code&gt; means the 1st triangle is &lt;code&gt;330 143 338&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;CHALLENGE: &lt;code&gt;vertical&lt;/code&gt; means the 1st triangle is &lt;code&gt;330 769 930&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;Here is a larger test input:&lt;/h4&gt;
&lt;pre&gt;330  143  338
769  547   83
930  625  317
669  866  147
15  881  210
662   15   70
273  277  707
50  592  770
280  313  407
642  487  372
94  619  295
734  243  141
220  141  515
198  824  745
210  787  964
330  143  338
769  547   83
930  625  317
669  866  147
15  881  210
662   15   70
273  277  707
50  592  770
280  313  407
642  487  372
94  619  295
734  243  141
220  141  515
198  824  745
210  787  964&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-04n"/><published>2024-11-04T12:00:00+00:00</published></entry><entry><id>2024-11-05n</id><title>2024-11-05</title><updated>2024-11-05T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-05n"&gt;
&lt;h5&gt;2024-11-05&lt;/h5&gt;
&lt;h3&gt;Stuy Quantum&lt;/h3&gt;
&lt;p&gt;StuyQuantum is holding its very own Qiskit Fall Fest in partnership with IBM Quantum from Thursday, November 7th at 4:30 pm to Thursday, November 14th at 5:30 pm! Join us this Thursday for instructions and the kickoff event! If you can not make it, all instructions will be available on our website!
It is not necessary to be in the club to participate, but definitely consider joining! Our website also has our lesson slides in case you want to review any topics. The old lesson slides are password protected, so email either Matthew Karp or Jay Chen for the password. Join our discord to discuss and ask questions about the event. No prior experience is necessary! Any submission will receive a certificate of completion if effort is shown!&lt;/p&gt;
&lt;a href="https://stuyquantum.com/fallfest.html"&gt;stuyquantum.com/fallfest.html&lt;/a&gt;
&lt;p&gt;Join our social media (Discord, Insta, Epsilon) found on &lt;a href="linktr.ee/stuyquantum"&gt;DiscordLink&lt;/a&gt; for more updates!&lt;/p&gt;
&lt;h2 id="2024-11-05h"&gt;Lab08 Directory info&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Deadline is Tuesday 8am.&lt;/strong&gt;, You will be assigned a new lab on Tuesday!&lt;/p&gt;
&lt;p&gt;Write a program that will gather various information about a directory.&lt;/p&gt;
&lt;p&gt;This will use your args parsing , as well as your ability to use dirent and stat().&lt;/p&gt;
&lt;h3&gt;Functionality:&lt;/h3&gt;
&lt;p&gt;By default the target is the current directory ("./")&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;list all the files in the directory&lt;/li&gt;
&lt;li&gt;specify which files are directories (if any)&lt;/li&gt;
&lt;li&gt;
        show the total size of all the regular files the directory. Do NOT include the size of folders (they show as 4096bytes). You can use &lt;code&gt;du -h -d 1&lt;/code&gt; to see the total size of the current directory including all subdirectories.
        &lt;ul&gt;
&lt;li&gt;note that you do not need to recursively go through any subdirectories to find their size for this part (unless you want to, but that is not a simple task)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;As always you should have compile and run targets in your makefile&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Possible enhancements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recursively traverse sub directories and calculate the size of the files in those subdirectories.
           Display the current directory total, AND the total including all sub directories (do not traverse &lt;code&gt;.&lt;/code&gt; or &lt;code&gt;..&lt;/code&gt; ) .
        &lt;/li&gt;
&lt;li&gt;Print out the size in a more readable format (like using KB, MB, GB for -byte prefixes)&lt;/li&gt;
&lt;li&gt;Make it look more like &lt;code&gt;ls -l&lt;/code&gt; by including permissions&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;User Input:&lt;/h3&gt;
&lt;p&gt;After you complete the above portion your program should handle user input as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If a command line argument is entered, use that as the directory to scan, otherwise use "./" &lt;/li&gt;
&lt;li&gt;If the argument does not have a trailing / you may wish to add one.&lt;/li&gt;
&lt;li&gt;if an invalid directory is entered or you do not have permission, print a reasonable error message. (hint: you must use errno)&lt;/li&gt;
&lt;li&gt;In your makefile you can use &lt;code&gt;$(ARGS)&lt;/code&gt; to represent your command line arguments. So:
        &lt;p&gt;If your recipe says:  &lt;code&gt;./a.out $(ARGS)&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;Then you call make as follows: &lt;code&gt;make run ARGS="PATH_GOES_HERE"&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Make would then run: &lt;code&gt;./a.out PATH_GOES_HERE&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Testing:&lt;/h3&gt;
&lt;p&gt;Make a few different directories with some files in them.&lt;/p&gt;
&lt;p&gt;Your &lt;code&gt;make run&lt;/code&gt; should work on the current directory, which should be the same as &lt;code&gt;make run ARGS="./"&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;You should test many different cases for the path: &lt;code&gt;make run ARGS="folder1/"&lt;/code&gt; , &lt;code&gt;make run ARGS="../folder3/"&lt;/code&gt; , and &lt;code&gt;make run ARGS="folder1/folder2/"&lt;/code&gt; &lt;/p&gt;
&lt;h3&gt;Repository&lt;/h3&gt;
&lt;a href="https://classroom.github.com/a/oPbjOmbk"&gt;Create Your Lab08 repo&lt;/a&gt;
&lt;h3&gt;Example:&lt;/h3&gt;
&lt;p&gt;Below is sample output, yours may differ slightly, but as long as it presents the information requested above you will receive full credit.&lt;/p&gt;
&lt;p&gt;Please list the directories first, alphabetically is not required.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ make run
  Statistics for directory: .
  Total Diectory Size: 17766 Bytes
  Directories:
        .
        ..
        dir
        structRW
  Regular files:
        a.out
        error.log
        filelist
        files.c
        read.c
        ReadTest
        redirect.c
        redirect.c~
        redirect_full.c
        redirect_full.c~
        redirTest
        statfiles.c
        statfiles.c~
        write.c
        WriteTest
  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-05n"/><published>2024-11-05T12:00:00+00:00</published></entry><entry><id>2024-11-12n</id><title>2024-11-12</title><updated>2024-11-12T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-12n"&gt;
&lt;h5&gt;2024-11-12&lt;/h5&gt;
&lt;h3&gt;strtok() is tokxic&lt;/h3&gt;
&lt;p&gt;The limitation of strtok(char *str, const char *delim) is that it can't work on
  multiple strings simultaneously as it maintains a static pointer. This is a hidden state, it is not a pure function.&lt;/p&gt;
&lt;p&gt;You should never use strtok in a library because your library calls will break any existing strtok() usage.&lt;/p&gt;
&lt;h3&gt;strsep() to the rescue&lt;/h3&gt;
&lt;p&gt; &lt;code&gt;strsep&lt;/code&gt; is in &lt;code&gt;&amp;amp;LTstring.h&amp;gt;&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;Strsep will parse a string with a common delimiter : &lt;code&gt;strsep( source, delimiters )&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;Locates the first occurrence of any of the specified delimiters in a string and replaces it with NULL&lt;/p&gt;
&lt;p&gt;delimiters is a string, each character is interpreted as a distinct delimiter.&lt;/p&gt;
&lt;p&gt;Returns the beginning of the original string, sets source to the string starting at 1 index past the location of the new NULL&lt;/p&gt;
&lt;p&gt; Since source's value is changed, it must be a pointer to a string (char **). &lt;/p&gt;
&lt;p&gt;example:&lt;/p&gt;
&lt;pre&gt;
&lt;code&gt;char line[100] = "woah-this-is-cool";
char *curr = line;
char * token;
token = strsep( &amp;amp;curr, "-" );&lt;/code&gt;
  &lt;/pre&gt;
&lt;p&gt;The code above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;replaces the '-' after woah with NULL &lt;/li&gt;
&lt;li&gt;returns a pointer to the w in "woah"&lt;/li&gt;
&lt;li&gt;sets curr to point to the t in "this-is-cool"&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2024-11-12h"&gt;Lab09 Struct Files&lt;/h2&gt;
&lt;h5&gt;Deadline: Monday 2024/11/18 8am &lt;/h5&gt;
&lt;p&gt;You should have a makefile with compile target that creates the correctly named program.&lt;/p&gt;
&lt;p&gt;GH Classroom link: &lt;a href="https://classroom.github.com/a/Bb1mCg4X"&gt;https://classroom.github.com/a/Bb1mCg4X&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirement:&lt;/strong&gt; Your &lt;code&gt;make compile&lt;/code&gt; should output an executable named "structrw" for ease of scripting on my end. That is compile must use &lt;code&gt;-o structrw&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;You will find a csv file of NYC census population values here: &lt;a href="src/nyc_pop.csv"&gt;nyc_pop.csv&lt;/a&gt;  Place this in the same directory as your code/makefile but don't add it to your repo.  &lt;/p&gt;
&lt;p&gt;For testing, here is another file: &lt;a href="src/us_pop.csv"&gt;us_pop.csv&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The header of the file is this: &lt;code&gt;Year,Manhattan,Brooklyn nine-nine,Queens,The Bronx,Staten Island&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;An example line of data is this: &lt;code&gt;1790,33131,4549,6159,1781,3827&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;You should support comma separated headers of boroughs with spaces in them. (e.g.) Staten island does not have to be the last entry. There will always be 6 columns in my test cases.&lt;/li&gt;
&lt;li&gt;You must use &lt;code&gt;strsep()&lt;/code&gt; to parse the header. There are multiple ways to do this but I want you to learn &lt;code&gt;strsep()&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;There will always be 5 locations plus the year per line, so you can use &lt;code&gt;sscanf&lt;/code&gt; to get the numbers.&lt;/li&gt;
&lt;li&gt;Additionally you should probably terminate the header string by replacing the first '\n' (or '\r') with a 0. This will remove the newline from your strings, and handle windows and unix line endings.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your goal: write a program that will perform the following actions based on a command line argument: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;-read_csv&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt; Read the contents of the &lt;code&gt;nyc_pop.csv&lt;/code&gt; file (this is text).&lt;/li&gt;
&lt;li&gt;
          Store each piece of data using the following struct (exactly) :
          &lt;pre&gt;struct pop_entry {
  int year;
  int population;
  char boro[20];
};&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Create &amp;amp; write a new file &lt;code&gt;nyc_pop.dat&lt;/code&gt; containing the population data using &lt;code&gt;struct pop_entry&lt;/code&gt; . This file should contain byte data. &lt;/li&gt;
&lt;li&gt;If the file already exists, overwrite the existing one.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-read_data&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;
          Read the contents of the data file into an array of &lt;code&gt; struct pop_entry&lt;/code&gt; values.
          This array should be dynamically allocated based on the file size.       &lt;/li&gt;
&lt;li&gt; Display the data in human-readable format, provide a number for each data entry when displaying.       &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-add_data&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt; Ask the user for new data to put into a &lt;code&gt;struct pop_entry&lt;/code&gt; value.&lt;/li&gt;
&lt;li&gt; The data should be entered to stdin on one line in the format: Year population borough. (see note at end)&lt;/li&gt;
&lt;li&gt; Append the entry in the data file (not the csv).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-update_data&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt; Start by showing the dat file just like &lt;code&gt;-read_data&lt;/code&gt; .       &lt;/li&gt;
&lt;li&gt;  Then prompt the user to enter the corresponding number of an entry to modify.      &lt;/li&gt;
&lt;li&gt;  Then prompt the user for new data.&lt;/li&gt;
&lt;li&gt;The data should be entered to stdin on one line in the format: Year population borough.(see note at end)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Update the entry in the data file (not the csv).&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Sample output:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;-read_csv &lt;/code&gt;
&lt;pre&gt;
        &lt;code&gt;$ ./structrw -read_csv
reading nyc_pop.csv
wrote 2760 bytes to nyc_pop.data&lt;/code&gt;
      &lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-read_data &lt;/code&gt;
&lt;p&gt;This is only the fist 11 entries, there should be 115 in nyc_pop.csv at the start. &lt;/p&gt;
&lt;pre&gt;
        &lt;code&gt;$ ./structrw -read_data
0: year: 1790	boro: Manhattan	pop: 33131
1: year: 1790	boro: Brooklyn nine-nine	pop: 4549
2: year: 1790	boro: Queens	pop: 6159
3: year: 1790	boro: The Bronx	pop: 1781
4: year: 1790	boro: Staten Island	pop: 3827
5: year: 1800	boro: Manhattan	pop: 60515
6: year: 1800	boro: Brooklyn nine-nine	pop: 5740
7: year: 1800	boro: Queens	pop: 6642
8: year: 1800	boro: The Bronx	pop: 1755
9: year: 1800	boro: Staten Island	pop: 4563
10: year: 1810	boro: Manhattan	pop: 96373&lt;/code&gt;
      &lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-add_data &lt;/code&gt;
&lt;p&gt; &lt;code&gt;2020 Bronx 1390450&lt;/code&gt; Was entered into stdin as a single input at the time of the program running.&lt;/p&gt;
&lt;pre&gt;
        &lt;code&gt;$ ./structrw -add_data
Enter year population borough: 2020 1390450 Bronx
Appended data to file: year: 2020	boro: Bronx	pop: 1390450&lt;/code&gt;
      &lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-update_data  &lt;/code&gt;
&lt;p&gt;Only showing the last few lines of output, but all the data should be displayed.&lt;/p&gt;
&lt;p&gt; &lt;code&gt;108&lt;/code&gt; and &lt;code&gt;9999 4000 Stuy&lt;/code&gt; where entered into stdin. &lt;/p&gt;
&lt;pre&gt;
        &lt;code&gt;$ ./structrw -update_data
...
...MORE LINES HERE...
...
107: year: 2000	boro: Queens	pop: 2229379
108: year: 2000	boro: Bronx	pop: 1332650
109: year: 2000	boro: Staten Island	pop: 443728
110: year: 2010	boro: Manhattan	pop: 1585873
111: year: 2010	boro: Brooklyn	pop: 2504700
112: year: 2010	boro: Queens	pop: 2230722
113: year: 2010	boro: Bronx	pop: 1385108
114: year: 2010	boro: Staten Island	pop: 468730
115: year: 2020	boro: Bronx	pop: 1390450
entry to update: 108
Enter year pop boro: 9999 4000 Stuy
File updated.&lt;/code&gt;
      &lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;How to deal with input&lt;/h3&gt;
&lt;p&gt;The above sections mentioned: &lt;em&gt;The data should be entered to stdin on one line in the format: Year population borough&lt;/em&gt; &lt;/p&gt;
&lt;p&gt;This can be done using &lt;code&gt;sscanf()&lt;/code&gt; and some special notation for strings.&lt;/p&gt;
&lt;p&gt; using &lt;code&gt;%[SET]&lt;/code&gt; in your sscanf will scan a strings containing characters in the set until it sees somthing not in the set.&lt;/p&gt;
&lt;p&gt;Using the ^ character will negate the set.&lt;/p&gt;
&lt;h3&gt;Example:&lt;/h3&gt;
&lt;h4&gt;Parsing stdin strings using sscanf&lt;/h4&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char line_buff[256];
char s0[32];
char s1[32];
char s2[32];
char s3[32];
printf("Enter string: (I only read up to the first whitespace)");
printf("e.g. You cannot store 'abc def ghi'");
fgets(line_buff,255,stdin);
//read a string up to the first whitespace
sscanf(line_buff,"%s",s0);
printf("'%s'\n",s0);

printf("Enter string: (try 123abc)");
fgets(line_buff,255,stdin);
//read a string of digits, up to the first non-digit, start by consuming the newline
sscanf(line_buff,"\n%[0-9]",s1);
printf("'%s'\n",s1);

printf("Enter string: (try asdf123)");
fgets(line_buff,255,stdin);
//read a string of non-digits, stopping at the first digit.
sscanf(line_buff,"%[^0-9]",s2);
printf("'%s'\n",s2);

printf("Enter string: (try abc def ghi");
fgets(line_buff,255,stdin);
//read a string of non-digits, stopping at the first newline
sscanf(line_buff,"%[^\n]",s3);
printf("'%s'\n",s3);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-12n"/><published>2024-11-12T12:00:00+00:00</published></entry><entry><id>2024-11-15n</id><title>2024-11-15</title><updated>2024-11-15T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-15n"&gt;
&lt;h5&gt;2024-11-15&lt;/h5&gt;
&lt;h2&gt;Processes&lt;/h2&gt;
&lt;p&gt;Every running program is a process.&lt;/p&gt;
&lt;p&gt;A process can create subprocesses, but these are no different from regular processes.&lt;/p&gt;
&lt;p&gt;A processor can handle 1 process per cycle (per core).&lt;/p&gt;
&lt;p&gt;"Multitasking" appears to happen because the processor switches between all the active processes quickly.&lt;/p&gt;
&lt;p&gt;On *nix style machines, processes are also files, listed in the /proc directory.&lt;/p&gt;
&lt;h2&gt;pid&lt;/h2&gt;
&lt;p&gt;Every process has a unique identifier called the pid.&lt;/p&gt;
&lt;p&gt;pid 1 is the init process&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ps&lt;/code&gt; command shows status of processes. You will probably want the flags -aux, where -a will include other users, -x will include processes that are not attached to a terminal session (daemons and services), and -u shows more information including the username that ran the process.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ps -u&lt;/code&gt; or for even more processes &lt;code&gt;ps -aux&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;There are many options, but they aren't super critical.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ps -u --sort pid&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ps -u --sort %mem&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Signals&lt;/h2&gt;
&lt;p&gt;Limited way of sending information to a process.&lt;/p&gt;
&lt;p&gt;Sending a signal just sends an integer value to a process, these integers have special values like SIGINT (interupt signal) or SIGTSTP (keyboard signal to background a process).&lt;/p&gt;
&lt;h3&gt;Some keyboard shortcuts send signals to the active program in your shell:&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ctrl-c&lt;/code&gt; will send the signal &lt;code&gt;SIGINT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ctrl-\&lt;/code&gt; will send the signal &lt;code&gt;SIGQUIT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ctrl-z&lt;/code&gt; will send the signal &lt;code&gt;SIGTSTP&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Sending signals via the terminal&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;kill&lt;/code&gt; - Command line utility to send a signal to a process&lt;/p&gt;
&lt;p&gt;&lt;code&gt;kill pid&lt;/code&gt;  - Sends signal 15 (SIGTERM) to pid	&lt;/p&gt;
&lt;p&gt;&lt;code&gt;kill -signal pid&lt;/code&gt;  Sends signal to pid &lt;/p&gt;
&lt;p&gt;&lt;code&gt;$ killall [-signal_name] process_name&lt;/code&gt; - Sends SIGTERM (or signal_name if provided) to all processes with process_name&lt;/p&gt;
&lt;p&gt;&lt;code&gt;man 7 signal&lt;/code&gt; : shows all signals.	3: quit, 9: kill, 17/18: stop, 19: continue&lt;/p&gt;
&lt;h3&gt;Signals in your program&lt;/h3&gt;
&lt;p&gt;All these functions can be found in &amp;amp;ltsignal.h&amp;gt;&lt;/p&gt;
&lt;h4&gt;Finding PID:&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;getpid()&lt;/code&gt; - &lt;code&gt;&amp;amp;ltunistd.h&amp;gt;&lt;/code&gt; - returns the current process- pid&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getppid()&lt;/code&gt; - &lt;code&gt;&amp;amp;ltunistd.h&amp;gt;&lt;/code&gt; - returns the current process- parent pid&lt;/p&gt;
&lt;h4&gt;Sending a signal:&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;kill(pid, signal)&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Returns 0 on success or -1 (errno) on failure.&lt;/li&gt;
&lt;li&gt;Works like the command line kill program&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Listening for signals:&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;sighandler&lt;/code&gt; &lt;/strong&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To intercept signals in a c program you must create a signal handling function.&lt;/li&gt;
&lt;li&gt;Some signals (like SIGKILL, SIGSTOP) cannot be caught.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static void sighandler( int signo )&lt;/code&gt;
&lt;ul class="subList"&gt;
&lt;li&gt;Must be static, must be void, must take a single int parameter.&lt;/li&gt;
&lt;li&gt;Static values in c exist outside the normal call stack, they can be accessed regardless of the function at the top.&lt;/li&gt;
&lt;li&gt;For variables, static also means they retain their value even if the function they are declared in has ended.&lt;/li&gt;
&lt;li&gt;Static values (variables and functions) can only be accessed from within the file they are declared.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;signal&lt;/code&gt; &lt;/strong&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Attach a signal to a signal handling function&lt;/li&gt;
&lt;li&gt;signal( SIGNUMBER, sighandler)&lt;/li&gt;
&lt;li&gt;Note that you are passing the name of the signal handling function as a parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;singal/sighandler example:&lt;/h3&gt;
&lt;p&gt;Make the sighandler function:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;static void sighandler(int signo) {
    if ( signo == SIGUSR1 )
      printf("Who you talkin to?\n”);
    }
  }
  &lt;/code&gt; &lt;/pre&gt;
&lt;p&gt;Then in your make sure you activate the sighandler by attaching it with the signal command:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;signal(SIGUSR1, sighandler);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-15n"/><published>2024-11-15T12:00:00+00:00</published></entry><entry><id>2024-11-18n</id><title>2024-11-18</title><updated>2024-11-18T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-18n"&gt;
&lt;h5&gt;2024-11-18&lt;/h5&gt;
&lt;h3&gt;static&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;static variables&lt;/strong&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
        preserve their value even after they are out of their scope! Hence,
        static variables preserve their previous value in their previous scope
        and are not initialized again in the new scope.
      &lt;/li&gt;
&lt;li&gt;can only be initialized using constant literals. No function calls. &lt;/li&gt;
&lt;li&gt;should not be declared inside a struct.&lt;/li&gt;
&lt;li&gt;are initialized as 0 if not initialized explicitly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;static functions&lt;/strong&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Functions are declared static to limit access. They cannot be used in other files.&lt;/li&gt;
&lt;li&gt;You can reuse of the same function name in other files as a result.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example of a functin with a static variable:&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#include &lt;stdio.h&gt;
int fun(){
    //This assignment only happens the first time the function is run
    static int count = 0;
    count++;
    return count;
}

int main(){
    printf("%d ", fun());
    printf("%d ", fun());
    printf("%d ", fun());
    return 0;
}&lt;/stdio.h&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;1 2 3&lt;/code&gt; &lt;/p&gt;
&lt;h2 id="2024-11-18h"&gt;Lab10&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Deadline&lt;/strong&gt; : Thu 11/21 8am&lt;/p&gt;
&lt;p&gt;You will have class time Today and Monday to work on it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GitHub link&lt;/strong&gt;: &lt;a href="https://classroom.github.com/a/9SRoOA3D"&gt;10-Signals-That-You-Need-To-Sleep-More&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Write a C program with the following features:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Runs constantly inside a forever while loop.&lt;/li&gt;
&lt;li&gt;Print out the process' PID inside the loop &lt;code&gt;"My PID is : XXX"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use the sleep(1) function to have the program wait 1 second between inner loop iterations.&lt;/li&gt;
&lt;li&gt;Catch the following signals
      &lt;ul&gt;
&lt;li&gt;&lt;code&gt;SIGINT&lt;/code&gt;
&lt;p&gt;
&lt;/p&gt;&lt;ul class="sublist"&gt;
&lt;li&gt;Print to stdout &lt;code&gt;"Process with PID: XXX Exiting due to SIGINT"&lt;/code&gt; replacing XXX with the actual process id.&lt;/li&gt;
&lt;li&gt;Append the above message to a file &lt;code&gt;output.txt&lt;/code&gt;, one message per line. The file should be created if it doesn't exist, or append new lines if it does. (See the notes on sprintf to format a string in memory like you do with printf).&lt;/li&gt;
&lt;li&gt;Exit your program with a 0 exit code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SIGQUIT&lt;/code&gt;
&lt;ul class="sublist"&gt;
&lt;li&gt;Print out the PID and Parent PID in the format:
            &lt;code&gt;"PPID: XXX , PID: YYY"&lt;/code&gt;
            replacing XXX and YYY with the correct ID values.&lt;/li&gt;
&lt;li&gt;DO NOT cause the program to exit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Include a makefile with a run and compile target.&lt;/li&gt;
&lt;li&gt;I will make compile and then make run. I will then use the kill command (or ctrl-c and ctrl-\) to send the signals to your program.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Sample run:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$make compile
$make run
PID is : 10432
PID is : 10432
PID is : 10432
^-\ (sigquit)
PPID: 10401 , PID: 10432
PID is : 10432
PID is : 10432
^-c (sigint)
Process with PID: 10432 Exiting due to SIGINT
$cat output.txt
Process with PID: 10432 Exiting due to SIGINT
$
&lt;/code&gt; &lt;/pre&gt;
&lt;p&gt;Please test your programs on a clean clone of your repo. The number of mistakes due to this last time was astoundingly high.&lt;/p&gt;
&lt;h3&gt;sprintf - print to a string buffer. This is used to format a string as if you were printing it. It is useful if you want to print the string, and do something else with it (like write it to a file also).&lt;/h3&gt;
&lt;p&gt;&lt;code&gt; int sprintf(char *str, const char *string,...); &lt;/code&gt; &lt;/p&gt;
&lt;h4&gt;Return value:&lt;/h4&gt;
&lt;p&gt;If successful, it returns the total number of characters written excluding null-character appended in the string.&lt;/p&gt;
&lt;p&gt;In case of failure a negative number is returned .  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;char buffer[100];
float pi = 3.14159;
int bytes = sprintf(buffer, "The value of pi is %.2f.", pi);
//check your bytes for negative
printf("%s\n", buffer);&lt;/code&gt; &lt;/pre&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-18n"/><published>2024-11-18T12:00:00+00:00</published></entry><entry><id>2024-11-20n</id><title>2024-11-20</title><updated>2024-11-20T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-20n"&gt;
&lt;h5&gt;2024-11-20&lt;/h5&gt;
&lt;h2&gt;Exec&lt;/h2&gt;
&lt;p&gt;The exec functions are a group of c functions that can be used to run other programs.&lt;/p&gt;
&lt;p&gt;When used, they replace the current process with the new program.&lt;/p&gt;
&lt;p&gt;These functions are all in &lt;code&gt;&amp;amp;ltunistd.h&amp;gt;&lt;/code&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h4&gt;execl&lt;/h4&gt;
&lt;code&gt;execl(path, command, arg0, arg1 … NULL)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;path&lt;/em&gt;: The path to the program (ex: "/bin/ls" )&lt;/li&gt;
&lt;li&gt;&lt;em&gt;command&lt;/em&gt;: The name of the program (ex: "ls") &lt;/li&gt;
&lt;li&gt;&lt;em&gt;arg0 ... &lt;/em&gt; : Each command line argument you wish to give the program. (ex "-a", "-l")
        The last argument must be NULL &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;execlp&lt;/h4&gt;
&lt;code&gt;execlp(path, command, arg0, arg1 ... NULL)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Works like execl, except it uses the &lt;code&gt;$PATH&lt;/code&gt; environment variable for commands.&lt;/li&gt;
&lt;li&gt;For example, you can use "ls" as the path instead of "/bin/ls"&lt;/li&gt;
&lt;li&gt;To check the &lt;code&gt;$PATH&lt;/code&gt; environment variable, use: &lt;code&gt;echo $PATH&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h4&gt;execvp&lt;/h4&gt;
&lt;code&gt;execvp(path, argument_array)&lt;/code&gt;
&lt;p&gt;argument_array&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Array of strings containing the arguments to the command.&lt;/li&gt;
&lt;li&gt;argument_array[0] must be the name of the program.&lt;/li&gt;
&lt;li&gt;The last entry must be NULL&lt;/li&gt;
&lt;li&gt;Like execlp, the path argument will use the $PATH environment variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample argument_array&lt;/p&gt;
&lt;p&gt;&lt;img alt="argument array example" src="img/cmdargv.jpg" width="300px"/&gt;&lt;/p&gt;
&lt;p&gt;A much better example is displayed in class... your notes are supreme in this case.&lt;/p&gt;
&lt;h3&gt;How would you convert a command line into an argument array?&lt;/h3&gt;
&lt;p&gt;The way execvp works is it requires you to use an argument array. This means to run a command like &lt;code&gt;"ls -a -l"&lt;/code&gt; must be parsed and manipulated into an array of 3 strings and a terminating null:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;argumentarray[0] must be "ls"&lt;/li&gt;
&lt;li&gt;argumentarray[1] must be "-a"&lt;/li&gt;
&lt;li&gt;argumentarray[2] must be "-l"&lt;/li&gt;
&lt;li&gt;argumentarray[3] must be NULL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example of what you would do in memory:&lt;/p&gt;
&lt;img alt="diagram of parsing ls -a -l" src="img/execargsParsing.png"/&gt;
&lt;p&gt;Note this is also why you must not destroy your buffer until after the tokens are no longer needed.
        Some of you had bugs where you used a buffer for your csv header, then re-used that buffer for the individual lines. At the end of your program, the header strings were erased.&lt;/p&gt;
&lt;h3&gt;This looks like a job for strsep()!&lt;/h3&gt;
&lt;p&gt;Remember you have a pointer to the string, that is mutable, in this case it is called string.&lt;/p&gt;
&lt;p&gt;Store the locations of the different string starting points in your command args array.&lt;/p&gt;
&lt;img alt="strsep" src="img/parseArgsBefore.png"/&gt;
&lt;p&gt;After a few iterations:&lt;/p&gt;
&lt;img alt="strsep" src="img/parseArgsDurring.png"/&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-20n"/><published>2024-11-20T12:00:00+00:00</published></entry><entry><id>2024-11-21n</id><title>2024-11-21</title><updated>2024-11-21T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-21n"&gt;
&lt;h5&gt;2024-11-21&lt;/h5&gt;
&lt;h2 id="2024-11-21h"&gt;Lab11&lt;/h2&gt;
&lt;h5&gt;Deadline: Tues 11-26&lt;/h5&gt;
&lt;h3&gt;Main Goal&lt;/h3&gt;
&lt;p&gt;Write a function that uses strsep to parse a line of arguments&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The library is &lt;code&gt;parse.c/h&lt;/code&gt; your code will be tested by including parse.h so there should be no other extrernal requirements.&lt;/li&gt;
&lt;li&gt;header: &lt;code&gt;void parse_args( char * line, char ** arg_ary );&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Parameter &lt;code&gt;line&lt;/code&gt; a mutable string with the command line invocation of a program e.g. "ls -a -l" or "cat fish.txt"&lt;/li&gt;
&lt;li&gt;Parameter &lt;code&gt;arg_ary&lt;/code&gt; is an array of char* which will be modified to have each index point to the corresponding argument in the parameter string, that could be used for execvp()&lt;/li&gt;
&lt;li&gt;Note that there is exactly one space separting adjacent arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example:&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;char * cmdargv[16];
char line[] = "mkdir aaa";
parse_args(line,cmdargv);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the result of running the code above is the following array:&lt;/p&gt;
&lt;p&gt;&lt;img alt="argument array example" src="img/cmdargv.jpg" width="300px"/&gt;&lt;/p&gt;
&lt;p&gt;Also note that &lt;code&gt;cmdargv&lt;/code&gt; is pointing to memory locations of &lt;code&gt;line&lt;/code&gt;, so further manipulation of the &lt;code&gt;line&lt;/code&gt; variable will result in damage to your array's strings.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;To test this function, your main program (separate c file!) should use it on a string and then call execvp successfully.&lt;/li&gt;
&lt;li&gt;For example, the following code should work assuming all variables are declared appropriately:
      &lt;pre&gt;&lt;code&gt;char * args[16];
char line[] = "ls -l -h";
parse_args( line, args );
execvp(args[0], args);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;You can make the following assumptions:
      &lt;ol&gt;
&lt;li&gt;There is exactly 1 space between each argument in the original string&lt;/li&gt;
&lt;li&gt;&lt;code&gt;char** arg_ary&lt;/code&gt; is long enough to store the tokens of the provided &lt;code&gt;line&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;code&gt;char* line&lt;/code&gt; is correctly formatted.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;char* line&lt;/code&gt; is a muteable string&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Assignment Repo:&lt;/h3&gt;
&lt;p&gt;Clone the repo: &lt;a href="https://classroom.github.com/a/8ifXTxo7"&gt;https://classroom.github.com/a/8ifXTxo7&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Test with a variety of lengths of commands such as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;yes a b c d e f g h i&lt;/code&gt; (test with different numbers of args, but it must fit in your arg array)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;echo 8 6 7 5 3 0 9&lt;/code&gt; (test with different numbers of args, but it must fit in your arg array)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toilet -f emboss Execute!&lt;/code&gt; (you may not have this) &lt;/li&gt;
&lt;li&gt;&lt;code&gt;toilet Hello --metal&lt;/code&gt; (you may not have this)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cowsay -f dragon-and-cow roar&lt;/code&gt; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-21n"/><published>2024-11-21T12:00:00+00:00</published></entry><entry><id>2024-11-25n</id><title>2024-11-25</title><updated>2024-11-25T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-25n"&gt;
&lt;h5&gt;2024-11-25&lt;/h5&gt;
&lt;h2&gt;Managing Sub-Processes&lt;/h2&gt;
&lt;p&gt;
&lt;/p&gt;&lt;p&gt;&lt;code&gt;fork() - &amp;lt;unistd.h&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creates a separate process based on the current one, the new process is called a child, the original is the parent.&lt;/li&gt;
&lt;li&gt;The child process is a duplicate of the parent process.&lt;/li&gt;
&lt;li&gt;All parts of the parent process are copied, including stack and heap memory, and the file table.&lt;/li&gt;
&lt;li&gt;Returns a pid_t type (signed int), the value returned is:
        &lt;ul class="sublist"&gt;
&lt;li&gt;-1 if the fork failed, check your &lt;code&gt;errno&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The child's pid to the parent&lt;/li&gt;
&lt;li&gt;0 to the child&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If a parent process ends before the child, the child's new parent pid is 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;/p&gt;&lt;pre class="codeblock"&gt;&lt;code&gt;pid_t p;
p = fork();
if(p&amp;lt;0){
  perror("fork fail");//output to stderr instead of stdout
  exit(1);
} else if ( p == 0){
    printf("Hello from Child!\n");
}else{
    printf("Hello from Parent!\n");
}&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;wait - &amp;lt;sys/wait.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Stops a parent process from running until any child has exited.&lt;/li&gt;
&lt;li&gt;Returns the pid of the child that exited, or -1 (&lt;code&gt;errno&lt;/code&gt;), and gathers information about the child process (this is called reaping)&lt;/li&gt;
&lt;li&gt;If multiple child processes exit, an arbitrary one will be reaped.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wait(int* status)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Pass in an address to an int &lt;code&gt;status&lt;/code&gt; which is used to store information about how the process exited.&lt;/li&gt;
&lt;li&gt;Status macros
          &lt;ul&gt;
&lt;li&gt;Usage: &lt;code&gt;MACRO( status )&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WIFEXITED&lt;/code&gt;: True if child exited normally&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WEXITSTATUS&lt;/code&gt;: The return value of the child&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WIFSIGNALED&lt;/code&gt;: True if child exited due to a signal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WTERMSIG&lt;/code&gt;: The signal number intercepted by the child&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;code&gt;waitpid - &amp;lt;sys/wait.h&amp;gt;&lt;/code&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Wait for a specific child&lt;/li&gt;
&lt;li&gt;&lt;code&gt;waitpid(pid, status, options)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pid&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;The pid of the specific child to look for&lt;/li&gt;
&lt;li&gt;If -1, will wait for any child (normal wait)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;options&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Can set other behavior for waitpid,.&lt;/li&gt;
&lt;li&gt;This is 0 or more flags.&lt;/li&gt;
&lt;li&gt;if 0, will work normally, otherwise you would or the flags together. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2024-11-25h"&gt;Lab12&lt;/h2&gt;
&lt;p&gt;Repo link: &lt;a href="https://classroom.github.com/a/0glxvVjC"&gt;https://classroom.github.com/a/0glxvVjC&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Make should have compile and run targets.&lt;/p&gt;
&lt;p&gt;Write a c program that does the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Forks off 2 child processes&lt;/li&gt;
&lt;li&gt;
    Child process instructions:
    &lt;ul&gt;
&lt;li&gt;At the start print its pid, and a random number in the range [1, 5]. e.g. "123531 5sec". These numbers should be different each time, but could match sometimes (1/5 of the time NOT ALL THE TIME!)&lt;/li&gt;
&lt;li&gt;Sleep for a random number of seconds equal to the random number printed earlier (do not re-random the value!)&lt;/li&gt;
&lt;li&gt;Each child calculates their own random, so they can each sleep for a different number of seconds&lt;/li&gt;
&lt;li&gt;At the end print a message "PID finished" e.g. "123531 finished after 5 seconds."&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Parent process instructions. Note the strings have _placeholders_ designated with underscores.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before forking, print out the initial message "_PID_ about to create 2 child processes."&lt;/li&gt;
&lt;li&gt;After the fork, wait for any child to finish&lt;/li&gt;
&lt;li&gt;Once a child has finished, print out a message. That includes its own PID and information about the child that exited.  Then end the program.&lt;/li&gt;
&lt;li&gt;The message should be: "Main Process _PID_  is done. Child _EXITING_CHILD_PID_ slept for _SEC_ sec"&lt;/li&gt;
&lt;li&gt;The other child might still be running and can finish after the parent, that's intended behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Sample output:&lt;/h3&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;user@host $ ./a.out
68724 about to create 2 child processes
68726 2sec
68725 4sec
68726 finished after 2sec
Main Process 68724 is done. Child 68726 slept for 2sec
user@host $
68725 finished after 4sec&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the 2nd child prints after your shell prompt is printed.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-25n"/><published>2024-11-25T12:00:00+00:00</published></entry><entry><id>2024-11-27n</id><title>2024-11-27</title><updated>2024-11-27T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-11-27n"&gt;
&lt;h5&gt;2024-11-27&lt;/h5&gt;
&lt;h2&gt;Open a remote repo in a browser using the CLI:&lt;/h2&gt;
&lt;h3&gt;WSL:&lt;/h3&gt;
&lt;code&gt;alias gh='explorer.exe https://$(git config remote.origin.url | cut -f2 -d@ | tr ':' /)'&lt;/code&gt;
&lt;h3&gt;Non-wsl:&lt;/h3&gt;
&lt;p&gt;Change the explorer.exe to some other application... like &lt;code&gt;firefox&lt;/code&gt; , or on mac, you can use the &lt;code&gt;open&lt;/code&gt; command &lt;/p&gt;
&lt;p&gt;Like this: &lt;code&gt;firefox "https://`(git config remote.origin.url | cut -f2 -d@ | tr ':' /)`"&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;SHELL PROJECT After break:&lt;/h2&gt;
&lt;p&gt;You (and up to 2 partners if desired - at least 1 partner highly suggested) are to
    write a shell.&lt;/p&gt;
&lt;p&gt;By Monday, you should have a group chosen. You may not work with the same partner as before.&lt;/p&gt;
&lt;h2&gt;Redirection&lt;/h2&gt;
&lt;p&gt;Redirection is when you change the usual input/output behavior of a program&lt;/p&gt;
&lt;h2&gt;Command line redirection&lt;/h2&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Symbol&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;gt&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Redirects stdout to a file.&lt;/p&gt;
&lt;p&gt;  Overwrites the contents of the file.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;gt&amp;amp;gt&lt;/td&gt;
&lt;td&gt;Redirects stdout to a file by appending.
      &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;lt&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Redirect stdin from a file.&lt;/p&gt;
&lt;p&gt;The file is treated exactly like stdin, for example scanf() will read up until a newline is found.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;| (pipe)&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;Redirect stdout from one program to stdin of the next.&lt;/p&gt;
&lt;p&gt;  Very useful for chaining programs together.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;h2&gt;Redirection in c programs&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;dup2&lt;/code&gt; - &lt;code&gt;  &amp;amp;ltunistd.h&amp;gt;&lt;/code&gt; is used to redirect a file descriptor
        &lt;ul&gt;
&lt;li&gt;dup2( fd1, fd2 )&lt;/li&gt;
&lt;li&gt;Redirects fd2 to fd1&lt;/li&gt;
&lt;li&gt;Any use of fd2 will now act on the file for fd1.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dup &lt;/code&gt; - &lt;code&gt; &amp;amp;ltunistd.h&amp;gt;&lt;/code&gt; is used to backup a file descriptor.

        &lt;ul&gt;
&lt;li&gt;Duplicates an existing entry in the file table.&lt;/li&gt;
&lt;li&gt;Returns a new file descriptor for the duplicate entry.&lt;/li&gt;
&lt;li&gt;dup( fd )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;USING dup and dup2 together:&lt;/h3&gt;
&lt;p&gt;Note: the filenumber for stdout is just &lt;code&gt;stdout&lt;/code&gt; &lt;/p&gt;
&lt;pre&gt;
      &lt;code&gt;int fd1 = open("foo.txt", O_WRONLY);
int stdout = STDOUT_FILENO;//stdout filenumber is 1, but this makes it clear
int backup_stdout = dup( stdout ) // save for later
dup2(fd1, stdout); //sets stdout's entry to the file "foo.txt".
printf("TO THE FILE!!!\n");
fflush(stdout);//not needed when a child process exits, becaue exiting a process will flush automatically.
dup2(backup_stdout, stdout); //sets the stdout entry to backup_stdout, which is the original stdout&lt;/code&gt;
    &lt;/pre&gt;
&lt;h3&gt;Your shell project will need to use dup() and dup2()&lt;/h3&gt;
&lt;p&gt;It should be reasonably straight forward that you can implement the redirection operators &lt;code&gt;&amp;amp;lt&lt;/code&gt; or &lt;code&gt;&amp;amp;gt&lt;/code&gt; by changing the input to be a file instead of stdin, or the output to be a file not stdout. &lt;/p&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;p&gt;You can make redirection with pipes  &lt;code&gt;ls | wc&lt;/code&gt; in the following manner:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;run ls and redirect stdout to a temp file&lt;/li&gt;
&lt;li&gt;run wc and redirect the temp file to stdin&lt;/li&gt;
&lt;li&gt;remove the temp file when done. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The above strategy is a little inelegant, as it would pollute the ls command with the temp file. There is a better way we will learn in the near future. &lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-11-27n"/><published>2024-11-27T12:00:00+00:00</published></entry><entry><id>2024-12-02n</id><title>2024-12-02</title><updated>2024-12-02T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-02n"&gt;
&lt;h5&gt;2024-12-02&lt;/h5&gt;
&lt;h2&gt;Cowabunga, let's kick some shell 🐢&lt;/h2&gt;
&lt;h3&gt;Project (MyShell) Overview&lt;/h3&gt;
&lt;p&gt;You (and up to 2 partners if desired - at least 1 partner highly suggested) are to write a shell. The shell should implement as many of these features as possible. The first being the most basic up to the last which is the most complex.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;General Functionality:
     &lt;ol&gt;
&lt;li&gt;Prompt the user for input and read a line at a time from stdin.&lt;/li&gt;
&lt;li&gt;parse the user input line to separate the command from its arguments.&lt;/li&gt;
&lt;li&gt;The shell should then fork for each command and the child should execvp that command.&lt;/li&gt;
&lt;li&gt;The parent process (shell) should wait until the exec'd program exits and then it should go back to step 1.&lt;/li&gt;
&lt;li&gt;Semicolons act as a separator of commands, so you can have multiple commands on the same line. e.g. &lt;code&gt;echo 1;echo 2;echo 3&lt;/code&gt; Important note: The semicolon is the only symbol that will not be separated by spaces (for easy splitting)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;The working directory:
     &lt;ol&gt;
&lt;li&gt;The command &lt;code&gt;cd&lt;/code&gt; is not a program to execvp, your shell has to keep track of the current working directory instead.&lt;/li&gt;
&lt;li&gt;Look at the &lt;code&gt;chdir()&lt;/code&gt;  and &lt;code&gt;getcwd()&lt;/code&gt; functions &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;The prompt:
     &lt;ol&gt;
&lt;li&gt;The prompt should includ the cwd path, e.g. &lt;code&gt;"/home/konstans/Documents/ $"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;The prompt can shorten the path using the &lt;code&gt;~&lt;/code&gt; as the home directory. e.g. &lt;code&gt;"~/Documents/ $"&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;You should &lt;code&gt;fflush(stdout);&lt;/code&gt; after printing so that a partial lines are displayed and the children don't print a second copy of things. (The shell prompt is a partial line!)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Exiting:
     &lt;ol class="sublist"&gt;
&lt;li&gt;To quit your shell use the &lt;code&gt;exit&lt;/code&gt; command. This is not a program to execute.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl-D&lt;/code&gt; (end of file) shoud terminate the shell. Check your &lt;code&gt;fgets()&lt;/code&gt; return value.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Implement simple redirection.
       &lt;ol class="sublist"&gt;
&lt;li&gt;Support both redrection oprators: the &lt;code&gt;&amp;amp;gt&lt;/code&gt; (redirecting stdout) and &lt;code&gt;&amp;amp;lt&lt;/code&gt; (redirecting stdin).
           &lt;/li&gt;&lt;li&gt;This will be explained in class.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
       Implement simple pipes. Only one pipe at a time is required.
       &lt;ol class="sublist"&gt;
&lt;li&gt;The pipe operator &lt;code&gt;|&lt;/code&gt; redirects one program's output to be another program's input.  e.g. &lt;code&gt;ls | wc&lt;/code&gt; would run ls and use the output from ls as the input for wc.&lt;/li&gt;
&lt;li&gt;Check out popen() for the advanced way of doing this, otherwise use a temp file.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
       Compilation, running, and testing:
       &lt;ol class="sublist"&gt;
&lt;li&gt;The project should be built using make and a makefile, I will only compile by using &lt;code&gt;make compile&lt;/code&gt; which should output an executable file &lt;code&gt;shell&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;The project should be runnable by running &lt;code&gt;./shell&lt;/code&gt; after the make compile command. &lt;/li&gt;
&lt;li&gt;You must be able to test your shell using the syntax: &lt;code&gt;./shell &amp;amp;lt lines.txt&lt;/code&gt; where lines.txt contains commands on each line.&lt;/li&gt;
&lt;li&gt;All of the features discussed work in bash, so use it to check out the functionality of each feature if you are unclear about anything.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Code/Documentation requirements&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Every function you write must have a &lt;strong&gt;function header comment &lt;/strong&gt; describing the arguments, return value and what the function does. &lt;/li&gt;
&lt;li&gt;Use modular design liberally. This is a large program.&lt;/li&gt;
&lt;li&gt;You should have a readme file with the following:
        &lt;ul&gt;
&lt;li&gt;All group member's names&lt;/li&gt;
&lt;li&gt;Your group's "creative team name" where you can optionally flex on other groups by making a really good name.&lt;/li&gt;
&lt;li&gt;A description of what features your shell implements&lt;/li&gt;
&lt;li&gt;A description of what features you attempted to implement but were unsuccessful&lt;/li&gt;
&lt;li&gt;Any bugs or things you want me to know about your program&lt;/li&gt;
&lt;li&gt;I am much more forgiving of reported bugs than bugs I discover while testing&lt;/li&gt;
&lt;li&gt;A copy of every function header&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This project should use separate C files as necessary.&lt;/li&gt;
&lt;li&gt;Restrictions on input (to make your job easier):
      &lt;ul&gt;
&lt;li&gt;Command line arguments will be separated by single spaces. (Except the semicolon)&lt;/li&gt;
&lt;li&gt;I will only test a single pipe  &lt;code&gt;|&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;I will only test up to one  &lt;code&gt;&amp;amp;gt&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;I will only use the &lt;code&gt;&amp;amp;gt&lt;/code&gt; syntax, not the &lt;code&gt;2&amp;amp;gt&lt;/code&gt; or &lt;code&gt;&amp;amp;amp&amp;amp;gt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&amp;amp;lt would go after the first command only, &lt;/li&gt;
&lt;li&gt;&amp;amp;gt would go at the end of the command only. &lt;/li&gt;
&lt;li&gt;e.g. &lt;pre&gt;&lt;code&gt;a &amp;amp;lt c.txt | b  &amp;amp;gt d.txt&lt;/code&gt;&lt;/pre&gt; This would cause: c.txt goes into program a, the output of a goes into program b, the output of b goes into the file d.txt  )&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;If you would like to implement other features after getting these ones down, please do. Look at what bash does and see what else you can do!&lt;/li&gt;
&lt;/ol&gt;
&lt;h5&gt;Due: Monday  12/09 8:00 am&lt;/h5&gt;
&lt;h5&gt;Repo Name format:&lt;/h5&gt;
&lt;p&gt; &lt;code&gt;PERIOD-NAME1-NAME2&lt;/code&gt; (This is separate from your creative team name)&lt;/p&gt;
&lt;p&gt; Where NAME is last name + first initial e.g.  &lt;code&gt;3-WrightE-WongL-WongJ&lt;/code&gt; &lt;/p&gt;
&lt;p&gt; Team name and other information will go in the &lt;code&gt;README.md&lt;/code&gt;&lt;/p&gt;
&lt;h5&gt;GitHub Submission Link:&lt;/h5&gt;
&lt;p&gt; &lt;a href="https://classroom.github.com/a/Tfg6waJb"&gt;https://classroom.github.com/a/Tfg6waJb&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-02n"/><published>2024-12-02T12:00:00+00:00</published></entry><entry><id>2024-12-09n</id><title>2024-12-09</title><updated>2024-12-09T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-09n"&gt;
&lt;h5&gt;2024-12-09&lt;/h5&gt;
&lt;h2&gt;Inter-Process Communication (IPC)&lt;/h2&gt;
&lt;p&gt;There are many kinds of Inter-Process Communication, &lt;em&gt;but&lt;/em&gt; there is a specific set of IPC features that have competing standardized implementations, these are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Shared Memory&lt;/li&gt;
&lt;li&gt;Semaphores&lt;/li&gt;
&lt;li&gt;Message Queues&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;System V IPC&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
    For the IPC features mentioned, there are 2 standards:
    &lt;ol&gt;
&lt;li&gt;Portable Operating System Interface (POSIX)&lt;/li&gt;
&lt;li&gt;System V&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Both of these cover more than IPC, and their functionality, thought not their implementations, are mostly the same.&lt;/li&gt;
&lt;li&gt; We will be using System V IPC.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ ipcs&lt;/code&gt; is a useful command line utility to see active System V IPC structures.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shared Memory&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A segment of heap-like memory that can be accessed by multiple processes.&lt;/li&gt;
&lt;li&gt;Shared memory is accessed via a key that is known by any process that needs to access it.&lt;/li&gt;
&lt;li&gt;Shared memory does not get released when a program exits.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5 Shared memory operations&lt;/strong&gt;
&lt;ul class="sublist"&gt;
&lt;li&gt;Create the segment (happens once) - &lt;code&gt;shmget&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Access the segment (happens once per process) - &lt;code&gt;shmget&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Attach the segment to a variable (once per process) - &lt;code&gt;shmat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Detach the segment from a variable (once per process) - &lt;code&gt;shmdt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Remove the segment (happens once) - &lt;code&gt;shmctl&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Using shared memory in C:
Headers: &lt;code&gt;&amp;lt;sys/shm.h&amp;gt; &amp;lt;sys/ipc.h&amp;gt; &amp;lt;sys/types.h&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int *data;
int shmid;
shmid = shmget(INTEGER_KEY_GOES_HERE, sizeof(int), IPC_CREAT | 0640);
printf("shmid: %d\n", shmid);
data = shmat(shmid, 0, 0); //attach
printf("data: %p\n", data);
printf("*data: %d\n", *data);
*data = * data + 10; //work with the segment as a normal pointer
printf("*data: %d\n", *data);
shmdt(data); //detach
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To remove the segment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int shmid;
shmid = shmget(INTEGER_KEY_GOES_HERE, sizeof(int), IPC_CREAT | 0640);
shmctl(shmid, IPC_RMID, 0); //remove the segment
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Controlling access&lt;/h3&gt;
&lt;p&gt;Before utilizing shared memory, we need a way to control access to shared resources.  Files and shared memory are both resources that are commonly shared.&lt;/p&gt;
&lt;p&gt;You have seen lockfiles, or files that tell you another file is being edited by some other program. These are common for files specifically, but they don't always work. When programs crash, they do not clean up the lock files. If you ever had a "firefox is already running error" or seen a file in your directory with almost the same name as something you are editing, that is an example of a file that controls access. &lt;/p&gt;
&lt;p&gt;Unfortunately files to control access are not appropriate for shared memory.&lt;/p&gt;
&lt;p&gt;Tomorrow we will learn about semaphores. A semaphore is method of visual signaling, usually by means of flags or lights.&lt;/p&gt;
&lt;h3&gt;Monty Python semaphore video&lt;/h3&gt;
&lt;p&gt;Jump to the 18 minute mark of this video and watch the semaphore version of withering heights: &lt;a href="https://www.dailymotion.com/video/xsefeg"&gt;https://www.dailymotion.com/video/xsefeg&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now you will remember that a semaphore is method of visual signaling, usually by means of flags or lights.&lt;/p&gt;
&lt;p&gt;In a programming language we use semaphores to "notify" a program that a resource is either free or in use much like how the flags signal.&lt;/p&gt;
&lt;h3&gt;Semaphores in c&lt;/h3&gt;
&lt;p&gt;Semaphores are an IPC construct used to control access to a shared resource (like a file or shared memory).&lt;/p&gt;
&lt;p&gt;Most commonly, a semaphore is used as a counter representing how many processes can access a resource at a given time.
    &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;If a semaphore has a value of 3, then it can have 3 active “users”.&lt;/li&gt;
&lt;li&gt;If a semaphore has a value of 0, then it is unavailable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some semaphore operations are &lt;em&gt;atomic&lt;/em&gt;, meaning they will not be split up into multiple processor instructions.&lt;/p&gt;
&lt;h3&gt;Semaphore operations&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;“Maintenance operations”
      &lt;ul&gt; &lt;li&gt;Create a semaphore&lt;/li&gt; &lt;li&gt;Set an initial value&lt;/li&gt; &lt;li&gt;Remove a semaphore&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Traditional Semaphore Usage
      &lt;ul style="list-style-type:square"&gt;
&lt;li&gt;&lt;code&gt;Up(S)&lt;/code&gt; | &lt;code&gt;V(S)&lt;/code&gt; - &lt;em&gt;atomic&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Release the semaphore to signal you are done with its associated resource&lt;/li&gt;
&lt;li&gt;Pseudocode
              &lt;ul&gt; &lt;li&gt;&lt;code&gt;S++&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Down(S)&lt;/code&gt; | &lt;code&gt;P(S)&lt;/code&gt; - &lt;em&gt;atomic&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;Attempt to take the semaphore.&lt;/li&gt;
&lt;li&gt;If the semaphore is 0, wait for it to be available.&lt;/li&gt;
&lt;li&gt;Pseudocode
              &lt;ul&gt;
&lt;li&gt;&lt;code&gt;while (S == 0) { block } S--;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Important distinction that the blocking is not atmoic, so if a processess checks the semaphore
                and it is unavailable, other processes can run, &lt;em&gt;but&lt;/em&gt; if the semaphore is available,
                the process will immediately modify the semaphore.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-09n"/><published>2024-12-09T12:00:00+00:00</published></entry><entry><id>2024-12-10n</id><title>2024-12-10</title><updated>2024-12-10T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-10n"&gt;
&lt;h5&gt;2024-12-10&lt;/h5&gt;
&lt;h3&gt;Using semaphores in C&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;headers: &lt;code&gt;&amp;lt;sys/types.h&amp;gt; &amp;lt;sys/ipc.h&amp;gt; &amp;lt;sys/sem.h&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;semget&lt;/code&gt;
&lt;ul clas="sublist"&gt;
&lt;li&gt;Create/Get access to a semaphore.&lt;/li&gt;
&lt;li&gt;Returns a semaphore descriptor or -1 (&lt;code&gt;errno&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;semget( key, amount, flags )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;key&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Unique semaphore identifier&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;amount&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Semaphores are stored as sets of one or more. The number of semaphores to create/get in the set.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flags&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IPC_CREAT&lt;/code&gt;: create the semaphore and set value to &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IPC_EXCL&lt;/code&gt;: Fail if the semaphore already exists and &lt;code&gt;IPC_CREAT&lt;/code&gt; is on.&lt;/li&gt;
&lt;li&gt;Includes permissions for the semaphore, combine with bitwise or (&lt;code&gt;|&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;semctl&lt;/code&gt;
&lt;ul style="list-style-type:square"&gt;
&lt;li&gt;Control the semaphore, including
              &lt;ul&gt;
&lt;li&gt;Set the semaphore value&lt;/li&gt;
&lt;li&gt;Remove the semaphore&lt;/li&gt;
&lt;li&gt;Get the current value&lt;/li&gt;
&lt;li&gt;Get/set semaphore metadata&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;semctl(descriptor, index, operation, data)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;descriptor&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;The return value of &lt;code&gt;semget&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;The index of the semaphore you want to control in the semaphore set.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;operation&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IPC_RMID&lt;/code&gt;: remove the semaphore&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SETVAL&lt;/code&gt;: Set the value (requires data)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GETVAL&lt;/code&gt;: Return the value&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Variable for setting/storing semaphore metadata&lt;/li&gt;
&lt;li&gt;Type is &lt;code&gt;union semun&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You have to declare this union in your main c file on linux machines.&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;pre&gt;&lt;code&gt;union semun {
  int val;                  //used for SETVAL
  struct semid_ds *buf;     //used for IPC_STAT and IPC_SET
  unsigned short  *array;   //used for SETALL
  struct seminfo  *__buf;
};
                    &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;union&lt;/code&gt;?
                &lt;ul&gt;
&lt;li&gt;A c structure designed to hold only one value at a time from a group of potential values.&lt;/li&gt;
&lt;li&gt;Just large enough to hold the largest piece of data it could potentially contain&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;semop&lt;/code&gt;
&lt;ul class="sublist"&gt;
&lt;li&gt;Perform an atomic semaphore operation&lt;/li&gt;
&lt;li&gt;You can &lt;code&gt;Up/Down&lt;/code&gt; a semaphore by any integer value, not just &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;semop( descriptor, operation, amount )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;amount&lt;/code&gt; - The amount of operations you want to perform on the semaphore set.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;operation&lt;/code&gt; - A pointer to a &lt;code&gt;struct sembuf&lt;/code&gt;
&lt;/li&gt;&lt;/ul&gt;
&lt;/li&gt;&lt;li&gt; &lt;code&gt;struct sembuff&lt;/code&gt;:
            &lt;pre&gt;&lt;code&gt;struct sembuf {
  short sem_op;
  short sem_num;
  short sem_flag;
};&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sem_num&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;The index of the semaphore you want to work on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sem_op&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Down(S)&lt;/code&gt;: Any negative number&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Up(S)&lt;/code&gt;: Any positive number&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;: Block until the semaphore reaches &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sem_flag&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SEM_UNDO&lt;/code&gt;: Allow the OS to undo the given operation. Useful in the event that a program exits before it could release a semaphore.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IPC_NOWAIT&lt;/code&gt;: Instead of waiting for the semaphore to be available, return an err&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Putting it all together.
      &lt;ul&gt;
&lt;li&gt;Creating a single semaphore and initializing its value to &lt;code&gt;1&lt;/code&gt;:
          &lt;pre&gt;&lt;code&gt;int semd = semget(KEY, 1, IPC_CREAT | IPC_EXCL | 0644);
union semun us;
us.val = 1;
r = semctl(semd, 0, SETVAL, us);&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Removing a semaphore:
          &lt;code&gt;semctl(semd, IPC_RMID, 0);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Getting a a semaphore &amp;amp; upping and downing it.
            &lt;pre&gt;&lt;code&gt;semd = semget(KEY, 1, 0); //get access
struct sembuf sb;
sb.sem_num = 0;
sb.sem_flg = SEM_UNDO;
sb.sem_op = -1; //setting the operation to down

semop(semd, &amp;amp;sb, 1); //perform the operation
printf("got the semaphore!\n");
sleep(10); //simulate doing something.

sb.sem_op = 1; //set the operation to up
semop(semd, &amp;amp;sb, 1); //perform the operation
            &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Sample IPC code:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="src/ipc/sem_control.c"&gt;sem_control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="src/ipc/sem_user.c"&gt;sem_user&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="src/ipc/shm.c"&gt;shm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="src/ipc/shm2.c"&gt;shm2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="src/ipc/shmrm.c"&gt;shmrm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="src/ipc/unnamed.c"&gt;unnamed&lt;/a&gt;(for pipes later in the week)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Lab13&lt;/h3&gt;
&lt;p&gt;Deadline Thursday, you will have 2 lab days to work in class.&lt;/p&gt;
&lt;a href="https://classroom.github.com/a/lZQ6Uun6"&gt;https://classroom.github.com/a/lZQ6Uun6&lt;/a&gt;
&lt;p&gt;You're going to write a game where each program adds on a new line to a story, but they can only see the one previous line!&lt;/p&gt;
&lt;p&gt;It will use a semaphore to control access to a file and shared memory.&lt;/p&gt;
&lt;p&gt;
  Before doing any of this check out the notes page for &lt;sub&gt;i&lt;/sub&gt;nformation on using semaphores in c.
  At the bottom are full code snippets that demonstrate the usage. I will add some sample programs that use shared memory and semaphores.&lt;/p&gt;
&lt;p&gt;You will need 2 programs, one to create/monitor/remove the file (stores a story), shared memory (stores the size of the last line added.) and a semaphore (to block write access), and one to use those structures to implement the telephone style game:&lt;/p&gt;
&lt;p&gt;Both programs should be compiled with the compile target of your makefile.&lt;/p&gt;
&lt;p&gt;Note: Only one program should be able to modify the resources at a given time. This includes creating and writing, but not reading!&lt;/p&gt;
&lt;h4&gt;Control program:&lt;/h4&gt;
&lt;p&gt;The control program should be run with a make target "control" (&lt;code&gt;make control ARGS=???&lt;/code&gt; e.g. &lt;code&gt;make control ARGS=create&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;create&lt;/code&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Should make the shared memory segment (one integer), semaphore and file called &lt;code&gt;story.txt&lt;/code&gt; (open the file with the truncate flag to erase any prior data.)&lt;/li&gt;
&lt;li&gt;Set any values that are needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;remove&lt;/code&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Remove the shared memory and the semaphore&lt;/li&gt;
&lt;li&gt;Display the full contents of the story.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;view&lt;/code&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Display the full contents of the story.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;The writing program:&lt;/h4&gt;
&lt;p&gt;Your program will allow multiple people to collaborate on a story, BUT the intent is that you can only see one previous entry when adding new text. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Should be run with a make target write. ( &lt;code&gt;make write&lt;/code&gt; ) &lt;/li&gt;
&lt;li&gt;Will attempt to access the resources using the semaphore. &lt;/li&gt;
&lt;li&gt;Display a message indicating that it attempting to open the resource. This means there will be some message prior to the program blocking.&lt;/li&gt;
&lt;li&gt;Once it gains access to the resources it should:&lt;/li&gt;
&lt;ul class="subList"&gt;
&lt;li&gt;Finds the size of the last line added by looking at the value in the shared memory. If the size is 0, then you are the first person.&lt;/li&gt;
&lt;li&gt;Display the last line added to the file (seek using the size).&lt;/li&gt;
&lt;li&gt;Prompt the use for the next line to be added to the story.&lt;/li&gt;
&lt;li&gt;Read the user input from stdin&lt;/li&gt;
&lt;li&gt;Once a new line of input is read, it should write that &lt;strong&gt;message to the file&lt;/strong&gt; and write the &lt;strong&gt;size to the shared memory&lt;/strong&gt; .&lt;/li&gt;
&lt;li&gt;After completing these steps you release the semaphore, and end the write program.&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-10n"/><published>2024-12-10T12:00:00+00:00</published></entry><entry><id>2024-12-13n</id><title>2024-12-13</title><updated>2024-12-13T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-13n"&gt;
&lt;h5&gt;2024-12-13&lt;/h5&gt;
&lt;h3&gt;Pipes&lt;/h3&gt;
&lt;p&gt;A pipe is a conduit in memory between 2 separate processes on the same computer.&lt;/p&gt;
&lt;p&gt;Pipes have 2 ends, a read end and a write end. Pipes act just like files (i.e. you can use read() and write() to send any set of bytes).&lt;/p&gt;
&lt;p&gt;Unnamed pipes have no external identifier (more on named pipes later).&lt;/p&gt;
&lt;h3&gt;Working with pipes&lt;/h3&gt;
&lt;p&gt;Pipes are in &lt;code&gt;&amp;amp;ltunistd.h&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pipe( descriptor_array )&lt;/code&gt; creates an unnamed pipe.&lt;/p&gt;
&lt;p&gt;Returns 0 if the pipe was created, -1 if not (errno).&lt;/p&gt;
&lt;p&gt;This opens two file descriptors, the reading end and the writing end.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;descriptor_array&lt;/code&gt; will contain the descriptors for each end of the pipe. Must be an int array of size 2.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;descriptor_array[0]&lt;/code&gt; is the read end.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;descriptor_array[1]&lt;/code&gt; is the write end.&lt;/p&gt;
&lt;h4&gt;Example:&lt;/h4&gt;
&lt;pre&gt;&lt;code class="codeblock"&gt;//it is usefull to add these definitions to make your code more readible
#define READ 0
#define WRITE 1
int main() {
  int fds[2];
  pipe( fds );
  char line[100];

  f = fork();
  if (f == 0) {
    close( fds[READ] ); //it is a good idea to close the end of the pipe your are not using.
    write( fds[WRITE], "hello!", 7);
  }
  else {
    close( fds[WRITE] );
    read( fds[READ], line, sizeof(line) );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Named Pipes&lt;/h3&gt;
&lt;p&gt;Named pipes are also known as FIFOs.&lt;/p&gt;
&lt;p&gt;Same as unnamed pipes except FIFOs have a name that can be used to identify them via different programs.&lt;/p&gt;
&lt;p&gt;Like unnamed pipes, FIFOS are unidirectional.&lt;/p&gt;
&lt;p&gt; &lt;code&gt;mkfifo&lt;/code&gt; is a shell command to make a FIFO &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkfifo nameOfPipeHere&lt;/code&gt; &lt;/pre&gt;
&lt;p&gt; &lt;code&gt;mkfifo&lt;/code&gt; is a c function to create a FIFO that requires: &lt;code&gt;&amp;amp;ltsys/types.h&amp;gt; &amp;amp;ltsys/stat.h&amp;gt;&lt;/code&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Returns 0 on success and -1 on failure&lt;/li&gt;
&lt;li&gt;Once created, the FIFO acts like a regular file, and we can use &lt;code&gt;open&lt;/code&gt; , &lt;code&gt; read&lt;/code&gt;, &lt;code&gt;write&lt;/code&gt;, and &lt;code&gt;close&lt;/code&gt; on it.&lt;/li&gt;
&lt;li&gt;FIFOs will block on open until both ends of the pipe have a connection.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Classwork + Homework:&lt;/h3&gt;
&lt;p&gt;Design a program that uses unnamed pipes to send one-way messages from a parent to a child or vice versa.&lt;/p&gt;
&lt;p&gt;The parent can prompt the user for a message, and the child process can print it.&lt;/p&gt;
&lt;p&gt;You should print the pid of the process in your &lt;code&gt;printf&lt;/code&gt; statements so you know which process is saying what. e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code class="codeblock"&gt;$ make run
pid 32041: Enter text: blah blah backslash.
pid 32050: Recieved message: blah blah backslash.
$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-13n"/><published>2024-12-13T12:00:00+00:00</published></entry><entry><id>2024-12-07n</id><title>2024-12-16</title><updated>2024-12-16T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-07n"&gt;
&lt;h5&gt;2024-12-16&lt;/h5&gt;
&lt;h3&gt;Lab 14&lt;/h3&gt;
&lt;h5&gt;Deadline: 12-18 8am&lt;/h5&gt;
&lt;a href="https://classroom.github.com/a/BrV3rDjy"&gt;https://classroom.github.com/a/BrV3rDjy&lt;/a&gt;
&lt;h3&gt;Phase 1&lt;/h3&gt;
&lt;p&gt;Design a program that uses unnamed pipes to facilitate two-way parent/child process communication.&lt;/p&gt;
&lt;p&gt;Hint: In order to facilitate 2 way communication, you will need 2 pipes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Parent&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;constantly prompts a user for input&lt;/li&gt;
&lt;li&gt;sends that input to child&lt;/li&gt;
&lt;li&gt;waits for a response&lt;/li&gt;
&lt;li&gt;displays the response to the user&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Child&lt;/strong&gt;
&lt;ol&gt;
&lt;li&gt;Get input from parent&lt;/li&gt;
&lt;li&gt;"processes" the input. process could be any of a number of string processes (all caps, all lower, reverse, rot13, etc. ).&lt;/li&gt;
&lt;li&gt;Send the processsed string back to the parent.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Phase 2&lt;/h3&gt;
&lt;h4&gt;Add the following features to your lab:&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Use one named pipe (create in the same directory) for child processes to communicate back with the parent.&lt;/li&gt;
&lt;li&gt;Instead of 1 child, spawn 2-4 child processes randomly, give each their own unnammed pipe to receive messages from the parent.&lt;/li&gt;
&lt;li&gt;You may wish to create a "childID" variable that helps you know which pipe to use&lt;/li&gt;
&lt;li&gt;The parent will send all 4 processes the same input text.&lt;/li&gt;
&lt;li&gt;Each process will sleep a random amount of time 0-4 seconds. To do this, you should use the system call &lt;code&gt;usleep()&lt;/code&gt; which uses microseconds instead of seconds, so random int from 0 to 4000000.&lt;/li&gt;
&lt;li&gt;After sleeping the child processes will process the string and send the pid of the child process + the processed string back to the parent using the named pipe.  &lt;/li&gt;
&lt;li&gt;You should use one write command to send all the data to avoid collisions with the other child processes.&lt;/li&gt;
&lt;li&gt;The parent will then print the PID and the processed string for each child&lt;/li&gt;
&lt;li&gt;The parent loops and asks for more input, use ctrl-c to exit.&lt;/li&gt;
&lt;li&gt;Note: There is no reason to use a named pipe here except to learn to used named pipes.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Output format to make y'all have some consistency&lt;/h3&gt;
&lt;pre&gt;&lt;code class="codeblock"&gt;$make run
Spawning 4 worker threads.
User Control Program (1244909) enter a line:
one fish two fish
(1244910) sleeping for 2.565000 seconds
(1244913) sleeping for 3.185000 seconds
(1244911) sleeping for 0.066000 seconds
(1244912) sleeping for 3.802000 seconds
result 0: pid(1244911): tsj knxm ybt knxm
result 1: pid(1244910): sri jmwl xas jmwl
result 2: pid(1244913): vul mpzo adv mpzo
result 3: pid(1244912): utk loyn zcu loyn
User Control Program (1244909) enter a line:
^C
$make run
Spawning 2 worker threads.
User Control Program (1244993) enter a line:
RED fisH! BluE fash.
(1244994) sleeping for 3.856000 seconds
(1244995) sleeping for 0.436000 seconds
result 0: pid(1244995): CPO qtdS! MwfP qlds.
result 1: pid(1244994): BON pscR! LveO pkcr.
User Control Program (1244993) enter a line:
fish fish
(1245066) sleeping for 1.327000 seconds
(1245067) sleeping for 1.374000 seconds
result 0: pid(1245066): jmwl jmwl
result 1: pid(1245067): knxm knxm
User Control Program (12444993) enter a line:
^C
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-07n"/><published>2024-12-16T12:00:00+00:00</published></entry><entry><id>2024-12-18n</id><title>2024-12-18</title><updated>2024-12-18T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-18n"&gt;
&lt;h5&gt;2024-12-18&lt;/h5&gt;
&lt;h3&gt;Pipe Networking&lt;/h3&gt;
&lt;p&gt;For the purposes of these notes, the words server and client will be used only to differentiate two programs with respect to their roles in a connection attempt, and not with respect to their usage once a connection is made.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server will be the program that starts up and awaits an incoming connection.&lt;/li&gt;
&lt;li&gt;Client will be the program that initiates a connection to a waiting server.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Handshake&lt;/h3&gt;
&lt;p&gt;A handshake procedure to ensure that a connection has been established between 2 programs.&lt;/p&gt;
&lt;p&gt;Both ends of the connection must verify that they can send and receive data to and from each other.&lt;/p&gt;
&lt;h4&gt;3 way handshake&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;Client sends a message to the server (in TCP networking, this is called SYN). At this point, the server knows it can receive data.&lt;/li&gt;
&lt;li&gt;Server sends a response to the client based on the client's initial message (SYN_ACK). At this point the client knows it can recieve and send data.&lt;/li&gt;
&lt;li&gt;Client sends a response back to the server based on the server's response (ACK). At this point, the server knows it can receive and send data.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Server-Client Designs&lt;/h3&gt;
&lt;p&gt;There are a number of different ways to implement server/client systems.&lt;/p&gt;
&lt;h4&gt;Single Use Server&lt;/h4&gt;
&lt;p&gt;In this system, the server exits along with the client.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Handshake&lt;/li&gt;
&lt;li&gt;Client: sends data to server.&lt;/li&gt;
&lt;li&gt;Server: gets response, acknowledges the response.&lt;/li&gt;
&lt;li&gt;Client: gets the response, acknowledges the acknowledgement.  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When the client exits, so does the server.&lt;/p&gt;
&lt;h4&gt;Persistent Single Client Server&lt;/h4&gt;
&lt;p&gt;Pay attention to the setup/handshake which will be useful for your lab.&lt;/p&gt;
&lt;p&gt;In this system, the server will communicate with a single client. When the client exits, the server will reset to handle a new client.&lt;/p&gt;
&lt;p&gt;A Well Known Pipe (WKP) is a named pipe that exists only while the server exists, all clients know the name.&lt;/p&gt;
&lt;p&gt;A Private Pipe (PP) is a pipe that exists while the client is running. The client tells the server about this pipe. We will use a named pipe with the name that is the PID of the client.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup
      &lt;ol&gt;
&lt;li&gt;Server creates a WKP and waits for a connection.&lt;/li&gt;
&lt;li&gt;Client creates a private fifo (can use the PID in the name so it is unique.)&lt;/li&gt;
&lt;li&gt;Server waits for a connection to the WKP.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Handshake
      &lt;ol&gt;
&lt;li&gt;Client: sends a message to server. (SYN) We will send the PP name to server. e.g. "120350"&lt;/li&gt;
&lt;li&gt;Server: gets the message, Removes the WKP. Sends an (SYN_ACK) We can send a random int to the PP.&lt;/li&gt;
&lt;li&gt;Client: gets the acknowledgement. Removes the PP. Sends the (ACK) its own acknowledgement to the server (same random integer + 1).&lt;/li&gt;
&lt;li&gt;Server reads and verifies the 2nd acknowledgement. This completes the handshake and both ends know that both send/recieve are working.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Operation
      &lt;ol&gt;
&lt;li&gt;Server and client send data back and forth in a pre-determined pattern (protocol).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Reset
      &lt;ol&gt;
&lt;li&gt;Client exits, server closes any connections to the client.&lt;/li&gt;
&lt;li&gt;Server goes back to setup and recreates a WKP...&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The only way to quit the server is via ctl-c. This is fine, but it will leave the WKP on the filesystem. A cleaner exit would involve creating a signal handler that catches SIGINT and remove the WKP before exiting. Some of you did this on your prior lab.&lt;/p&gt;
&lt;h4&gt;Forking Server&lt;/h4&gt;
&lt;p&gt;Pay attention to the setup/handshake which will be useful for your lab.&lt;/p&gt;
&lt;p&gt;In this system, the server will create subservers for client communication. This will allow for multiple simultanious connections.&lt;/p&gt;
&lt;p&gt;The main server's job is to wait for a connection and create subservers.&lt;/p&gt;
&lt;p&gt;The subserver will handle all communication with the client.&lt;/p&gt;
&lt;p&gt;The client can work exactly the same as the persistent server client.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server: creates WKP and blocks until connection.&lt;/li&gt;
&lt;li&gt;Client: creates PP, connects to WKP, sends PP name, blocks on connection to PP.&lt;/li&gt;
&lt;li&gt;Server: gets connection on WKP, creates subserver.&lt;/li&gt;
&lt;li&gt;Server: Closes &amp;amp; removes WKP from disk.&lt;/li&gt;
&lt;li&gt;Server: Resets back to step 1.&lt;/li&gt;
&lt;li&gt;Subserver: reads PP name from client. (Subserver still has the WKP in memory)&lt;/li&gt;
&lt;li&gt;Subserver: sends secret message to client.(ack1)&lt;/li&gt;
&lt;li&gt;Client: gets subserver secret, removes PP, responds with (ack2). &lt;/li&gt;
&lt;li&gt;Subserver: verfies response from client, completing 3-way handshake.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following table will show the ordered sequence or steps. The steps can happen concurrently EXCEPT for when either server or client is blocked due to opening a pipe or reading.&lt;/p&gt;
&lt;p&gt;This sequence also shows how to design a setup()/handshake() method for the server/client.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;$ ./server                              &lt;/th&gt;&lt;th&gt;$ ./client&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-- server_handshake() --                  &lt;/td&gt;&lt;td&gt;-- client_handshake() --&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-- server_setup() --                      &lt;/td&gt;&lt;td&gt;3  Client making Private pipe&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1 Server making the pipe.                 &lt;/td&gt;&lt;td&gt;3  Client opening WKP [Unblock Server]&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2 Server opening the WKP.[BLOCKS]       &lt;/td&gt;&lt;td&gt;3  Client Writing PP to WKP (matches with step 5)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;4 Server removing the WKP.               &lt;/td&gt;&lt;td&gt;3  Client Opening PP [BLOCKS]&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-- end server_setup() --                  &lt;/td&gt;&lt;td&gt;8 Client Deleting PP&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;5 Server reading SYN (the pid)           &lt;/td&gt;&lt;td&gt;8 Client reading SYN_ACK (matches with step 7)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;6 Server opening the Private Pipe [Unblock client]&lt;/td&gt;&lt;td&gt;8 Client Sending (matches with step 9) ACK&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;7 Server sending SYN_ACK                  &lt;/td&gt;&lt;td&gt;-- end client_handshake() --&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;9 Server reading final ACK                &lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;9 Server received ACK, handshake complete&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;-- end server_handshake() --              &lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;h4&gt;Classwork/HW&lt;/h4&gt;
&lt;p&gt;Clone the lab: &lt;a href="https://classroom.github.com/a/qfzEQx6Z"&gt;https://classroom.github.com/a/qfzEQx6Z&lt;/a&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fill in the function definitions for server_handshake and client_handshake in pipe_networking.c.&lt;/li&gt;
&lt;li&gt;These should do everything needed to establish a 3-way handshake between the client and server.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure you include diagnostic print messages in your functions.&lt;/p&gt;
&lt;p&gt;Note: To remove files, there is a simple function remove(PATH) that will remove the file at PATH.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Make and test&lt;/li&gt;
&lt;li&gt;Your final version should not modify any other files for this assignment.&lt;/li&gt;
&lt;li&gt;You CAN test to see if the handshake worked by writing a byte from client to server and vice versa.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-18n"/><published>2024-12-18T12:00:00+00:00</published></entry><entry><id>2025-01-02n</id><title>2025-01-02</title><updated>2025-01-02T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2025-01-02n"&gt;
&lt;h5&gt;2025-01-02&lt;/h5&gt;
&lt;h3&gt;Upgrade your pipe server!&lt;/h3&gt;
&lt;p&gt;Deadline is Tuesday.&lt;/p&gt;
&lt;p&gt;You should have tested your client and server by sending information back and forth somehow.&lt;/p&gt;
&lt;h3&gt;Basic client/erver functionality:&lt;/h3&gt;
&lt;p&gt;Now we want our &lt;strong&gt;server&lt;/strong&gt; to choose a random int x from 0 to 100 and then send it to the client. Do this once every second (sleep after sending).&lt;/p&gt;
&lt;p&gt;Now we want our &lt;strong&gt;client&lt;/strong&gt; (all clients will be this same behavior) to reapatedly: read the int sent by the server and print it.&lt;/p&gt;
&lt;p&gt;If you ctrl-c the client or the server they should both exit gracefully.&lt;/p&gt;
&lt;h3&gt;Update 1&lt;/h3&gt;
&lt;p&gt;Make a new file for this part: &lt;code&gt;persistant_server.c&lt;/code&gt;™ (copy your working basic_server.c and start with that).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Have the server loop to accept a new clients after the first client disconnects (ctrl-c the client).
    That is many sequential clients, one after another.&lt;/li&gt;
&lt;li&gt;Close the old file descriptors before you end your loop, or you will have an ever-growing file table. (close from_client and to_client)&lt;/li&gt;
&lt;li&gt;You must now also add a sighandler for SIGINT. This will delete the WKP befor ending the server.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Update 2&lt;/h3&gt;
&lt;p&gt;Make a new file for this part: &lt;code&gt;forking_server.c&lt;/code&gt; (copy your working persistant_server.c and start with that.) This server fork to handle multiple concurrent connections. &lt;/p&gt;
&lt;p&gt;The server should only:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create the WKP&lt;/li&gt;
&lt;li&gt;await a connection&lt;/li&gt;
&lt;li&gt;upon connection remove the WKP.&lt;/li&gt;
&lt;li&gt;Fork to create a subserver which will handle the client.&lt;/li&gt;
&lt;li&gt;Go back to step 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A subserver should:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Complete the 3-way handshake.&lt;/li&gt;
&lt;li&gt;Send random ints to the client repeatedly as before.&lt;/li&gt;
&lt;li&gt;Close when the client exits.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice the server steps 1-3 are all contained in the server setup command! Your server sets up the handshake, but your subserver actually does the rest of the handshake.&lt;/p&gt;
&lt;p&gt;You should write a half-handshake function that takes in the from_client fd as an additional argument: &lt;code&gt;server_handshake_half(int *to_client, int from_client)&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;Your server will &lt;code&gt;server_setup()&lt;/code&gt; and your sub-server will finish the job with &lt;code&gt;server_handshake_half()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To provide some communication, after the handshake: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repeatedly Send a random number to the cleint (use sleep(1), client prints the value.)&lt;/li&gt;
&lt;p&gt;You can test by spawning multiple clients and verifying they all can maintain communication with the subservers&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;The end result should be one server that processes client input from any number of clients.&lt;/p&gt;
&lt;p&gt;You can spawn 2 or more clients, each of which should be printing data every second.&lt;/p&gt;
&lt;h3&gt;UPDATE:&lt;/h3&gt;
&lt;p&gt;Required make targets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;compile as usual: &lt;code&gt;make compile&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;to run the forking server: &lt;code&gt;make server&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;to run the client: &lt;code&gt;make client&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will run multiple clients in separate terminals this way.&lt;/p&gt;
&lt;h3&gt;Final Projects&lt;/h3&gt;
&lt;h3&gt;Project requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The final project is to be a significant piece of work that illustrates many of the ideas and techniques studied in the class:
      &lt;ul class="subList"&gt;
&lt;li&gt;Allocating memory&lt;/li&gt;
&lt;li&gt;Working with files&lt;/li&gt;
&lt;li&gt;Finding information about files (stat and such)&lt;/li&gt;
&lt;li&gt;Processes (fork, exec etc.)&lt;/li&gt;
&lt;li&gt;Signals&lt;/li&gt;
&lt;li&gt;Shared memory&lt;/li&gt;
&lt;li&gt;Semaphores&lt;/li&gt;
&lt;li&gt;Pipes (named and unnamed)&lt;/li&gt;
&lt;li&gt;Sockets&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
    Your project should be able to meaningfully use at least 4 of these concepts.
    Don't just toss in a topic if there is no need for it in your project.
    Part of your design process should include considering how to incorporate the class material.
  &lt;/li&gt;
&lt;li&gt;
    You should also focus on creating a program that works well.
    It is better to have fewer features in a project that compiles &amp;amp; runs smoothly
    than to have a lot of features that contain a lot of bugs.
  &lt;/li&gt;
&lt;li&gt;When designing your project, it is best to be able to generate a base working project early and then add features modularly as time goes on.&lt;/li&gt;
&lt;li&gt;You may work with one or two partners, all partners should be in the same section.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Project Ideas/Suggestions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
      If you are having difficulty coming up with a project idea, look back at some of the bigger assignments
      we-ve done over the semester and think about how you can add to them. These are just some ideas to get
      you going, please do not consider theses as superior to any other ideas you might have.
      &lt;ul class="subList"&gt;
&lt;li&gt;
          The music library could become much more useful by incoperating a music player (fork/exec),
          saving the library data (maybe even as a binary file), interacting with actual music files etc.
        &lt;/li&gt;
&lt;li&gt;The data file/csv assignment could become a more useful data organizing program.&lt;/li&gt;
&lt;li&gt;Semaphone could be tunred into a pipe/socket based live game.&lt;/li&gt;
&lt;li&gt;With pipes/sockets, you could write simplified versions of different kinds of servers.&lt;/li&gt;
&lt;li&gt;With pipes/sockets and semaphores you could write a SIMPLE database program.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
      If you are going to write a multi-program system with sockets/pipes, start simply.
      For example, if you-re making a 2 player game, then just have the programs connect
      directly do each other, instead of wirting a separate server to connnect them.
    &lt;/li&gt;
&lt;li&gt;
      As stated earlier, it's better to &lt;strong&gt;start small and grow&lt;/strong&gt; than start large and have to cut things out (or live with bugs).
    &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;URGENT NOTE:&lt;/h3&gt;
&lt;p&gt;we have not covered networking and we are about 1 week short to cover the material.&lt;/p&gt;
&lt;p&gt;I will post notes, and sample code, but do NOT suggest networking except for groups that want to learn more on their own.&lt;/p&gt;
&lt;h3&gt;Prior Projects&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Distributed computing tool&lt;/li&gt;
&lt;li&gt;file editor (text/spreadsheet)&lt;/li&gt;
&lt;li&gt;Database program&lt;/li&gt;
&lt;li&gt;Client server program
    &lt;ul class="subList"&gt;
&lt;li&gt;chat&lt;/li&gt;
&lt;li&gt;simple game many players concurrently&lt;/li&gt;
&lt;li&gt;2-player game tournament&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2025-01-02n"/><published>2025-01-02T12:00:00+00:00</published></entry><entry><id>2024-12-18n</id><title>2024-12-18</title><updated>2024-12-18T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-18n"&gt;
&lt;h5&gt;2024-12-18&lt;/h5&gt;
&lt;p&gt;Motivation: Wouldn't it be nice if your server could accept clients from different computers? You could then distribute a client to your classmates and have them all use it.&lt;/p&gt;
&lt;h2 id="sockets"&gt;Sockets
    &lt;ul&gt;
&lt;li&gt;A connection between 2 programs using network protocols.
        &lt;ul&gt;
&lt;li&gt;This is usually between 2 computers, but does not have to be.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A socket corresponds to an IP (internet protocol) Address / Port pair.&lt;/li&gt;
&lt;li&gt;To use a socket:
        &lt;ol&gt;
&lt;li&gt;create the socket: &lt;code&gt;socket&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;bind it to an address and port: &lt;code&gt;bind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;listen &amp;amp; accept/initiate a connection: &lt;code&gt;listen&lt;/code&gt; &lt;code&gt;accept&lt;/code&gt;, &lt;code&gt;connect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;send/receive data
            &lt;ul&gt;
&lt;li&gt;Functions vary depeding on type of socket&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Most functions and structres in &lt;code&gt;sys/socket.h&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;socket( domain, type, protocol )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Creates a socket, opens it like a file, returning a socket descriptor (int that works like a file descriptor)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domain&lt;/code&gt;: type of address
                    &lt;ul&gt;
&lt;li&gt;&lt;code&gt;AF_INET&lt;/code&gt; or &lt;code&gt;AF_INET6&lt;/code&gt; or &lt;code&gt;AF_UNSPEC&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SOCK_STREAM&lt;/code&gt; or &lt;code&gt;SOCK_DGRAM&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;protocol&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Combination of domain and type settings&lt;/li&gt;
&lt;li&gt;If set to 0 the OS will set to correct protocol (TCP or UDP)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;example: &lt;code&gt;int sd = socket(AF_INET, SOCK_STREAM, 0);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="socket-protocols"&gt;Socket Protocols&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stream Sockets (TCP)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Reliable 2 way communication.&lt;/li&gt;
&lt;li&gt;Must be connected on both ends.
            &lt;ul&gt;
&lt;li&gt;3 way handshake&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Data is received in the order it is sent.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Datagram Sockets (UDP)&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;“Connectionless”: an established connection is not required.&lt;/li&gt;
&lt;li&gt;Data sent may be received out of order (or not at all).&lt;/li&gt;
&lt;li&gt;Cannot use the usual &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; function calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="sockets-in-c"&gt;Sockets in C&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Most functions and structres in &lt;code&gt;sys/socket.h&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;socket( domain, type, protocol )&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Creates a socket, opens it like a file, returning a socket descriptor (int that works like a file descriptor)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domain&lt;/code&gt;: type of address
            &lt;ul&gt;
&lt;li&gt;&lt;code&gt;AF_INET&lt;/code&gt; or &lt;code&gt;AF_INET6&lt;/code&gt; or &lt;code&gt;AF_UNSPEC&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SOCK_STREAM&lt;/code&gt; or &lt;code&gt;SOCK_DGRAM&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;protocol&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Combination of domain and type settings&lt;/li&gt;
&lt;li&gt;If set to 0 the OS will set to correct protocol (TCP or UDP)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;example: &lt;code&gt;int sd = socket(AF_INET, SOCK_STREAM, 0);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;getaddrinfo&lt;/code&gt; &lt;code&gt;&amp;lt;sys/types.h&amp;gt; &amp;lt;sys/socket.h&amp;gt; &amp;lt;netdb.h&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;System library calls use a &lt;code&gt;struct addrinfo&lt;/code&gt; to represent network addresses (containing information like IP address, port, protocol…)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Will lookup information about the desired network address and get one or more matching &lt;code&gt;struct addrinfo&lt;/code&gt; entries as a linked list.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;getaddrinfo(node, service, hints, results)&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;node&lt;/code&gt;: String containing an IP address or hostname to lookup
          &lt;ul&gt;
&lt;li&gt;If &lt;code&gt;NULL&lt;/code&gt;, use the local machine's IP addresses (all of them).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;service&lt;/code&gt;: String with a port number or service name (if the service is in &lt;code&gt;/etc/services&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hints&lt;/code&gt;: Pointer to a &lt;code&gt;struct addrinfo&lt;/code&gt; used to provide settings for the lookup.
          &lt;ul&gt;
&lt;li&gt;Think of this as a filter for the lookup that &lt;code&gt;getaddrinfo&lt;/code&gt; performs. For example, if you only want to get an IPv4 address, you can set &lt;code&gt;hints&lt;/code&gt; to be an IPv4 address.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;results&lt;/code&gt;: Pointer to a linked list of &lt;code&gt;struct addrinfo&lt;/code&gt; containing entries for each matching address.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getaddrinfo&lt;/code&gt; will allocate memory for these structs. Since &lt;code&gt;results&lt;/code&gt; will be a linked list of unknown size, you should use &lt;code&gt;freeaddrinfo&lt;/code&gt; to release the entire linked list when you are done.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bind( socket descriptor, address, address_length)&lt;/code&gt; (server only)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Binds the socket to an address and port. This allows a server has to have a set public* adrress and port.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Returns 0 (success) or -1 (failure)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;socket descriptor&lt;/code&gt;: return value of socket&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;address&lt;/code&gt;: pointer to a &lt;code&gt;struct sockaddr&lt;/code&gt; representing the address.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;address_length&lt;/code&gt;: Size of the address, in bytes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;address&lt;/code&gt; and &lt;code&gt;address_length&lt;/code&gt; can be retrieved from &lt;code&gt;getaddrinfo&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="using-getaddrinfo-socket--bind-on-a-server"&gt;Using getaddrinfo, socket &amp;amp; bind on a server&lt;/h4&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;//use getaddrinfo
  struct addrinfo * hints, * results;//results is allocated in getaddrinfo
  hints = calloc(1,sizeof(struct addrinfo));
  hints-&amp;gt;ai_family = AF_INET;
  hints-&amp;gt;ai_socktype = SOCK_STREAM; //TCP socket
  hints-&amp;gt;ai_flags = AI_PASSIVE; //only needed on server
  getaddrinfo(NULL, "9845", hints, &amp;amp;results);  //Server sets node to NULL

  //create socket
  int sd = socket(results-&amp;gt;ai_family, results-&amp;gt;ai_socktype, results-&amp;gt;ai_protocol);

  bind(sd, results-&amp;gt;ai_addr, results-&amp;gt;ai_addrlen);

  //DO STUFF

  free(hints)
  freeaddrinfo(results);
  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;listen (socket_descriptor, backlog)&lt;/code&gt; (server only)
      &lt;ul&gt;
&lt;li&gt;Set a socket to passively await a connection.&lt;/li&gt;
&lt;li&gt;Needed for stream sockets.&lt;/li&gt;
&lt;li&gt;Does not block.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;socket descriptor&lt;/code&gt;: return value of &lt;code&gt;socket&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;backlog&lt;/code&gt;: Number of connections that can be queued up.
          &lt;ul&gt;
&lt;li&gt;Depending on the protocol, this may not do much.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;accept&lt;/code&gt; (server only)
      &lt;ul&gt;
&lt;li&gt;Accept the next client in the queue of a socket in the listen state.&lt;/li&gt;
&lt;li&gt;Used for stream sockets.&lt;/li&gt;
&lt;li&gt;Performs the server side of the 3 way handshake&lt;/li&gt;
&lt;li&gt;Creates a new socket for communicating with the client, the listening socket is not modified.&lt;/li&gt;
&lt;li&gt;Returns a descriptor to the new socket&lt;/li&gt;
&lt;li&gt;Blocks until a connection attempt is made&lt;/li&gt;
&lt;li&gt;&lt;code&gt;accept(socket_descriptor, address, address_length)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;socket descriptor&lt;/code&gt;: descriptor for the listening socket &lt;code&gt;address&lt;/code&gt;: Pointer to a &lt;code&gt;struct sockaddr_storage&lt;/code&gt; that will contain information about the new socket after accept succeeds.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;address length&lt;/code&gt;: Pointer to a variable that will contain the size of the new socket address after accept succeeds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="using-listen-and-accept-for-servers"&gt;Using listen and accept for servers&lt;/h3&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;//use getaddrinfo (not shown)
  //create socket
  int sd = socket(results-&amp;gt;ai_family, results-&amp;gt;ai_socktype, results-&amp;gt;ai_protocol);
  //use bind
  bind(sd, results-&amp;gt;ai_addr, results-&amp;gt;ai_addrlen);
  listen(sd, 10);
  int client_socket;
  socklen_t sock_size;
  struct sockaddr_storage client_address;
  sock_size = sizeof(client_address);
  client_socket = accept(sd,(struct sockaddr *)&amp;amp;client_address, &amp;amp;sock_size);
  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id="using-connect-for-clients"&gt;Using connect for clients&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;connect&lt;/code&gt; (client only) &lt;code&gt;&amp;lt;sys/socket.h&amp;gt; &amp;lt;sys/types.h&amp;gt;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Connect to a socket currently in the listening state.&lt;/li&gt;
&lt;li&gt;Used for stream sockets.&lt;/li&gt;
&lt;li&gt;Performs the client side of the 3 way handshake&lt;/li&gt;
&lt;li&gt;Binds the socket to an address and port&lt;/li&gt;
&lt;li&gt;Blocks until a connection is made (or fails)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;connect(socket descriptor, address, address length)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;socket descriptor&lt;/code&gt;: descriptor for the socket&lt;/li&gt;
&lt;li&gt;&lt;code&gt;address&lt;/code&gt;: Pointer to a &lt;code&gt;struct sockaddr&lt;/code&gt; representing the address.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;address length&lt;/code&gt;: Size of the address, in bytes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;address&lt;/code&gt; and &lt;code&gt;address length&lt;/code&gt; can be retrieved from &lt;code&gt;getaddrinfo()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Note that the arguments mirror those of &lt;code&gt;bind()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;//use getaddrinfo (not shown)
  //create socket
  int sd = socket(results-&amp;gt;ai_family, results-&amp;gt;ai_socktype, results-&amp;gt;ai_protocol);

  connect(sd, results-&amp;gt;ai_addr, results-&amp;gt;ai_addrlen);
  &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3&gt;Beej's Guide to network programming using internet sockets&lt;/h3&gt;
&lt;a href="https://beej.us/guide/bgnet/html/"&gt;https://beej.us/guide/bgnet/html/&lt;/a&gt;
&lt;/h2&gt;&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-18n"/><published>2024-12-18T12:00:00+00:00</published></entry><entry><id>2024-12-19n</id><title>2024-12-19</title><updated>2024-12-19T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-19n"&gt;
&lt;h4&gt;2024-12-19&lt;/h4&gt;
&lt;h2&gt;Networking.&lt;/h2&gt;
&lt;h3 id="layer-models-of-networking"&gt;Layer Models of Networking&lt;/h3&gt;
&lt;p&gt;  Due to the complexity of network communications, the topic is often conceptualized into distinct layers so people can work on specific components rather than everything at once.&lt;/p&gt;
&lt;p&gt;  The bottom layer is the most concrete, with each subsequent layer becoming more abstract (relying less on the physical connections and more on code).&lt;/p&gt;
&lt;p&gt;  There are various competing models, including the OSI (Open Systems Interconnections) and TCP/IP Models.&lt;/p&gt;
&lt;h3&gt;  TCP/IP Model Layers&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Application - (process)&lt;/li&gt;
&lt;li&gt;Transport - (OS)&lt;/li&gt;
&lt;li&gt;Network - (OS) &lt;/li&gt;
&lt;li&gt;Link - (Physical) &lt;/li&gt;
&lt;/ol&gt;
&lt;hr/&gt;
&lt;h3 id="link-layer"&gt;Link Layer&lt;/h3&gt;
&lt;p&gt;  Point-to-point transmission between devices on the same (local) network.&lt;/p&gt;
&lt;p&gt;  Combines physically connecting computers with basic addressing and transmission protocols.&lt;/p&gt;
&lt;p&gt;  Physical connection&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How to transmit bits between two computers.&lt;/li&gt;
&lt;li&gt;Electrons, photons, radio waves…&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;h4 id="link-layer-a-brief-history-of-physical-connections"&gt;Link Layer: A brief history of physical connections&lt;/h4&gt;
&lt;p&gt; &lt;strong&gt;Thicknet&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;  A single coaxial cable runs along the network.&lt;/p&gt;
&lt;p&gt;  “Vampire taps” cut into the cable and connect to a computer.&lt;/p&gt;
&lt;p&gt; &lt;img alt="vtap0" src="img/l31_vtap0.png"/&gt; &lt;img alt="vtap1" src="img/l31_vtap1.png"/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt; &lt;strong&gt;Thinnet&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;  A single coaxial cable runs along the network.&lt;/p&gt;
&lt;p&gt;  T-Connectors connect computers to the main cable.&lt;/p&gt;
&lt;p&gt; &lt;img alt="tcon" src="img/l31_tconnect.png"/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt; &lt;strong&gt;Thin/Thicknet network topology&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt; &lt;img alt="topology" src="img/l31_thick-thin.png"/&gt;&lt;/p&gt;
&lt;p&gt;  Each new computer degrades the network
    collisions could cause issues&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt; &lt;strong&gt;Token Ring&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;  Each computer is connected in a ring to each other.&lt;/p&gt;
&lt;p&gt;  Only one computer has command of network resources at a time. This is called "having the token”.&lt;/p&gt;
&lt;p&gt;  The network sends a "token" throughout the ring, which contains the identity of the computer allowed to use the network. All other computers must wait to send data over the network.&lt;/p&gt;
&lt;p&gt; &lt;img alt="token" src="img/l31_token.png"/&gt;&lt;/p&gt;
&lt;p&gt;  Each computer provides its own power and keeps single strength constant.&lt;/p&gt;
&lt;p&gt;  No possibility of collisions&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt; &lt;strong&gt;Ethernet&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;  Multiple computers connect to a single hub or switch.&lt;/p&gt;
&lt;p&gt;  Hub: Broadcasts the data to all the computers&lt;/p&gt;
&lt;p&gt;  Switch: Sends data to a specific computer&lt;/p&gt;
&lt;p&gt; &lt;img alt="ethernet" src="img/l31_ethernet.png"/&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;!--
  &lt;h4 id="link-layer-the-softer-side"&gt;Link Layer: The Softer Side&lt;/h4&gt;
  &lt;p&gt;  In order for data to be sent between computers:&lt;/p&gt;
  &lt;ul&gt;
  &lt;li&gt;Each computer needs a unique address (MAC Address).&lt;/li&gt;
  &lt;li&gt;The data needs to be sent in a standardized format (Frames).&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;MAC (Media Access Control) Address&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;6 - Byte Hex address: &lt;code&gt;2a:00:1e:b9:70:f6&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;MAC addresses only need to be unique on the same local network.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr&gt;

  &lt;h4 id="link-layer-the-softer-side"&gt;Link Layer: The Softer Side&lt;/h4&gt;
  &lt;p&gt;  &lt;strong&gt;Ethernet Frames&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;  Each frame has the following format:&lt;/p&gt;
  &lt;p&gt;  &lt;code&gt;prefix&lt;/code&gt; &lt;code&gt;dest&lt;/code&gt; &lt;code&gt;source&lt;/code&gt; &lt;code&gt;type&lt;/code&gt; &lt;code&gt;data&lt;/code&gt; &lt;code&gt;checksum&lt;/code&gt;&lt;/p&gt;
    &lt;hr&gt;

  &lt;p&gt;  &lt;code&gt;prefix&lt;/code&gt; 8B: &lt;code&gt;10101010&lt;/code&gt; x7 + &lt;code&gt;10101011&lt;/code&gt;&lt;/p&gt;
  &lt;p&gt;  &lt;code&gt;dest&lt;/code&gt; &amp;amp; &lt;code&gt;source&lt;/code&gt; 6B each: MAC addresses&lt;/p&gt;
  &lt;p&gt;  &lt;code&gt;type&lt;/code&gt; 2B&lt;/p&gt;
  &lt;p&gt;  &lt;code&gt;data&lt;/code&gt;: MTU (Maximum Transmission Unit) of 1500B&lt;/p&gt;
  &lt;p&gt;  &lt;code&gt;checksum&lt;/code&gt; 4B: ensures data integrity&lt;/p&gt;

    &lt;thead&gt;
    &lt;tr&gt;
    &lt;th&gt;prefix&lt;/th&gt;
    &lt;th&gt;dest&lt;/th&gt;
    &lt;th&gt;source&lt;/th&gt;
    &lt;th&gt;type&lt;/th&gt;
    &lt;th&gt;data&lt;/th&gt;
    &lt;th&gt;checksum&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
    &lt;td&gt;  8B&lt;/td&gt;
    &lt;td&gt;6B&lt;/td&gt;
    &lt;td&gt;6B&lt;/td&gt;
    &lt;td&gt;2B&lt;/td&gt;
    &lt;td&gt;4B&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt; --&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-19n"/><published>2024-12-19T12:00:00+00:00</published></entry><entry><id>2024-12-20n</id><title>2024-12-20</title><updated>2024-12-20T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-20n"&gt;
&lt;p&gt;&lt;img class="center" height="400" src="img/l32_breakin.png"/&gt;&lt;/p&gt;
&lt;h4 id="link-layer-the-softer-side"&gt;Link Layer: The Softer Side&lt;/h4&gt;
&lt;p&gt;In order for data to be sent between computers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each computer needs a unique address (MAC Address).&lt;/li&gt;
&lt;li&gt;The data needs to be sent in a standardized format (Frames).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;MAC (Media Access Control) Address&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;6 - Byte Hex address: &lt;code&gt;2a:00:1e:b9:70:f6&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MAC addresses only need to be unique on the same local network.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="link-layer-the-softer-side"&gt;Link Layer: The Softer Side&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Ethernet Frames&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Each frame has the following format:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; &lt;code&gt;dest&lt;/code&gt; &lt;code&gt;source&lt;/code&gt; &lt;code&gt;type&lt;/code&gt; &lt;code&gt;data&lt;/code&gt; &lt;code&gt;checksum&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; 8B: &lt;code&gt;10101010&lt;/code&gt; x7 + &lt;code&gt;10101011&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dest&lt;/code&gt; &amp;amp; &lt;code&gt;source&lt;/code&gt; 6B each: MAC addresses&lt;/p&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; 2B&lt;/p&gt;
&lt;p&gt;&lt;code&gt;data&lt;/code&gt;: MTU (Maximum Transmission Unit) of 1500B&lt;/p&gt;
&lt;p&gt;&lt;code&gt;checksum&lt;/code&gt; 4B: ensures data integrity&lt;/p&gt;
&lt;table style="border: solid 1px black"&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;prefix&lt;/th&gt;&lt;th&gt;dest&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;prefix&lt;/th&gt;
&lt;th&gt;dest&lt;/th&gt;
&lt;th&gt;source&lt;/th&gt;
&lt;th&gt;type&lt;/th&gt;
&lt;th&gt;data&lt;/th&gt;
&lt;th&gt;checksum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;6B&lt;/td&gt;
&lt;td&gt;6B&lt;/td&gt;
&lt;td&gt;2B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;4B&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="internet-layer"&gt;Internet Layer&lt;/h4&gt;
&lt;p&gt;Transmission of data between two separate networks.&lt;/p&gt;
&lt;p&gt;Major features of this layer are addressing and routing.&lt;/p&gt;
&lt;p&gt;Routers are physical devices used to connect different local networks.&lt;/p&gt;
&lt;p&gt;Internet layer traffic ignores the specifics of link layer traffic.&lt;/p&gt;
&lt;p&gt;Inernet Protocol (IP) covers the standards for addressing and packet format.&lt;/p&gt;
&lt;p&gt;&lt;img class="center" src="img/l32_internet.png" width="600"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Routing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Routers break IPv4 packets (more later) into fragments.&lt;/p&gt;
&lt;p&gt;When a router receives a packet, it has 2 options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Send that packet to the attached local network.&lt;/li&gt;
&lt;li&gt;Forward that packet to a different router.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Routers have address tables that identify all connected networks/devices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP Packets&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;IPv4 Packet format:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;header&lt;/code&gt; &lt;code&gt;source&lt;/code&gt; &lt;code&gt;destination&lt;/code&gt; &lt;code&gt;data&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;code&gt;header&lt;/code&gt; 12B: Packet metadata&lt;/p&gt;
&lt;p&gt;&lt;code&gt;source&lt;/code&gt; and &lt;code&gt;destination&lt;/code&gt; 4B each: IP Address&lt;/p&gt;
&lt;p&gt;&lt;code&gt;data&lt;/code&gt;: MTU is 65,535 Bytes&lt;/p&gt;
&lt;p&gt;IPv6 uses 8 Byte addresses
  IPv6 allows for jumbograms, with an MTU of 4GB&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv4 packet header&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; &lt;code&gt;size&lt;/code&gt; &lt;code&gt;fragment info&lt;/code&gt; &lt;code&gt;ttl&lt;/code&gt; &lt;code&gt;protocol&lt;/code&gt; &lt;code&gt;header checksum&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; 2B: IPv4 / v6, length of header&lt;/p&gt;
&lt;p&gt;&lt;code&gt;size&lt;/code&gt; 2B: Total size of the packet&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fragment info&lt;/code&gt; 4B: full payloads may be broken into multiple fragments. Each packet will count the number of fragments and its individual fragment number.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ttl&lt;/code&gt; (time-to-live) 1B: Maximum number of hops a packet can make before reaching its destination.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;protocol&lt;/code&gt; 1B: TCP / UDP (this is transport layer information)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;header checksum&lt;/code&gt; 2B: only a checksum of the header, not the full packet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP Addressess&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Every device connected to the internet has an I.P. (Internet Protocol) address.&lt;/p&gt;
&lt;p&gt;They might look like this: &lt;code&gt;149.89.150.100&lt;/code&gt;  (IPv4)&lt;/p&gt;
&lt;p&gt;or this: &lt;code&gt;0:0:0:0:0:ffff:9559:9664&lt;/code&gt; (IPv6)&lt;/p&gt;
&lt;p&gt;IP addresses are only needed when connected.&lt;/p&gt;
&lt;p&gt;For the most part, organizations own blocks of IP addresses, and give them to their users as needed.&lt;/p&gt;
&lt;p&gt;Because IP addresses are released in blocks, internet traffic can be routed in an efficient manner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv4 / IPv6 differences&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Address space: 2^32 / 2^128&lt;/p&gt;
&lt;p&gt;Packet format: In addition to address size change, IPv6 packet headers have less information. They do not include a checksum or fragment information.&lt;/p&gt;
&lt;p&gt;MTU:  IPv6 can allot for an MTU of 2^32 (these are called jumbograms)&lt;/p&gt;
&lt;p&gt;IPv6 puts more work onto Link layer devices and individual hosts (computers)&lt;/p&gt;
&lt;p&gt;IPv6 does not fragment packets at all, relying on other devices to potentially take advantage of jumbograms&lt;/p&gt;
&lt;p&gt;IPv6 has no checksum, assuming Link layer devices and hosts will check for data integrity if needed.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-20n"/><published>2024-12-20T12:00:00+00:00</published></entry><entry><id>2024-12-21n</id><title>2024-12-21</title><updated>2024-12-21T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-21n"&gt;
&lt;p&gt;&lt;img src="img/l33_3d.png"/&gt;&lt;/p&gt;
&lt;pfast&gt;&lt;strong&gt;Routing&lt;/strong&gt;
&lt;p&gt;Routers break IPv4 packets (more later) into fragments.&lt;/p&gt;
&lt;p&gt;When a router receives a packet, it has 2 options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Send that packet to the attached local network.&lt;/li&gt;
&lt;li&gt;Forward that packet to a different router.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Routers have address tables that identify all connected networks/devices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP Packets&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;IPv4 Packet format:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;header&lt;/code&gt; &lt;code&gt;source&lt;/code&gt; &lt;code&gt;destination&lt;/code&gt; &lt;code&gt;data&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;--&lt;/p&gt;
&lt;p&gt;&lt;code&gt;header&lt;/code&gt; 12B: Packet metadata&lt;/p&gt;
&lt;p&gt;&lt;code&gt;source&lt;/code&gt; and &lt;code&gt;destination&lt;/code&gt; 4B each: IP Address&lt;/p&gt;
&lt;p&gt;&lt;code&gt;data&lt;/code&gt;: MTU is 65,535 Bytes&lt;/p&gt;
&lt;p&gt;IPv6 uses 8 Byte addresses
  IPv6 allows for jumbograms, with an MTU of 4GB&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv4 packet header&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; &lt;code&gt;size&lt;/code&gt; &lt;code&gt;fragment info&lt;/code&gt; &lt;code&gt;ttl&lt;/code&gt; &lt;code&gt;protocol&lt;/code&gt; &lt;code&gt;header checksum&lt;/code&gt;&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;--&lt;/p&gt;
&lt;p&gt;&lt;code&gt;type&lt;/code&gt; 2B: IPv4 / v6, length of header&lt;/p&gt;
&lt;p&gt;&lt;code&gt;size&lt;/code&gt; 2B: Total size of the packet&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fragment info&lt;/code&gt; 4B: full payloads may be broken into multiple fragments. Each packet will count the number of fragments and its individual fragment number.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ttl&lt;/code&gt; (time-to-live) 1B: Maximum number of hops a packet can make before reaching its destination.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;protocol&lt;/code&gt; 1B: TCP / UDP (this is transport layer information)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;header checksum&lt;/code&gt; 2B: only a checksum of the header, not the full packet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IP Addressess&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Every device connected to the internet has an I.P. (Internet Protocol) address.&lt;/p&gt;
&lt;p&gt;They might look like this: &lt;code&gt;149.89.150.100&lt;/code&gt;  (IPv4)&lt;/p&gt;
&lt;p&gt;or this: &lt;code&gt;0:0:0:0:0:ffff:9559:9664&lt;/code&gt; (IPv6)&lt;/p&gt;
&lt;p&gt;IP addresses are only needed when connected.&lt;/p&gt;
&lt;p&gt;For the most part, organizations own blocks of IP addresses, and give them to their users as needed.&lt;/p&gt;
&lt;p&gt;Because IP addresses are released in blocks, internet traffic can be routed in an efficient manner.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IPv4 / IPv6 differences&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Address space: 2^32 / 2^128&lt;/p&gt;
&lt;p&gt;Packet format: In addition to address size change, IPv6 packet headers have less information. They do not include a checksum or fragment information.&lt;/p&gt;
&lt;p&gt;MTU:  IPv6 can allot for an MTU of 2^32 (these are called jumbograms)&lt;/p&gt;
&lt;p&gt;IPv6 puts more work onto Link layer devices and individual hosts (computers)&lt;/p&gt;
&lt;p&gt;IPv6 does not fragment packets at all, relying on other devices to potentially take advantage of jumbograms&lt;/p&gt;
&lt;p&gt;IPv6 has no checksum, assuming Link layer devices and hosts will check for data integrity if needed.&lt;/p&gt;
&lt;h4 id="transport-layer"&gt;Transport Layer&lt;/h4&gt;
&lt;p&gt;Computer to computer connection over a network.&lt;/p&gt;
&lt;p&gt;Unconcerned with the individual hops of internet layer traffic.&lt;/p&gt;
&lt;p&gt;In a program, a &lt;em&gt;socket&lt;/em&gt; is the data type associated with a transport layer connection.&lt;/p&gt;
&lt;p&gt;Network ports are used at the transport layer that allow a computer to have multiple open network connections at the same time.&lt;/p&gt;
&lt;p&gt;TCP and UDP are transport layer protocols.&lt;/p&gt;
&lt;h4 id="network-ports"&gt;Network Ports&lt;/h4&gt;
&lt;p&gt;A network port is a computer specific sub-address that allows computers (that have a single IP address) to have multiple open netowkr connections.&lt;/p&gt;
&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers"&gt;65,536 ports&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ports &amp;lt; 1024 are well known, reserved ports used for specific services.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For example, an ssh server will have an open socket on port 22 (this is similar to a WKP). When a child process is created to communicate with a client, that process uses a different port, leaving 22 open for the listening server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regulated by the Internet Assigned Numbers Authority (IANA)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transmission Control Protocol (TCP)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reliable connection, guarantees delivery of data.&lt;/li&gt;
&lt;li&gt;Data is considered a continuous stream that arrives in the order it is sent (which may not be true in the lower layers)&lt;/li&gt;
&lt;li&gt;Connections are established using a 3-way handshake&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;User Datagram Protocol (UDP)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not require an explicit connection, no gaurantee of data delivery (at the transport layer).&lt;/li&gt;
&lt;li&gt;Data is sent as discrete datagrams with a set size (as opposed to a continuous stream).&lt;/li&gt;
&lt;li&gt;Datagrams may be dropped, or received out of order.&lt;/li&gt;
&lt;li&gt;UDP connections are faster because they do not need to be reassembled at the other end.&lt;/li&gt;
&lt;li&gt;Error checking can still be handled at an upper level.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="data-encapsulation"&gt;Data Encapsulation&lt;/h4&gt;
&lt;p&gt;As data crosses from an upper layer to a lower one, layer-specific metadata is added to help aid transmission.&lt;/p&gt;
&lt;p&gt;Application —&amp;gt; Transport&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UDP or TCP headers are added, including network port information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Transport —&amp;gt; Internet&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data (including Transport headers) is packaged into IP Packets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Internet —&amp;gt; Link&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Packets (including IP and Transport headers) are packaged into Ethernet Frames.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Data decapsulation
  When data crosses back up a layer, the packaging for the lower layer is removed.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/pfast&gt;&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-21n"/><published>2024-12-21T12:00:00+00:00</published></entry><entry><id>2024-12-22n</id><title>2024-12-22</title><updated>2024-12-22T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2024-12-22n"&gt;
&lt;h5&gt;2024-12-22&lt;/h5&gt;
&lt;h3 id="systems-networking-iv-a-new-hope"&gt;Systems: Networking IV: A New Hope&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Star Wars" src="img/l34_starwars.jpg" width="400px"/&gt; &lt;/p&gt;
&lt;h4 id="transport-layer"&gt;Transport Layer&lt;/h4&gt;
&lt;p&gt;Computer to computer connection over a network.&lt;/p&gt;
&lt;p&gt;Unconcerned with the individual hops of internet layer traffic.&lt;/p&gt;
&lt;p&gt;In a program, a &lt;em&gt;socket&lt;/em&gt; is the data type associated with a transport layer connection.&lt;/p&gt;
&lt;p&gt;Network ports are used at the transport layer that allow a computer to have multiple open network connections at the same time.&lt;/p&gt;
&lt;p&gt;TCP and UDP are transport layer protocols.&lt;/p&gt;
&lt;h4 id="network-ports"&gt;Network Ports&lt;/h4&gt;
&lt;p&gt;A network port is a computer specific sub-address that allows computers (that have a single IP address) to have multiple open netowkr connections.&lt;/p&gt;
&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers"&gt;65,536 ports&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ports &amp;lt; 1024 are well known, reserved ports used for specific services.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For example, an ssh server will have an open socket on port 22 (this is similar to a WKP). When a child process is created to communicate with a client, that process uses a different port, leaving 22 open for the listening server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regulated by the Internet Assigned Numbers Authority (IANA)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transmission Control Protocol (TCP)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reliable connection, guarantees delivery of data.&lt;/li&gt;
&lt;li&gt;Data is considered a continuous stream that arrives in the order it is sent (which may not be true in the lower layers)&lt;/li&gt;
&lt;li&gt;Connections are established using a 3-way handshake&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;User Datagram Protocol (UDP)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Does not require an explicit connection, no gaurantee of data delivery (at the transport layer).&lt;/li&gt;
&lt;li&gt;Data is sent as discrete datagrams with a set size (as opposed to a continuous stream).&lt;/li&gt;
&lt;li&gt;Datagrams may be dropped, or received out of order.&lt;/li&gt;
&lt;li&gt;UDP connections are faster because they do not need to be reassembled at the other end.&lt;/li&gt;
&lt;li&gt;Error checking can still be handled at an upper level.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="application-layer"&gt;Application Layer&lt;/h4&gt;
&lt;p&gt;Once a socket (transport layer connection) has been established, the data transmitted between computers is at the application layer.&lt;/p&gt;
&lt;p&gt;Think about the data/payload section of an IP packet, anything inside that is application layer inforation.&lt;/p&gt;
&lt;p&gt;Data at this layer will be packaged depending on the program or protcol being used.&lt;/p&gt;
&lt;p&gt;Common application layer protocols: http, ftp, ssh, dns...&lt;/p&gt;
&lt;p&gt;Many application layer applications have registered ports at the transport layer.&lt;/p&gt;
&lt;h4 id="data-encapsulation"&gt;Data Encapsulation&lt;/h4&gt;
&lt;p&gt;As data crosses from an upper layer to a lower one, layer-specific metadata is added to help aid transmission.&lt;/p&gt;
&lt;p&gt;Application —&amp;gt; Transport&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UDP or TCP headers are added, including network port information&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Transport —&amp;gt; Internet&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Data (including Transport headers) is packaged into IP Packets.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Internet —&amp;gt; Link&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Packets (including IP and Transport headers) are packaged into Ethernet Frames.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2024-12-22n"/><published>2024-12-22T12:00:00+00:00</published></entry><entry><id>2025-01-03h</id><title>2025-01-03</title><updated>2025-01-03T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2025-01-03h"&gt;
&lt;h5&gt;2025-01-03&lt;/h5&gt;
&lt;h2&gt;Final Projects!&lt;/h2&gt;
&lt;p&gt;Your final project calendar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jan 2: Choose 0-2 partners and a topic. If you have 2 partners, your project should be larger in scope.&lt;/li&gt;
&lt;li&gt;Jan 3: Create a proposal with your project outline and how you intend to create it.&lt;/li&gt;
&lt;li&gt;Jan 6: You will be given your repos. Start work on your project.&lt;/li&gt;
&lt;li&gt;Jan 21: (Tues) all projects due. Final commits 8am including links to your presentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The deadline is a cutoff date: &lt;strong&gt;students will lose write access to their repository after the deadline&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;Any group-issues must be communicated to me ASAP. If a group member gets sick, or lazy, you must tell me what is going on.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;PROPOSAL.md&lt;/code&gt; - due Monday in class.(You must place it into a repo during class.)&lt;/h3&gt;
&lt;p&gt;This should contain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A list of Group Members&lt;/li&gt;
&lt;li&gt;A statement of the problem you are solving and/or a high level description of the project.&lt;/li&gt;
&lt;li&gt;A description as to how the project will be used (describe the user interface).&lt;/li&gt;
&lt;li&gt; A description of your technical design. This should include:&lt;/li&gt;
&lt;ul class="subList"&gt;
&lt;li&gt;How you will be using the topics covered in class in the project.&lt;/li&gt;
&lt;li&gt;How you are breaking down the project and who is responsible for which parts.&lt;/li&gt;
&lt;li&gt;What algorithms and / data structures you will be using and how they will be used..&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;A timeline with expected completion dates of various milestones of the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Documentation Specifications&lt;/h3&gt;
&lt;p&gt;Documentation &lt;strong&gt;30% of your grade.&lt;/strong&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;PROPOSAL.md&lt;/code&gt; as described above.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;README.md&lt;/code&gt;
&lt;p&gt;It should have the following information:
          &lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Project Name&lt;/li&gt;
&lt;li&gt;Team name&lt;/li&gt;
&lt;li&gt;Team Members&lt;/li&gt;
&lt;li&gt;Broad description of project&lt;/li&gt;
&lt;li&gt;Link to your 5-8 minute video demo&lt;/li&gt;
&lt;li&gt;(Optional) List of any required libraries. Include instructions on how to install the libraries&lt;/li&gt;
&lt;li&gt;Instructions on how to install/use your project&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DEVLOG.md&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;This will contain a running list of updates to the project.&lt;/li&gt;
&lt;li&gt;Each entry should be timestamped and attributed to the student(s) that contributed to the update, along with a brief description of what was done.&lt;/li&gt;
&lt;li&gt;You must update this daily for full credit.&lt;/li&gt;
&lt;li&gt;The updates are indended to be made when you remember what you did and why.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;makefile&lt;/code&gt; with compile and run targets. The exact instruction to use should be in the &lt;code&gt;README.md&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Git commits, messages, anti-procrastination:&lt;/h3&gt;
&lt;p&gt;commits/anti-procrastination &lt;strong&gt;30% of your grade.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;You have classwork and homework EVERY DAY to work on this project, there are no exceptions unless you are sick.&lt;/p&gt;
&lt;p&gt;You must make commits daily for your project. There should be multiple commits per work session. A single commit in class and a single commit at home is not sufficient.&lt;/p&gt;
&lt;p&gt;You will be penalized if you procrastinate, do not do work regularly, or do not commit regularly with meaningful commit messages.&lt;/p&gt;
&lt;p&gt;It is acceptable to occasionally make few commits when stuck on a difficult part of the code, or when fixing bugs. This should not be the normal workflow however.&lt;/p&gt;
&lt;h3&gt;Presentation&lt;/h3&gt;
&lt;p&gt;Presentation &lt;strong&gt;10% of your grade.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;You and your partner(s) will give a 5-8 minute video presentation of what your program does, and how it works.&lt;/p&gt;
&lt;p&gt;You will not edit code, or show code.&lt;/p&gt;
&lt;p&gt;You will discuss what works, and what "almost" works in the case of features that are slightly buggy.&lt;/p&gt;
&lt;p&gt;Do not talk about what you could have done with more time.&lt;/p&gt;
&lt;p&gt;Your presentation should sound rehearsed/planned.&lt;/p&gt;
&lt;h3&gt;The actual project&lt;/h3&gt;
&lt;p&gt;The codebase and project &lt;strong&gt;30% of your grade.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;This includes if you worked on a sufficiently technical project of appropriate scope.&lt;/p&gt;
&lt;p&gt;Does the project work, can it be run on the lab computers.&lt;/p&gt;
&lt;h3&gt;Grade Summary&lt;/h3&gt;
&lt;p&gt;30% The codebase and project&lt;/p&gt;
&lt;p&gt;30% Documentation&lt;/p&gt;
&lt;p&gt;30% commits/anti-procrastination&lt;/p&gt;
&lt;p&gt;10% Presentation&lt;/p&gt;
&lt;h3 id="project-notes"&gt;Project Notes&lt;/h3&gt;
&lt;p&gt;You can use any external libraries you-d like, for example, gtk for windowing, sdl for games, etc. but you must do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sure to mention any libraries in the README where you describe compiling instructions.&lt;/li&gt;
&lt;li&gt;Check with me to make sure we can install them.&lt;/li&gt;
&lt;li&gt;Make sure your program will run in the cs lab computers.&lt;/li&gt;
&lt;li&gt;Make sure they don't trivialize a systems programming aspect of the project.
        (You get no credit for features that come from the libraries)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2025-01-03h"/><published>2025-01-03T12:00:00+00:00</published></entry><entry><id>2025-01-06n</id><title>2025-01-06</title><updated>2025-01-06T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2025-01-06n"&gt;
&lt;h5&gt;2025-01-06&lt;/h5&gt;
&lt;h3&gt;Final Project Repo:&lt;/h3&gt;
&lt;p&gt;Please add your proposal to the repo today.&lt;/p&gt;
&lt;p&gt;Please use formatting in your md files. The DEVLOG in particular should be formatted so that you do not have merge conflicts with your partner.&lt;/p&gt;
&lt;p&gt;Please create the README and replace the placeholder text. You should not have a readme that says "Group Name" in it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://classroom.github.com/a/Vh67aNdh"&gt;https://classroom.github.com/a/Vh67aNdh&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Today/Tonight&lt;/h3&gt;
&lt;p&gt;Design the functions/comments/headers of your project. Organization is extremely important.&lt;/p&gt;
&lt;p&gt;Create the skeleton files for your project and organize things as much as you can.&lt;/p&gt;
&lt;p&gt;All members should try to commit from EACH device of theirs, so they know that their commits show up the correct way. Please check the commits from the website to ensure ALL devices commit using YOUR name and link to your profile. You should see your avatar icon next to your commits as well. &lt;/p&gt;
&lt;p&gt;Make sure you are each working on your own dedicated branch, and merging onto main when you have good code.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;only place you should commit changes directly to main&lt;/strong&gt; would be the DEVLOG, and README files.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2025-01-06n"/><published>2025-01-06T12:00:00+00:00</published></entry><entry><id>2025-01-09n</id><title>2025-01-09</title><updated>2025-01-09T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2025-01-09n"&gt;
&lt;h5&gt;2025-01-09&lt;/h5&gt;
&lt;h3select&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;select&lt;/code&gt; is a function that monitors multiple file descriptors, allowing a program to read from different sources.
    &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;select&lt;/code&gt; can also be used for writing to files, but we will not focus on that usage.
    &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;select&lt;/code&gt; will &lt;strong&gt;block&lt;/strong&gt; on all the provided file descriptors, and return when any of them have data to be read.
    &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;select&lt;/code&gt; returns the number of file descriptors that have data to read, and then modifies a parameter to set which descriptors are available. If an error occured, return &lt;code&gt;-1&lt;/code&gt;.
    &lt;/li&gt;
&lt;li&gt;
      To use select, you create a set of potential file descriptors using the type &lt;code&gt;fd_set&lt;/code&gt;. Most of what we want from &lt;code&gt;select&lt;/code&gt; involves interacting with an &lt;code&gt;fd_set&lt;/code&gt; variable by using various macros.
    &lt;/li&gt;
&lt;li&gt;To use &lt;code&gt;select&lt;/code&gt; we must:
      &lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;fd_set&lt;/code&gt; variable.
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;fd_set desciptors;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Clear the &lt;code&gt;fd_set&lt;/code&gt; (&lt;code&gt;FD_ZERO&lt;/code&gt;)
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;FD_ZERO( &amp;amp;desciptors );&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Add file descriptors to the &lt;code&gt;fd_set&lt;/code&gt; (&lt;code&gt;FD_SET&lt;/code&gt;).
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;FD_SET(listen_socket, &amp;amp;descriptors);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;select&lt;/code&gt; and wait until any of the provided descriptors are available.
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;select(max_descriptor+1, &amp;amp;desciptors, NULL, NULL, NULL);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The first argument is &lt;code&gt;1&lt;/code&gt; more than the largest file desciptor in &lt;code&gt;desciptors&lt;/code&gt;. This is an artifact of how &lt;code&gt;select&lt;/code&gt; works.&lt;/li&gt;
&lt;li&gt;The second argument is the &lt;code&gt;fd_set&lt;/code&gt; of descriptors waiting to be read from.&lt;/li&gt;
&lt;li&gt;The third and fourth arguments are for descriptors for other actions, like writing.&lt;/li&gt;
&lt;li&gt;The final argument allows you to set a timeout, if &lt;code&gt;NULL&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt; will block indefinitely.&lt;/li&gt;
&lt;li&gt;Returns the number of file descriptors that are ready (this is usually 1).&lt;/li&gt;
&lt;li&gt;Modifies &lt;code&gt;desciptors&lt;/code&gt; to contain the desciptors that are available.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Once &lt;code&gt;select&lt;/code&gt; returns, loop through the potential file desciptors and determine which one is available (&lt;code&gt;FD_ISSET&lt;/code&gt;).
          &lt;ul&gt;
&lt;li&gt;&lt;code&gt;FD_ISSET(listen_socket, &amp;amp;desciptors);&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
          If you are going to use &lt;code&gt;select&lt;/code&gt; multiple times, you-ll have to repeatedly zero out the &lt;code&gt;fd_set&lt;/code&gt; and
          add the descriptors to it, since &lt;code&gt;select&lt;/code&gt; modifies it.
        &lt;/li&gt;
&lt;li&gt;It is usually a good idea to have a backup &lt;code&gt;fd_set&lt;/code&gt; to keep all your descriptors in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Putting it all together for a program that reads from a socket or &lt;code&gt;stdin&lt;/code&gt;:
      &lt;pre class="codeblock"&gt;&lt;code&gt;fd_set read_fds;
int listen_socket, client_socket;
char buffer[100];

FD_ZERO(&amp;amp;read_fds);
//assume this functuion correcly sets up a listening socket
listen_socket = server_setup();

//add listen_socket and stdin to the set
FD_SET(listen_socket, &amp;amp;read_fds);
//add stdin's file desciptor
FD_SET(STDIN_FILENO, &amp;amp;read_fds);

int i = select(listen_socket+1, &amp;amp;read_fds, NULL, NULL, NULL);

//if standard in, use fgets
if (FD_ISSET(STDIN_FILENO, &amp;amp;read_fds)) {
  fgets(buffer, sizeof(buffer), stdin);
}
//if socket, accept the connection
//assume this function works correctly
if (FD_ISSET(listen_socket, &amp;amp;read_fds)) {
  client_socket = server_connect(listen_socket);
}
  &lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Server with Select demo&lt;/h3&gt;
&lt;p&gt;This server is compatible with telnet for testing. To make a similar client to go with it, you would use select as well, but whatever you type gets sent over the socket instead of printed.&lt;/p&gt;
&lt;p&gt;This includes some code snippets to prevent the open port from lingering.&lt;/p&gt;
&lt;p&gt;To connect to the server use the command &lt;code&gt;telnet 127.0.0.1 PORT&lt;/code&gt; e.g. &lt;code&gt;telnet 127.0.0.1 9998&lt;/code&gt; &lt;/p&gt;
&lt;p&gt;You can exit out of telnet by pressing Ctrl+] and then typing quit&lt;/p&gt;
&lt;p&gt;The server will EITHER: 1. process STDIN or 2. accept a connection and process the message from the client.&lt;/p&gt;
&lt;p&gt;If you want to make a server that listens to multiple connections, you would have to engineer a more complicated soluition using this tool.&lt;/p&gt;
&lt;pre class="codeblock"&gt;&lt;code&gt;#include &amp;amp;ltsys/socket.h&amp;gt;
#include &amp;amp;ltsys/types.h&amp;gt;
#include &amp;amp;ltsys/socket.h&amp;gt;
#include &amp;amp;ltnetdb.h&amp;gt;
#include &amp;amp;lttime.h&amp;gt;
#include &amp;amp;ltstdio.h&amp;gt;
#include &amp;amp;ltstring.h&amp;gt;
#include &amp;amp;lterrno.h&amp;gt;
#include &amp;amp;ltunistd.h&amp;gt;
#include &amp;amp;ltstdlib.h&amp;gt;

int main(){
    struct addrinfo * hints, * results;
    hints = calloc(1,sizeof(struct addrinfo));
    char* PORT = "9998";


    hints-&amp;gt;ai_family = AF_INET;
    hints-&amp;gt;ai_socktype = SOCK_STREAM; //TCP socket
    hints-&amp;gt;ai_flags = AI_PASSIVE; //only needed on server
    getaddrinfo(NULL, PORT , hints, &amp;amp;results);  //NULL is localhost or 127.0.0.1

    //create socket
    int listen_socket = socket(results-&amp;gt;ai_family, results-&amp;gt;ai_socktype, results-&amp;gt;ai_protocol);\

    //this code allows the port to be freed after program exit.  (otherwise wait a few minutes)
    int yes = 1;
    if ( setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &amp;amp;yes, sizeof(yes)) == -1 ) {
        printf("sockopt  error\n");
        printf("%s\n",strerror(errno));
        exit(-1);
    }

    int err = bind(listen_socket, results-&amp;gt;ai_addr, results-&amp;gt;ai_addrlen);
    if(err == -1){
        printf("Error binding: %s",strerror(errno));
        exit(1);
    }
    listen(listen_socket, 3);//3 clients can wait to be processed
    printf("Listening on port %s\n",PORT);

    socklen_t sock_size;
    struct sockaddr_storage client_address;
    sock_size = sizeof(client_address);

    fd_set read_fds;

    char buff[1025]="";

    while(1){

        FD_ZERO(&amp;amp;read_fds);
        FD_SET(STDIN_FILENO, &amp;amp;read_fds);
        FD_SET(listen_socket,&amp;amp;read_fds);
        int i = select(listen_socket+1, &amp;amp;read_fds, NULL, NULL, NULL);

        //if standard in, use fgets
        if (FD_ISSET(STDIN_FILENO, &amp;amp;read_fds)) {
            fgets(buff, sizeof(buff), stdin);
            buff[strlen(buff)-1]=0;
            printf("Recieved from terminal: '%s'\n",buff);
        }

        // if socket
        if (FD_ISSET(listen_socket, &amp;amp;read_fds)) {
            //accept the connection
            int client_socket = accept(listen_socket,(struct sockaddr *)&amp;amp;client_address, &amp;amp;sock_size);
            printf("Connected, waiting for data.\n");

            //read the whole buff
            read(client_socket,buff, sizeof(buff));
            //trim the string
            buff[strlen(buff)-1]=0; //clear newline
            if(buff[strlen(buff)-1]==13){
                //clear windows line ending
                buff[strlen(buff)-1]=0;
            }

            printf("\nRecieved from client '%s'\n",buff);
            close(client_socket);
        }
    }



    free(hints);
    freeaddrinfo(results);
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Select with many clients.&lt;/h3&gt;
&lt;p&gt;If you want to keep connections to multiple clients, you need to maintain a list of file descriptors for the connections.&lt;/p&gt;
&lt;p&gt;When one of the clients disconnects, you need to remove the corresponding file desciptor from the list. &lt;/p&gt;
&lt;p&gt;It is surprisingly easy to do this! When a client disconnects, the socket will show up as having data to read with select, but when you read from it, there will be 0 bytes read. At that point you should remove that fd from your list.&lt;/p&gt;
&lt;p&gt;&lt;a href="#TOP"&gt;[back to top of page]&lt;/a&gt;&lt;/p&gt;
&lt;/h3select&gt;&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2025-01-09n"/><published>2025-01-09T12:00:00+00:00</published></entry><entry><id>2025-01-17n</id><title>2025-01-17</title><updated>2025-01-17T12:00:00+00:00</updated><content type="html">&lt;div class="contentBlock" id="2025-01-17n"&gt;
&lt;h5&gt;2025-01-17&lt;/h5&gt;
&lt;p&gt;This is a REQUIRED &lt;a href="https://forms.gle/H6EThf9kttq6A5Hb6"&gt;Final Exit Survey&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;ALL STUDENTS must fill this out over the weekend. If you do not fill this out your project grade will be in jeapordy.&lt;/p&gt;
&lt;a href="#TOP"&gt;go back to the top of the page&lt;/a&gt;
&lt;/div&gt;</content><link href="https://konstantinnovation.github.io/systems.html#2025-01-17n"/><published>2025-01-17T12:00:00+00:00</published></entry></feed>