Skip to content

system: subprocessing interface #911

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 60 commits into from
Feb 25, 2025
Merged

Conversation

perazz
Copy link
Member

@perazz perazz commented Dec 26, 2024

With this PR I want to introduce for discussion a comprehensive API for managing external processes in Fortran.
This is a fully cross-platform implementation for synchronous (similar to execute_command_line) or asynchronous (fully detached process) processes, and mimics functionality from the Python subprocess module.

Previous discussion

Proposed API

Here’s the simplified list of interfaces with their types and example usage:

  • type(process_type): A derived type representing the external process state containing the state handler as well as stdin, stdout, stderr as strings.
  • run a synchronous (blocking) process:
    process = run(cmd [, stdin=string] [, want_stdout=.false.] [, want_stderr=.false.])
  • runasync an asynchronous (non-blocking) process:
    process = runasync(cmd [, stdin=string] [, want_stdout=.false.] [, want_stderr=.false.])
  • update query process state and update the state variable:
    call update(process)
  • is_running check if a process is still running and update the handler:
    status = is_running(process)
  • is_completed check if a process has finished and update the handler:
    status = is_completed(process)
  • wait for completion (option for max waiting time in seconds):
    call wait(process [, max_wait_time=10.0])
  • elapsed time since process start, or total process lifetime:
    duration = elapsed(process)
  • kill a running external process:
    call kill(process, success)
  • sleep implementation is moved to C so that a slightly better wrapper based on nanosecond can be used

This provides a concise overview of the interfaces for quick reference.

Key facts

  • Traditional Fortran interfaces are used rather than type-bound procedures because that seems more similar to the other stdlib interfaces, but I'm happy to introduce them as well and further discuss the API.
  • stderr, stdout, stdin are stored via temporary files, but that is completely internal to the implementation. So, we can later implement faster memory-only communication via pipes without changing the API.
  • A cross-platform C interface routine was necessary. Because C macros are more informative, all platform-dependent operation is kept on the C side only.
  • Error handling is currently made via integer exit codes. If/when the type(state_type) general error handler is approved, we can improve this and use it throughout the subprocessing API too.

Prior art

@perazz
Copy link
Member Author

perazz commented Feb 4, 2025

I believe all community-requested features have been introduced.

Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice PR @perazz . Very valuable additions.
It could be helpful if the changes in stdlib_strings would have its own PR. It would be easier to review, and I believe it could be merged sooner. But it is also ok like this for me.

@perazz perazz mentioned this pull request Feb 11, 2025
Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for this PR.

@perazz
Copy link
Member Author

perazz commented Feb 19, 2025

Thank you @jvdp1 and @jalvesz for the reviews - let's wait another few days for comments, and then we can merge imho.

@perazz perazz merged commit 7ab1a5b into fortran-lang:master Feb 25, 2025
14 checks passed
@perazz
Copy link
Member Author

perazz commented Feb 25, 2025

Merging due to no further comments.

@perazz perazz deleted the subprocess branch March 1, 2025 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants