linux-sysprog · intermediate · ~15 min

Substitute $VAR with environment value

Combine string scanning with getenv and bounded output.

Challenge

Expand $VAR references in a string using the process environment, like a tiny envsubst.

Task

Implement int env_subst(const char *in, char *out, size_t out_sz) that copies in into out, replacing every $WORD reference with the value of that environment variable.

Input

  • in: a NUL-terminated source string. A reference is a $ immediately followed by one or more characters from [A-Za-z0-9_]; that run is the variable name.
  • out, out_sz: destination buffer and its size in bytes.

Output

Writes the expanded text into out (always NUL-terminated). Each $WORD is replaced by getenv("WORD"), or by nothing if that variable is unset. A $ not followed by a name character is copied verbatim. Returns 0 on success, or -1 if the result would not fit in out_sz.

Example

env CPLAT_USER=alice CPLAT_AGE=30
env_subst("hi $CPLAT_USER, age $CPLAT_AGE", out, 128)   ->   0, out = "hi alice, age 30"
env_subst("$NOPE here", out, 128)                        ->   0, out = " here"   (unset -> empty)
env_subst("hello $CPLAT_USER", out, 5)                   ->   -1                 (overflow)

Edge cases

  • An unset variable expands to the empty string.
  • If the output would exceed out_sz - 1 bytes, return -1.

Rules

  • Always NUL-terminate out.

Input format

A NUL-terminated source string in, plus an output buffer out of size out_sz. A $WORD reference is a $ followed by one or more [A-Za-z0-9_] characters.

Output format

Writes the expanded text (NUL-terminated) into out. Returns 0 on success, -1 if it would not fit.

Constraints

Unset variables expand to empty. A lone $ is copied as-is. Always NUL-terminate.

Starter code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int env_subst(const char *in, char *out, size_t out_sz) {
    /* TODO */
    return -1;
}

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.