Skip to content

Commit 1449b8d

Browse files
committed
fixes to build
1 parent 519d53d commit 1449b8d

File tree

2 files changed

+87
-7
lines changed

2 files changed

+87
-7
lines changed

src/stdlib_system_subprocess.F90

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module fortran_subprocess
22
use iso_c_binding
33
use iso_fortran_env, only: int64, real64
44
use stdlib_system
5-
use stdlib_strings, only: to_c_string
5+
use stdlib_strings, only: to_c_string, join
66
use stdlib_linalg_state, only: linalg_state_type, LINALG_ERROR, linalg_error_handling
77
implicit none
88
public
@@ -59,6 +59,12 @@ subroutine process_wait(seconds) bind(C,name='process_wait')
5959
implicit none
6060
real(c_float), intent(in) :: seconds
6161
end subroutine process_wait
62+
63+
type(c_ptr) function process_null_device(len) bind(C,name='process_null_device')
64+
import c_ptr, c_int
65+
implicit none
66+
integer(c_int), intent(out) :: len
67+
end function process_null_device
6268

6369
end interface
6470

@@ -189,11 +195,11 @@ subroutine launch_asynchronous(process, args, stdin)
189195
character(c_char), dimension(:), allocatable, target :: c_cmd,c_stdin,c_stdin_file,c_stdout_file,c_stderr_file
190196

191197
! Assemble C strings
192-
c_cmd = c_string(join(args))
193-
if (present(stdin)) c_stdin = c_string(stdin)
194-
if (allocated(process%stdin_file)) c_stdin_file = c_string(process%stdin_file)
195-
if (allocated(process%stdout_file)) c_stdout_file = c_string(process%stdout_file)
196-
if (allocated(process%stderr_file)) c_stderr_file = c_string(process%stderr_file)
198+
c_cmd = to_c_string(join(args))
199+
if (present(stdin)) c_stdin = to_c_string(stdin)
200+
if (allocated(process%stdin_file)) c_stdin_file = to_c_string(process%stdin_file)
201+
if (allocated(process%stdout_file)) c_stdout_file = to_c_string(process%stdout_file)
202+
if (allocated(process%stderr_file)) c_stderr_file = to_c_string(process%stderr_file)
197203

198204
! On Windows, this 1) creates 2) launches an external process from C.
199205
! On unix, this 1) forks an external process
@@ -417,7 +423,68 @@ function scratch_name(prefix) result(temp_filename)
417423

418424
end function scratch_name
419425

420-
!> Helper function.
426+
427+
!> Assemble a single-line proces command line from a list of arguments.
428+
!>
429+
!> Version: Helper function.
430+
function assemble_cmd(args, stdin, stdout, stderr) result(cmd)
431+
!> Command to execute as a string
432+
character(len=*), intent(in) :: args(:)
433+
!> [optional] File name standard input (stdin) should be taken from
434+
character(len=*), optional, intent(in) :: stdin
435+
!> [optional] File name standard output (stdout) should be directed to
436+
character(len=*), optional, intent(in) :: stdout
437+
!> [optional] File name error output (stderr) should be directed to
438+
character(len=*), optional, intent(in) :: stderr
439+
440+
character(:), allocatable :: cmd,stdout_file,input_file,stderr_file
441+
442+
if (present(stdin)) then
443+
input_file = stdin
444+
else
445+
input_file = null_device()
446+
end if
447+
448+
if (present(stdout)) then
449+
! Redirect output to a file
450+
stdout_file = stdout
451+
else
452+
stdout_file = null_device()
453+
endif
454+
455+
if (present(stderr)) then
456+
stderr_file = stderr
457+
else
458+
stderr_file = null_device()
459+
end if
460+
461+
cmd = join(args)//" <"//input_file//" 1>"//stdout_file//" 2>"//stderr_file
462+
463+
end function assemble_cmd
464+
465+
!> Returns the file path of the null device for the current operating system.
466+
!>
467+
!> Version: Helper function.
468+
function null_device()
469+
character(:), allocatable :: null_device
470+
471+
integer(c_int) :: i, len
472+
type(c_ptr) :: c_path_ptr
473+
character(kind=c_char), pointer :: c_path(:)
474+
475+
! Call the C function to get the null device path and its length
476+
c_path_ptr = process_null_device(len)
477+
call c_f_pointer(c_path_ptr,c_path,[len])
478+
479+
! Allocate the Fortran string with the length returned from C
480+
allocate(character(len=len) :: null_device)
481+
482+
do concurrent (i=1:len)
483+
null_device(i:i) = c_path(i)
484+
end do
485+
486+
end function null_device
487+
421488
!> Reads a whole ASCII file and loads its contents into an allocatable character string..
422489
!> The function handles error states and optionally deletes the file after reading.
423490
!> Temporarily uses `linalg_state_type` in lieu of the generalized `state_type`.

src/stdlib_system_subprocess.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <stdio.h>
33
#include <stdbool.h>
44
#include <stdint.h>
5+
#include <string.h>
56

67
#ifdef _WIN32
78
#include <windows.h>
@@ -250,3 +251,15 @@ void process_wait(float seconds)
250251
usleep(uSeconds);
251252
#endif // _WIN32
252253
}
254+
255+
// Returns the cross-platform file path of the null device for the current operating system.
256+
const char* process_null_device(int* len)
257+
{
258+
#ifdef _WIN32
259+
(*len) = strlen("NUL");
260+
return "NUL";
261+
#else
262+
(*len) = strlen("/dev/null");
263+
return "/dev/null";
264+
#endif
265+
}

0 commit comments

Comments
 (0)