@@ -2,7 +2,7 @@ module fortran_subprocess
2
2
use iso_c_binding
3
3
use iso_fortran_env, only: int64, real64
4
4
use stdlib_system
5
- use stdlib_strings, only: to_c_string
5
+ use stdlib_strings, only: to_c_string, join
6
6
use stdlib_linalg_state, only: linalg_state_type, LINALG_ERROR, linalg_error_handling
7
7
implicit none
8
8
public
@@ -59,6 +59,12 @@ subroutine process_wait(seconds) bind(C,name='process_wait')
59
59
implicit none
60
60
real (c_float), intent (in ) :: seconds
61
61
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
62
68
63
69
end interface
64
70
@@ -189,11 +195,11 @@ subroutine launch_asynchronous(process, args, stdin)
189
195
character (c_char), dimension (:), allocatable , target :: c_cmd,c_stdin,c_stdin_file,c_stdout_file,c_stderr_file
190
196
191
197
! 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)
197
203
198
204
! On Windows, this 1) creates 2) launches an external process from C.
199
205
! On unix, this 1) forks an external process
@@ -417,7 +423,68 @@ function scratch_name(prefix) result(temp_filename)
417
423
418
424
end function scratch_name
419
425
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
+
421
488
! > Reads a whole ASCII file and loads its contents into an allocatable character string..
422
489
! > The function handles error states and optionally deletes the file after reading.
423
490
! > Temporarily uses `linalg_state_type` in lieu of the generalized `state_type`.
0 commit comments