Softanza
DémarrerEnglish
Softanza
Recherche · narration

Your First Taste of Systems Programming - Without the Fear

Systems programming traditionally requires mastering three domains:

par Mansour Ayouni · dans le dépôt depuis le 2025-07-12 · essai de fonction · domaine Programmation système

Cet article est écrit en anglais, comme la bibliothèque.

How Softanza's Complete Low-Level Framework Takes You from Buffers to OS Integration


The Three Pillars of Systems Programming

  1. Memory Management - Allocating, manipulating, and freeing memory safely
  2. Process Control - Spawning programs, capturing output, managing execution
  3. Data Transformation - Moving data between memory, files, and external tools

Softanza gives you all three in a safe, learnable environment:

  • stkBuffer/stkPointer - Safe memory operations with bounds checking
  • stzSystemCall - Cross-platform process execution with named commands
  • Integration layer - Seamless data flow between memory and OS

Part 1: Memory - Your Foundation

Understanding Buffers

Buffers are chunks of memory you directly control:

Haro
# Create a buffer - like a box that holds 50 bytes
oMemory = new stkMemory()
oBuffer = oMemory.CreateBuffer(50)

? oBuffer.Size()        # --> 0 (nothing in it yet)
? oBuffer.Capacity()    # --> 50 (but can hold 50 bytes)

# Put data in it
oBuffer.Write(0, "Hello")
? oBuffer.Size()        # --> 5 (now has 5 bytes)
? oBuffer.Read(0, 5)    # --> "Hello"

illustration

Working with Pointers

Pointers let you reference memory indirectly:

Haro
# Create pointer to buffer section
oPointer = oBuffer.GetReadPointer()
? oPointer.Read(0, 5)   # --> "Hello"

# Create view of specific range
oView = oPointer.CreateSubView(0, 3)
? oView.ReadAll()       # --> "Hel"

illustration


Part 2: Process Control - Talking to the OS

The stzSystemCall Class

Instead of cryptic shell commands, use named operations:

Haro
# List files (cross-platform)
Sy = new stzSystemCall(:ListFiles)
? Sy.Run()
# Works on Windows, Linux, macOS automatically

# Copy file with parameters
Sy = new stzSystemCall(:CopyFile)
Sy.SetParam(:source, "data.txt")
Sy.SetParam(:dest, "backup.txt")
Sy.Run()

if Sy.Succeeded()
    ? "File copied successfully"
ok

illustration

Available Command Domains

Over 80 pre-built commands across categories:

  • Files: :CopyFile, :MoveFile, :FindFiles
  • Network: :Ping, :DownloadFile, :CurlPost
  • Git: :GitCommit, :GitPush, :GitStatus
  • Media: :ResizeImage, :VideoToGif, :CompressVideo
  • Database: :SqliteQuery, :SqliteBackup
  • Security: :EncryptFile, :Sha256sum
  • Docker: :DockerBuild, :DockerRun

All handle cross-platform differences automatically.


Part 3: Integration - Where Power Emerges

Buffer → SystemCall Pipeline

Process data through external tools:

Haro
# Create buffer with data
oBuffer = oMemory.CreateBuffer(1000)
oBuffer.Write(0, "# My Document\n\nContent here")

# Save to file
oBuffer.SaveToFileAll("doc.md")

# Convert with Pandoc
Sy = new stzSystemCall(:Markdown2Html)
Sy.SetParam(:input, "doc.md")
Sy.SetParam(:output, "doc.html")
Sy.Run()

# Load result back
oBuffer.Clear()
oBuffer.LoadFromFile("doc.html")
? oBuffer.Size()  # HTML is larger than Markdown

illustration

SystemCall → Buffer Pattern

Capture external tool output directly:

Haro
# Download file
Sy = new stzSystemCall(:DownloadFile)
Sy.SetParams([
    [:url, "https://api.example.com/data.json"],
    [:file, "temp.json"]
])
Sy.Run()

# Load into buffer for parsing
oBuffer.LoadFromFile("temp.json")
cJson = oBuffer.Read(0, oBuffer.Size())

# Process in memory
oData = ParseJson(cJson)

illustration

Direct Integration Methods

Enhanced buffer methods for syscalls:

Haro
# Load syscall output directly
oBuffer.LoadFromSystemCall(
    StzSystemCallQ(:GitLog).WithParamQ(:n, "5")
)

# Process buffer through tool
oBuffer.Write(0, "uncompressed data...")
Sy = new stzSystemCall(:GzipCompress)
oBuffer.SaveAndProcess("data.txt", Sy)

illustration


Part 4: Real-World Examples

Example 1: Image Processing Pipeline

Haro
# Download images
aUrls = ["url1", "url2", "url3"]
oDownload = new stzSystemCall(:DownloadFile)

for i = 1 to len(aUrls)
    oDownload.SetParams([
        [:url, aUrls[i]],
        [:file, "image" + i + ".jpg"]
    ])
    oDownload.Run()
next

# Batch resize
oResize = new stzSystemCall(:ResizeImage)
for i = 1 to 3
    oResize.Reset()
    oResize.SetParams([
        [:input, "image" + i + ".jpg"],
        [:size, "800x600"],
        [:output, "thumb" + i + ".jpg"]
    ])
    oResize.Run()
next

illustration

Example 2: Git Workflow Automation

Haro
# Check status
Sy = new stzSystemCall(:GitStatus)
cStatus = Sy.Run()

if substr(cStatus, "modified:") > 0
    # Commit changes
    new stzSystemCall(:GitCommit) {
        SetParam(:message, "Auto-commit: " + TimeStamp())
        Run()
    }
    
    # Push to remote
    new stzSystemCall(:GitPush) {
        SetParam(:branch, "main")
        Run()
        
        if Succeeded()
            ? "Pushed successfully"
        else
            ? "Push failed: " + Error()
        ok
    }
ok

illustration

Example 3: Data Processing Chain

Haro
# Download → Decompress → Parse → Process → Save

# 1. Download
StzSystemCallQ(:DownloadFile).
    SetParamsQ([[:url, "..."], [:file, "data.zip"]]).
    Run()

# 2. Extract
StzSystemCallQ(:UnzipFiles).
    SetParamsQ([[:source, "data.zip"], [:dest, "data/"]]).
    Run()

# 3. Load into buffer
oBuffer = oMemory.CreateBuffer(10000)
oBuffer.LoadFromFile("data/records.csv")

# 4. Process in memory
cCsv = oBuffer.Read(0, oBuffer.Size())
aRecords = ParseCSV(cCsv)
aFiltered = FilterRecords(aRecords)

# 5. Save results
oBuffer.Clear()
oBuffer.Write(0, RecordsToJSON(aFiltered))
oBuffer.SaveToFileAll("output.json")

illustration

Example 4: Binary File Analysis

Haro
# Download binary file
Sy = new stzSystemCall(:DownloadFile)
Sy.SetParams([[:url, "..."], [:file, "program.exe"]])
Sy.Run()

# Calculate checksum
oHash = new stzSystemCall(:Sha256sum)
oHash.SetParam(:file, "program.exe")
cChecksum = oHash.Run()

# Load into buffer for analysis
oBuffer = oMemory.CreateBuffer(1000000)
oBuffer.LoadFromFile("program.exe")

# Read header
cHeader = oBuffer.Read(0, 64)
? "Magic bytes: " + hex(cHeader[1]) + hex(cHeader[2])

# Get pointer to specific section
oPtr = oBuffer.GetReadPointer()
oView = oPtr.CreateSubView(100, 200)
? "Section data: " + oView.ReadAll()

illustration


Part 5: Advanced Patterns

Pattern 1: Streaming Large Files

Haro
# Process file in chunks
oBuffer = oMemory.CreateBuffer(4096)  # 4KB buffer
fp = fopen("large_file.dat", "rb")

nBytesRead = 0
while TRUE
    # Read chunk
    cChunk = fread(fp, 4096)
    if len(cChunk) = 0
        break
    ok
    
    # Load into buffer
    oBuffer.Clear()
    oBuffer.Write(0, cChunk)
    
    # Process through syscall
    oBuffer.SaveToFileAll("chunk.tmp")
    Sy = new stzSystemCall(:ProcessChunk)
    Sy.SetParam(:file, "chunk.tmp")
    Sy.Run()
    
    nBytesRead += len(cChunk)
end

fclose(fp)
? "Processed " + nBytesRead + " bytes"

illustration

Pattern 2: Error Recovery with Retry

Haro
def DownloadWithRetry(cUrl, cFile, nMaxRetries)
    Sy = new stzSystemCall(:DownloadFile)
    Sy.SetParams([[:url, cUrl], [:file, cFile]])
    
    for i = 1 to nMaxRetries
        Sy.Run()
        
        if Sy.Succeeded() and fexists(cFile)
            ? "Downloaded on attempt " + i
            return TRUE
        ok
        
        ? "Attempt " + i + " failed, retrying..."
        sleep(i * 1000)  # Exponential backoff
    next
    
    return FALSE

illustration

Pattern 3: Parallel Processing

Haro
# Process multiple files concurrently
aFiles = ["file1.jpg", "file2.jpg", "file3.jpg"]
aCalls = []

# Queue all operations
for cFile in aFiles
    Sy = new stzSystemCall(:ResizeImage)
    Sy.SetParams([
        [:input, cFile],
        [:size, "800x600"],
        [:output, "thumb_" + cFile]
    ])
    aCalls + Sy
next

# Execute (would need async support)
for oCall in aCalls
    oCall.Run()  # Future: oCall.RunAsync()
next

illustration


Part 6: Learning Path

Stage 1: Buffers (Week 1)

  • Create and manipulate buffers
  • Understand capacity vs size
  • Practice read/write operations
  • File loading and saving

Stage 2: System Calls (Week 2)

  • Execute simple commands
  • Work with parameters
  • Handle success/failure
  • Capture output

Stage 3: Integration (Week 3)

  • Buffer → File → SysCall → Buffer
  • Process data through external tools
  • Build simple pipelines
  • Error handling

Stage 4: Pointers (Week 4)

  • Create pointer views
  • Copy between pointers
  • Understand indirection
  • Zero-copy operations

Stage 5: Real Projects (Week 5+)

  • Build complete workflows
  • Optimize performance
  • Handle edge cases
  • Production patterns

Installation Requirements

For full functionality, install these external tools:

Bash, montré pour comparaison, non exécuté
# Git
https://git-scm.com/downloads

# ImageMagick
https://imagemagick.org/script/download.php

# FFmpeg
https://ffmpeg.org/download.html

# Pandoc
https://pandoc.org/installing.html

Optional Tools

Bash, montré pour comparaison, non exécuté
# Docker
https://docker.com/products/docker-desktop

# SQLite
https://sqlite.org/download.html

# GPG
https://gnupg.org/download/

Most tools provide installers for Windows, Linux, and macOS.


Why This Matters

Traditional systems programming requires:

  • Learning C/C++ syntax
  • Understanding pointers and segfaults
  • Platform-specific APIs
  • Manual memory management

Softanza's approach gives you:

  • ✅ Safe memory operations (no segfaults)
  • ✅ Cross-platform abstractions (one API)
  • ✅ Named operations (self-documenting)
  • ✅ Gradual learning curve (high → low level)
  • ✅ Real-world utility (production-ready)

You're not becoming a C programmer - you're becoming a systems-aware Haro programmer who understands what happens beneath the surface and can drop down when needed.

Citer

Mansour Ayouni. « Your First Taste of Systems Programming - Without the Fear ». Softanza narrations, 2025. https://mayouni.github.io/stzsite/fr/narrations/stz-lowlevel-system-programming.html

Non exécuté : son code touche aux fichiers, au réseau, à l'horloge ou au hasard. L'article est publié tel qu'il est écrit ; ses blocs sont des illustrations. Le code des articles est du code Haro. Là où un article a été écrit avant que la langue prenne son nom actuel, le nom a été changé et rien d'autre. Genre, domaine et série lus dans le nom du fichier, année tirée du premier commit : dérivés, jusqu'à ce que l'article porte son propre en-tête. Le fichier sur GitHub(s'ouvre dans un nouvel onglet)