--- id: "bug-1716" status: "fixed" status_updated: "2026-09-24" status_note: "" component: "controller" severity: "unknown" timestamp: "2026-08-26T14:25:00Z" last_seen: "2026-09-19T09:00:00Z" occurrences: 1 files: ["src/controller/testsuite/rcfile.c"] tags: ["rcfile", "fopen", "EISDIR", "directory", "getline", "xce-test-rc-file", "controller-testsuite", "stderr-warning"] related: [] legacy: true --- # bug-1716: test_rcfile_load_directory_path_warns_and_returns_0:FAIL: Expected TRUE Was FALSE (stderr capture… ## Description test_rcfile_load_directory_path_warns_and_returns_0:FAIL: Expected TRUE Was FALSE (stderr capture was empty -- no warning printed) when rcfile_load() opened a directory path ## Environment _Not recorded (migrated from buglog.json)._ ## Reproduction _Not recorded (migrated from buglog.json)._ ## Root cause On this platform (glibc/Linux), fopen(path, "r") SUCCEEDS for a directory path -- it does not return NULL/set errno the way the design doc's error-handling section (and a naive reading of 'the file could not be opened for another reason') implied. The open failure only surfaces on the FIRST READ: getline() returns -1 with errno==EISDIR and ferror(f) set (feof(f) stays 0). rcfile_load()'s original implementation only checked `if (!f)` right after fopen() and had no post-loop check on the stream's error state, so a directory path silently produced rc=0 with zero lines processed and NO warning ever printed -- functionally 'safe' (no crash, no runner call) but silently violating the design's documented 'present but unreadable: print one stderr warning' contract for exactly this case. ## Fix Added a check after the getline() loop in rcfile_load(): `if (rc == 0 && ferror(f)) { fprintf(stderr, ...); }` -- prints the same warning message used for the fopen()-failure branch, keyed off ferror(f) rather than assuming the failure is only detectable at fopen() time. Confirmed live via a small standalone C repro (fopen("/tmp","r") then fread/getline) that fopen() returns a valid FILE* for a directory and the read call is what fails with EISDIR + ferror set. ## Verification _Not recorded (migrated from buglog.json)._ ## References _Not recorded (migrated from buglog.json)._