A Continuation of my Review of the book Systems Programming in Linux

Alright, so I am continuing to review this book, which by the way I find to be excellent so far, and with that in mind I am giving summaries of what you can find in each chapter. Of course, I am not one to give away the contents of a book as I believe everyone should really read it themselves to get the full benefit. With that in mind, you will find a link to a discount on this book at the end of this review if you’re so inclined.

Chapter 6: Overview of Filesystems and Files

So, I believe, chapter 6 is basically the ground floor of understanding Linux. It’s all about files—which, let’s be real, is everything in Linux.

We chat about how Linux treats almost everything as a file: regular files, directories, even hardware devices. The core idea is the file descriptor, which is just a small, non-negative integer the kernel gives you when you open a file (like $0$, $1$, and $2$ for standard input, output, and error, respectively). We cover the classic functions:

  • open() and close(): Pretty obvious, opening and closing the file.
  • read() and write(): How you actually move data in and out.
  • lseek(): This is the cool one! It lets you jump to a specific spot in a file to read or write, making it a random access file instead of just a sequential one.

It also introduces the concept of file metadata—stuff like who owns the file, its size, when it was last modified, and its permissions (read, write, execute). The stat family of functions is what you use to grab all that juicy info.

Chapter 7: The Directory Hierarchy

Building on Chapter 6, Chapter 7 zooms out from a single file to the big picture: how all those files are organized.

This is where we talk about the directory hierarchy—that inverted tree structure starting at the root, /. The chapter walks you through the essential directories (like /bin, /etc, /home, /dev, etc.) and what lives inside them.

The key functions here are about navigating and manipulating this structure:

  • chdir(): Changes the current working directory.
  • getcwd(): Gets the name of the current working directory.
  • mkdir() and rmdir(): Making and deleting directories.
  • link() and symlink(): The difference between hard links and symbolic (soft) links. A hard link is like an alias that points to the data itself, while a symbolic link is just a file containing the path to another file.

Chapter 8: Introduction to Signals

Alright, Chapter 8 is where things get a little more…interesting and asynchronous. Signals are a form of inter-process communication (IPC), but they are very lightweight and often used to notify a process of an event.

Think of a signal like a tap on the shoulder for a running process. For example:

  • SIGINT (Interrupt Signal): What happens when you press Ctrl+C—it tells the foreground process to stop.
  • SIGKILL (Kill Signal): A non-catchable, non-ignorable signal that forces a process to terminate immediately. The brute-force method!
  • SIGCHLD (Child Signal): A parent process gets this when one of its child processes dies or stops.

The chapter explains how a process can deal with a signal:

  1. Ignore it (most signals, not SIGKILL/SIGSTOP).
  2. Catch it, meaning you define a special function (a signal handler) to run when the signal arrives.
  3. Do the default action (usually terminate, dump core, or stop).

Chapter 9: Timers and Sleep Functions

Chapter 9 is all about controlling the flow of time (well, the program’s perception of it, anyway). If you need a program to wait, do something later, or measure performance, this is your go-to chapter.

We talk about different ways to pause or schedule activity:

  • sleep() and usleep() (or nanosleep()): The simple way to pause your process for a set amount of seconds or microseconds. Great for basic delays.
  • Interval Timers (setitimer): These are cooler. They let you schedule an action (like sending a signal, often SIGALRM) to happen repeatedly or after a specific delay. This is how you build something that needs to fire an event every, say, 5 seconds.

It also covers functions for getting the current time and performing basic time arithmetic, which is crucial for things like logging and benchmarking.

Chapter 10: Process Fundamentals

This chapter is the heart of Linux multi-tasking! It dives deep into what a process is and how they relate to each other.

Every running program is a process, and they are defined by their unique Process ID (PID). The chapter introduces the most important function in process creation: fork().

  • fork(): This function creates a nearly identical copy of the calling process (the parent), which becomes the child. They are initially identical, except for their PIDs and the return value of fork().
  • exec family of functions: This is how the child process stops being an identical copy and becomes a new program. The exec functions load a new executable file into the current process’s memory space, effectively replacing the old program with the new one.
  • wait()/waitpid(): A parent process uses these to pause and wait for a child process to terminate, collecting the child’s exit status. This is vital to prevent zombie processes (processes that are dead but still take up a slot in the process table because the parent hasn’t acknowledged their death).

Okay, so with that in mind, this book is fantastic. It has really helped me gain a deeper understanding of how Linux works. Of course, there are other additional books you will need to read and review in order to gain a much deeper and broader understanding but this one should definitely be on your bookshelf.

I can safely recommend that you go out and get this book. With the advent of artificial intelligence it is very necessary to obtain curated knowledge from known subject matter experts. The author of this book is definitely a subject matter expert and I am sad to learn he may have retired.

However, with that in mind, I would recommend you pick up this book if this is something you may need to learn about in the near future.

You can find a discount to this book here from nostarch.com.

System Programming in Linux – A Book Review

Recently, I was approached by a member of No Starch Press to review their latest version of Systems Programming in Linux by Professor Weiss. This book is perhaps one of the fundamental or pivotal books anyone who is involved in Linux should read. It is quite a lot of information to get through and that is why I have chosen to break my review of the book into multiple parts.

Now before you read on, I want to make sure you know that I was given this book to review for free but No Starch Press had no say in my review, nor did they have any say in what I would say about this book. I’ll provide an overview of the first five chapters, since this book is quite extensive.


Chapter 1: Core Concepts
This chapter sets the stage: what does “system programming” actually mean, and why does Linux make it so interesting? Instead of thinking in terms of flashy GUIs or big frameworks, system programming is all about talking directly to the operating system. You learn how Linux separates user space from kernel space, how files and devices are unified under the “everything is a file” philosophy, and why system calls are the tiny trapdoors your programs use to ask the kernel for help. It’s essentially a tour of how Linux thinks, which turns out to be refreshingly simple once you see the patterns.


Chapter 2: Fundamentals of System Programming
Once you understand the big picture, you start exploring the toolkit. This chapter covers the nuts and bolts every system programmer lives by: how processes exist and execute, what actually happens when you call a function that wraps a system call, how memory inside a running program is arranged, and why error handling matters at this level. It also touches on essential tools like compilers, debuggers, and tracing utilities. Think of it as foundational training—getting comfortable with the command line, build tools, and the mechanics of how your code interacts with the OS.

Chapter 3: Times, Dates, and Locales
Timekeeping in Linux is a surprisingly deep rabbit hole, and this chapter is all about understanding how the operating system measures, represents, and formats it. You get introduced to the difference between real time and monotonic time (which is a lifesaver when you want accurate timing), how time zones and daylight savings complicate things, and how Linux stores and manipulates timestamps. The chapter also expands into locales—how programs adapt to cultural differences in numbers, dates, and character encoding. It’s a reminder that system programming isn’t just about bits and bytes; it’s also about building software that plays nicely with a global audience.

Chapter 4: Basic Concepts of File I/O
If Linux had a religion, it would be “Everything is a file.” This chapter shows you why that matters and how to take advantage of it. You explore the basic file system operations—opening files, reading from them, writing to them, closing them—and how these operations differ between low-level system calls and higher-level standard library functions. You also learn how file descriptors serve as the universal handles for interacting with everything from regular files to pipes and devices. It’s all about building fluency in the fundamental I/O patterns that most higher-level tools are based on.

Chapter 5: File I/O and Login Accounting
After you’re comfortable with basic file handling, this chapter digs into more specialized territory. First, it deepens your understanding of file I/O by explaining additional flags, permissions, and behaviors that let you control how data moves between your program and the system. Then it shifts gears into login accounting—a uniquely Unixy concept. Linux keeps track of user sessions in a series of structured files, which system utilities use to show who’s logged in, when they logged in, and how the system is being used. You get a peek into how system monitoring tools get their information and why these tracking files matter for security and auditing.


So, that should give you an idea of what to expect from just the beginning of this book. While most guides you may find online only give cursory overviews this book gives in-depth explanations as to what is going on behind the scenes. That is why it should be on any enthusiasts bookshelf and it should be a part of your library if you have any role in using Linux in your day to day life or are just curious as to what is going on.


My first impressions of this book are quite good. I did learn quite a few things and some items that were a bit confusing about Linux to me were clarified. Clearly, the multiple decades of experience this author has in teaching the subject shows and I look forward to continue to review this book and gain a much deeper understanding of the subject.

One of the caveats of my reviewing this book was to give a discount code to my audience. You can get 25% off at checkout at the nostarch.com website by applying the code SYSPLINUX25. If this code changes I will update this post over time. One thing to note though is that this code is only valid until December 31th, 2025 so be sure to hurry to get that discount.

I will continue to review this book over the course of this month. Stay tuned!