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.
164 lines
4.6 KiB
164 lines
4.6 KiB
/** @file |
|
|
|
$Id$ |
|
|
|
$Date$ |
|
$Author$ |
|
|
|
@copy © Marc Wäckerlin |
|
@license LGPL, see file <a href="license.html">COPYING</a> |
|
|
|
$Log$ |
|
Revision 1.8 2005/11/29 12:39:43 marc |
|
make it compilable with gcc 4.0.2 and newer doxygen |
|
|
|
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
|
|
|