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;
 }

Reply via email to