<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://codingbeyond.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://codingbeyond.com/" rel="alternate" type="text/html" /><updated>2026-07-18T13:29:17-04:00</updated><id>https://codingbeyond.com/feed.xml</id><title type="html">Coding Beyond</title><subtitle>Coding beyond user space</subtitle><entry><title type="html">Spicing Things up w/ i3 and Polybar</title><link href="https://codingbeyond.com/ricing/2026/07/18/spcing-things-up-with-i3-and-polybar.html" rel="alternate" type="text/html" title="Spicing Things up w/ i3 and Polybar" /><published>2026-07-18T00:00:00-04:00</published><updated>2026-07-18T00:00:00-04:00</updated><id>https://codingbeyond.com/ricing/2026/07/18/spcing-things-up-with-i3-and-polybar</id><content type="html" xml:base="https://codingbeyond.com/ricing/2026/07/18/spcing-things-up-with-i3-and-polybar.html"><![CDATA[<p>One of the big perks of Linux is that you can customize just about anything to your heart’s content. The open source nature of Linux allows for this. As such there is some great open source software out there that I use myself to build out a minimalistic desktop environment for my machines at home. i3 and Polybar.</p>

<h2 id="why-i3">Why i3?</h2>

<p>i3 is a window tiling manager, a window manager where the sizing and layout of windows is done by the manager itself rather than the user. When you open a new window it snaps right into position with its dimensions calculated by the manager. i3 also has workspaces which one can think of as virtual desktops. Here is an example of two workspaces I have open.</p>

<h3 id="workspace-1">Workspace 1</h3>

<p><img src="/assets/images/rice-example.png" alt="Workspace 1 example" /></p>

<h3 id="workspace-2">Workspace 2</h3>
<p><img src="/assets/images/rice-example2.png" alt="Workspace 2 example" /></p>

<p>As one can see, i3 evenly spaces out the windows in each workspace. If there is only one window as shown on workspace #2 then the window fills the whole screen.</p>

<p>i3 is also a neat developer productivity tool in that it has baked in commands so that you rarely have to touch the mouse when locking in on the task at hand.</p>

<p>Please refer to the <a href="https://i3wm.org/downloads/">i3 distributions</a> if you wish to install it and the <a href="https://i3wm.org/docs/userguide.html">i3 user guide</a> for more information on how to utilize i3.</p>

<h2 id="customizing-i3">Customizing i3</h2>

<p>Ok, onto the fun part. A freshly installed i3 is pretty bland in my opinion and doesn’t look visually appealing.</p>

<p>In order to begin to customize i3 you’ll want to copy <code class="language-plaintext highlighter-rouge">/etc/i3/config</code> to <code class="language-plaintext highlighter-rouge">~/.i3/config</code> or <code class="language-plaintext highlighter-rouge">~/.config/i3/config</code>.</p>

<p>From here on out any configuration changes you make will be to either of those later two locations on your machine. Already the default config file does a lot of hand holding with its baked in comments. For example, some of the default keybinds should be there which are simple to switch out, or default workspace names which can be renamed to your heart’s content. Another big thing which I do is I configure programs that I want i3 to start at boot up. In order to do this just slap this on your config file: <code class="language-plaintext highlighter-rouge">exec --no-startup-id \[command\]</code>. A good example of an exec line I have (and one which will be relevant in the next section) is <code class="language-plaintext highlighter-rouge">exec_always --no-startup-id ~/.config/polybar/launch.sh</code> (note exec only launches the program once on boot, exec_always launches it on boot and every single time you reload i3).</p>

<p>On my i3 config I’ve also changed the default color scheme to a monochrome-grey one, there are many inspirations online you can use to find the right color scheme for you but here’s mine:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># class                   border   bground  text     idcator  child_brdr
client.focused            #333333  #D4C9BE  #030303  #123458  #333333
client.focused_inactive   #333333  #5F676A  #F1EFEC  #484E50  #5F676A
client.unfocused          #333333  #222222  #888888  #292D2E  #222222
client.urgent             #333333  #900000  #F1EFEC  #900000  #900000
client.placeholder        #333333  #0C0C0C  #F1EFEC  #000000  #0C0C0C
client.background         #F1EFEC
</code></pre></div></div>

<p>Again, more information on configuration is up above in the linked user guide.</p>

<h2 id="complete-the-i3-setup-w-polybar">Complete the i3 setup w/ Polybar</h2>

<p>So far we’ve gone over i3 which just manages your windows and some startup applications of your choosing. However i3’s default status bar isn’t really visually appealing. That’s where Polybar comes in. Polybar is essentially a tool used to create custom status bars.</p>

<p>For installation refer to the <a href="https://github.com/polybar/polybar/blob/master/README.md">readme</a> over on their github.</p>

<p>Next create a directory for polybar configs in your config directory of choice and in it create this simple shell script.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
killall <span class="nt">-q</span> polybar

<span class="k">while </span>pgrep <span class="nt">-x</span> polybar <span class="o">&gt;</span>/dev/null<span class="p">;</span> <span class="k">do </span><span class="nb">sleep </span>1<span class="p">;</span> <span class="k">done

</span>polybar <span class="nt">--config</span><span class="o">=</span>~/.config/polybar/config.ini top &amp;
</code></pre></div></div>

<p>This will be the launch script that the i3 exec_always config I mentioned above points to. This will essentially kill any already running polybar process and boot up a new one. So it doubles as both a launch and refresh script.</p>

<p>Then as one can probably note I’ve pointed to a config.ini file. It is here that you will define your status bars. Here the syntax for the bars is simple, here’s an example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#you can also define the bottom bar with [bar/bottom]
[bar/top]
monitor = None-1
width = 100%
height = 38

background = #00000000
foreground = #ccffffff
 
line-color = ${bar/bottom.background}
line-size = 2
 
spacing = 2
padding-right = 5
padding-left = 5
module-margin = 4
 
font-0 = NotoSans-Regular:size=12;-1
font-1 = MaterialIcons:size=10;0
font-2 = Termsynu:size=8:antialias=false;-2
font-3 = FontAwesome:size=10;0
font-4 = Unifont:size=8;0
font-5 = Unifont:size=8;0
font-6 = Unifont:size=8;0
font-7 = JetBrainsMono Nerd Font:size=10;1

modules-left = spotify volume
modules-right = cpu temperature memory date
modules-center = xworkspaces
</code></pre></div></div>

<p>As one can see we can define a vast amount of properties relating to your bar. The most peculiar properties however are those of modules-left, modules-right, and modules-center. Here you define your own custom modules in the order and position you want them to appear on your status bar. I’ll use my right hand modules as an example.</p>

<p>Here we have three modules I built to get a visual cue of resource usage on my machine:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#user defined name
[module/cpu]

#defined type, view https://polybar.readthedocs.io/en/stable/user/modules/ for the different available internal modules
type = internal/cpu
interval = 0.5

#defines the format (look) of the module, view https://github.com/polybar/polybar/wiki/Formatting for more details on formats
format = &lt;label&gt; &lt;ramp-coreload&gt;
label = CPU

ramp-coreload-0 = ▁
ramp-coreload-0-font = 5
ramp-coreload-0-foreground = #F1EFEC
ramp-coreload-1 = ▂
ramp-coreload-1-font = 5
ramp-coreload-1-foreground = #F1EFEC
ramp-coreload-2 = ▃
ramp-coreload-2-font = 5
ramp-coreload-2-foreground = #F1EFEC
ramp-coreload-3 = ▄
ramp-coreload-3-font = 5
ramp-coreload-3-foreground = #F1EFEC
ramp-coreload-4 = ▅
ramp-coreload-4-font = 5
ramp-coreload-4-foreground = #F1EFEC
ramp-coreload-5 = ▆
ramp-coreload-5-font = 5
ramp-coreload-5-foreground = #F1EFEC
ramp-coreload-6 = ▇
ramp-coreload-6-font = 5
ramp-coreload-6-foreground = #F1EFEC
ramp-coreload-7 = █
ramp-coreload-7-font = 5
ramp-coreload-7-foreground = #F1EFEC
 
[module/date]
type = internal/date
date =    %%{F#99}%Y-%m-%d%%{F-}  %%{F#fff}%H:%M%%{F-}
date-alt = %%{F#fff}%A, %d %B %Y  %%{F#fff}%H:%M%%{F#666}:%%{F#fff}%S%%{F-}

[module/memory]
type = internal/memory
format = &lt;label&gt; &lt;bar-used&gt;
label = RAM
 
bar-used-width = 30
bar-used-foreground-0 = #F1EFEC
bar-used-foreground-1 = #F1EFEC
bar-used-foreground-2 = #FFBBAA
bar-used-foreground-3 = #FF5555
bar-used-indicator = |
bar-used-indicator-font = 6
bar-used-indicator-foreground = #ff
bar-used-fill = ─
bar-used-fill-font = 6
bar-used-empty = ─
bar-used-empty-font = 6
bar-used-empty-foreground = #444444
</code></pre></div></div>

<p>These three modules provide a good basis for getting started. If you wish to get more crafty and utilize custom types look into the type <code class="language-plaintext highlighter-rouge">custom/script</code>. Actually as a bonus I’ll throw in my own configs for my custom spotify module:</p>

<p>spotify-status shell script:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="k">if</span> <span class="o">!</span> pgrep <span class="nt">-x</span> spotify <span class="o">&gt;</span> /dev/null<span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Spotify inactive"</span>
    <span class="nb">exit </span>0
<span class="k">fi

</span><span class="nv">status</span><span class="o">=</span><span class="si">$(</span>playerctl <span class="nt">--player</span><span class="o">=</span>spotify status 2&gt;/dev/null<span class="si">)</span>
<span class="nv">artist</span><span class="o">=</span><span class="si">$(</span>playerctl <span class="nt">--player</span><span class="o">=</span>spotify metadata artist<span class="si">)</span>
<span class="nv">title</span><span class="o">=</span><span class="si">$(</span>playerctl <span class="nt">--player</span><span class="o">=</span>spotify metadata title<span class="si">)</span>
<span class="k">if</span> <span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="nv">$artist</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nv">artist</span><span class="o">=</span><span class="si">$(</span>playerctl <span class="nt">--player</span><span class="o">=</span>spotify metadata album<span class="si">)</span>
<span class="k">fi
</span><span class="nb">echo</span> <span class="s2">"Spotify - </span><span class="nv">$artist</span><span class="s2"> - </span><span class="nv">$title</span><span class="s2">"</span>
</code></pre></div></div>

<p>spotify polybar module:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[module/spotify]
type = custom/script
exec = ~/.config/polybar/spotify-status.sh
interval = 2
format = &lt;label&gt;
label = %output%
</code></pre></div></div>

<p>-Nate</p>]]></content><author><name></name></author><category term="ricing" /><summary type="html"><![CDATA[Customize your linux desktop with these two popular modifications]]></summary></entry><entry><title type="html">Everything Is a File</title><link href="https://codingbeyond.com/io/2026/07/10/everything-is-a-file.html" rel="alternate" type="text/html" title="Everything Is a File" /><published>2026-07-10T22:05:42-04:00</published><updated>2026-07-10T22:05:42-04:00</updated><id>https://codingbeyond.com/io/2026/07/10/everything-is-a-file</id><content type="html" xml:base="https://codingbeyond.com/io/2026/07/10/everything-is-a-file.html"><![CDATA[<p>In the linux and unix operating systems everything is a file. Well not literally but the phrase describes a common pattern used to interact with these operating systems. It is through manipulating file descriptors that programmers can interact with I/O devices, disk partitions, and even processes themselves. But what are they?</p>

<h2 id="what-is-a-file-descriptor">What Is a File Descriptor?</h2>

<p>Firstly a file descriptor is basically just a non-negative integer that identifies any input/output resource (files included). This is neat because it gives the programmer a common api for which to interact with I/O.</p>

<p>Each process running in the Linux operating system has a set of open file descriptors associated with it (actually it’s more of a map as we’ll see shortly). This set can be accessed by reading from the proc directory: <code class="language-plaintext highlighter-rouge">ls -l /proc/PID/fd</code></p>

<p>For example if I run <code class="language-plaintext highlighter-rouge">ls -l /proc/self/fd</code> then I’ll see the open file descriptors associated with my current shell:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>total 0
lrwx------ 1 nate nate 64 Jul 10 20:55 0 -&gt; /dev/pts/0
lrwx------ 1 nate nate 64 Jul 10 20:55 1 -&gt; /dev/pts/0
lrwx------ 1 nate nate 64 Jul 10 20:55 2 -&gt; /dev/pts/0
lr-x------ 1 nate nate 64 Jul 10 20:55 3 -&gt; /proc/2336340/fd
</code></pre></div></div>

<p>The first three file descriptors here correspond to <em>standard input</em>, <em>standard output</em>, and <em>standard error</em> respectively. Another way to read this is that the three I/O descriptors point to the current psuedo-terminal <code class="language-plaintext highlighter-rouge">/dev/pts/0</code>.</p>

<p>Now you may be wondering how this is possible. In the Linux kernel each process has filesystem information associated with it via a structure called files_struct:</p>

<p><a href="https://elixir.bootlin.com/linux/v7.1.3/source/include/linux/fdtable.h#L38">Linux Kernel files_struct definition</a></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/*
 * Open file table structure
 */</span>
<span class="k">struct</span> <span class="n">files_struct</span> <span class="p">{</span>
  <span class="cm">/*
   * read mostly part
   */</span>
	<span class="n">atomic_t</span> <span class="n">count</span><span class="p">;</span>
	<span class="n">bool</span> <span class="n">resize_in_progress</span><span class="p">;</span>
	<span class="n">wait_queue_head_t</span> <span class="n">resize_wait</span><span class="p">;</span>

	<span class="k">struct</span> <span class="n">fdtable</span> <span class="n">__rcu</span> <span class="o">*</span><span class="n">fdt</span><span class="p">;</span>
	<span class="k">struct</span> <span class="n">fdtable</span> <span class="n">fdtab</span><span class="p">;</span>
  <span class="cm">/*
   * written part on a separate cache line in SMP
   */</span>
	<span class="n">spinlock_t</span> <span class="n">file_lock</span> <span class="n">____cacheline_aligned_in_smp</span><span class="p">;</span>
	<span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">next_fd</span><span class="p">;</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">close_on_exec_init</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">open_fds_init</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">full_fds_bits_init</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
	<span class="k">struct</span> <span class="n">file</span> <span class="n">__rcu</span> <span class="o">*</span> <span class="n">fd_array</span><span class="p">[</span><span class="n">NR_OPEN_DEFAULT</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Peering closer into it one notices the fdtable structure:</p>

<p><a href="https://elixir.bootlin.com/linux/v7.1.3/source/include/linux/fdtable.h#L26">Linux Kernel fdtable Definition</a></p>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">fdtable</span> <span class="p">{</span>
	<span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">max_fds</span><span class="p">;</span>
	<span class="k">struct</span> <span class="n">file</span> <span class="n">__rcu</span> <span class="o">**</span><span class="n">fd</span><span class="p">;</span>      <span class="cm">/* current fd array */</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="o">*</span><span class="n">close_on_exec</span><span class="p">;</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="o">*</span><span class="n">open_fds</span><span class="p">;</span>
	<span class="kt">unsigned</span> <span class="kt">long</span> <span class="o">*</span><span class="n">full_fds_bits</span><span class="p">;</span>
	<span class="k">struct</span> <span class="n">rcu_head</span> <span class="n">rcu</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Notice the fd array, this is where file descriptors play a role. My shell process above, if it wanted to fetch one of those terminal devices, would use 0, 1, or 2 as the index for the fd array (hence why file descriptors are represented as non-negative integers).</p>

<h2 id="interacting-w-file-descriptors">Interacting w/ File Descriptors</h2>

<p>In order to interact with file descriptors Linux provides some key system calls to do so:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">open(path, flags, mode)</code> <a href="https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html">POSIX open</a></li>
  <li><code class="language-plaintext highlighter-rouge">read(fd, buffer, count)</code> <a href="https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html">POSIX read</a></li>
  <li><code class="language-plaintext highlighter-rouge">write(fd, buffer, count)</code> <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html">POSIX write</a></li>
  <li><code class="language-plaintext highlighter-rouge">close(fd)</code> <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html">POSIX close</a></li>
</ul>

<p>These are some of the basic ones, there are others such as <code class="language-plaintext highlighter-rouge">lseek</code> and <code class="language-plaintext highlighter-rouge">ioctl</code> but I’ve yet to use these extensively.</p>

<p>The usage of these is pretty straight forward with some caveats for read and write.</p>

<p>Back when I was taking my OS class I figured that I can just make both my buffer and count absurdly large in order to make less calls to read and write, however your OS will determine how many bytes it wants to flush out, so don’t assume that your calls to read and write will return the exact same count you specified. The same goes for sockets as well which are interacted with through this same file descriptor api.</p>

<h2 id="resources-for-further-reading">Resources for Further Reading</h2>
<ul>
  <li><a href="https://pubs.opengroup.org/onlinepubs/9799919799/">The POSIX Standard</a></li>
  <li><a href="https://elixir.bootlin.com/linux/v7.1.3/source/include/linux/fdtable.h">fdtable.h</a></li>
</ul>

<p>-Nate</p>]]></content><author><name></name></author><category term="IO" /><summary type="html"><![CDATA[In *nix, everything is a file (sortof)]]></summary></entry><entry><title type="html">Welcome to Coding Beyond!</title><link href="https://codingbeyond.com/introduction/2026/07/09/welcome-to-coding-beyond.html" rel="alternate" type="text/html" title="Welcome to Coding Beyond!" /><published>2026-07-09T17:55:42-04:00</published><updated>2026-07-09T17:55:42-04:00</updated><id>https://codingbeyond.com/introduction/2026/07/09/welcome-to-coding-beyond</id><content type="html" xml:base="https://codingbeyond.com/introduction/2026/07/09/welcome-to-coding-beyond.html"><![CDATA[<p>Hello and welcome to Coding Beyond. I’m Nate, a software engineer and current CS master’s student.</p>

<p>For the last few years I’ve been debating on what the focus of this site would be, at first I thought maybe technical tutorials…</p>

<p>However with that comes the dreaded tutorial hell, and I believe that learning is best done hands on or in a way that encourages exploration
rather than memorizing and copying off a screen. To wit this site won’t have any sort of tutorials and will assume a fundamental understanding
of computer science. I will provide some explanation here and there of why I went with a paradigm or why I used a circular buffer here and there,
or what it means to save cpu cycles.</p>

<p>This site will mainly serve as a blog to document the areas of computer science that I find interesting, mainly that of low level programming and
systems engineering. Maybe on the rare occassion I’ll write about the hotest new JS framework out there but this site’s primary focus will be the former. So expect alot of posts about linux, kernel modules, device driver development, C programming, and so forth.</p>

<p>-Nate</p>]]></content><author><name></name></author><category term="introduction" /><summary type="html"><![CDATA[An introduction to Coding Beyond and what the site will focus on.]]></summary></entry></feed>