* [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows @ 2022-12-19 9:09 Tobias Burnus 2022-12-19 9:26 ` Tobias Burnus 0 siblings, 1 reply; 4+ messages in thread From: Tobias Burnus @ 2022-12-19 9:09 UTC (permalink / raw) To: gcc-patches, fortran, Jerry D, NightStrike [-- Attachment #1: Type: text/plain, Size: 696 bytes --] 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. 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 [-- Attachment #2: fix-read_dir.diff --] [-- Type: text/x-patch, Size: 3633 bytes --] 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows 2022-12-19 9:09 [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows Tobias Burnus @ 2022-12-19 9:26 ` Tobias Burnus 2022-12-19 10:51 ` Tobias Burnus 0 siblings, 1 reply; 4+ messages in thread From: Tobias Burnus @ 2022-12-19 9:26 UTC (permalink / raw) To: gcc-patches, fortran, Jerry D, NightStrike [-- Attachment #1: Type: text/plain, Size: 1372 bytes --] 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'. Thoughts about which variant is better? Other suggestions or comments? Tobias PS: On my x86-64 Linux, OPEN works but READ fails with EISDIR/errno == 21. 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. ----------------- 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 [-- Attachment #2: fix-read_dir-var2.diff --] [-- Type: text/x-patch, Size: 1667 bytes --] gfortran.dg/read_dir.f90: Make PASS on Windows Avoid call to the shell using POSIX syntax and use '.' instead. Additionally, expect fail on non-Cygwin Windows as opening a directory is documented to fail with EACCESS. gcc/testsuite/ChangeLog: * gfortran.dg/read_dir.f90: Open '.' instead of a freshly created directory; expect error on Windows when opening a directory. gcc/testsuite/gfortran.dg/read_dir.f90 | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/gfortran.dg/read_dir.f90 b/gcc/testsuite/gfortran.dg/read_dir.f90 index c7ddc51fb90..c91d0f78413 100644 --- a/gcc/testsuite/gfortran.dg/read_dir.f90 +++ b/gcc/testsuite/gfortran.dg/read_dir.f90 @@ -1,20 +1,27 @@ ! { dg-do run } +! { dg-additional-options "-cpp" } +! ! PR67367 + program bug implicit none 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') + open(unit=10, file='.',iostat=ios,action='read',access='stream') + +#if defined(__WIN32__) && !defined(__CYGWIN__) + ! Windows is documented to fail with EACCESS when trying to open a directory + if (ios == 0) & + stop 3 ! Expected EACCESS + stop 0 ! OK +#endif + if (ios.ne.0) then - call system('rmdir junko.dir') STOP 1 end if read(10, iostat=ios) c - if (ios.ne.21.and.ios.ne.0) then - close(10, status='delete') + close(10) + if (ios.ne.21.and.ios.ne.0) then ! EISDIR has often the value 21 STOP 2 end if - close(10, status='delete') end program bug ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows 2022-12-19 9:26 ` Tobias Burnus @ 2022-12-19 10:51 ` Tobias Burnus 2022-12-21 7:18 ` Tobias Burnus 0 siblings, 1 reply; 4+ messages in thread From: Tobias Burnus @ 2022-12-19 10:51 UTC (permalink / raw) To: gcc-patches, fortran, Jerry D, NightStrike [-- Attachment #1: Type: text/plain, Size: 2304 bytes --] 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 [-- Attachment #2: fix-read_dir-v2.diff --] [-- Type: text/x-patch, Size: 5286 bytes --] gfortran.dg/read_dir.f90: Make PASS on Windows On non-Cygwin Windows, use '.' and expect the documented fail when opening a directory (EACCESS). As gfortran does not set __WIN32__ this check is done on the C side. (On __CYGWIN__, __WIN32__ is not set - but to make it clear, !__CYGWIN__ is used in #if.) On non-Windows, replace the 'call system' shell call by the POSIX functions stat/mkdir/rmdir for better compatibility, especially on embedded systems; additionally add some more checks. In particular, confirm that 'close' with status='delete' indeed deleted the directory. gcc/testsuite/ChangeLog: * gfortran.dg/read_dir-aux.c: New; provides my_mkdir, my_rmdir, my_verify_not_exists and expect_open_to_fail. * gfortran.dg/read_dir.f90: Call those; expect that opening a directory fails on Windows. gcc/testsuite/gfortran.dg/read_dir-aux.c | 68 ++++++++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/read_dir.f90 | 54 ++++++++++++++++++++++--- 2 files changed, 117 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..307b44472af --- /dev/null +++ b/gcc/testsuite/gfortran.dg/read_dir-aux.c @@ -0,0 +1,68 @@ +#if defined(__WIN32__) && !defined(__CYGWIN__) + /* Mostly skip on Windows, cf. main file why. */ + +int expect_open_to_fail () { return 1; } + +void my_verify_not_exists (const char *dir) { } +void my_mkdir (const char *dir) { } +void my_rmdir (const char *dir) { } + +#else + +#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. */ + + +int expect_open_to_fail () { return 0; } + +void +my_verify_not_exists (const char *dir) +{ + struct stat path_stat; + int err = stat (dir, &path_stat); + if (err && errno == ENOENT) + return; /* OK */ + if (err) + perror ("my_verify_not_exists"); + else + printf ("my_verify_not_exists: pathname %s still exists\n", dir); + 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); +} + +#endif /* !defined(__WIN32__) || defined(__CYGWIN__) */ diff --git a/gcc/testsuite/gfortran.dg/read_dir.f90 b/gcc/testsuite/gfortran.dg/read_dir.f90 index c7ddc51fb90..2778210f079 100644 --- a/gcc/testsuite/gfortran.dg/read_dir.f90 +++ b/gcc/testsuite/gfortran.dg/read_dir.f90 @@ -1,20 +1,64 @@ ! { dg-do run } +! { dg-additional-sources read_dir-aux.c } +! ! PR67367 + program bug + use iso_c_binding implicit none + + interface + integer(c_int) function expect_open_to_fail () bind(C) + import + end + subroutine my_verify_not_exists(s) bind(C) + ! Aborts if the passed pathname (still) exists + import + character(len=1,kind=c_char) :: s(*) + end subroutine + 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') + + if (expect_open_to_fail () /= 0) then + ! Windows is documented to fail with EACCESS when trying to open a + ! directory. However, target macros such as __WIN32__ are not defined + ! in Fortran; hence, we use a detour via this C function. + ! Check for '.' which is a known-to-exist directory: + open(unit=10, file='.',iostat=ios,action='read',access='stream') + if (ios == 0) & + stop 3 ! Error: open to fail (EACCESS) + stop 0 ! OK + endif + + call my_mkdir(c_sdir) + open(unit=10, file=sdir,iostat=ios,action='read',access='stream') + 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') + call my_verify_not_exists(c_sdir) STOP 2 end if close(10, status='delete') + call my_verify_not_exists(c_sdir) end program bug ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows 2022-12-19 10:51 ` Tobias Burnus @ 2022-12-21 7:18 ` Tobias Burnus 0 siblings, 0 replies; 4+ messages in thread From: Tobias Burnus @ 2022-12-21 7:18 UTC (permalink / raw) To: gcc-patches, fortran, Jerry D, NightStrike 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-12-21 7:18 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-12-19 9:09 [Patch] gfortran.dg/read_dir.f90: Make PASS on Windows Tobias Burnus 2022-12-19 9:26 ` Tobias Burnus 2022-12-19 10:51 ` Tobias Burnus 2022-12-21 7:18 ` Tobias Burnus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).