From cd215f0da23e16c3f1a7200f2b9f67f23c9b4be7 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 23 Nov 2007 22:58:19 +0000 Subject: Added the Process stream class, this will allow us to do some really cool stuff coming up...it's just like popen only cool and managed, and streamey. --- src/fstring.h | 2 + src/process.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/process.h | 64 +++++++++++++++++++++++ src/tests/procs.cpp | 22 ++++++++ 4 files changed, 234 insertions(+) create mode 100644 src/process.cpp create mode 100644 src/process.h create mode 100644 src/tests/procs.cpp diff --git a/src/fstring.h b/src/fstring.h index ee6be28..8cccd5c 100644 --- a/src/fstring.h +++ b/src/fstring.h @@ -246,6 +246,8 @@ namespace Bu { if( nLength == nNewSize ) return; + if( nNewSize < 0 ) + nNewSize = 0; flatten(); diff --git a/src/process.cpp b/src/process.cpp new file mode 100644 index 0000000..8fe98f3 --- /dev/null +++ b/src/process.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2007 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#include "process.h" +#include +#include +#include + +Bu::Process::Process( const char *sName, char *const argv[] ) +{ + gexec( sName, argv ); +} + +Bu::Process::Process( const char *sName, const char *argv, ...) +{ + int iCnt = 0; + va_list ap; + va_start( ap, argv ); + for(; va_arg( ap, const char *); iCnt++ ); + va_end( ap ); + + char const **list = new char const *[iCnt+2]; + va_start( ap, argv ); + list[0] = argv; + for( int j = 1; j < iCnt; j++ ) + list[j] = va_arg( ap, const char *); + list[iCnt+1] = NULL; + va_end( ap ); + + gexec( sName, (char *const *)list ); + delete[] list; +} + +Bu::Process::~Process() +{ +} + +void Bu::Process::gexec( const char *sName, char *const argv[] ) +{ + int iaStdIn[2]; + int iaStdOut[2]; + int iaStdErr[2]; + pipe( iaStdIn ); + pipe( iaStdOut ); + pipe( iaStdErr ); + + iStdIn = iaStdIn[1]; + iStdOut = iaStdOut[0]; + iStdErr = iaStdErr[0]; + + iPid = fork(); + if( iPid == 0 ) + { + ::close( iaStdIn[1] ); + ::close( iaStdOut[0] ); + ::close( iaStdErr[0] ); + dup2( iaStdIn[0], 0 ); + dup2( iaStdOut[1], 1 ); + dup2( iaStdErr[1], 2 ); + execvp( sName, argv ); + } +} + +void Bu::Process::close() +{ +} + +size_t Bu::Process::read( void *pBuf, size_t nBytes ) +{ + return ::read( iStdOut, pBuf, nBytes ); +} + +size_t Bu::Process::write( const void *pBuf, size_t nBytes ) +{ + return ::write( iStdIn, pBuf, nBytes ); +} + +long Bu::Process::tell() +{ + return 0; +} + +void Bu::Process::seek( long offset ) +{ +} + +void Bu::Process::setPos( long pos ) +{ +} + +void Bu::Process::setPosEnd( long pos ) +{ +} + +bool Bu::Process::isEOS() +{ + return false; +} + +bool Bu::Process::isOpen() +{ + return true; +} + +void Bu::Process::flush() +{ +} + +bool Bu::Process::canRead() +{ + return true; +} + +bool Bu::Process::canWrite() +{ + return true; +} + +bool Bu::Process::isReadable() +{ + return true; +} + +bool Bu::Process::isWritable() +{ + return true; +} + +bool Bu::Process::isSeekable() +{ + return false; +} + +bool Bu::Process::isBlocking() +{ + return true; +} + +void Bu::Process::setBlocking( bool bBlocking ) +{ +} + diff --git a/src/process.h b/src/process.h new file mode 100644 index 0000000..dbf1553 --- /dev/null +++ b/src/process.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ + +#ifndef BU_PROCESS_H +#define BU_PROCESS_H + +#include +#include + +#include "bu/stream.h" +#include "bu/fstring.h" + +namespace Bu +{ + /** + * Runs a program and attaches streams to it's stdin, stdout, and stderr. + * Reading from a Bu::Process will read from the program's standard output, + * writing to a Bu::Process will write to the program's standard input. + */ + class Process : public Bu::Stream + { + public: + Process( const char *sName, char *const argv[] ); + Process( const char *sName, const char *argv, ...); + virtual ~Process(); + + virtual void close(); + virtual size_t read( void *pBuf, size_t nBytes ); + virtual size_t write( const void *pBuf, size_t nBytes ); + + virtual long tell(); + virtual void seek( long offset ); + virtual void setPos( long pos ); + virtual void setPosEnd( long pos ); + virtual bool isEOS(); + virtual bool isOpen(); + + virtual void flush(); + + virtual bool canRead(); + virtual bool canWrite(); + + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); + + virtual bool isBlocking(); + virtual void setBlocking( bool bBlocking=true ); + + private: + int iStdIn; + int iStdOut; + int iStdErr; + pid_t iPid; + + void gexec( const char *sName, char *const argv[] ); + }; +} + +#endif diff --git a/src/tests/procs.cpp b/src/tests/procs.cpp new file mode 100644 index 0000000..53e5142 --- /dev/null +++ b/src/tests/procs.cpp @@ -0,0 +1,22 @@ +#include "bu/process.h" + +#include + +int main( int agrc, char *argv[] ) +{ + Bu::Process p( argv[1], argv+1 ); + + char buf[1000]; + for(;;) + { + int iSize = p.read( buf, 1000 ); + if( iSize == 0 ) + break; + fwrite( buf, iSize, 1, stdout ); + if( iSize < 1000 ) + break; + } + + return 0; +} + -- cgit v1.2.3