Create path via libc mkdir(2) if it does not already exist
(single path component — not a recursive mkdir -p; a missing
grandparent still fails, loudly, at the inquire re-check
below). Exists to close the headline P7 crash: &ocean_diag_nml/
&output_nml default output_dir = "./output"
(rdb_config.F90:2316), so a first-time create() against a
fresh checkout with no ./output/ directory would otherwise
reach nc_create_file -> nf90_create -> ENOENT ->
error stop, killing the whole host process.
Never error stops itself, present ierr or not — the caller
decides how to fail (via its OWN nc_create_file(..., ierr=)
call on the resulting still-missing directory, or by checking
this routine’s ierr directly). ierr is a plain 0-ok/
non-zero-failed flag (not an nf90_* status), because mkdir
is not a NetCDF call and has no nc_check counterpart.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | path | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero iff |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | private, | allocatable, target | :: | c_path(:) | |||
| logical, | private | :: | exists | ||||
| integer(kind=c_int), | private | :: | rc |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | dirpath | ||
| integer(kind=c_int), | intent(in), | value | :: | mode |
subroutine ensure_directory_exists(path, ierr) !! Create `path` via libc `mkdir(2)` if it does not already exist !! (single path component — not a recursive `mkdir -p`; a missing !! grandparent still fails, loudly, at the `inquire` re-check !! below). Exists to close the headline P7 crash: `&ocean_diag_nml`/ !! `&output_nml` default `output_dir = "./output"` !! (`rdb_config.F90:2316`), so a first-time `create()` against a !! fresh checkout with no `./output/` directory would otherwise !! reach `nc_create_file` -> `nf90_create` -> ENOENT -> !! `error stop`, killing the whole host process. !! !! Never `error stop`s itself, present `ierr` or not — the caller !! decides how to fail (via its OWN `nc_create_file(..., ierr=)` !! call on the resulting still-missing directory, or by checking !! this routine's `ierr` directly). `ierr` is a plain 0-ok/ !! non-zero-failed flag (not an `nf90_*` status), because `mkdir` !! is not a NetCDF call and has no `nc_check` counterpart. character(len=*), intent(in) :: path integer, intent(out), optional :: ierr !! Non-zero iff `path` still does not exist after the `mkdir` !! attempt. Absent is legal — the routine just does its best and !! lets the caller's own I/O call fail loud. logical :: exists integer(c_int) :: rc character(kind=c_char), allocatable, target :: c_path(:) interface function c_mkdir(dirpath, mode) bind(C, name="mkdir") result(r) import :: c_ptr, c_int implicit none type(c_ptr), value, intent(in) :: dirpath integer(c_int), value, intent(in) :: mode integer(c_int) :: r end function c_mkdir end interface if (present(ierr)) ierr = 0 if (len_trim(path) == 0) return inquire (file=trim(path), exist=exists) if (exists) return c_path = path_to_c_string(trim(path)) rc = c_mkdir(c_loc(c_path), int(o'755', c_int)) if (rc /= 0_c_int) then call logger%warning("ensure_directory_exists: mkdir('"//trim(path)// & "') returned "//to_string(int(rc))// & " -- the subsequent NetCDF create/open will "// & "report the exact failure if the directory "// & "is still missing") end if inquire (file=trim(path), exist=exists) if (.not. exists) then if (present(ierr)) ierr = -1 end if end subroutine ensure_directory_exists