Implement uptime command - display system uptime and load averages
Overview
Implement the uptime command to display system status information. This is a standard POSIX utility that shows how long the system has been running, current time, logged-in users, and system load averages.
Reference: https://man7.org/linux/man-pages/man1/uptime.1.html
Purpose
Display a one-line summary of system status:
- Current system time
- System uptime (how long since boot)
- Number of logged-in users
- System load averages (1, 5, and 15 minutes)
Requirements
Core Functionality
- [ ] Display current time
- [ ] Display system uptime (days, hours, minutes)
- [ ] Display number of active users
- [ ] Display load averages (1, 5, 15 minute intervals)
- [ ] Single-line output format
Essential Options
Must Have:
- [ ] Default format:
HH:MM:SS up DD days, HH:MM, N users, load average: X.XX, X.XX, X.XX - [ ]
-p, --pretty- Show uptime in human-readable format - [ ]
-s, --since- Show system boot time (YYYY-MM-DD HH:MM:SS)
Nice to Have:
- [ ]
--help- Display usage information - [ ]
--version- Display version information
Implementation Approach
Phase 1: Basic Uptime Display
Goal: Show system uptime without load averages or user count
// uptime.c - minimal version
#include <stdio.h>
#include <time.h>
#include <sys/sysinfo.h>
int main(int argc, char *argv[]) {
struct sysinfo info;
if (sysinfo(&info) < 0) {
perror("sysinfo");
return 1;
}
// Current time
time_t now = time(NULL);
struct tm *tm = localtime(&now);
printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec);
// Uptime
long uptime_secs = info.uptime;
int days = uptime_secs / 86400;
int hours = (uptime_secs % 86400) / 3600;
int minutes = (uptime_secs % 3600) / 60;
if (days > 0) {
printf("up %d day%s, %2d:%02d, ",
days, days > 1 ? "s" : "", hours, minutes);
} else {
printf("up %2d:%02d, ", hours, minutes);
}
// Placeholder for users (implement later)
printf("0 users, ");
// Placeholder for load (implement later)
printf("load average: 0.00, 0.00, 0.00\n");
return 0;
}
Phase 2: Add Load Averages
Implement system load tracking:
// Load averages represent average # of runnable/waiting processes
struct sysinfo {
unsigned long loads[3]; // 1, 5, 15 minute load averages
// ... scaled by 65536
};
// Display
printf("load average: %.2f, %.2f, %.2f\n",
info.loads[0] / 65536.0,
info.loads[1] / 65536.0,
info.loads[2] / 65536.0);
Phase 3: Add User Count
Count logged-in users (via utmp/wtmp or session tracking):
int count_users(void) {
// Option 1: Parse /var/run/utmp (if available)
// Option 2: Count active login sessions
// Option 3: Track via kernel session info
return 0; // Placeholder
}
Phase 4: Pretty Format
Add -p option for human-readable output:
// Example: "up 2 days, 3 hours, 45 minutes"
void print_pretty_uptime(long uptime_secs) {
int days = uptime_secs / 86400;
int hours = (uptime_secs % 86400) / 3600;
int minutes = (uptime_secs % 3600) / 60;
printf("up ");
if (days > 0) printf("%d day%s, ", days, days > 1 ? "s" : "");
if (hours > 0) printf("%d hour%s, ", hours, hours > 1 ? "s" : "");
printf("%d minute%s\n", minutes, minutes != 1 ? "s" : "");
}
Dependencies
Required (Check Availability)
-
Time syscalls -
time(),localtime()(likely available via #193, #240) - System boot time - Kernel must track boot timestamp
- sysinfo syscall - Or equivalent mechanism to get uptime
- Load average tracking - Kernel must calculate 1/5/15 minute averages
Optional (For Full Features)
- utmp/wtmp - For user count (if session tracking exists)
- Session management - Alternative to utmp for counting users
Check These Issues:
- #193 - Minimal libc (provides time functions?)
- #240 - time() syscall
- #239 - Kernel time syscalls
Kernel Support Needed
System Uptime:
- Kernel must track
boot_timeoruptime_seconds - Expose via
sysinfo()syscall or/proc/uptime
Load Averages:
- Track exponential moving average of runnable processes
- Calculate over 1, 5, and 15 minute windows
- Standard Unix algorithm (see Linux kernel
kernel/sched/loadavg.c)
Load Average Calculation:
// Simplified algorithm (runs periodically, e.g., every 5 seconds)
void update_load_averages(void) {
unsigned long active = nr_running + nr_uninterruptible;
// Exponential moving average with decay constants
load_avg_1 = (load_avg_1 * exp_1) + active * (1 - exp_1);
load_avg_5 = (load_avg_5 * exp_5) + active * (1 - exp_5);
load_avg_15 = (load_avg_15 * exp_15) + active * (1 - exp_15);
}
Testing Strategy
Basic Tests
# Test 1: Basic uptime display
uptime
# Expected: HH:MM:SS up X min, 0 users, load average: 0.00, 0.00, 0.00
# Test 2: Pretty format
uptime -p
# Expected: up X minutes
# Test 3: Since (boot time)
uptime -s
# Expected: YYYY-MM-DD HH:MM:SS
# Test 4: After running for hours
# (Run after system has been up for a while)
uptime
# Expected: Shows correct days/hours/minutes
Edge Cases
- System just booted (0 minutes uptime)
- System up for multiple days
- System up for exactly 24 hours
- Leap seconds / time changes
Implementation Phases
Phase 1: Minimal MVP (1-2 days)
- Display current time
- Display uptime (requires kernel boot_time)
- Hardcode users=0, load=0.00
- Basic format only
Phase 2: Load Averages (2-3 days)
- Implement kernel load tracking
- sysinfo() syscall to expose loads
- Display real load averages
Phase 3: User Count (1-2 days)
- Count active sessions/logins
- Display real user count
Phase 4: Options (1 day)
- Add -p (pretty)
- Add -s (since)
- Add --help
Integration
Build System
# app/uptime/Makefile
$(BUILD_DIR)/uptime: app/uptime/uptime.c
$(CC) $(CFLAGS) -o $@ $<
Disk Image
Package in /bin/uptime alongside other utilities:
- cat, echo, env, true, false, touch, realpath, stat, head
Documentation
Update README.md:
### System Utilities
- **uptime** — Display system uptime and load averages
Acceptance Criteria
- [ ]
uptimecommand available in/bin - [ ] Displays current time correctly
- [ ] Displays system uptime correctly
- [ ] Displays load averages (or 0.00 if not implemented)
- [ ] Displays user count (or 0 if not tracked)
- [ ]
-ppretty format works - [ ]
-ssince format works - [ ] Error handling for missing kernel support
- [ ] Documentation updated
Timeline
Estimated: 1-2 weeks (depending on kernel support required)
| Phase | Duration | Description |
|---|---|---|
| Phase 1 | 2-3 days | Basic uptime display (MVP) |
| Phase 2 | 2-3 days | Kernel load average tracking |
| Phase 3 | 1-2 days | User count integration |
| Phase 4 | 1 day | Pretty/since options |
| Documentation | 1 day | README, help text |
Priority
Medium - Useful system monitoring tool, commonly expected in Unix-like systems
Not critical for core functionality, but useful for:
- System administration
- Performance monitoring
- Debugging (understanding system load)
- Expected by users familiar with Unix/Linux
Related Issues
- #183 - /bin utilities (cat, echo, env, etc.) - Similar userland tools
- #240 - time() syscall - Required for current time
- #239 - Kernel time syscalls - May provide uptime support
- #370 - stat command - Recent userland utility
- #374 - head command - Recent userland utility
- #326 - Centralized timekeeper abstraction - May provide boot_time
Notes
Why Implement This?
- Common Unix Utility - Expected in most Unix-like systems
- System Monitoring - Quick way to check system status
- Performance Insight - Load averages show system health
- Administrative Tool - Useful for system management
- Quick Win - Basic version is straightforward
Scope Decisions
Include in MVP:
- Current time display
- System uptime (days/hours/minutes)
- Basic output format
- Pretty format (-p)
- Since format (-s)
Defer to Future:
- Accurate load averages (requires kernel work)
- User count (requires session tracking)
- Advanced options (--raw, etc.)
Implementation Notes
Kernel Support Required:
- Track system boot time (boot_timestamp)
- Expose via sysinfo() syscall or /proc/uptime
- Load average calculation (optional, can show 0.00)
Load Average Considerations:
- Standard Unix uses exponential moving average
- Decay constants: ~0.92 (1 min), ~0.98 (5 min), ~0.99 (15 min)
- Updated periodically (every 5 seconds typically)
- Not adjusted for CPU count
User Count Alternatives:
- Parse /var/run/utmp (if exists)
- Count active TTY sessions
- Track login/logout in kernel
- Start with 0 if tracking not available
Labels: enhancement, build Priority: Medium Complexity: Medium (requires kernel support for full implementation)