PreviousUpNext

15.3.512  src/lib/std/src/posix/spawn.api

## spawn.api    -- high-level api for spawning unix child processes.

# Compiled by:
#     src/lib/std/src/standard-core.sublib



# An API for running subprocesses which is richer than
# the portable one provided by Winix_Process in
#
#     src/lib/std/src/winix/winix-process.api
#
# but simpler than the raw Posix api provided by Posix_Process in
#
#     src/lib/std/src/posix-1003.1b/posix-process.api 

# This API is implemented in:
#     src/lib/std/src/posix/spawn.pkg

stipulate
    package bio =  data_file;                                                                   # data_file             is from   src/lib/std/src/posix/data-file.pkg
    package fil =  file;                                                                        # file                  is from   src/lib/std/src/posix/file.pkg
    package ps  =  posix_signal;                                                                # posix_signal          is from   src/lib/std/src/posix-1003.1b/posix-signal.pkg
    package u1b =  one_byte_unt;                                                                # one_byte_unt          is from   src/lib/std/types-only/basis-structs.pkg
    package wt  =  winix_types;                                                                 # winix_types           is from   src/lib/std/src/posix/winix-types.pkg
herein                                                                                          # winix_types           is from   src/lib/std/src/win32/winix-types.pkg

    api Spawn {
        #
        Process(X,Y,Z);                         # The type variables are the stream types for child's stdin/stdout/stderr streams, as seen by the parent process. (i.e., output,input,input).

        Exit_Status
          #
          = W_EXITED
          | W_EXITSTATUS u1b::Unt
          | W_SIGNALED   ps::Signal
          | W_STOPPED    ps::Signal
          ;

        from_status
            :
            wt::process::Status
            ->
            Exit_Status;

        Spawn_Option
          #
          = WITH_ENVIRONMENT List(String)               # Defaults to posix_1003_1b::environment().
          #
          | REDIRECT_STDIN_IN_CHILD   Bool              # Defaults to TRUE.
          | REDIRECT_STDOUT_IN_CHILD  Bool              # Defaults to TRUE.
          | REDIRECT_STDERR_IN_CHILD  Bool              # Defaults to FALSE.
          #
          | REDIRECT_STDERR_TO_STDOUT_IN_CHILD  Bool    # Defaults to FALSE.
          ;

        spawn_process
            :
            { executable: String,               # executable -- "/usr/bin/foo" or such.
              arguments:  List(String),         # Remaining arguments for executable.
              options:    List(Spawn_Option)    
            }
            ->
            Process(X,Y,Z);
            #
            # spawn_process is the call to start up a program in a subprocess.
            #
            # By default the subprocess inherits the parent's environment
            # and stderr unchanged;  stdin/stdout are redirected into pipes
            # leading to the parent process. This behavior may be changed
            # via the options
            #
            #     WITH_ENVIRONMENT List(String)         # Defaults to posix_1003_1b::environment().
            #     REDIRECT_STDIN_IN_CHILD   Bool        # Defaults to TRUE.
            #     REDIRECT_STDOUT_IN_CHILD  Bool        # Defaults to TRUE.
            #     REDIRECT_STDERR_IN_CHILD  Bool        # Defaults to FALSE.
            #
            # Once the subprocess is spawned, its redirected streams
            # may be opened for text or binary I/O via
            #
            #     get_stdin_to_child_as_text_stream:            Process( fil::Output_Stream, X, Y ) ->  fil::Output_Stream;
            #     get_stdin_to_child_as_binary_stream:          Process( bio::Output_Stream, X, Y ) ->  bio::Output_Stream;
            #
            #     get_stdout_from_child_as_text_stream:         Process( X, fil::Input_Stream,  Y ) ->  fil::Input_Stream;
            #     get_stdout_from_child_as_binary_stream:       Process( X, bio::Input_Stream,  Y ) ->  bio::Input_Stream;
            #
            #     get_stderr_from_child_as_text_stream:         Process( X, Y, fil::Input_Stream ) ->  fil::Input_Stream;
            #     get_stderr_from_child_as_binary_stream:       Process( X, Y, bio::Input_Stream ) ->  bio::Input_Stream;
            #
            #   
            # invoking get_text_input_stream_from/get_text_output_stream_to or
            # get_binary_input_stream_from/get_binary_output_stream_to:
            #
            #
            # forks/execs new process running 'executable'.
            # The new process will have parent's environment 
            # unless overridden by WITH_ENVIRONMENT option.     
            # arguments args prepended by the last arc in 'executable'
            # (following the Unix convention that the first argument
            # is the command name).
            # Returns an abstract type Process(X,Y,Z) which represents
            # the child process plus streams attached to
            # the child process stdin/stdout.
            #
            # Sample call:
            #
            #   new_process
            #       =
            #       spawn_process
            #         {
            #           executable => "/usr/bin/foo",                                                                           # Process to run.
            #           arguments  => [ "-x", "this", "that" ],                                                                 # argv for process. ("foo" will be prepended.)
            #           options    => [ WITH_ENVIRONMENT ["LOGNAME=cynbe", "SHELL=/bin/tcsh", "HOME=/pub/home/cynbe" ]  ]       # This is an example, if WITH_ENVIRONMENT is omitted parent environment is inherited unchanged.
            #         };
            #
            # Simple command searching can be obtained by using
            #     spawn_process_in_environment { executable => "/bin/sh", arguments => [ "-c", args ], options => [] };

        fork_process:   List(Spawn_Option) -> Null_Or( Process(X,Y,Z) );
            #
            # fork_process is basically just a spawn_process()
            # that doesn't do an exece(), so we wind up with the
            # subprocess being a clone of ourself.
            #
            # The child  sees a NULL return value,
            # the parent sees a (THE process) return value:
            #
            # For a lower-level (essentially unix-level) fork() call see
            #
            #     src/lib/std/src/posix-1003.1b/posix-process.api
            #     src/lib/std/src/posix-1003.1b/posix-process.pkg

        

        bash: String -> String;

        # Access to stdin/stdout/stderr of child process.
        # NB: These are available only if fork_process/spawn_process
        # redirected them.
        # By default stdin and stdout are redirected, stderr is not.
        # This behavior may be changed via the options
        #     REDIRECT_STDIN_IN_CHILD   Bool    # Defaults to TRUE.
        #     REDIRECT_STDOUT_IN_CHILD  Bool    # Defaults to TRUE.
        #     REDIRECT_STDERR_IN_CHILD  Bool    # Defaults to FALSE.
        #
        # The underlying files are set to be close-on-exec.

        get_stdin_to_child_as_text_stream:      Process( fil::Output_Stream, X, Y ) ->  fil::Output_Stream;
        get_stdin_to_child_as_binary_stream:    Process( bio::Output_Stream, X, Y ) ->  bio::Output_Stream;

        get_stdout_from_child_as_text_stream:   Process( X, fil::Input_Stream,  Y ) ->  fil::Input_Stream;
        get_stdout_from_child_as_binary_stream: Process( X, bio::Input_Stream,  Y ) ->  bio::Input_Stream;

        get_stderr_from_child_as_text_stream:   Process( X, Y, fil::Input_Stream  ) ->  fil::Input_Stream;
        get_stderr_from_child_as_binary_stream: Process( X, Y, bio::Input_Stream  ) ->  bio::Input_Stream;

        process_id_of: Process(X,Y,Z) -> Int;

        text_streams_of
            :
            Process
              ( fil::Output_Stream,
                fil::Input_Stream,
                fil::Input_Stream
              )
            ->
            { stdin_to_child:       fil::Output_Stream,
              stdout_from_child:    fil::Input_Stream
            };

        reap:  Process(X,Y,Z) -> wt::process::Status;
            #
            # Closes the associated streams and wait for the
            # child process to finish, then return its exit status.
            #
            # Note that even if the child process has already exited,
            # so that reap returns immediately,
            # the parent process should eventually reap it. Otherwise,
            # the process will remain a zombie and take a slot in the
            # process table.

        # kill (proc, signal)
        # sends the Posix signal to the associated process.

        kill:  (Process(X,Y,Z), ps::Signal) -> Void;

        exit:  u1b::Unt -> X;
    };
end;

# SML/NJ (unhelpfully) calls this file/package 'Unix'


## COPYRIGHT (c) 1995 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2012,
## released under Gnu Public Licence version 3.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext