Interface CommandCursor

All Superinterfaces:
AutoCloseable

public interface CommandCursor extends AutoCloseable
A cursor over the raw output of a running remote command, returned by WindowsRemoteExecutor.startCommand(String, String, long). Each next() is one WSMan Receive round trip yielding the output bytes exactly as the server handed them out — undecoded, because a multibyte character can be split across chunks; decode with a stateful CharsetDecoder (or accumulate the bytes and decode once at the end).

The cursor owns the executor's serial connection until the command completes or the cursor is closed: no other operation can run on the same executor while the cursor is open. Completion (a null return from next()) sends the protocol's terminate Signal and releases the connection on its own; closing earlier sends the same Signal, which actually stops the still-running remote command. Always close the cursor — use try-with-resources.

A cursor is not thread-safe: advance and close it from one thread at a time.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Interface
    Description
    static final class 
    One Receive response's worth of raw output bytes, split by stream.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Terminate the command (when it is still running) with the WinRM terminate Signal and release the executor's connection.
    int
    Get the command's exit code.
    default void
    Interrupt the command the way a console Ctrl+C would — the WSMan Signal operation with the ctrl_c code.
    Block until the remote command produces output (or completes), for at most one per-round-trip timeout.
    poll(long maxWaitMillis)
    Bounded variant of next(): block at most the given wait for output.
    poll(long askMillis, long maxWaitMillis)
    Cadence variant of poll(long): ask the server to answer within askMillis — the polling cadence — while allowing the answer itself up to maxWaitMillis to arrive.
    default void
    send(byte[] data, boolean end)
    Feed standard input to the running command — the WSMan Send operation, carrying the bytes to the command's stdin stream.
  • Method Details

    • next

      Block until the remote command produces output (or completes), for at most one per-round-trip timeout.
      Returns:
      the next chunk of raw output — possibly empty — or null once the command has completed; the exit code is then available from exitCode()
      Throws:
      TimeoutException - when the command produces no output for a whole per-round-trip timeout (the inactivity timeout of the stream)
      WindowsRemoteException - for any other failure while receiving
    • poll

      default CommandCursor.Chunk poll(long maxWaitMillis) throws TimeoutException, WindowsRemoteException
      Bounded variant of next(): block at most the given wait for output. When the command produces nothing in that window, an empty chunk is returned — a bounded poll expiring is not a failure, and the cursor remains fully usable — unlike next(), whose whole per-round-trip timeout counts as the stream's inactivity limit. Deadline-bounded waits (e.g. RemoteProcess.waitFor(Duration)) are built on this.

      The default implementation does not bound the wait: it delegates to next().

      Parameters:
      maxWaitMillis - how long to block at most, capped by the cursor's per-round-trip timeout
      Returns:
      the next chunk of raw output — empty when the wait elapsed first — or null once the command has completed
      Throws:
      TimeoutException - when the server does not even answer the bounded request
      WindowsRemoteException - for any other failure while receiving
    • poll

      default CommandCursor.Chunk poll(long askMillis, long maxWaitMillis) throws TimeoutException, WindowsRemoteException
      Cadence variant of poll(long): ask the server to answer within askMillis — the polling cadence — while allowing the answer itself up to maxWaitMillis to arrive. A polling consumer (e.g. an interactive session pump) wants short idle rounds, but must not fail the stream when a loaded or distant server takes longer than one cadence to get its answer across; poll(long) is exactly this call with askMillis == maxWaitMillis.

      The default implementation delegates to poll(long) with the full wait.

      Parameters:
      askMillis - when the server should answer at the latest — with output when it has any, with the protocol's "nothing yet" otherwise
      maxWaitMillis - how long to block at most, capped by the cursor's per-round-trip timeout
      Returns:
      the next chunk of raw output — empty when nothing arrived — or null once the command has completed
      Throws:
      TimeoutException - when the server does not even answer the bounded request
      WindowsRemoteException - for any other failure while receiving
    • send

      default void send(byte[] data, boolean end) throws TimeoutException, WindowsRemoteException
      Feed standard input to the running command — the WSMan Send operation, carrying the bytes to the command's stdin stream. Input larger than one envelope's worth is split into several Send requests automatically. A Send is an ordinary request on the executor's serial connection: it alternates with next()/poll(long) on the caller's thread, it never runs concurrently with them.

      The default implementation throws UnsupportedOperationException: only executors that support command input (such as the built-in lightweight backend) implement this method.

      Parameters:
      data - the input bytes (possibly empty — with end, a pure end-of-input Send)
      end - true to mark the end of input: the command's stdin then reaches EOF, and no further input may be sent
      Throws:
      IllegalStateException - when the command has already completed or the cursor is closed
      TimeoutException - when the server does not answer the Send in time
      WindowsRemoteException - for any other failure while sending
    • interrupt

      default void interrupt() throws TimeoutException, WindowsRemoteException
      Interrupt the command the way a console Ctrl+C would — the WSMan Signal operation with the ctrl_c code. Unlike close()'s terminate Signal, it interrupts the command's child process without ending the command itself: the cursor stays fully usable. A no-op once the command has completed or the cursor is closed.

      The default implementation throws UnsupportedOperationException: only executors that support it (such as the built-in lightweight backend) implement this method.

      Throws:
      TimeoutException - when the server does not answer the Signal in time
      WindowsRemoteException - for any other failure while signaling
    • exitCode

      int exitCode()
      Get the command's exit code.
      Returns:
      the exit code
      Throws:
      IllegalStateException - when the command has not completed yet — completion is observed as a null return from next()
    • close

      void close()
      Terminate the command (when it is still running) with the WinRM terminate Signal and release the executor's connection. Idempotent; a no-op when the command already completed. After an early close, next() returns null without touching the connection again (and no exit code is available, since the command never completed). May throw an unchecked WinRMClientException when the Signal itself fails — the remote command may then still be running.
      Specified by:
      close in interface AutoCloseable