diff options
author | Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com> | 2021-05-27 20:04:51 +0200 |
---|---|---|
committer | Sebastian Ehlert <28669218+awvwgk@users.noreply.github.com> | 2021-05-27 20:09:13 +0200 |
commit | 3c9e6105c8458f6a59d2edc6fd7f2e79c18de943 (patch) | |
tree | 7c6f9a5e47460f7661941e1e866571036a84c1b7 /src/fpm_os.F90 | |
parent | 6d9004d93460dc15b99051c90d1b58d724b010e6 (diff) | |
download | fpm-3c9e6105c8458f6a59d2edc6fd7f2e79c18de943.tar.gz fpm-3c9e6105c8458f6a59d2edc6fd7f2e79c18de943.zip |
Allow fpm to change the working directory
Diffstat (limited to 'src/fpm_os.F90')
-rw-r--r-- | src/fpm_os.F90 | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/fpm_os.F90 b/src/fpm_os.F90 new file mode 100644 index 0000000..825df58 --- /dev/null +++ b/src/fpm_os.F90 @@ -0,0 +1,79 @@ +module fpm_os + use, intrinsic :: iso_c_binding, only : c_char, c_int, c_null_char + use fpm_error, only : error_t, fatal_error + implicit none + private + public :: change_directory, get_current_directory + +#ifndef _WIN32 + character(len=*), parameter :: pwd_env = "PWD" +#else + character(len=*), parameter :: pwd_env = "CD" +#endif + + interface + function chdir(path) result(stat) & +#ifndef _WIN32 + bind(C, name="chdir") +#else + bind(C, name="_chdir") +#endif + import :: c_char, c_int + character(kind=c_char, len=1), intent(in) :: path(*) + integer(c_int) :: stat + end function chdir + end interface + +contains + + subroutine change_directory(path, error) + character(len=*), intent(in) :: path + type(error_t), allocatable, intent(out) :: error + + character(kind=c_char, len=1), allocatable :: cpath(:) + integer :: stat + + allocate(cpath(len(path)+1)) + call f_c_character(path, cpath, len(path)+1) + + stat = chdir(cpath) + + if (stat /= 0) then + call fatal_error(error, "Failed to change directory to '"//path//"'") + end if + end subroutine change_directory + + subroutine f_c_character(rhs, lhs, len) + character(kind=c_char), intent(out) :: lhs(*) + character(len=*), intent(in) :: rhs + integer, intent(in) :: len + integer :: length + length = min(len-1, len_trim(rhs)) + + lhs(1:length) = transfer(rhs(1:length), lhs(1:length)) + lhs(length+1:length+1) = c_null_char + + end subroutine f_c_character + + subroutine get_current_directory(path) + character(len=:), allocatable, intent(out) :: path + + integer :: length, stat + + call get_environment_variable(pwd_env, length=length, status=stat) + if (stat /= 0) return + + allocate(character(len=length) :: path, stat=stat) + if (stat /= 0) return + + if (length > 0) then + call get_environment_variable(pwd_env, path, status=stat) + if (stat /= 0) then + deallocate(path) + return + end if + end if + + end subroutine get_current_directory + +end module fpm_os |