w: exits with error when utmp session references a missing tty device

Open
#718 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
72/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
linux, rust

Research direction

Start with tests/by-util/test_w.rs and reproduce the failure using the provided stale utmp record, then run the focused test or cargo test. Trace the w command path that reports the missing tty device and verify that sessions referencing nonexistent devices no longer make w exit with an error while the test passes on ubuntu-latest.

Written by the indexing model from the issue text.

Description

w

Summary

On Linux, w can fail with exit code 1 when /var/run/utmp (or /run/utmp) contains a user session whose tty device does not exist under /dev/.

This is visible in CI (cargo test on ubuntu-latest) and can also happen on real systems when utmp records reference stale or non-device tty names (e.g. certain pts/N, seat names, or leftover entries).

This fails on ubuntu-latest in GitHub Actions, while the same test often passes locally when no utmp records are present.

test test_watch::test_valid_interval_comma ... ok

failures:

---- test_w::test_option_short stdout ----
bin: "/home/runner/work/procps/procps/target/debug/procps"
run: /home/runner/work/procps/procps/target/debug/procps w --short

thread 'test_w::test_option_short' (11461) panicked at tests/by-util/test_w.rs:44:42:
Command was expected to succeed. code: 1
stdout = 
 stderr = w: failed to fetch user info: No such file or directory (os error 2)

note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    test_w::test_option_short

test result: FAILED. 221 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 3.90s

error: test failed, to rerun pass `-p procps --test tests`
Error: Process completed with exit code 101.

Local Reproduction

Create a utmp record with a user session pointing at a non-existent tty:

python3 << 'PY'
import ctypes, os, time

class ExitStatus(ctypes.Structure):
    _fields_ = [("e_termination", ctypes.c_short), ("e_exit", ctypes.c_short)]

class Utmpx(ctypes.Structure):
    _fields_ = [
        ("ut_type", ctypes.c_short), ("_pad", ctypes.c_short),
        ("ut_pid", ctypes.c_int), ("ut_line", ctypes.c_char * 32),
        ("ut_id", ctypes.c_char * 4), ("ut_user", ctypes.c_char * 32),
        ("ut_host", ctypes.c_char * 256), ("ut_exit", ExitStatus),
        ("ut_session", ctypes.c_int), ("ut_tv_sec", ctypes.c_long),
        ("ut_tv_usec", ctypes.c_long), ("ut_addr_v6", ctypes.c_int * 4),
        ("reserved", ctypes.c_char * 20),
    ]

u = Utmpx()
u.ut_type = 7  # USER_PROCESS
u.ut_pid = os.getpid()
u.ut_line = b"no-such-tty-ci"
u.ut_user = b"testuser"
u.ut_tv_sec = int(time.time())
open("/tmp/fake-ci.utmp", "wb").write(bytes(u))
print("wrote /tmp/fake-ci.utmp")
PY

sudo cp /tmp/fake-ci.utmp /run/utmp
cargo run -q w --short
echo "exit code: $?"
sudo rm -f /run/utmp
Dominant language
Rust
Stars
116
Forks
38
Avg merge
1d 3h
Merged PRs (30d)
14

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from uutils/procps

All issues in uutils/procps

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.