<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Beka Modebadze</title>
    <description>The latest articles on DEV Community by Beka Modebadze (@bexxmodd).</description>
    <link>https://dev.to/bexxmodd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F639052%2Fa962e8f1-26ef-4a18-b942-3a78c5ae311b.jpg</url>
      <title>DEV Community: Beka Modebadze</title>
      <link>https://dev.to/bexxmodd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bexxmodd"/>
    <language>en</language>
    <item>
      <title>LLVM Infrastructure and Rust</title>
      <dc:creator>Beka Modebadze</dc:creator>
      <pubDate>Thu, 23 Dec 2021 23:22:34 +0000</pubDate>
      <link>https://dev.to/bexxmodd/llvm-infrastructure-and-rust-5g71</link>
      <guid>https://dev.to/bexxmodd/llvm-infrastructure-and-rust-5g71</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;You can find original post &lt;a href="https://www.bexxmodd.com/log/llvm-infrastrucutre-and-rust/7" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LLVM is an engine behind many programming languages. It's used by C, C++, Rust, Go, Swift and others. This log is all about LLVM and I'll explore following topics:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;What is LLVM Infrastructure&lt;/li&gt;
    &lt;li&gt;How LLVM Works&lt;/li&gt;
    &lt;li&gt;LLVM's Program Structure&lt;/li&gt;
    &lt;li&gt;LLVM and Rustc&lt;/li&gt;
&lt;/ul&gt; 

&lt;h3 id="p1"&gt;What is LLVM Infrastructure&lt;/h3&gt;

&lt;p&gt;
    LLVM Infrastructure is a collection of modular and reusable compiler and toolchain technologies. LLVM umbrella contains several sub-projects like Clang, C/C++/Objective-C compiler, Debugger LLDB, libc++, etc. Decades of research and improvement created an amazing tool for building languages and compilers, which some of the modern technologies are taking advantage of.
&lt;/p&gt;

&lt;p&gt;
    LLVM project started in 2000 at the University of Illinois at Urbana-Champaign, by Vikram Adve and Chris Lattner. LLVM's name initially was the acronym for Low-Level Virtual Machine. Even though modern LLVM Infrastructure has nothing to do with virtual machines the name remained unchanged. But the abbreviation itself was later removed and LLVM became the full name of the project.
&lt;/p&gt;

&lt;p&gt;
    The LLVM Project was released under the Open Source License. Later Lattner was hired by Apple, and the whole team was assigned to work on the LLVM system for several uses within Apple products. LLVM started expanding its features and grew into an umbrella project which combines LLVM IR, LLVM Debugger, and LLVM API C++ Library.
&lt;/p&gt;

&lt;p&gt;
    LLVM Compiler Framework is a modular and reusable compiler framework using LLVM infrastructure to provide the end-to-end compilation of code. It is used to build, optimize, sanitize, and produce intermediate code (IR) or binary (machine) code (BC). LLVM allows the translation of programming language code into the intermediate representation (IR) which can be converted into binary code (BC) for any given hardware architecture. IR language is independent of the source and target languages.
&lt;/p&gt;

&lt;p&gt;
    LLVM is used in multiple ways. The main way it can be used is as a compiler framework. Here you provide, what's called, the front end and the back end, or machine code and it produces the IR. This IR can be converted into binary code and linked into machine-dependent assembly language for the target platform.
&lt;/p&gt;

&lt;p&gt;
    LLVM's intermediate representation (IR) is a low-level programming language similar to assembly. But in addition to assembly, it provides better type annotation and human-friendly syntax. Also, IR uses an infinite set of registered instead of a predefined number of registers. We will explore IR's internal workings in a later segment.
&lt;/p&gt;

&lt;h3 id="p3"&gt;How LLVM Works&lt;/h3&gt;

&lt;p&gt;
    As mentioned already LLVM is a modular and reusable compiler framework that supports multiple front-ends and back-ends. The lifecycle of the program consists of writing a source code and then compiling it into binary code for execution. Our point of interest is the compiler stage. When source code is compiled into binary it goes through several steps in a subsequent order.
&lt;/p&gt;

&lt;p&gt;
    The compilation process can be divided into three parts. Front-End, Optimization, Back-End (Fig. 1-a). The compilation process starts on the front end. First, Pre-Processor starts to organize the source code. This is the phase when external libraries are extended into the target source code. In Rust, this directive is defined by the &lt;code&gt;use&lt;/code&gt; statement. A similar directive in C and C++ is &lt;code&gt;#include&lt;/code&gt; statement.
&lt;/p&gt;

&lt;center&gt;
&lt;p href=""&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FCofrtbC.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FCofrtbC.png" title="source: imgur.com"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Figure 1-a. Program's Lifecycle&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;
    Second, is Parsing. At this stage the code is evaluated for the syntatic errors and the &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;Abstract Syntax Tree (AST)&lt;/a&gt; is built. Third step at the front-end compilation is IR Generation. At this step compiler converts AST to the intermediate representation (IR) and outputs the result.
&lt;/p&gt;

&lt;p&gt;
    At the Optimization stage the compiler performs various transformations and sanitization to the program. This improves program performance, secures it by preventing various bugs, and does some utility runs. Later we'll explore IR and look at some optimization passes that come with compilers.
&lt;/p&gt;

&lt;p&gt;
    After the program is optimized it goes in the back-end stage. Here, Compiler Back-End converts IR to the target-specific assembly code. Then Assembler converts target-specific assembly code to target-specific machine code. And finally, Linker combines multiple machine code files into a single image, what we refer to as executable.
&lt;/p&gt;

&lt;p&gt;
    There are several language-specific Front ends. We have clang for &lt;b&gt;C&lt;/b&gt; and &lt;b&gt;C++&lt;/b&gt;, &lt;b&gt;Go&lt;/b&gt; has gollvm, and &lt;b&gt;Rust&lt;/b&gt; has it's compiler called rustc. Similarly after LLVM IR's optimizer passes code is converted into architecture-specific back-ends, like x86, ARM, MIPS.
&lt;/p&gt;

&lt;p&gt;
    The part between the front-end and back-end, called optimizer is where the magic of code optimization and sanitization happens. This is done through the series of what's called Pass. Each pass run one after another and there can be N number of passes. Passes can be categorized into two groups: &lt;b&gt;Analysis&lt;/b&gt; and &lt;b&gt;Transfromation&lt;/b&gt;. Analysis pass analyzes IR to check program properties, while Transformation pass transforms IR to monitor and optimize the program.
&lt;/p&gt;

&lt;p&gt;
    When source code is converted into LLVM IR it can take one of three formats (Figure 1-b). &lt;b&gt;In-memory&lt;/b&gt; format is a binary which is suitable for front-ends during the compilation process. Other two formats are &lt;b&gt;Bitcode&lt;/b&gt; and &lt;b&gt;Assembly&lt;/b&gt;. Bitcode is a binary on-disk stored format, suitable for fast loading as it's more memory efficient. Assembly is a textual format for human readability.
&lt;/p&gt;


&lt;center&gt;
    &lt;a href="https://imgur.com/GY2HcMK" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FGY2HcMK.png" title="source: imgur.com"&gt;&lt;/a&gt;
    &lt;p&gt;Figure 1-b. LLVM IR Formats&lt;/p&gt;
&lt;/center&gt;


&lt;p&gt;
    You may want to know why to use IR/BC instead of Native Assembly and Native binary? The reason is Native assembly has one-to-one binding to the platform's machine code. It depends on the target's architecture, for example, the program's assembly for the x86 and assembly for ARM will be different. Native assembly is turned into native binary via assembler, the feature that LLVM also includes. Here is &lt;a href="https://github.com/llvm/llvm-project/blob/main/llvm/docs/Passes.rst" rel="noopener noreferrer"&gt;the extensive list of LLVM passes available out of box.&lt;/a&gt; But that's not all of it, you can implement your passes to sanitize, or optimize source code.
&lt;/p&gt;

&lt;h3 id="p4"&gt;LLVM's Program Structure&lt;/h3&gt;

&lt;p&gt;
    LLVM IR, just like any other system, has its program structure (Fig. 2-a). The top-level container is a &lt;b&gt;Module&lt;/b&gt; that corresponds to each translation unit of the front-end compiler. Module can consist of one or many &lt;b&gt;functions&lt;/b&gt;. Each function has one or many &lt;b&gt;basic blocks&lt;/b&gt;, which has instructions. &lt;b&gt;Instruction&lt;/b&gt; is a single line and there are multiple instructions available in the IR language.
&lt;/p&gt;

&lt;p&gt;
    You can get the &lt;code&gt;.ll&lt;/code&gt; (IR assembly) file from your Rust source code by running following command in the terminal:
&lt;/p&gt;

&lt;p&gt;
    &lt;code&gt; $ rustc someprogram.rs --emit=llvm-ir -o somename.ll&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;
    Here we tell to &lt;code&gt;rustc&lt;/code&gt; compiler to give us llvm-ir (this is done by the flag &lt;code&gt;--emit=llvm-ir&lt;/code&gt;) form for the &lt;code&gt;someprogram.rs&lt;/code&gt; and output it (using option &lt;code&gt;-o&lt;/code&gt;) as &lt;code&gt;someoname.ll&lt;/code&gt;. Similarly, you can emit bitcode by using &lt;code&gt;--emit=llvm-bc&lt;/code&gt; flag.
&lt;/p&gt;

&lt;p&gt;
    The actual program structure in LLVM IR consists of hierarchical containers. At the top level, you have &lt;b&gt;Module.&lt;/b&gt; It corresponds to each translation unit of the front-end compiler. Modules may be combined with the LLVM linker, which merges function definitions. &lt;b&gt;Function&lt;/b&gt; is a next-level container, that includes function signature and its basic blocks. &lt;b&gt;Basic Block&lt;/b&gt; is a set of instructions that are executed sequentially. Basic blocks have one entry and one exit. The first block is called the entry block. Finally, IR has instructions. &lt;b&gt;Instructions&lt;/b&gt; are a single line executables (Figure 2-a).
&lt;/p&gt;

&lt;center&gt;
&lt;a href="https://imgur.com/YphTMST" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FYphTMST.png" title="source: imgur.com"&gt;&lt;/a&gt;
&lt;p&gt;Figure 2-a. IR Program Structure&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;
    In the IR file you'll encounter two kinds of variables, local variables, indicated with &lt;code&gt;%&lt;/code&gt; symbol and global variables, indicated with &lt;code&gt;@&lt;/code&gt; symbol. LLVM IR can use an infinite number of temporary registers, instead of a predefined number of registers, as native assemblers do. IR's registers are defined by integer numbers, like 1,2,3,..N. For example, &lt;code&gt;%2 = load i32, i32* %x&lt;/code&gt; means that value that is stored at the address of the local variable &lt;code&gt;x&lt;/code&gt; is loaded into the temporary register 2.
&lt;/p&gt;

&lt;p&gt;
    Another advantage of LLVM IR is that it utilizes what's called &lt;a href="https://en.wikipedia.org/wiki/Static_single_assignment_form" rel="noopener noreferrer"&gt;Static Single Assignment (SSA) form&lt;/a&gt;. This allows various optimizations to be done on a code. Instead of regular variables that can be reassigned multiple times, SSA variables can only be assigned once. This allows compilers to do more efficient register allocation because it's easy to approximate a number of live variables at any given point. It can detect unused variables and prevent programs from unnecessary pointer allocation.
&lt;/p&gt;

&lt;p&gt;
    For example, the following code &lt;code&gt;x = x * x&lt;/code&gt; in an SSA form will be &lt;code&gt;x_2 := x_1 * x_1&lt;/code&gt;. If we get into the loop where the variable constantly gets a new value, SSA uses what's called Phi Nodes. Phi will merge the variables into the final value that will be returned/outputted from the branch or loop. We'll look at concrete examples and go over IR syntax in the next segment of this log.
&lt;/p&gt;

&lt;h3 id="p5"&gt;LLVM and Rustc&lt;/h3&gt;

&lt;p&gt;
    The official guide to the Rustc development has all the reasons listed of why they are using LLVM, which I'm reciting directly:

&lt;/p&gt;


&lt;ul&gt;
    &lt;li&gt;
    We don't have to write a whole compiler backend. This reduces the implementation and maintenance burden.
    &lt;/li&gt;
    &lt;li&gt;
    We benefit from the large suite of advanced optimizations that the LLVM project has been collecting.
    &lt;/li&gt;
    &lt;li&gt;
    We can automatically compile Rust to any of the platforms for which LLVM has support. For example, as soon as LLVM added support for wasm, voila! rustc, clang, and a bunch of other languages were able to compile to wasm! (Well, there was some extra stuff to be done, but we were 90% there anyway).
    &lt;/li&gt;
    &lt;li&gt;
    We and other compiler projects benefit from each other. For example, when the Spectre and Meltdown security vulnerabilities were discovered, only LLVM needed to be patched.
    &lt;/li&gt;
    &lt;/ul&gt;
 

&lt;p&gt;
    Now, as we got familiar with what LLVM IR is, what id does, and why so many compilers are built on it, it's time to get our hands dirty and explore IR's internals using a simple Rust program called &lt;code&gt;simple1.rs&lt;/code&gt;:
&lt;/p&gt;


&lt;pre&gt;&lt;span&gt;//simple1.rs&lt;/span&gt;

&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;square(x&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;-&amp;gt;&lt;/span&gt; &lt;span&gt;u32&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;x&lt;/span&gt; &lt;span&gt;*&lt;/span&gt; &lt;span&gt;x&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;

&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;factorial(&lt;/span&gt;&lt;span&gt;mut&lt;/span&gt; &lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;u32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;-&amp;gt;&lt;/span&gt; &lt;span&gt;u32&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;let&lt;/span&gt; &lt;span&gt;mut&lt;/span&gt; &lt;span&gt;acc&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;while&lt;/span&gt; &lt;span&gt;n&lt;/span&gt; &lt;span&gt;&amp;gt;&lt;/span&gt; &lt;span&gt;0&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
        &lt;span&gt;acc&lt;/span&gt; &lt;span&gt;*=&lt;/span&gt; &lt;span&gt;n;&lt;/span&gt;
        &lt;span&gt;n&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;n&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;}&lt;/span&gt;
    &lt;span&gt;&lt;/span&gt; &lt;span&gt;acc&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
    
&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;main()&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;let&lt;/span&gt; &lt;span&gt;s&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;square(&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
    &lt;span&gt;let&lt;/span&gt; &lt;span&gt;f&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;factorial(s);&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
    &lt;/pre&gt;
    




&lt;p&gt;
    Our program has three functions, &lt;code&gt;main&lt;/code&gt; function that is an entry point in our program, &lt;code&gt;square&lt;/code&gt; function that returns the square of a given number, and &lt;code&gt;factorial&lt;/code&gt; that calculates factorial of the supplied integer. We output the LLVM IR file by invoking the following command in the terminal:
&lt;/p&gt;

&lt;p&gt;
    &lt;code&gt;&amp;gt;$ rustc simple1.rs --emit=llvm-ir&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;
    Now we should have &lt;code&gt;simple1.ll&lt;/code&gt; in the same folder as our source code. Let's open the &lt;code&gt;.ll&lt;/code&gt; file in the text editor and start exploring. At the beginning of the file, you'll find a bunch of metadata and other information and directives related to the program, but we are interested in delving into how our Rust functions are translated to IR, and we'll start doing it by first looking at &lt;code&gt;square&lt;/code&gt; function.
&lt;/p&gt;

&lt;p&gt;
    Search for the line which has a comment &lt;code&gt;simple1::square&lt;/code&gt; and next to it you'll find the LLVM IR container of a give function. Which looks like this:
&lt;/p&gt;


&lt;pre&gt;&lt;span&gt;; simple1::square&lt;/span&gt;
&lt;span&gt;; Function Attrs: nonlazybind uwtable&lt;/span&gt;
&lt;span&gt;define&lt;/span&gt; &lt;span&gt;internal&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;@_ZN7simple16square17h74fdb775aec225a0E(&lt;/span&gt;&lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%x)&lt;/span&gt; &lt;span&gt;unnamed_addr&lt;/span&gt; &lt;span&gt;#&lt;/span&gt;&lt;span&gt;1&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;start:&lt;/span&gt;
  &lt;span&gt;%0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;@llvm.umul.with.overflow.i32(&lt;/span&gt;&lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%x,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%x)&lt;/span&gt;
  &lt;span&gt;%_4.0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%0,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;
  &lt;span&gt;%_4.1&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%0,&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;
  &lt;span&gt;%1&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;@llvm.expect.i1(&lt;/span&gt;&lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%_4.1,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;false&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%1,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%panic,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb1&lt;/span&gt;

&lt;span&gt;bb1:&lt;/span&gt;                                              &lt;span&gt;; preds = %start&lt;/span&gt;
  &lt;span&gt;ret&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_4.0&lt;/span&gt;

&lt;span&gt;panic:&lt;/span&gt;                                            &lt;span&gt;; preds = %start&lt;/span&gt;
&lt;span&gt;; call core::panicking::panic&lt;/span&gt;
  &lt;span&gt;call&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; &lt;span&gt;@_ZN4core9panicking5panic17h50b51d19800453c0E([&lt;/span&gt;&lt;span&gt;0&lt;/span&gt; &lt;span&gt;x&lt;/span&gt; &lt;span&gt;i8&lt;/span&gt;&lt;span&gt;]*&lt;/span&gt; &lt;span&gt;...&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/pre&gt;



&lt;p&gt;
    IR starts by defining function with a randomly generated unique name (that also includes original function name in it) that returns i32 value and takes i32 value as a parameter. The &lt;code&gt;start&lt;/code&gt; is the label for the entry point of the function. In the first instruction LLVM IR &lt;code&gt;call&lt;/code&gt;s its intrinsic function &lt;code&gt;@llvm.umul.with.overflow.i32&lt;/code&gt;. This function takes two i32 arguments (in this case both ar &lt;code&gt;x&lt;/code&gt;), performs unsigned multiplication and outputs tuple-like result, where first value is i32 and the second value is i1. The result is assigned to a unnamed temporary &lt;code&gt;%0&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
    You may ask here a couple of questions. First, why does the &lt;code&gt;square&lt;/code&gt; function take and return the i32 value instead of the u32 value as was declared In the source code? LLVM IR doesn't provide separately defined data types for signed and unsigned values. Instead, it performs operations specific to the value type, signed operation for signed values, unsigned operations for unsigned values. If our &lt;code&gt;square&lt;/code&gt; function took i32 as an argument and returned i32, IR would have called &lt;code&gt;@llvm.smul.with.overflow.i32&lt;/code&gt; instead, which is an intrinsic function for signed multiplication.
&lt;/p&gt;

&lt;p&gt;
    The next question you may ask is why does multiplying an integer over an integer returns a tuple? If you look at the types of the outputted tuple, the second item is an i1 (a single bit value), which is for binary/boolean values. The name of the called function suggests that it does unsigned multiplication with overflow. If the overflow is detected, that is multiplied value exceeds the maximum unsigned value 32 bits can hold, because we performed unsigned multiplication, it sets i1 to 1, e.g. &lt;code&gt;true&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
    In two following instructions IR unpacks the result of multiplication. The unnamed temporary &lt;code&gt;%_4.0&lt;/code&gt; takes the multiplied value and the boolean result is assigned to &lt;code&gt;%_4.1&lt;/code&gt;. Next, IR calls another intrinsic function &lt;code&gt;@llvm.expect.i1(i1 %_4.1, i1 false)&lt;/code&gt; where it expects value assigned to unnamed temporary &lt;code&gt;%_4.1&lt;/code&gt; to be &lt;code&gt;false&lt;/code&gt;. Program assigns evaluated result to another unnamed temporary &lt;code&gt;%1&lt;/code&gt;. Unnamed temporaries are unsigned numeric values with prefix % or @ (example, &lt;code&gt;%1&lt;/code&gt;) created by IR. Named values are represented as string characters with similar prefixes introduced from a source code (example &lt;code&gt;%acc&lt;/code&gt;).
&lt;/p&gt;

&lt;p&gt;
    After that, IR performs branching. The &lt;code&gt;br&lt;/code&gt; directive checks if the value placed in temporary &lt;code&gt;%1&lt;/code&gt; is true, and if so jumps to &lt;code&gt;%panic&lt;/code&gt;, otherwise to &lt;code&gt;%bb1&lt;/code&gt;. Two above mentioned names are labels for the basic blocks. The &lt;code&gt;%panic&lt;/code&gt; calls Rust's panic method (if you have programmed in Rust you should know what &lt;code&gt;panic&lt;/code&gt; does), while &lt;code&gt;bb1&lt;/code&gt; returns value stored in temporary &lt;code&gt;%_4.0&lt;/code&gt; from the function &lt;code&gt;square&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
    Now, let's look at our &lt;code&gt;factorial&lt;/code&gt; function, as there are more interesting things happening:
&lt;/p&gt;


&lt;pre&gt;&lt;span&gt;; simple1::factorial&lt;/span&gt;
&lt;span&gt;; Function Attrs: nonlazybind uwtable&lt;/span&gt;
&lt;span&gt;define&lt;/span&gt; &lt;span&gt;internal&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;@_ZN7simple19factorial17hceebae2a8a73b808E(&lt;/span&gt;&lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%0)&lt;/span&gt; &lt;span&gt;unnamed_addr&lt;/span&gt; &lt;span&gt;#&lt;/span&gt;&lt;span&gt;1&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
&lt;span&gt;start:&lt;/span&gt;
  &lt;span&gt;%acc&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;alloca&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%n&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;alloca&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;store&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%0,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%n,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;store&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%acc,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb1&lt;/span&gt;

&lt;span&gt;bb1:&lt;/span&gt;                                              &lt;span&gt;; preds = %bb4, %start&lt;/span&gt;
  &lt;span&gt;%_3&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;load&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%n,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%_2&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;icmp&lt;/span&gt; &lt;span&gt;ugt&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_3,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%_2,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb2,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb5&lt;/span&gt;

&lt;span&gt;bb5:&lt;/span&gt;                                              &lt;span&gt;; preds = %bb1&lt;/span&gt;
  &lt;span&gt;%1&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;load&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%acc,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;ret&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%1&lt;/span&gt;

&lt;span&gt;bb2:&lt;/span&gt;                                              &lt;span&gt;; preds = %bb1&lt;/span&gt;
  &lt;span&gt;%_4&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;load&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%n,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%2&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;load&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%acc,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%3&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;@llvm.umul.with.overflow.i32(&lt;/span&gt;&lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%2,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_4)&lt;/span&gt;
  &lt;span&gt;%_5.0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%3,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;
  &lt;span&gt;%_5.1&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%3,&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;
  &lt;span&gt;%4&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;@llvm.expect.i1(&lt;/span&gt;&lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%_5.1,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;false&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%4,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%panic,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb3&lt;/span&gt;

&lt;span&gt;bb3:&lt;/span&gt;                                              &lt;span&gt;; preds = %bb2&lt;/span&gt;
  &lt;span&gt;store&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_5.0,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%acc,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%_6&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;load&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%n,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;%5&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;@llvm.usub.with.overflow.i32(&lt;/span&gt;&lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_6,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
  &lt;span&gt;%_7.0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%5,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;
  &lt;span&gt;%_7.1&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;extractvalue&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;}&lt;/span&gt; &lt;span&gt;%5,&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;
  &lt;span&gt;%6&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;call&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;@llvm.expect.i1(&lt;/span&gt;&lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%_7.1,&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;false&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;i1&lt;/span&gt; &lt;span&gt;%6,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%panic1,&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb4&lt;/span&gt;

&lt;span&gt;panic:&lt;/span&gt;                                            &lt;span&gt;; preds = %bb2&lt;/span&gt;
&lt;span&gt;; call core::panicking::panic&lt;/span&gt;
  &lt;span&gt;call&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; &lt;span&gt;@_ZN4core9panicking5panic17h50b51d19800453c0E&lt;/span&gt; &lt;span&gt;...&lt;/span&gt;

&lt;span&gt;bb4:&lt;/span&gt;                                              &lt;span&gt;; preds = %bb3&lt;/span&gt;
  &lt;span&gt;store&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt; &lt;span&gt;%_7.0,&lt;/span&gt; &lt;span&gt;i32&lt;/span&gt;&lt;span&gt;*&lt;/span&gt; &lt;span&gt;%n,&lt;/span&gt; &lt;span&gt;align&lt;/span&gt; &lt;span&gt;4&lt;/span&gt;
  &lt;span&gt;br&lt;/span&gt; &lt;span&gt;label&lt;/span&gt; &lt;span&gt;%bb1&lt;/span&gt;

&lt;span&gt;panic1:&lt;/span&gt;                                           &lt;span&gt;; preds = %bb3&lt;/span&gt;
&lt;span&gt;; call core::panicking::panic&lt;/span&gt;
  &lt;span&gt;call&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; &lt;span&gt;@_ZN4core9panicking5panic17h50b51d19800453c0E&lt;/span&gt;  &lt;span&gt;...&lt;/span&gt;
&lt;/pre&gt;
    


&lt;p&gt;
    Recall that as an argument, &lt;code&gt;factorial&lt;/code&gt; takes mutable u32 value, which in IR is defined as a unnamed temporary &lt;code&gt;%0&lt;/code&gt;. While function &lt;code&gt;square&lt;/code&gt;'s definition takes named variable &lt;code&gt;%n&lt;/code&gt; as an argument, just like in a source code. This is because square never modifies its value, while &lt;code&gt;factorial&lt;/code&gt; requires it to be mutable, and later makes argument's copy inside a function's scope. At the start of the function two named variables are defined &lt;code&gt;%n&lt;/code&gt; and &lt;code&gt;%acc&lt;/code&gt;. Each of them gets the allocated (with &lt;code&gt;alloca&lt;/code&gt; call) 32 bits of memory with data alignment of 4 bytes. You can read more about memory alignment &lt;a href="https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
    After allocation, &lt;code&gt;store&lt;/code&gt; instruction stores content laying in &lt;code&gt;%0&lt;/code&gt; temporary in the address of &lt;code&gt;%n&lt;/code&gt;. In the address of &lt;code&gt;%acc&lt;/code&gt; it stores constant value 1. Finally, it jumps to the entry point of a while loop. The &lt;code&gt;bb1&lt;/code&gt; label marks entry into the while condition. IR loads value stored at the address of &lt;code&gt;%n&lt;/code&gt; into temporary &lt;code&gt;%_3&lt;/code&gt; and makes comparison between it and constant value 0. &lt;code&gt;icmp&lt;/code&gt; checks if value stored at &lt;code&gt;%_3&lt;/code&gt; is unsigned greater than (&lt;code&gt;ugt&lt;/code&gt;) 0 and assigns result to another temporary &lt;code&gt;%_2&lt;/code&gt;. After that, it evaluates contents of &lt;code&gt;%_2&lt;/code&gt;. If it's true, branch jumps to the label &lt;code&gt;%bb2&lt;/code&gt; if false - to label &lt;code&gt;%bb5&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
    The &lt;code&gt;bb5&lt;/code&gt; label is marks the exit block of the while loop. Here it loads the value from the address of &lt;code&gt;%acc&lt;/code&gt; into temporary &lt;code&gt;%1&lt;/code&gt; and returns it from the function. The label &lt;code&gt;bb2&lt;/code&gt; is the entry into the body of a while loop. The body of a while loop is split in two halves. First one, responsible for the multiplication operation (&lt;code&gt;bb2&lt;/code&gt; label) and the second one responsible for decrementing &lt;code&gt;n&lt;/code&gt;, or subtraction operation. The operation &lt;code&gt;n = n - 1&lt;/code&gt; is done by calling another intrinsic function for unsigned subtraction. The rest are the same operations as we saw in &lt;code&gt;square&lt;/code&gt; function (Fig 4-a).
&lt;/p&gt;

&lt;center&gt;
    &lt;a href="https://imgur.com/Rb7zvTN" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FRb7zvTN.png" title="source: imgur.com"&gt;&lt;/a&gt;
    &lt;p&gt;Figure 4-a. Control Flow Graph &amp;amp; Basic Blocks&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;
    You'd noticed the SSA form in action here. For every assignment instruction, instead of reassigning value back to &lt;code&gt;n&lt;/code&gt; and &lt;code&gt;acc&lt;/code&gt;, as it's defined in the source code, IR introduces new unnamed temporary for each instruction. The numbering of unnamed temporaries is incremented within a function at each instance when they are spawned, starting from 0.
&lt;/p&gt;

&lt;p&gt;
    LLVM IR supports Two's Complement of binary numbers. It has data types for integers like i8, i16, i32, i64 and floats f16, f32, etc. which are referred es operands. If you see an asterisk symbol after integer type that means we are dealing with a pointer (example: i32*). Value can also be constant. Each instruction also has its types, for example, arithmetic operators, binary comparison, data stores, and loads. There is much more of what IR performs and you can find the full list on the link at the end of this section.
&lt;/p&gt;

&lt;p&gt;
    The class hierarchy of LLVM is little bit complicated. The base object is what's called &lt;code&gt;Value&lt;/code&gt;, that is used to represent a SSA register. All the other classes inherit from it. Then comes &lt;code&gt;User&lt;/code&gt; class followed by &lt;code&gt;Instruction&lt;/code&gt;, &lt;code&gt;Operator&lt;/code&gt;, &lt;code&gt;Constant&lt;/code&gt; classes and so on (Fig. 4-b). Here is the &lt;a href="https://llvm.org/doxygen/classllvm_1_1Value.html" rel="noopener noreferrer"&gt;full tree of class inheritance&lt;/a&gt; inside LLVM.
&lt;/p&gt;

&lt;center&gt;
    &lt;a href="https://imgur.com/qjLmuFW" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FqjLmuFW.png" title="source: imgur.com"&gt;&lt;/a&gt;
    &lt;p&gt;Figure 4-b. LLVM Class Hierarchy&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;
    LLVM Language has many high-level structures, types, constants, functions, codegen instructions, etc. If you are interested learning more about it you can scroll through the &lt;a href="https://llvm.org/docs/LangRef.html" rel="noopener noreferrer"&gt;reference manual&lt;/a&gt;.
&lt;/p&gt;

&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;
    As we reviewed in this article LLVM IR has many use-cases and allows us to analyze and optimize source code through its passes. Knowing IR language itself will help us to write our passes and build projects around it for debugging, testing, optimizing. Currently, LLVM IR doesn't have Rust API. It's mainly used through the C++ library. However, some user-created repos are available on crates.io. There is a Rust binding to LLVM's C API - &lt;a href="https://lib.rs/crates/llvm-sys" rel="noopener noreferrer"&gt;llvm-sys&lt;/a&gt; and two other, more Rusty APIs that are using LLVM: &lt;a href="https://github.com/TheDan64/inkwell" rel="noopener noreferrer"&gt;inkwell&lt;/a&gt; and &lt;a href="https://github.com/cdisselkoen/llvm-ir" rel="noopener noreferrer"&gt;llvm-ir&lt;/a&gt;. And finally, if you want to learn how to write a LLVM pass you should start &lt;a href="https://github.com/cdisselkoen/llvm-ir" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&lt;/p&gt;



</description>
      <category>rust</category>
      <category>llvm</category>
      <category>programming</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Getting Started with Systems Programming with Rust (Part 2)</title>
      <dc:creator>Beka Modebadze</dc:creator>
      <pubDate>Thu, 19 Aug 2021 06:39:14 +0000</pubDate>
      <link>https://dev.to/bexxmodd/getting-started-with-systems-programming-with-rust-part-2-2lei</link>
      <guid>https://dev.to/bexxmodd/getting-started-with-systems-programming-with-rust-part-2-2lei</guid>
      <description>&lt;h2&gt; Building a Mini-Shell &lt;/h2&gt;



&lt;p&gt;
    In the introductory Part 1, we discussed what system processes are, how to spawn them, and how to pass commands and execute them. If you want to review this material first you can 
    &lt;a href="https://www.bexxmodd.com/log/systems-programming-with-rust-1/1" rel="noopener noreferrer"&gt;click here.&lt;/a&gt;
&lt;/p&gt;



&lt;p&gt;
    In this section we’ll learn:

    &lt;/p&gt;
&lt;ul&gt;- What are system signals and how to handle them.&lt;/ul&gt;
    &lt;ul&gt;- What are stdout, stdin, and stderr, and how to use them efficiently.&lt;/ul&gt;
    &lt;ul&gt;- Writing to stdout and reading from stdin, instead of printing and what’s the advantage of doing so.&lt;/ul&gt;
    &lt;ul&gt;- Managing parent and child processes and their execution order.&lt;/ul&gt;




&lt;p&gt;
    To demonstrate the above-listed topics in practice, we’ll be building a UNIX mini-shell, which will be able to take commands from a user in the terminal and execute them. The program will also handle some invalid commands and deal with stuck programs gracefully.
&lt;/p&gt;



&lt;h2&gt;stdin, stdout, and stderr&lt;/h2&gt;

&lt;p&gt;
    Probably you are familiar with what streams are in computing, if not just like water streams, it refers to the flow of data from source to an endpoint. Streams allow connecting commands, processes, files, etc. There are three special streams:
&lt;/p&gt;




&lt;ul&gt;- stdin (Standard Input): which takes text as an input.&lt;/ul&gt;
    &lt;ul&gt;- stdout (Standard Output): stores text output in the stdout stream.&lt;/ul&gt;
    &lt;ul&gt;- stderr (Standard Error): When an error occurs during a stream the error message is stored in this stream.&lt;/ul&gt;




&lt;p&gt;
The Linux system is file-oriented. This means nearly all streams are treated as files, and those streams are processed based on the unique identifier code that each file type has. For stdio (collection of standard output, input, and error) assigned values are 0 for stdin, 1 for stdout, and 2 for stderr. If we want to read a stream of text from the command line, in C we use the function &lt;code&gt;read()&lt;/code&gt; and supply code 0 as one of the arguments for stdin (Figure 1-a).
&lt;/p&gt;



&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2400%2F1%2Ay3_tArgpKbZp1CiR5MpKeg.png" alt="centered image"&gt;&lt;p&gt;Figure 1-a. Stdin Stdout &amp;amp; Stderr diagram&lt;/p&gt;
&lt;/center&gt;



&lt;p&gt;
    Reading and writing from &lt;code&gt;stdio&lt;/code&gt; is a little bit different in Rust, but fundamentals remain the same. To better demonstrate their use we’ll start writing code for our mini-shell program. Initially, we’ll create a loop that will be asking the user to type in a command that the system will execute. The first two functionalities we need to create are writing to stdout and reading from stdin.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// flushes text buffer to the stdout&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="nf"&gt;.as_ref&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// flush to the terminal&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    We’ll use a standard &lt;code&gt;io&lt;/code&gt;&amp;gt; module to write to the terminal. Instead of passing &lt;code&gt;String&lt;/code&gt; by copy, the function &lt;code&gt;write_to_stdout()&lt;/code&gt; takes a reference to a string slice as an argument. The &lt;code&gt;str&lt;/code&gt; is different from &lt;code&gt;String&lt;/code&gt;. It’s what Rust refers to as a slice, is a reference to a part of a &lt;code&gt;String&lt;/code&gt;. If you want to better understand the difference between those two, I’d recommend reading &lt;a href="https://doc.rust-lang.org/nightly/book/ch04-01-what-is-ownership.html" rel="noopener noreferrer"&gt;chapter 4 from Rust's official book.&lt;/a&gt;
&lt;/p&gt;



&lt;p&gt;
    The &lt;code&gt;write_to_stdout()&lt;/code&gt; function returns &lt;code&gt;Result&lt;/code&gt; object which can be &lt;code&gt;Ok&lt;/code&gt; or &lt;code&gt;Err&lt;/code&gt;. As those names suggest if everything goes as planned we’ll return &lt;code&gt;Ok&lt;/code&gt; otherwise &lt;code&gt;Err&lt;/code&gt; is returned. This procedure is so common in Rust that to return &lt;code&gt;Err&lt;/code&gt; we have a special symbol &lt;code&gt;?&lt;/code&gt; at the end of the function call that can end up in error.
&lt;/p&gt;



&lt;p&gt;
    Inside the function, we call a &lt;code&gt;write()&lt;/code&gt; function that fills the text buffer of the &lt;code&gt;stdout&lt;/code&gt; and then we flush text on the screen. Inside &lt;code&gt;write()&lt;/code&gt; we usa &lt;code&gt;as_ref()&lt;/code&gt; method which converts string slice into an ASCII byte literal, as this is what the above-mentioned function expects as an argument.
&lt;/p&gt;



&lt;p&gt;
    Next, we need to build a function that will read the user inputted command, and process it. For this, we’ll write a custom function &lt;code&gt;get_user_command()&lt;/code&gt; that returns &lt;code&gt;String&lt;/code&gt;.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// fetch the user inputted command from terminal&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;get_user_command&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.read_line&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// not receommended&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="nf"&gt;.ends_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// remove last char&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;input&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    The function reads a full line from the terminal and copies a value into an &lt;code&gt;input&lt;/code&gt; variable. The &lt;code&gt;read_line()&lt;/code&gt; takes mutable reference of the input &lt;code&gt;String&lt;/code&gt; variable, dereferences inside the function call, writes user-supplied command, and returns &lt;code&gt;Result&lt;/code&gt;. When we read a line from stdin it’s EOL (end of line) terminated, which includes the &lt;code&gt;\n&lt;/code&gt; control character at the end and we need to get rid of it before returning input.
&lt;/p&gt;



&lt;p&gt;
    Finally, we glue our input and output functions together with our mini-shell program.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;run_shell&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run_shell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;shellname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ghost# "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;shellname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to write to stdout : {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cmnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_command&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cmnd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}: command not found!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    In our &lt;code&gt;main()&lt;/code&gt; function we run a loop that prints the shell name to the terminal screen and waits for the user to input the command. The &lt;code&gt;run_shell()&lt;/code&gt; writes to stdout using previously defined function by us and handles an error if it occurs during printing. If something goes wrong it notifies a user about it and exits the program with error code 1 (Unsuccessful compilation).
&lt;/p&gt;



&lt;p&gt;
    Next, it reads the user-supplied command and passes that command to a newly created process. Then we check the status of the command execution, and if the command was unsuccessful we notify a user that the “command not found” and instead of exiting here, we return to the loop of prompting the user for an input.
&lt;/p&gt;



&lt;p&gt;
    Run the program with &lt;code&gt;cargo run&lt;/code&gt; and we should see output similar to this:
&lt;/p&gt;



&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2400%2F1%2ARYlhw2gMUvCkS3eJpvUD3w.png" alt="centered image"&gt;
&lt;/center&gt;



&lt;p&gt;
    A good question to ask here is why we use to read and write functions instead of simply printing to the screen. The reason behind this is that directives like &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; are what’s called Async-Signal Safe functions, while C's &lt;code&gt;printf&lt;/code&gt; is not. They can be safely called within a signal handler (which we’ll review next).
&lt;/p&gt;



&lt;p&gt;
    The functions that are Async-Signal Safe are guaranteed not to be interrupted or interfered with when some signal is sent. For example, if we are in the middle of &lt;code&gt;println!()&lt;/code&gt; call and a signal occurs whose handler itself calls &lt;code&gt;println!()&lt;/code&gt; can result in undefined behavior. Because in this case, the output of the two &lt;code&gt;println!()&lt;/code&gt; statements would be intertwined.
&lt;/p&gt;



&lt;h2&gt;System Signals&lt;/h2&gt;

&lt;p&gt;
    To improve our mini-shell we have to handle system signals. Signals in the UNIX environment are sort of notifications that are sent by an operating system to a process to notify about a certain event, which usually ends up interrupting the process. Each signal has a unique name and integer value assigned to it. You can check the full list of signals of your system by typing &lt;code&gt;kill -l&lt;/code&gt; in your terminal.
&lt;/p&gt;



&lt;p&gt;
    By default, each signal has its handler defined which is a function that is called when a certain signal arrives. We can modify the handling of those signals (which we’ll do for our mini-shell project). However, some of the signal handlers can’t be modified.
&lt;/p&gt;



&lt;p&gt;
    For our project will take a look at four following signals:
&lt;/p&gt;



&lt;ul&gt;- &lt;code&gt;SIGINT&lt;/code&gt; which is called by pressing &lt;b&gt;Ctrl+C&lt;/b&gt; and causes the system to send a &lt;b&gt;INT&lt;/b&gt; signal to the running process. By default this causes the processes to terminate immediately. The Signal code for &lt;code&gt;SIGINT&lt;/code&gt; is 2.&lt;/ul&gt;

&lt;ul&gt;- &lt;code&gt;SIGQUIT&lt;/code&gt; is called by pressing &lt;b&gt;Ctrl+\&lt;/b&gt; and will send the &lt;b&gt;QUIT&lt;/b&gt; signal to the running process. This also terminates the process but more ungracefully. However, cleanup of absolutely necessary resources that need to be cleaned is performed. The assigned code is 3&lt;/ul&gt;

&lt;ul&gt;
    - &lt;code&gt;SIGALRM&lt;/code&gt; is like an alarm clock with a countdown in seconds. If the seconds' count hits zero, any pending alarm is canceled and the &lt;code&gt;SIGALRM&lt;/code&gt; signal is sent to the process. The alarm code is 14.
&lt;/ul&gt;

&lt;ul&gt;- &lt;code&gt;SIGKILL&lt;/code&gt; is the most forceful signal sent by the system which forces the process to halt. This signal can’t be handled manually by a user but the system will still perform a cleanup after process termination. It has a code 9.&lt;/ul&gt;



&lt;p&gt;
    Now, it’s time to check how we’ll be handling the above-listed signals in Rust (except &lt;code&gt;SIGKILL&lt;/code&gt; for which we can’t change default behavior). For example, if you run &lt;code&gt;cat&lt;/code&gt; command in the Linux terminal without a file argument it will get stuck in an infinite loop. When this happens in our mini-shell we’ll rewire the &lt;code&gt;SIGINT&lt;/code&gt; signal so it will forward the interrupt signal to the child process. This will only terminate the running loop but will keep our shell program running.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;signal_hook&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;nix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// Registers UNIX system signals&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;register_signal_handlers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Signals&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// signal execution is forwarded to the child process&lt;/span&gt;
    &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt;&lt;span class="nf"&gt;.forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;SIGINT&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;assert_ne!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// assert that the signal is sent&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    First, we create an iterator of signals which stores a vector of signal references. Here we indicate which signals are expected to be handled. Next, we need to forward the signal to the child process, the one which is actively running, and perform desired behavior on it. This is done by spawning a new thread that returns a &lt;code&gt;JoinHandler&lt;/code&gt;.
&lt;/p&gt;



&lt;p&gt;
    This handler will detach a child process after being dropped. This means when &lt;code&gt;SIGINT&lt;/code&gt; arrives at the child's process, that process will be separated from the parent and it will only interrupt whatever the child process is doing, while the parent process will continue running. If there is no child process in execution it will do nothing.
&lt;/p&gt;



&lt;p&gt;
    We use &lt;code&gt;forever()&lt;/code&gt; function on signals iterator which returns an infinite loop over arriving signals. As soon as the signal arrives it will be evaluated with a match-case and if it matches &lt;code&gt;SIGINT&lt;/code&gt; it will assert that signal was sent successfully. For any other signal, the iterator will continue to wait for the next signal.
&lt;/p&gt;



&lt;p&gt;
    Since we rewired the &lt;code&gt;SIGINT&lt;/code&gt; signal to only handle child processes, what if we want to exit the program completely? We’ll handle a different signal and let it print “Goodbye” to the stdout and exit graciously. For this one, we’ll use the &lt;code&gt;SIGQUIT&lt;/code&gt; signal, which can be sent from the keyboard by pressing &lt;b&gt;Ctrl + \&lt;/b&gt;.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;signal_hook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIGQUIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// .. previous function introduction and matching ..&lt;/span&gt;

        &lt;span class="n"&gt;SIGQUIT&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Goodbye!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;

&lt;span class="c1"&gt;// .. rest of the function ..&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    When the &lt;code&gt;SIGQUIT&lt;/code&gt; signal is called it’s matched in our iterator and this calls our &lt;code&gt;write_to_stdout()&lt;/code&gt; function. Then program exits with code 0, which in Linux stands for a successful compilation. Notice we are importing &lt;code&gt;SIGNAL&lt;/code&gt; consts from &lt;code&gt;signal_hook&lt;/code&gt; library, which is a library for easier Unix signal handling.
&lt;/p&gt;



&lt;p&gt;
    Finally, we’ll add a small feature to our program. The user will supply an integer at the program's start. This number will be used as a countdown for the program’s execution time. For example, if a user supplies 5, this will invoke &lt;code&gt;alarm(5)&lt;/code&gt; when the child process is started. If a function isn’t complete when the countdown ends, our manually defined &lt;code&gt;SIGALRM&lt;/code&gt; signal will kill it and return the program to the initial state.
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;signal_hook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIGALRM&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;nix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;nix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;unistd&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;alarm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pid&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// alarm will be called from `execute_shell(timeout: u32)`&lt;/span&gt;
&lt;span class="cd"&gt;/// after function collects user input it calls `alarm::set(timeout)`&lt;/span&gt;

&lt;span class="c1"&gt;// .. beginning of the register_signal_handlers function ..&lt;/span&gt;

        &lt;span class="n"&gt;SIGALRM&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This's taking too long...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// when alarm goes off it kills child process&lt;/span&gt;
            &lt;span class="nn"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Pid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;

&lt;span class="c1"&gt;// .. rest of the function ..&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    When &lt;code&gt;SIGALRM&lt;/code&gt; is matched, first, it will write to the stdout, and next, it does a very interesting thing. It will use the &lt;code&gt;signal::kill()&lt;/code&gt; function to send the &lt;code&gt;SIGINT&lt;/code&gt; signal on a process it operates. But since the same function handles &lt;code&gt;SIGINT&lt;/code&gt; by forwarding it to a child process it will only kill the child process and return back to the main program of running mini-shell. Full function:
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;signal_hook&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGALRM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGQUIT&lt;/span&gt;&lt;span class="p"&gt;}};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;nix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;nix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;unistd&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;alarm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pid&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cd"&gt;/// Register UNIX system signals&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;register_signal_handlers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Signals&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGALRM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGQUIT&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// signal execution is forwarded to the child process&lt;/span&gt;
    &lt;span class="nn"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt;&lt;span class="nf"&gt;.forever&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;SIGALRM&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"This's taking too long...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="c1"&gt;// when alarm goes off it kills child process&lt;/span&gt;
                    &lt;span class="nn"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Pid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIGINT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;SIGQUIT&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;write_to_stdout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Good bye!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// not safe&lt;/span&gt;
                    &lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="n"&gt;SIGINT&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;assert_ne!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sig&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// assert that the signal is sent&lt;/span&gt;
                &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;
    These should be an expected outcome if you run our mini-shell through the terminal:
&lt;/p&gt;



&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2400%2F1%2Apn1CzSKuvPAH2MJtg115ZA.png" alt="centered image"&gt;
&lt;/center&gt;



&lt;p&gt;
    You can find a full code of the mini-shell, which includes some additional features besides covered here, in &lt;a href="https://github.com/bexxmodd/systems-with-rust/blob/master/src/main.rs" rel="noopener noreferrer"&gt;this GitHub repository&lt;/a&gt;.
&lt;/p&gt;



&lt;h2&gt;Summary&lt;/h2&gt;



&lt;p&gt;
    Today we learned what are stdin, stdout, and stderr, and how to use them properly. We looked at the common UNIX system signals and manually handled three of them to fit the needs of our mini-shell program. The combined knowledge from &lt;a href="https://www.bexxmodd.com/log/systems-programming-with-rust-1/1" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt; allowed us to build a program that executes system commands and handles system signals safely and fast thanks to the Rust language.
&lt;/p&gt;



&lt;p&gt;
    In the upcoming parts, we’ll take a look at communicating between processes between pipes and review concurrency. We’ll demonstrate why Rust can be the best choice for this.
&lt;/p&gt;





&lt;center&gt;...&lt;/center&gt;

</description>
      <category>rust</category>
      <category>linux</category>
      <category>systems</category>
      <category>programming</category>
    </item>
    <item>
      <title>Getting Started with Systems Programming with Rust (Part 1)</title>
      <dc:creator>Beka Modebadze</dc:creator>
      <pubDate>Fri, 13 Aug 2021 13:25:35 +0000</pubDate>
      <link>https://dev.to/bexxmodd/getting-started-with-systems-programming-with-rust-part-1-2i13</link>
      <guid>https://dev.to/bexxmodd/getting-started-with-systems-programming-with-rust-part-1-2i13</guid>
      <description>&lt;p&gt;You can find original post on &lt;a href="https://www.bexxmodd.com/log/systems-programming-with-rust-1/1" rel="noopener noreferrer"&gt;my personal blog.&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;A modern computer is a very complex creation that evolved into the current state through decades of research and development. Sometimes it appears to be like black magic. There’s no magic in it, just science. However, some of the minds like Alan Turing, Charles Babbage, Ada Lovelace, John von Neumann, and many others are magical, as they made this possible.&lt;/p&gt;
&lt;br&gt;


&lt;p&gt;Ok, that’s enough of introductions and let us dive into the fundamentals of systems programming. In this part we’ll learn:&lt;/p&gt;
&lt;br&gt;&lt;ul&gt;- What is the process?&lt;/ul&gt;
&lt;ul&gt;- How are they created and executed?&lt;/ul&gt;
&lt;ul&gt;- Look at some code examples in Rust and compare them to C.&lt;/ul&gt;
&lt;br&gt;&lt;p&gt;  Before diving into code we’ll start to build up from the lowest level of the main components of the operating systems. As shown in Figure 1-a the lowest level of any computer is Hardware, next comes the Kernel mode which runs on bare metal. This is where the operating system, like Linux, is located.&lt;/p&gt;
&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F2400%2F1%2AYFdpr8NZXzEo8vSOOVKj0g.png"&gt;&lt;p&gt;  Figure 1-a.  &lt;/p&gt;


&lt;/center&gt;
&lt;br&gt;&lt;p&gt;  On top of the Kernel mode, we have a User-mode. For a user to be able to interact with the kernel AND use other higher-level software, like web browser, E-mail reader, etc. it requires a user interface program. This can be a window, Graphical User Interface, or it can be a shell which is a &lt;b&gt;command interpreted &lt;/b&gt;that is used to read commands from a terminal and execute them&lt;/p&gt;
&lt;br&gt;&lt;h2&gt;  Processes: Parent and Child&lt;/h2&gt;  The main concept in all operating systems is a process. A process is basically a running program. You can think of it as a drawer that contains all the information about that particular program. Some processes start running at the start of the computer, some run in the background, and some are called and interacted by the user, through the shell, for example.&lt;br&gt;&lt;p&gt;  All the processes have an id. The very first process is initiated, when the system is booted. This process has an id of 1 and is called init. After that, init will call other processes and so on. When we type a command in a shell for the OS to execute, the system should create a new process that will run the compiler. When the process has finished compiling, it will make a system call to terminate itself.&lt;/p&gt;
&lt;br&gt;&lt;p&gt;  In UNIX systems every new process is a child process of some parent process. Process creation is done by cloning a parent process, which is referred to as forking (Figure 1-b). Each process has one parent but can have multiple child processes. The structure of the processes resembles a tree, where init is the root, meaning it’s at the top of the hierarchy.&lt;/p&gt;
&lt;br&gt;&lt;p&gt;  After the process’s creation, the parent and the child processes are the same, except the parent will have some arbitrary ID number, and the child process will have an ID equal to 0. Next, the system substitutes the child process’s execution with a new program. When the process is done fulfilling its purpose, it’s terminated and exited normally (voluntary). The process can also be exited due to an error or killed by another process (involuntary).&lt;/p&gt;
&lt;br&gt;&lt;center&gt;
&lt;br&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F1%2AlCncraMXCqZZlRqm9mT31g.gif"&gt;&lt;p&gt;  Figure 1-b.  &lt;/p&gt;
&lt;br&gt;
&lt;/center&gt;
&lt;br&gt;&lt;br&gt;&lt;p&gt;  The system also keeps track of all the processes, maintaining their data in what’s called a &lt;b&gt;processes table&lt;/b&gt;. It holds information like process id, process owner, process priority, environment variables for each process, the parent process. In addition to that, it also holds the info in what state a particular process is. Each process can be in one of the following four states:&lt;/p&gt;
&lt;br&gt;&lt;ul&gt;RUNNABLE — The process is running / actively using the CPU.&lt;/ul&gt;
&lt;ul&gt;SLEEPING — The process is runnable, but is waiting for another process to stop/finish first.&lt;/ul&gt;
&lt;ul&gt;STOPPED — This state indicates that the process has been suspended for further proceeding. It can be restarted to run again by a signal.&lt;/ul&gt;
&lt;ul&gt;ZOMBIE — The process is terminated when ‘system exit’ is called or someone else kills the process. However, the process has not been removed from the process table.&lt;/ul&gt;
&lt;br&gt;&lt;p&gt;  Often processes have to interact with each other and can change the state and go from Running to sleeping, then back to running (Figure 1-c). This is usually done by a &lt;code&gt;SIGSTOP&lt;/code&gt; signal, which is issued by Ctrl + Z (We’ll review signals in-depth in upcoming parts). Same with the stopped process, its activity can be restarted. Except for the Zombie state, which once killed can’t be restarted or continued.&lt;/p&gt;
&lt;br&gt;&lt;center&gt;
&lt;br&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F1%2A9FvTHt_LyvtmJhfnjmwzFw.png"&gt;&lt;p&gt; Figure 1-c.  &lt;/p&gt;
&lt;br&gt;
&lt;/center&gt;
&lt;br&gt;&lt;h2&gt;C vs Rust&lt;/h2&gt;
&lt;p&gt;  In C, which is an official Linux kernel programming language, process creation is done first by forking the new process and then explicitly asking a system to execute a new directive on a child process. If we don’t do that, both parent and child processes will be executing the same directive. Here is an example of executing &lt;code&gt;ls&lt;/code&gt; command, which lists files of given directory:  &lt;/p&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include stdio.h
#include sys/types.h
#include sys/wait.h
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fork failed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I'm child process and I will execute ls command"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv_list&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;execv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ls"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error in execve"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"I'm parent process and I'll just print this"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;  As you can see we have to manage the processes manually and monitor if the execution was successful. Also, we have to handle errors. If we want a command to be executed only by a child we have to manually check if the current process is a child, which is done here by &lt;code&gt;case 0&lt;/code&gt;. In Rust, the same can be achieved with a &lt;a href="https://doc.rust-lang.org/std/process/struct.Command.html" rel="noopener noreferrer"&gt;standard library’s process module&lt;/a&gt;:&lt;br&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ls"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;.env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PATH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;.output&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"failed to execute process"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// if no error, program will continue..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;br&gt;&lt;p&gt; Here &lt;code&gt;Command::new()&lt;/code&gt;is a process builder which is responsible for spawning and handling a child process. Just like in a C code, we supply a command we want to execute, environmental variables, command argument, and call &lt;code&gt;output&lt;/code&gt; method on it. The output will execute the command as a child process, waiting for it to finish, and returns the collected output.&lt;/p&gt;
&lt;br&gt;&lt;p&gt;  Instead of &lt;code&gt;output()&lt;/code&gt; we also have options to use either &lt;code&gt;status()&lt;/code&gt; or &lt;code&gt;spawn()&lt;/code&gt;. Each of these methods is responsible for forking a child process with subtle differences:&lt;/p&gt;
&lt;br&gt;&lt;ul&gt;

&lt;code&gt;output()&lt;/code&gt; : Will run the program and return a result of the &lt;code&gt;Output&lt;/code&gt;, only after child processes finish running.  &lt;/ul&gt;
&lt;ul&gt;

&lt;code&gt;status()&lt;/code&gt;: Will run the program and return a result of &lt;code&gt;ExitStatus&lt;/code&gt; after process compilation. This allows checking the status of the compiled program.&lt;/ul&gt;
&lt;ul&gt;

&lt;code&gt;spawn()&lt;/code&gt;: Will run the program and return a result which is a &lt;code&gt;Child&lt;/code&gt; process. This doesn’t wait for the program compilation. This option allows for &lt;code&gt;wait&lt;/code&gt; and &lt;code&gt;kill&lt;/code&gt; directives or we can get an id of that process.&lt;/ul&gt;
&lt;br&gt;&lt;p&gt;  Here, &lt;code&gt;env()&lt;/code&gt; is optional, as the Command is smart enough to look for the path of a /bin folder. Finally, all the error handling is done by &lt;code&gt;expect()&lt;/code&gt;. It unwraps the result if &lt;code&gt;Ok&lt;/code&gt;, meaning the program was executed successfully, or &lt;code&gt;Err&lt;/code&gt; if something went wrong and will &lt;code&gt;panic!&lt;/code&gt;. If you want your program not to terminate if &lt;code&gt;Err&lt;/code&gt; encountered you can do something like this:&lt;/p&gt;
&lt;br&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;user_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_input&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// custom function&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;user_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="nf"&gt;.envs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PATH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/bin"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="nf"&gt;.status&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}: command not found!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// the rest of the program...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;br&gt;&lt;p&gt;  Here &lt;code&gt;status()&lt;/code&gt; is handier and calling it will return &lt;code&gt;Ok&lt;/code&gt; if the legit command is supplied by the user and execute. But we are only interested in handling if the unavailable command was supplied. That’s why we only check if &lt;code&gt;Err&lt;/code&gt; was returned, and if so print that “command was not found” into the terminal and continue the current program execution, instead of terminating.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;code&gt;spawn()&lt;/code&gt; is used to manage the order of execution between several children and parent processes. It contains &lt;code&gt;stdin&lt;/code&gt; &lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stderr&lt;/code&gt; fields and has, familiar to C programmers, &lt;code&gt;wait()&lt;/code&gt; , &lt;code&gt;kill()&lt;/code&gt; and &lt;code&gt;id()&lt;/code&gt; methods. We’ll look at this part of the processes in the next part and we’ll also see how Rust takes care of race conditions when two or more threads can access shared data and they try to change it at the same time.&lt;/p&gt;
&lt;br&gt;&lt;h2&gt; Summary&lt;/h2&gt;
&lt;p&gt;  In this introductory part, we reviewed what are processes, how they are created and compared Rust's implementation of the processes creation and command execution to C. We saw that Rust code not only is less prone to human errors but it’s less verbose and more concise. In the next parts, we’ll take a look at managing processes execution time and states, and handling system signals&lt;/p&gt;

</description>
      <category>rust</category>
      <category>systems</category>
      <category>programming</category>
      <category>linux</category>
    </item>
    <item>
      <title>5 Reasons Why You Should Start Using Rust for Personal Projects</title>
      <dc:creator>Beka Modebadze</dc:creator>
      <pubDate>Tue, 10 Aug 2021 19:43:33 +0000</pubDate>
      <link>https://dev.to/bexxmodd/5-reasons-why-you-should-start-using-rust-for-personal-projects-49pb</link>
      <guid>https://dev.to/bexxmodd/5-reasons-why-you-should-start-using-rust-for-personal-projects-49pb</guid>
      <description>&lt;p&gt;&lt;br&gt;
When one master's student at the University of Helsinki was not able to get his hands on one of the UNIX operating systems for his personal computer, he started a side project. He wanted to build a kernel that ran on his PC. Linus Torvalds'  side-project as you may know was Linux, which is the most popular operating system in the world and currently runs approximately on 1 billion devices.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;
    Steve Wozniak, the co-founder of Apple, was toying with computers in his basement when Jobs discovered and convinced him to make money off of his creations. These are just two famous stories. There are many more where the side-project started something interesting, something big, something game-changing, or at least resulted in a good job offer. In this post, I'll try to convince you why you should do side-projects and why you should do them with Rust.
&lt;/p&gt;



&lt;h2&gt;Importance of Personal Projects&lt;/h2&gt;

&lt;p&gt;
    Personal side-projects convey three important values. First, it's the best way to learn new technologies, and tools, frameworks. The only way you can retain some knowledge from recently learned material is to do some projects. It allows you to experiment, test out ideas, and practice the implementation of those ideas. I personally came to a firm conclusion that I can't say that I understand technology if I haven't done a personal implementation of it.
    
&lt;/p&gt;



&lt;p&gt;
    Second, it's a form of signaling. Signaling is an important part of the successful job search and career advancement. If you were an economist probably you don't need further clarification on what signaling is. However, I assume the majority of you are not so I'll give a quick tour of the signaling part of the &lt;a href="https://en.wikipedia.org/wiki/Contract_theory" rel="noopener noreferrer"&gt;contract theory.&lt;/a&gt;

&lt;/p&gt;



&lt;p&gt;
    Signaling is the way how one party (namely agent) dispatches the information about itself to another acting party (namely principal). In the job market, this can be seen as an attempt by the potential candidate to showcase their ability to the potential employer. For example, your bachelor's degree (if you have one) is a form of signaling. It shows that for at least four years you worked hard, managed to pass the required class, and hopefully attained knowledge.
&lt;/p&gt;



&lt;p&gt;
    Side projects or portfolio projects are also a form of signaling. They convey a message to the potential hiring managers that you can show initiative. You can take ownership of the project and work on it independently. It also demonstrates that you have a genuine interest in a field and a desire to learn. Often students and people looking for their first developer roles are highly encouraged to work on personal projects.
&lt;/p&gt;



&lt;p&gt;
    Third, it's a great way to network and make interesting connections. I've personally developed relationships with several developers who have contributed to my project or I contributed to theirs. This is a meaningful connection, because it's voluntary and built on mutual interest. You choose with whom you want to work on a project or task, you can find people with the same interest within interest.
&lt;/p&gt;



&lt;h2&gt;How Rust is Used by Developers&lt;/h2&gt;

&lt;p&gt;
Understanding the benefits of side-projects brings us to the second point. What is the current state of Rust? I'll not tell you that learning Rust will get you a job, because that would be a lie. There aren't many (especially entry-level) software Engineer jobs asking for Rust. However, the way it's currently utilized couples perfectly with the above-written argument.
&lt;/p&gt;



&lt;p&gt;
Recently JetBrains published &lt;a href="https://www.jetbrains.com/lp/devecosystem-2020/rust/" rel="noopener noreferrer"&gt;the developer survey for 2020 about Rust programming language &lt;/a&gt;. It was asking why developers chose to use Rust, how they used Rust, what kind of projects they worked with Rust, and if they interact with other languages and other people. It's worth mention that big majority of developers (67%) use Rust for personal projects/hobbies and 80% of them have been using it for less than a year.

&lt;/p&gt;



&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FspOIQ1U.png"&gt;&lt;p&gt;
    How Developers use Rust
&lt;/p&gt;
&lt;/center&gt;

&lt;p&gt;
I'm personally happy to see these numbers. Foremost because this is an organic programming language growth path. People start trying new things, building pet projects, get hooked, and then try to convince their employers to use those technologies, or even go and build their companies using those technologies.
&lt;/p&gt;



&lt;p&gt;
    The fact that the majority of developers have not been with Rust for more than a year also indicates that language is in an early stage and still needs to mature. Getting started with Rust now will give you a frontline seat for the senior roles when Big names will start looking for the experienced Rust developers. And believe me, the way language is progressing and gaining popularity that time is not that far away.
&lt;/p&gt;



&lt;p&gt;
    Rust's not only a systems programming language as usually it's advertised. Statistics of project types built with Rust also hint that it's a multipurpose programming language. Yes, it is prominently used for systems programming (56%) but the frequencies of its usage for Web (44%) and Network (32%) are not that far. People are even developing libraries for Machine Learning and building game engines. It's an illustrious community and there's a higher chance you'll find fellow tech enthusiasts to work on something exciting together.
&lt;/p&gt;



&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fdy8JM0G.png"&gt;&lt;p&gt;
    Project Types developed with Rust
&lt;/p&gt;
&lt;/center&gt;



&lt;p&gt;
In summary, we see that the popularity of Rust is on the rise. Developers are experimenting with various libraries and the community is growing every day. Rust goes beyond being just a systems programming language as people are discovering the advantages of including Rust in various ways in their projects.
&lt;/p&gt;



&lt;h2&gt;
Now, Why Rust?
&lt;/h2&gt;

&lt;p&gt;
    We examined how Rust is used and saw the multiple directions it's growing and gaining momentum. However, the question still stands. Why Rust? Why you should use Rust? What are eminent features that are alluring developers like a flower attracts bees?
&lt;/p&gt;



&lt;p&gt;
    Instead of just listing personal opinions I decided to ask more experienced Rust developers why they chose Rust and list personal opinions. The question I asked was simple: "What is your elevator pitch for Rust?". My question got a lot's of responses and stimulated some discussion on Rust's user forum. I handpicked the most interesting replies but if you want you can read through the whole feed &lt;a href="https://users.rust-lang.org/t/what-is-you-elevator-pitch-for-rust/61713/9" rel="noopener noreferrer"&gt;here&lt;/a&gt;.
&lt;/p&gt;


&lt;center&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.pinclipart.com%2Fpicdir%2Fbig%2F173-1736275_explain-alarmed-ferris-convention-rust-lang-clipart.png"&gt;&lt;p&gt;Rust Crab Ferris&lt;/p&gt;
&lt;/center&gt;
&lt;br&gt;


&lt;p&gt;
    To answer above asked questions I'm going to review following five arguments of why you should start using Rust for personal side-projects:
    &lt;br&gt;&lt;br&gt;
    &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Zero-cost abstraction&lt;/li&gt;
&lt;li&gt; Immutable and Private by default&lt;/li&gt;
&lt;li&gt; Full Experience with Cargo and Rust Compiler&lt;/li&gt;
&lt;li&gt; Safety first! no dangling pointers, no memory leaks, and no race conditions
&lt;/li&gt;
&lt;li&gt; Rust is not JAL (Just Another Language)&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;Zero-Cost Abstraction&lt;/h3&gt;

&lt;p&gt;
    You pay only for what you use. The runtime is based on what features you use for your program. What does this mean? For example, in Java or C#, every time you abstract code by introducing additional classes it adds overhead to your program. Because both languages have garbage collectors your extra layer of code needs to be cleaned after the program is done using it. This can significantly slow down your program. In Rust, high-level APIs will directly compile into machine code and can have as good performance as if you'd written lower-level code.
&lt;/p&gt;



&lt;h3&gt;Immutable and Private by Default&lt;/h3&gt;

&lt;p&gt;
    When you define variables in Rust they are immutable by default. If you want the variable to be modifiable you need to explicitly state that by using &lt;code&gt;mut&lt;/code&gt; keyword. The same goes for the data access modifiers. If you don't state that any field, function, struct, enum, or mod is &lt;code&gt;public&lt;/code&gt; its access level is inherently limited to the local scope. Similar to what Java and C# does when you set class or function to &lt;code&gt;private&lt;/code&gt;.
&lt;/p&gt;



&lt;p&gt;
    What's the advantage of this? - A reduction in human error. Popular philosophy about how to set access modifiers is to maximize data protection. For example, if you know a field or function shouldn't be used outside of the class where it's defined it should always be set to private. When data is being modified or accessed where it shouldn't this can cause major bugs and security issues. Private by default push developers to be more conscious of their program design choices and helps to faster detect bugs.
&lt;/p&gt;



&lt;h3&gt;Cargo and Compiler&lt;/h3&gt;

&lt;p&gt;
    When you set up Rust, you not only get Rust the programming language, you get a full environment. Rust comes with &lt;code&gt;cargo&lt;/code&gt;, a user-friendly package manager. Cargo gives ease of managing dependencies and setting up build configurations. With only a handful number of commands, you'll be able to create projects, run projects, test them, and even upload to the &lt;a href="crates.io"&gt;crates.io&lt;/a&gt; where other Rust libraries and packages reside.
&lt;/p&gt;



&lt;p&gt;
Rust also comes with an amazing compiler. One of the first pieces of advice given to me when I started using Rust was not to fight the compiler. Instead, listen to it. Rust compiler utilizes LLVM's decades of optimization. However, besides that, it's very verbose and descriptive of what went wrong. It also suggests potential fixes and alternative approaches developers may consider to overcome given errors during compilation. If your code compiles it's highly likely that it will run without errors.
&lt;/p&gt;



&lt;h3&gt;Safety First!&lt;/h3&gt;

&lt;p&gt;
    The core philosophy of the Rust language is to keep it safe without sacrificing performance. It may sound counterintuitive when you hear this first time (at least it was for me), but it's true. We already mentioned that Rust has no garbage collector. Instead, Rust uses what's called lifetimes. This not only allows code to run fast, but it also guarantees that no unused allocated memory lives in the program when its lifecycle is over. This exterminates the problems known to C developers like memory leaks and dangling pointers.
&lt;/p&gt;  



&lt;p&gt;
    Rust handles concurrent and parallel program design problems fearlessly. As Chapter 16 of Rust's official Book says:
    &lt;/p&gt;
&lt;ul&gt;"By leveraging ownership and type checking, many concurrency errors are compile-time errors in Rust rather than runtime errors. Therefore, rather than making you spend lots of time trying to reproduce the exact circumstances under which a runtime concurrency bug occurs, incorrect code will refuse to compile and present an error explaining the problem."&lt;/ul&gt;
&lt;br&gt;
    If you want to learn more about how Rust solves this problem I'd suggest reading above mentioned &lt;a href="https://doc.rust-lang.org/book/ch17-00-concurrency.html" rel="noopener noreferrer"&gt;Chapter 16: Fearless Concurrency&lt;/a&gt;




&lt;h3&gt;Rust isn't JAL (Just Another Language)&lt;/h3&gt;

&lt;p&gt;
There are so many new programming languages getting born and getting hyped and then dying out namelessly. But not Rust. Graydon Hoare and the team at Mozilla gave much thought to the language design to solve many issues other popular languages have. This attracted lots of developers. 
&lt;/p&gt;



&lt;p&gt;
Thoughtful conversations, suggestions, and contributions bestowed the language's growth in the right direction. Rust's community is very welcoming and offers immense support to the newcomers. The Rust's &lt;a href="https://www.reddit.com/r/rust/" rel="noopener noreferrer"&gt;Reddit&lt;/a&gt;, &lt;a href="https://discord.com/invite/rust-lang-community" rel="noopener noreferrer"&gt;Discord channel&lt;/a&gt;, and &lt;a href="https://users.rust-lang.org/" rel="noopener noreferrer"&gt;Rust forum&lt;/a&gt; are amazing places to connect with other Rusteceans, ask for help, or seek advice. So I'll ask you:

    &lt;br&gt;&lt;br&gt;
     &lt;/p&gt;
&lt;center&gt;&lt;h4&gt;For the next side-project try Rust!&lt;/h4&gt;&lt;/center&gt;




</description>
      <category>rust</category>
      <category>sideprojects</category>
      <category>systems</category>
    </item>
  </channel>
</rss>
