https://gcc.gnu.org/g:b2647ee4e0c3a4a55feb27d0d1e40fd2bba8a983
commit r17-4430-gb2647ee4e0c3a4a55feb27d0d1e40fd2bba8a983 Author: Xavier Del Campo Romero <[email protected]> Date: Thu Sep 17 23:10:57 2026 +0200 cobol: cdf-copy.cc: Report on COPY directory Otherwise, the compiler would fail to mmap(2) the directory and lead to a rather confusing diagnostic, when information about the file path is already lost, thus making it difficult to pinpoint the root cause. For example, the following diagnostic could be triggered previously: cobol1: fatal error: No such device: map_file: could not map fd 6 Now, a more descriptive error message is shown: dir.cbl:5:1: error: copybook 'thisisadir.cpy' is a directory gcc/cobol/ChangeLog: * cdf-copy.cc (copybook_elem_t::open_file): Use fstat(2). Diff: --- gcc/cobol/cdf-copy.cc | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc index 02c6240eaa35..978896650464 100644 --- a/gcc/cobol/cdf-copy.cc +++ b/gcc/cobol/cdf-copy.cc @@ -280,14 +280,21 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { dbgmsg("could not open %s: %s", path, xstrerror(errno)); return fd; } + struct stat sb; + if (fstat(fd, &sb)) { + error_msg(source.loc, "fstat %qs failed: %s", path, xstrerror(errno)); + goto failure; + } + else if (S_ISDIR(sb.st_mode)) { + error_msg(source.loc, "copybook %qs is a directory", path); + goto failure; + } this->source.name = path; if( ! cobol_filename(this->source.name, inode_of(fd)) ) { error_msg(source.loc, "recursive copybook: '%s' includes itself", path); - (void)! close(fd); - fd = -1; - } else { - cbl_message(LexInputN, "opening %qs for input", source.name); + goto failure; } + cbl_message(LexInputN, "opening %qs for input", source.name); return fd; } gcc_assert( ! literally ); @@ -314,17 +321,32 @@ copybook_elem_t::open_file( const char directory[], bool literally ) { auto filename = pattern.c_str(); if( (this->fd = open(filename, O_RDONLY)) != -1 ) { + struct stat sb; + if (fstat(fd, &sb)) { + error_msg(source.loc, "fstat %qs failed: %s", filename, + xstrerror(errno)); + goto failure; + } + else if (S_ISDIR(sb.st_mode)) { + error_msg(source.loc, "copybook %qs is a directory", filename); + goto failure; + } this->source.name = xstrdup(filename); if( ! cobol_filename(this->source.name, inode_of(fd)) ) { error_msg(source.loc, "recursive copybook: '%s' includes itself", this->source.name); - (void)! close(fd); - fd = -1; + + goto failure; } dbgmsg("%s: opened %s as fd %d", __func__, source.name, fd); return fd; } } +failure: + if (fd >= 0) { + (void)! close(fd); + } + return -1; }
