Commands

Interface for asyncronously operating on commands. You can write to STDIN, read from STDOUT and STDERR.

Note: currently the implementation is done in a separate thread for each new command,
as there is no possibility to read or write asynchronously from file descriptors.

File information

Filecommon/interface/command.h

Public functions CreateCommandProvider

Classes ICommandProvider
ICommand
Examples Command

Functions

Functions to initialize


    class ICommandProvider * CreateCommandProvider(class IIoMux * iomux);

Overview

This function will create an ICommandProvider instance. This instance can be used to create ICommand objects.


CreateCommandProvider

Parameters

class IIoMux * iomuxThe iomux instance which is to be used.

Return value

The ICommandProvider instance. That instance can be freed as soon as it no longer is used by calling the C++ delete operator.

Classes

ICommandProvider

class ICommandProvider {
public:
    virtual class ICommand * CreateCommand(class IInstanceLog * const log, class UTask * user, const char * command, int expectedExitCode, size_t initialReadLength = 0) = 0;
};

Public functions

virtual class ICommand * CreateCommand
Creates an ICommand instance.

Parameters

class IInstanceLog * const logThe IInstanceLog instance which is to be used.
class UTask * userThe UTask instance which will receive TaskProgress/TaskComplete/TaskFailed callbacks.
const char * commandThe actual command which will be executed.
int expectedExitCodeThe expected exit code. Use a negative value to ignore the exit code.
size_t initialReadLengthYou can specify a number to directly start reading the command output.

Return value

The ICommand instance. That instance can be freed as soon as it called TaskFailed/TaskComplete, not before!

Classes

ICommand

ICommand is derived from ITask, so the ITask/UTask mechanisms are used for progress and completion.
The ITask::Start function is called inside CreateCommand, so it is not needed to call this function on your own.

The buffer of the read data is maintained within this class.
STDERR is automatically redirected and can be fetched afterwards with Error(). Note that max 8192 bytes are fetched from STDERR, the remaining data is discarded.

General handling

The TaskProgress progress parameter is used differently, depending on a previous Read or Write. Valid values are:

class ICommand : public ITask {
public:
    virtual void Write(byte * data, size_t length, bool last = false) = 0;
    virtual void Read(size_t length) = 0;
    virtual void Get(const byte * & data, size_t & length) = 0;
    virtual void Close() = 0;
    virtual const char * Error() = 0;
    virtual int GetExitCode() = 0;
};

Public functions

void Write
Initiates writing of data to STDIN. May be called after TaskProgress from the previous block.
You mustn't call several writes without waiting for the TaskProgress callback which indicates that the data has been written.

Parameters

byte * dataA pointer to a byte array.
size_t lengthThe length of the data to write.
bool lastSet true if this is the last write call, which closes STDIN.
void Read
Initiates reading of the next block. May be called after TaskProgress from the previous block. You mustn't call several reads without waiting for the TaskProgress callback which indicates that the data has been read.

Parameters

size_t lengthThe length of the data to read.
void Get
Gets a pointer to the read block of data. May be called after the TaskProgress for the read operation. The pointer is valid until the next call to Read. I the length is not equal to the length of a previous Read call, the end of the stream is reached and you'll get a TaskComplete/TaskFailed afterwards.

Parameters

const byte * & dataPointer reference to the data buffer.
size_t & lengthThe available size in the data buffer.
void Close
Terminates the process if it is still running. You do not need to call Close() if you do not want to kill the process before it ends on its own.

Parameters

const char * Error
Returns the output of STDERR or NULL if nothing has been written to STDERR.

Parameters

Return value

The const char * error string.
int GetExitCode()

Parameters

Return value

The int exit code of the command.

Examples

Command


// in main.cpp
class ICommandProvider * provider = CreateCommandProvider(iomux);
    
// another cpp file
class Test : public UTask {
    class ICommand * command;
public:
    Test(class ICommandProvider * provider, class IInstanceLog * log) {
        this->command = provider::CreateCommand(log, this, "/usr/bin/...", 0);
        byte * data = ...;
        this->command->Write(data, dataLen, true);  // we write one data buffer and wait for TaskProgress
    }
    
    void TaskProgress(class ITask * task, dword progress = 0) {
        if(progress == COMMAND_PROGRESS_WRITE) {    // just one write op, so read now
            this->command->Read(1000);              // read 1000 bytes    
        }
        else if(progress == COMMAND_PROGRESS_READ) {
            size_t length = 0;
            const byte * data = NULL;
            this->command->Get(data, length);
            // do something with the data
            if(length == 1000) {                    // more data available
                this->command->Read(1000);
            }
            // else wait for TaskComplete/Failed
        }
    }
    
    void TaskComplete(class ITask * task) {
        delete this->command;   // this->command == task
        this->command = nullptr;
    }
    
    void TaskFailed(class ITask * task) {
        debug->printf("%i %s", this->command->GetExitCode(), this->command->Error());
        delete this->command;   // this->command == task
        this->command = nullptr;
    }
}