Directories in Co-array Fortran

Here’s the translation of the Go code example to Co-array Fortran, formatted in Markdown suitable for Hugo:

Our program demonstrates working with directories in Co-array Fortran. Here’s the full source code:

program directories
  use, intrinsic :: iso_fortran_env
  use, intrinsic :: iso_c_binding
  implicit none

  interface
    function mkdir(path, mode) bind(c, name="mkdir")
      import :: c_char, c_int
      character(kind=c_char), intent(in) :: path(*)
      integer(c_int), value :: mode
      integer(c_int) :: mkdir
    end function mkdir

    function rmdir(path) bind(c, name="rmdir")
      import :: c_char, c_int
      character(kind=c_char), intent(in) :: path(*)
      integer(c_int) :: rmdir
    end function rmdir

    function chdir(path) bind(c, name="chdir")
      import :: c_char, c_int
      character(kind=c_char), intent(in) :: path(*)
      integer(c_int) :: chdir
    end function chdir
  end interface

  integer :: ierr
  character(len=:), allocatable :: current_dir

  ! Create a new sub-directory in the current working directory
  ierr = mkdir("subdir"//c_null_char, int(o'755', c_int))
  if (ierr /= 0) error stop "Failed to create directory"

  ! Helper subroutine to create an empty file
  call create_empty_file("subdir/file1")

  ! Create a hierarchy of directories
  ierr = mkdir("subdir/parent"//c_null_char, int(o'755', c_int))
  if (ierr /= 0) error stop "Failed to create parent directory"
  ierr = mkdir("subdir/parent/child"//c_null_char, int(o'755', c_int))
  if (ierr /= 0) error stop "Failed to create child directory"

  call create_empty_file("subdir/parent/file2")
  call create_empty_file("subdir/parent/file3")
  call create_empty_file("subdir/parent/child/file4")

  ! List directory contents
  print *, "Listing subdir/parent"
  call list_directory("subdir/parent")

  ! Change current working directory
  ierr = chdir("subdir/parent/child"//c_null_char)
  if (ierr /= 0) error stop "Failed to change directory"

  print *, "Listing current directory (subdir/parent/child)"
  call list_directory(".")

  ! Change back to original directory
  ierr = chdir("../../.."//c_null_char)
  if (ierr /= 0) error stop "Failed to change back to original directory"

  ! Visit directory recursively
  print *, "Visiting subdir"
  call visit_directory("subdir")

  ! Clean up (remove the created directory)
  ierr = rmdir("subdir"//c_null_char)
  if (ierr /= 0) error stop "Failed to remove directory"

contains

  subroutine create_empty_file(filename)
    character(len=*), intent(in) :: filename
    integer :: unit
    open(newunit=unit, file=filename, status="replace")
    close(unit)
  end subroutine create_empty_file

  subroutine list_directory(path)
    character(len=*), intent(in) :: path
    character(len=256) :: filename
    logical :: is_dir
    integer :: i

    do i = 1, 100  ! Arbitrary limit
      call execute_command_line("ls -d " // trim(path) // "/* 2>/dev/null", &
                                 command_status=ierr, command_line=filename)
      if (ierr /= 0) exit

      inquire(file=trim(filename), exist=is_dir, directory=is_dir)
      print *, " ", trim(filename), is_dir
    end do
  end subroutine list_directory

  recursive subroutine visit_directory(path)
    character(len=*), intent(in) :: path
    character(len=256) :: filename
    logical :: is_dir
    integer :: i

    print *, " ", trim(path)

    do i = 1, 100  ! Arbitrary limit
      call execute_command_line("ls -d " // trim(path) // "/* 2>/dev/null", &
                                 command_status=ierr, command_line=filename)
      if (ierr /= 0) exit

      inquire(file=trim(filename), exist=is_dir, directory=is_dir)
      if (is_dir) then
        call visit_directory(trim(filename))
      else
        print *, " ", trim(filename)
      end if
    end do
  end subroutine visit_directory

end program directories

This program demonstrates various operations with directories in Co-array Fortran:

  1. We use C interoperability to call system functions like mkdir, rmdir, and chdir.
  2. We create a new directory and some files within it.
  3. We list the contents of directories.
  4. We change the current working directory and then change it back.
  5. We recursively visit and print the directory structure.
  6. Finally, we clean up by removing the created directory.

Note that Co-array Fortran doesn’t have built-in directory manipulation functions, so we’re using C interoperability to call system functions. The file operations are done using Fortran’s built-in facilities.

To compile and run this program, you would typically use:

$ gfortran -coarray=single directories.f90 -o directories
$ ./directories

The output will show the directory structure created and visited by the program.