{"record":{"id":"0172930aa6b514f1","repo":"NationalSecurityAgency/ghidra","slug":"s-error-file-refers-to-a-directory-n","errorCode":null,"errorMessage":"%s: error: @-file refers to a directory\\n","messagePattern":"(.+?): error: @-file refers to a directory\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"GPL/DemanglerGnu/src/demangler_gnu_v2_41/c/argv.c","lineNumber":414,"sourceCode":"#ifdef S_ISDIR\n      struct stat sb;\n#endif\n      /* We are only interested in options of the form \"@file\".  */\n      filename = (*argvp)[i];\n      if (filename[0] != '@')\n\tcontinue;\n      /* If we have iterated too many times then stop.  */\n      if (-- iteration_limit == 0)\n\t{\n\t  fprintf (stderr, \"%s: error: too many @-files encountered\\n\", (*argvp)[0]);\n\t  xexit (1);\n\t}\n#ifdef S_ISDIR\n      if (stat (filename+1, &sb) < 0)\n\tcontinue;\n      if (S_ISDIR(sb.st_mode))\n\t{\n\t  fprintf (stderr, \"%s: error: @-file refers to a directory\\n\", (*argvp)[0]);\n\t  xexit (1);\n\t}\n#endif\n      /* Read the contents of the file.  */\n      f = fopen (++filename, \"r\");\n      if (!f)\n\tcontinue;\n      if (fseek (f, 0L, SEEK_END) == -1)\n\tgoto error;\n      pos = ftell (f);\n      if (pos == -1)\n\tgoto error;\n      if (fseek (f, 0L, SEEK_SET) == -1)\n\tgoto error;\n      buffer = (char *) xmalloc (pos * sizeof (char) + 1);\n      len = fread (buffer, sizeof (char), pos, f);\n      if (len != (size_t) pos\n\t  /* On Windows, fread may return a value smaller than POS,","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/GPL/DemanglerGnu/src/demangler_gnu_v2_41/c/argv.c#L396-L432","documentation":"When expanding an @file argument, expandargv calls stat() on the path. If S_ISDIR reports the path is a directory, the tool cannot read it as a text response file and calls xexit(1). The check is guarded by #ifdef S_ISDIR.","triggerScenarios":"User passes `@/some/path` where that path resolves to a directory (S_ISDIR is true). The stat succeeds but the mode check fails. The tool exits with code 1.","commonSituations":"Typo or wrong path in the @file argument pointing to a directory; build system generates the @file path incorrectly; accidentally using a directory path instead of a file path.","solutions":["Point the @file argument at an actual file, not a directory","Verify the path exists and is a regular file with `ls -la`","Fix the build script that generates the @file path"],"exampleFix":"# before\n./tool @mydir\n# after\n./tool @mydir/options.txt","handlingStrategy":"validation","validationCode":"// Validate @file arguments: ensure they point to regular files, not directories\n#include <sys/stat.h>\nstatic int validate_at_files(int argc, char *const argv[]) {\n    for (int i = 0; i < argc; i++) {\n        if (argv[i][0] != '@') continue;\n        struct stat sb;\n        if (stat(argv[i] + 1, &sb) == 0 && S_ISDIR(sb.st_mode)) {\n            fprintf(stderr, \"@-file '%s' is a directory\\n\", argv[i] + 1);\n            return 0;\n        }\n    }\n    return 1;\n}","typeGuard":"static int is_regular_at_file(const char *arg) {\n    if (!arg || arg[0] != '@') return 0;\n    struct stat sb;\n    if (stat(arg + 1, &sb) != 0) return 0;\n    return S_ISREG(sb.st_mode);\n}","tryCatchPattern":null,"preventionTips":["Verify @file paths point to regular files with stat() before expanding","Use absolute paths to avoid directory confusion","Check return values of stat in build scripts before generating @file arguments"],"tags":["cli","arguments","response-file","filesystem","c"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}