C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

161 lines
4.5 KiB

/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
Revision 1.7 2004/12/18 20:58:19 marc
pipes can be blocking, non blocking or blocking on one side only
default is again blocking, because it causes less trouble
Revision 1.6 2004/12/14 20:32:10 marc
support for connect_cin
pipe is now non blocking by default
Revision 1.5 2004/08/28 16:21:25 marc
mrw-c++-0.92 (mrw)
- new file: version.cpp
- new file header for all sources
- work around warning in mrw::auto<T>
- possibility to compile without log4cxx
- work around bugs in demangle.h and libiberty.h
- corrections in documentation
- added simple tracing mechanism
- more warnings
- small corrections in Auto<>::Free and a new test for it
- possibility to compile without stack trace
Revision 1.4 2004/08/25 08:35:09 marc
change in file header
Revision 1.3 2004/08/25 08:22:19 marc
added file header
*/
#ifndef __MRW_UNISTD_HPP__
#define __MRW_UNISTD_HPP__
#include <unistd.h> // pipe, close
#include <fcntl.h> // fcntl (O_NONBLOCK)
#include <errno.h> // errno
namespace mrw {
/** @addtogroup AutoTools */
//@{
/** @brief class that implements an unnamed UNIX pipe
@pre #include <mrw/unistd.hpp>
Implements a UNIX pipe that is automatically closed in
destructor and offers some facilities. */
class Pipe {
private:
/// the filedescriptor, [0] to read and [1] to write
int _fd[2];
int _lastError;
public:
/// blocking mode
enum BlockingMode {
non_blocking, ///< both sides are non blocking
block_input, ///< pipe input is blocking
block_output, ///< pipe output is blocking
blocking ///< both sides are blocking
};
/// creates a unix pipe
/** @param mode Flag whether the pipe is blocking (default: yes) */
Pipe(BlockingMode mode=blocking) throw(std::bad_exception):
_lastError(-1) {
_fd[0] = -1;
_fd[1] = -1;
if (::pipe(_fd)==-1) {
_lastError=errno;
return;
}
if (mode==non_blocking || mode==block_output) {
int val(fcntl(_fd[0], F_GETFL, 0));
if (fcntl(_fd[0], F_SETFL, (val!=-1?val:0)|O_NONBLOCK) == -1)
_lastError=errno;
}
if (mode==non_blocking || mode==block_input) {
int val(fcntl(_fd[1], F_GETFL, 0));
if (fcntl(_fd[1], F_SETFL, (val!=-1?val:0)|O_NONBLOCK) == -1)
_lastError=errno;
}
}
/// destructor closes pipe if still open
~Pipe() throw(std::bad_exception) {
close();
}
/// closes pipe if open
void close() throw(std::bad_exception) {
close_in();
close_out();
}
/// closes input pipe if open
void close_in() throw(std::bad_exception) {
if (_fd[0]!=-1) while (::close(_fd[0])==-1) if (errno!=EINTR) {
_lastError = errno;
break;
}
_fd[0] = -1;
}
/// closes output pipe if open
void close_out() throw(std::bad_exception) {
if (_fd[1]!=-1) while (::close(_fd[1])==-1) if (errno!=EINTR) {
_lastError = errno;
break;
}
_fd[1] = -1;
}
/** @return true if no error occured */
operator bool() throw() {
return _lastError == -1;
}
/** @return last error code, -1 if no error */
int error() throw() {
return _lastError;
}
/// connect input stream to @c stdin
void connect_cin() throw(std::bad_exception) {
while (::dup2(_fd[0], 0)==-1) if (errno!=EINTR) {
_lastError = errno;
return;
}
}
/// connect output stream to @c stdout
void connect_cout() throw(std::bad_exception) {
while (::dup2(_fd[1], 1)==-1) if (errno!=EINTR) {
_lastError = errno;
return;
}
}
/// connect output stream to @c stderr
void connect_cerr() throw(std::bad_exception) {
while (::dup2(_fd[1], 2)==-1) if (errno!=EINTR) {
_lastError = errno;
return;
}
}
/// get an input stream
/** @return stream to read from
@note invalid after destruction or @c close or @c close_in */
int istream() throw(std::bad_exception) {
return _fd[0];
}
/// get an output stream
/** @return stream to write to
@note invalid after destruction or @c close or @c close_out */
int ostream() throw(std::bad_exception) {
return _fd[1];
}
};
//@}
}
#endif