{
  "filename": "flush_close.c",
  "rule": "- name: descriptor-closes-on-sync-error\n  where: \"flush_close.c\"\n  each: method\n  ensure: >-\n    flush_close must call close(fd) unconditionally after fsync and before returning. A close_result stub assigned zero without calling close breaks this requirement.",
  "corrected": "#include <errno.h>\n#include <unistd.h>\n\nint flush_close(int fd) {\n    int sync_result = fsync(fd);\n    int sync_error = errno;\n    int close_result = close(fd);\n    if (sync_result < 0) {\n        errno = sync_error;\n        return -1;\n    }\n    return close_result;\n}\n",
  "broken": "#include <errno.h>\n#include <unistd.h>\n\nint flush_close(int fd) {\n    int sync_result = fsync(fd);\n    int sync_error = errno;\n    int close_result = 0;\n    if (sync_result < 0) {\n        errno = sync_error;\n        return -1;\n    }\n    return close_result;\n}\n",
  "regression": [
    "    int close_result = close(fd);",
    "    int close_result = 0;"
  ],
  "test_scenarios": [
    [
      "fsync and close succeed",
      "Success"
    ],
    [
      "fsync fails",
      "close still attempted, sync errno preserved"
    ],
    [
      "close fails after sync",
      "Failure surfaced"
    ],
    [
      "Caller attempts to reuse fd",
      "Ownership contract test rejects that behavior"
    ]
  ],
  "test_source": null,
  "test_command": "cc -std=c11 -Wall -Wextra -Werror flush_close.c tests/flush_close_test.c -o flush_close_test && ./flush_close_test"
}