Message ID | c8e44598-adb6-8b3a-292b-6bef4622c86a@codesourcery.com |
---|---|
State | New |
Headers | show |
Series | gfortran.dg/read_dir.f90: Make PASS on Windows | expand |
On 19.12.22 10:26, Tobias Burnus wrote: > And here is a more light-wight variant, suggested by Nightstrike: > > Using '.' instead of creating a new directory - and checking for > __WIN32__ instead for __MINGW32__. > > The only downside of this variant is that it does not check whether > "close(10,status='delete')" will delete a directory without failing with > an error. – If the latter makes sense, I think a follow-up check should > be added to ensure the directory has indeed been removed by 'close'. I have now updated the heavy version. The #if check moved to C as those macros aren't set in Fortran. (That's now https://gcc.gnu.org/PR108175 - I thought that there was a PR before, but I couldn't find any.) Additionally, on Windows the '.' directory is now opened - avoiding issues with POSIX functions (and the requirement to use '#include <direct.h>' etc.). - As OPEN already fails, there is no point in checking for the rest. On the non-Windows side, there is now a check that 'CLOSE' with status='delete' indeed has deleted the directory. > Thoughts about which variant is better? Other suggestions or comments? ^- comments? > PS: On my x86-64 Linux, OPEN works but READ fails with EISDIR/errno == 21. And thanks to Nightstrike for testing, suggestions and reporting the issue at the first place. > On 19.12.22 10:09, Tobias Burnus wrote: >> As discussed in #gfortran IRC, on Windows opening a directory fails >> with EACCESS. >> (It works under Cygwin - nightstrike was so kind to test this.) >> >> Additionally, '[ -d dir ] || mkdir dir' is also not very portable. >> >> Hence, I use an auxiliary C file calling the POSIX functions and >> expect a fail for non-Cygwin windows. >> >> Comments? Suggestions? - If there aren't any, I plan to commit it >> as obvious tomorrow. I don't have a strong preference for the one-file/'.'/smaller solutions vs the two-file/mkdir/close-'delete' solution, but I am slightly inclined to the the one that tests more. Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
On 19.12.22 11:51, Tobias Burnus wrote: > On 19.12.22 10:26, Tobias Burnus wrote: >> And here is a more light-wight variant, suggested by Nightstrike: >> >> Using '.' instead of creating a new directory - and checking for >> __WIN32__ instead for __MINGW32__. [...] > I have now updated the heavy version. The #if check moved to C as those > macros aren't set in Fortran. (That's now https://gcc.gnu.org/PR108175 - > I thought that there was a PR before, but I couldn't find any.) This variant has now been committed as https://gcc.gnu.org/r13-4818-g18fc70aa9c753d17c00211cea9fa5bd843fe94fd Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
gfortran.dg/read_dir.f90: Make PASS on Windows Call POSIX's stat/mkdir/rmdir instead of using the shell via 'call system'. Additionally, expect EACCESS on non-Cygwin Windows as documented for trying to open a directory. gcc/testsuite/ChangeLog: * gfortran.dg/read_dir-aux.c: New; provides my_mkdir and my_rmdir. * gfortran.dg/read_dir.f90: Call my_mkdir/my_rmdir; expect error on Windows when opening a directory. gcc/testsuite/gfortran.dg/read_dir-aux.c | 39 +++++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/read_dir.f90 | 43 ++++++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gfortran.dg/read_dir-aux.c b/gcc/testsuite/gfortran.dg/read_dir-aux.c new file mode 100644 index 00000000000..e8404478517 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/read_dir-aux.c @@ -0,0 +1,39 @@ +#include <sys/stat.h> /* For mkdir + permission bits. */ +#include <unistd.h> /* For rmdir. */ +#include <errno.h> /* For errno. */ +#include <stdio.h> /* For perror. */ +#include <stdlib.h> /* For abort. */ + + +void +my_mkdir (const char *dir) +{ + int err; + struct stat path_stat; + + /* Check whether 'dir' exists and is a directory. */ + err = stat (dir, &path_stat); + if (err && errno != ENOENT) + { + perror ("my_mkdir: failed to call stat for directory"); + abort (); + } + if (err == 0 && !S_ISDIR (path_stat.st_mode)) + { + printf ("my_mkdir: pathname %s is not a directory\n", dir); + abort (); + } + + err = mkdir (dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + if (err != 0) + { + perror ("my_mkdir: failed to create directory"); + abort (); + } +} + +void +my_rmdir (const char *dir) +{ + rmdir (dir); +} diff --git a/gcc/testsuite/gfortran.dg/read_dir.f90 b/gcc/testsuite/gfortran.dg/read_dir.f90 index c7ddc51fb90..3a8ff6adbc7 100644 --- a/gcc/testsuite/gfortran.dg/read_dir.f90 +++ b/gcc/testsuite/gfortran.dg/read_dir.f90 @@ -1,18 +1,51 @@ ! { dg-do run } +! { dg-additional-options "-cpp" } +! { dg-additional-sources read_dir-aux.c } +! ! PR67367 + program bug + use iso_c_binding implicit none + + interface + subroutine my_mkdir(s) bind(C) + ! Call POSIX's mkdir - and ignore fails due to + ! existing directories but fail otherwise + import + character(len=1,kind=c_char) :: s(*) + end subroutine + subroutine my_rmdir(s) bind(C) + ! Call POSIX's rmdir - and ignore fails + import + character(len=1,kind=c_char) :: s(*) + end subroutine + end interface + + character(len=*), parameter :: sdir = "junko.dir" + character(len=*,kind=c_char), parameter :: c_sdir = sdir // c_null_char + character(len=1) :: c - character(len=256) :: message integer ios - call system('[ -d junko.dir ] || mkdir junko.dir') - open(unit=10, file='junko.dir',iostat=ios,action='read',access='stream') + + call my_mkdir(c_sdir) + open(unit=10, file=sdir,iostat=ios,action='read',access='stream') + +#if defined(__MINGW32__) + ! Windows is documented to fail with EACCESS when trying to open a directory + ! Note: Testing showed that __CYGWIN__ does permit opening directories + call my_rmdir(c_sdir) + if (ios == 0) & + stop 3 ! Expected EACCESS + stop 0 ! OK +#endif + if (ios.ne.0) then - call system('rmdir junko.dir') + call my_rmdir(c_sdir) STOP 1 end if read(10, iostat=ios) c - if (ios.ne.21.and.ios.ne.0) then + if (ios.ne.21.and.ios.ne.0) then ! EISDIR has often the value 21 close(10, status='delete') STOP 2 end if