#ifndef _PseudoTerminal_h
#define _PseudoTerminal_h
#include <bool.h>
#include <signal.h>
#include <sys/types.h>
#include <String.h>
class PseudoTerminal
{
private: // class members
static char* _pty_chars; // "/dev/ptyXY"
static char* _hexdigits; // [0-9a-f]
private: // instance members
char* _pty_name; // name of the opened master pty
char* _tty_name; // name of the slave tty
char _pty_x; // the X portion of the pty name
char _pty_y; // the Y portion of the pty name
int _master_fd; // handle to the master file
// descriptor (-1 if not open)
int _slave_fd; // handle to the slave file
// descriptor (can be -1)
pid_t _slave_pid; // process id of the running slave
char* _buf; // internal buffer used for
// read() / write()
size_t _buf_size; // how big is the buffer
// (default set by constructor)
ssize_t _buf_count; // how many bytes are in the
// buffer (from read)
protected:
// copy constructor (prevents copying object - could
// kill slave by accident)
PseudoTerminal(PseudoTerminal&) { /* empty */ }
PseudoTerminal& operator=(PseudoTerminal&);
// accessors
char* _getPtyChars() { return(_pty_chars); }
char* _getHexdigits() { return(_hexdigits); }
char* _getBuffer() { return(_buf); }
ssize_t& _getBufferCount() { return(_buf_count); }
// pty name setting helpers
void _setPtyX(char c);
void _setPtyY(char c);
public:
PseudoTerminal(size_t buf_size = 512); // opens the master pty
~PseudoTerminal();
// accessors
const char* getPtyName() const { return(_pty_name); }
const char* getTtyName() const { return(_tty_name); }
char getPtyX() const { return(_pty_x); }
char getPtyY() const { return(_pty_y); }
int getFd() const { return(_master_fd); }
operator int() const { return(_master_fd); }
int getSlaveFd() const { return(_slave_fd); }
pid_t getSlavePid() const { return(_slave_pid); }
const char* getBuffer() const { return(_buf); }
size_t getBufferSize() const { return(_buf_size); }
ssize_t getBufferCount() const { return(_buf_count); }
// line disipline
static bool getMode(int fd, struct termio* mode);
static bool setMode(int fd, struct termio* mode);
static bool setRawMode(int fd, struct termio* orig = NULL);
static bool copyMode(int src_fd, int dest_fd,
struct termio* orig = NULL);
// slave pty and child process management
int slave();
pid_t forkvp(char* argv[], bool control_terminal = false,
struct termio* mode = NULL);
bool isAlive();
int terminate(int signo = SIGTERM);
void closeMaster(bool close_slave = true);
void closeSlave();
// master io - can throw(int errno)
ssize_t read(bool throw_exception = true);
ssize_t write(const char* buf, size_t buf_size,
bool throw_exception = true);
PseudoTerminal& operator<<(PseudoTerminal& pty);
PseudoTerminal& operator>>(PseudoTerminal& pty);
friend PseudoTerminal& operator<<(PseudoTerminal& pty,
const String& str);
friend PseudoTerminal& operator>>(PseudoTerminal& pty, String& str);
friend PseudoTerminal& operator<<(PseudoTerminal& pty,
const char* str);
};
-- friend io operators -------------------------------------------
////
inline PseudoTerminal& operator<<(PseudoTerminal& pty,
const String& str)
{
pty.write(str, str.length());
return(pty);
}
inline PseudoTerminal& operator>>(PseudoTerminal& pty, String& str)
{
int nread = pty.read();
if (nread > 0)
str = pty.getBuffer();
return(pty);
}
inline PseudoTerminal& operator<<(PseudoTerminal& pty,
const char* str)
{
pty.write(str, strlen(str));
return(pty);
}
#endif // _PseudoTerminal_h
//End of File