Skip to content

Commit d8df028

Browse files
committed
document run interface
1 parent 136b5b8 commit d8df028

File tree

3 files changed

+97
-17
lines changed

3 files changed

+97
-17
lines changed

doc/specs/stdlib_system.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
title: system
3+
---
4+
5+
# System
6+
7+
[TOC]
8+
9+
## `run` - Execute an external process
10+
11+
### Status
12+
13+
Experimental
14+
15+
### Description
16+
17+
The `run` interface allows execution of external processes using a single command string or a list of arguments.
18+
Processes can be run either synchronously (blocking execution until the process finishes) or asynchronously (non-blocking execution).
19+
Optional arguments enable the collection of standard output and error streams, as well as sending input via standard input.
20+
21+
### Syntax
22+
23+
`process = ` [[stdlib_subprocess(module):run(interface)]] `(args [, wait] [, stdin] [, want_stdout] [, want_stderr])`
24+
25+
### Arguments
26+
27+
`args`: Shall be a `character(*)` string (for command-line execution) or a `character(*), dimension(:)` array (for argument-based execution). It specifies the command and arguments to execute. This is an `intent(in)` argument.
28+
29+
`wait` (optional): Shall be a `logical` flag. If `.true.` (default), the process will execute synchronously (blocking). If `.false.`, the process will execute asynchronously (non-blocking). This is an `intent(in)` argument.
30+
31+
`stdin` (optional): Shall be a `character(*)` value containing input to send to the process via standard input (pipe). This is an `intent(in)` argument.
32+
33+
`want_stdout` (optional): Shall be a `logical` flag. If `.true.`, the standard output of the process will be captured; if `.false.` (default), it will be lost. This is an `intent(in)` argument.
34+
35+
`want_stderr` (optional): Shall be a logical flag. If `.true.`, the standard error output of the process will be captured. Default: `.false.`. This is an `intent(in)` argument.
36+
37+
### Return Value
38+
39+
Returns an object of type `process_type` that contains information about the state of the created process.
40+
41+
### Example
42+
43+
```fortran
44+
! Example usage with command line or list of arguments
45+
type(process_type) :: p(2)
46+
47+
! Run a simple command line synchronously
48+
p(1) = run("echo 'Hello, world!'", wait=.true., want_stdout=.true.)
49+
50+
! Run a command using an argument list asynchronously
51+
p(2) = run(["/usr/bin/ls", "-l"], wait=.false.)
52+

src/stdlib_system.F90

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,57 @@ module stdlib_system
5454
end type process_type
5555

5656
interface run
57-
!> Open a new process from a command line
58-
module type(process_type) function process_open_cmd(cmd,wait,stdin,want_stdout,want_stderr) result(process)
59-
!> The command and arguments
57+
!! version: experimental
58+
!!
59+
!! Executes an external process, either synchronously or asynchronously.
60+
!! ([Specification](../page/specs/stdlib_system.html#run-execute-an-external-process))
61+
!!
62+
!! ### Summary
63+
!! Provides methods for executing external processes via a single command string or an argument list,
64+
!! with options for synchronous or asynchronous execution and output collection.
65+
!!
66+
!! ### Description
67+
!!
68+
!! This interface allows the user to spawn external processes using either a single command string
69+
!! or a list of arguments. Processes can be executed synchronously (blocking) or asynchronously
70+
!! (non-blocking), with optional request to collect standard output and error streams, or to provide
71+
!! a standard input stream via a `character` string.
72+
!!
73+
!! @note The implementation depends on system-level process management capabilities.
74+
!!
75+
!! #### Procedures
76+
!!
77+
!! - `process_open_cmd`: Opens a process using a command string.
78+
!! - `process_open_args`: Opens a process using an array of arguments.
79+
!!
80+
module type(process_type) function process_open_cmd(cmd, wait, stdin, want_stdout, want_stderr) result(process)
81+
!> The command line string to execute.
6082
character(*), intent(in) :: cmd
61-
!> Optional character input to be sent to the process via pipe
83+
!> Optional input sent to the process via standard input (stdin).
6284
character(*), optional, intent(in) :: stdin
63-
!> Define if the process should be synchronous (wait=.true.), or asynchronous(wait=.false.)
85+
!> Whether to wait for process completion (synchronous).
6486
logical, optional, intent(in) :: wait
65-
!> Require collecting output
66-
logical, optional, intent(in) :: want_stdout, want_stderr
87+
!> Whether to collect standard output.
88+
logical, optional, intent(in) :: want_stdout
89+
!> Whether to collect standard error output.
90+
logical, optional, intent(in) :: want_stderr
6791
end function process_open_cmd
68-
!> Open a new, asynchronous process from a list of arguments
69-
module type(process_type) function process_open_args(args,wait,stdin,want_stdout,want_stderr) result(process)
70-
!> The command and arguments
92+
93+
module type(process_type) function process_open_args(args, wait, stdin, want_stdout, want_stderr) result(process)
94+
!> List of arguments for the process to execute.
7195
character(*), intent(in) :: args(:)
72-
!> Optional character input to be sent to the process via pipe
96+
!> Optional input sent to the process via standard input (stdin).
7397
character(*), optional, intent(in) :: stdin
74-
!> Define if the process should be synchronous (wait=.true.), or asynchronous(wait=.false.)
98+
!> Whether to wait for process completion (synchronous).
7599
logical, optional, intent(in) :: wait
76-
!> Require collecting output
77-
logical, optional, intent(in) :: want_stdout, want_stderr
100+
!> Whether to collect standard output.
101+
logical, optional, intent(in) :: want_stdout
102+
!> Whether to collect standard error output.
103+
logical, optional, intent(in) :: want_stderr
78104
end function process_open_args
79105
end interface run
80106

107+
81108
!> Live check if a process is still running
82109
interface is_running
83110
module logical function process_is_running(process) result(is_running)

src/stdlib_system_subprocess.F90

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
use stdlib_linalg_state, only: linalg_state_type, LINALG_ERROR, linalg_error_handling
77
implicit none(type, external)
88

9-
logical(c_bool), parameter :: C_FALSE = .false._c_bool
10-
logical(c_bool), parameter :: C_TRUE = .true._c_bool
11-
129
! Number of CPU ticks between status updates
1310
integer(TICKS), parameter :: CHECK_EVERY_TICKS = 100
1411

@@ -70,6 +67,10 @@ end function process_has_win32
7067

7168
end interface
7269

70+
! C boolean constants
71+
logical(c_bool), parameter :: C_FALSE = .false._c_bool
72+
logical(c_bool), parameter :: C_TRUE = .true._c_bool
73+
7374
contains
7475

7576
! Call system-dependent wait implementation

0 commit comments

Comments
 (0)