linux-sysprog · intermediate · ~20 min
Hand-written colon-delimited parser without `strtok` (which has shared state).
Implement int parse_passwd_line(const char *line, char *user, size_t user_cap, int *uid, char *home, size_t home_cap).
The line format is:
username:x:uid:gid:gecos:home:shell
Extract:
user (field 0) — copy to user, NUL-terminated, capped at user_cap-1.uid (field 2) — parse as int into *uid.home (field 5) — copy to home, NUL-terminated, capped at home_cap-1.Return:
0 on success.-1 if any required field is missing, parsing fails, or any buffer is too small to hold its field.parse_passwd_line("alice:x:1000:1000:Alice:/home/alice:/bin/bash",
user, 32, &uid, home, 64)
-> 0, user="alice", uid=1000, home="/home/alice"
parse_passwd_line("incomplete:x:1", ...) -> -1
parse_passwd_line("alice:x:abc:1000:Alice:/home:/sh", ...) -> -1 // non-numeric uid
/etc/passwd is the canonical colon-separated file. Every Linux administration tool reads it. Practising the parse builds the muscle for any colon- or tab-separated config format.
Line + output buffers.
0 / -1 + populated outputs.
No strtok (re-entrancy concern); use pointer scanning.
#include <stddef.h>
int parse_passwd_line(const char *line, char *user, size_t user_cap,
int *uid, char *home, size_t home_cap) { /* TODO */ return -1; }
Using strtok and clobbering each delimiter — fine for this exercise but bad habit for multi-threaded code.
Missing fields; empty fields; UID = 0 (root); buffer too small.
O(strlen(line)).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.