winix/core/run.h

165 lines
3.6 KiB
C++
Executable File

/*
* This file is a part of Winix
* and is not publicly distributed
*
* Copyright (c) 2011-2013, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfile_winix_core_run
#define headerfile_winix_core_run
#include <string>
#include <cstdio>
#include <unistd.h>
/*
how many parameters and environment variables can be passed to a program
*/
#define WINIX_RUN_MAX_PARAMETERS 30
/*
objects of this class allows you to run an external program
when you call Go() then:
1. winix creates pipes for communicating with a child process
2. then winix fork()
3. the child process execve() the specified command
4. winix (parent) sends 'in' to the standard input of the child process
5. after sending it closes the descriptor so the child sees it as end-of-file
6. now winix reads what the child sends to standard output (until EOF)
7. winix waitpid() for the child
8. Go() returns
*/
class Run
{
public:
Run();
/*
clearing parameters, environment variables and the command
(and clearing LastStatus and LastResult)
so you can call another different program now
*/
void Clear();
/*
setting parameters
each parameter should be passed in different call to Par() method
sample:
if you want to call from your shell:
$ myprog -a -b -f "test file"
you should call Par() in this way:
Par("-a");
Par("-b");
Par("test file"); // apostrophes are not needed here
arguments passed to Par() should not be changed afterwards, this method does not copy them anywhere
it uses only the pointer
*/
void Par(const char * p);
void Par(const std::string & p);
/*
setting environment variables
one variable per one Env() call
arguments passed to Env() should not be changed afterwards, this method does not copy them anywhere
it uses only the pointer
*/
void Env(const char * e);
void Env(const std::string & e);
/*
full path to command you want to execute
arguments passed to Cmd() should not be changed afterwards, this method does not copy them anywhere
it uses only the pointer
*/
void Cmd(const char * c);
void Cmd(const std::string & c);
/*
executing the command
you should call Par(), Env() and Cmd() beforehand
*/
int Go(const char * in, size_t inlen, std::string & out);
int Go(const char * in, std::string & out);
int Go(const char * in, size_t inlen);
int Go(const char * in);
int Go(const std::string in, std::string & out);
int Go(const std::string in);
int Go(std::string & out);
int Go();
/*
last status:
0 - ok (program was successfully called)
1 - pipe failed
2 - fork failed
3 - write failed
4 - read failed
5 - child process has done something wrong (caught a signal etc.)
6 - waitpid failed
7 - the command is not set (call Cmd method first)
*/
int LastStatus();
/*
the code which the command returned (usually "0" means no errors found)
if LastStatus is different from zero then LastReturn always returns 255
(so you don't have to check LastStatus() first)
*/
int LastReturn();
private:
int Go(const char * in, size_t inlen, std::string * out);
void SetName();
void CheckStatus();
void WriteRead(const char * in, size_t inlen, std::string * out);
bool CreatePipes();
bool Fork();
void ChildThrow();
void Child();
void Write(const char * in, size_t inlen);
void Read(std::string & out);
int last_status;
// the return code returned by a program (if last_status==0)
// if last_status!=0 then last_return is 255
int last_return;
int desin[2];
int desout[2];
char * par[WINIX_RUN_MAX_PARAMETERS + 2];
char * env[WINIX_RUN_MAX_PARAMETERS + 1];
const char * command;
size_t parlen;
size_t envlen;
pid_t childpid;
};
#endif