00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/UnnamedPipe.hpp"
00041 #include "blocxx/AutoPtr.hpp"
00042 #include "blocxx/String.hpp"
00043 #include "blocxx/StringBuffer.hpp"
00044 #include "blocxx/ExceptionIds.hpp"
00045
00046 #ifdef BLOCXX_HAVE_UNISTD_H
00047 #include <unistd.h>
00048 #endif
00049
00050 #include <sys/types.h>
00051 #ifdef BLOCXX_WIN32
00052 #include "blocxx/WinUnnamedPipe.hpp"
00053 #else
00054 #include "blocxx/PosixUnnamedPipe.hpp"
00055 #include <sys/socket.h>
00056 #endif
00057
00058
00059 namespace BLOCXX_NAMESPACE
00060 {
00061
00062 BLOCXX_DEFINE_EXCEPTION_WITH_ID(UnnamedPipe);
00063
00065 UnnamedPipe::~UnnamedPipe()
00066 {
00067 }
00069 int
00070 UnnamedPipe::writeInt(int value)
00071 {
00072 return this->write(&value, sizeof(int));
00073 }
00075 int
00076 UnnamedPipe::writeString(const String& strData)
00077 {
00078 int rc;
00079 int len = static_cast<int>(strData.length()+1);
00080 if ((rc = this->writeInt(len)) != -1)
00081 {
00082 rc = this->write(strData.c_str(), len);
00083 }
00084 return rc;
00085 }
00087 int
00088 UnnamedPipe::readInt(int* value)
00089 {
00090 return this->read(value, sizeof(int));
00091 }
00093 int
00094 UnnamedPipe::readString(String& strData)
00095 {
00096 int len;
00097 int rc;
00098
00099 if ((rc = this->readInt(&len)) != -1)
00100 {
00101 AutoPtrVec<char> p(new char[len+1]);
00102
00103
00104 if ((rc = this->read(p.get(), len)) != -1)
00105 {
00106 strData = String(String::E_TAKE_OWNERSHIP, p.release(), len);
00107 }
00108 }
00109 return rc;
00110 }
00112 String
00113 UnnamedPipe::readAll()
00114 {
00115 char buf[1024];
00116 int readbytes;
00117 StringBuffer retval;
00118 do
00119 {
00120 readbytes = this->read(buf, sizeof(buf)-1, E_THROW_ON_ERROR);
00121 buf[readbytes] = 0;
00122 retval += buf;
00123 } while (readbytes > 0);
00124 return retval.releaseString();
00125 }
00126
00128
00129 UnnamedPipeRef
00130 UnnamedPipe::createUnnamedPipe(EOpen doOpen)
00131 {
00132 #ifdef BLOCXX_WIN32
00133 return WinUnnamedPipe::createUnnamedPipe(doOpen);
00134 #else
00135 return UnnamedPipeRef(new PosixUnnamedPipe(doOpen));
00136 #endif
00137 }
00138
00140
00141 UnnamedPipeRef
00142 UnnamedPipe::createStdin()
00143 {
00144 #ifdef BLOCXX_WIN32
00145 return WinUnnamedPipe::createStdin();
00146 #else
00147 AutoDescriptor duped(::dup(0));
00148 if (duped.get() == BLOCXX_INVALID_HANDLE)
00149 {
00150 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createStdin(): dup():");
00151 }
00152 return UnnamedPipeRef(new PosixUnnamedPipe(duped, AutoDescriptor()));
00153 #endif
00154 }
00155
00157
00158 UnnamedPipeRef
00159 UnnamedPipe::createStdout()
00160 {
00161 #ifdef BLOCXX_WIN32
00162 return WinUnnamedPipe::createStdout();
00163 #else
00164 AutoDescriptor duped(::dup(1));
00165 if (duped.get() == BLOCXX_INVALID_HANDLE)
00166 {
00167 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createStdout(): dup():");
00168 }
00169 return UnnamedPipeRef(new PosixUnnamedPipe(AutoDescriptor(), duped));
00170 #endif
00171 }
00172
00174
00175 UnnamedPipeRef
00176 UnnamedPipe::createStdinStdout()
00177 {
00178 #ifdef BLOCXX_WIN32
00179 return WinUnnamedPipe::createStdinStdout();
00180 #else
00181 AutoDescriptor dupedIn(::dup(0));
00182 if (dupedIn.get() == BLOCXX_INVALID_HANDLE)
00183 {
00184 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createStdout(): dup():");
00185 }
00186 AutoDescriptor dupedOut(::dup(1));
00187 if (dupedOut.get() == BLOCXX_INVALID_HANDLE)
00188 {
00189 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createStdout(): dup():");
00190 }
00191 return UnnamedPipeRef(new PosixUnnamedPipe(dupedIn, dupedOut));
00192 #endif
00193 }
00194
00196
00197 UnnamedPipeRef
00198 UnnamedPipe::createStderr()
00199 {
00200 #ifdef BLOCXX_WIN32
00201 return WinUnnamedPipe::createStderr();
00202 #else
00203 AutoDescriptor duped(::dup(2));
00204 if (duped.get() == BLOCXX_INVALID_HANDLE)
00205 {
00206 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createStderr(): dup():");
00207 }
00208 return UnnamedPipeRef(new PosixUnnamedPipe(AutoDescriptor(), duped));
00209 #endif
00210 }
00211
00213
00214 UnnamedPipeRef
00215 UnnamedPipe::createUnnamedPipeFromDescriptor(AutoDescriptor inputAndOutput)
00216 {
00217 #ifdef BLOCXX_WIN32
00218 return WinUnnamedPipe::createUnnamedPipeFromDescriptor(inputAndOutput);
00219 #else
00220 AutoDescriptor duped(::dup(inputAndOutput.get()));
00221 if (duped.get() == BLOCXX_INVALID_HANDLE)
00222 {
00223 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "UnnamedPipe::createUnnamedPipeFromDescriptor(): dup():");
00224 }
00225 return UnnamedPipeRef(new PosixUnnamedPipe(inputAndOutput, duped));
00226 #endif
00227 }
00228
00230
00231 UnnamedPipeRef
00232 UnnamedPipe::createUnnamedPipeFromDescriptor(AutoDescriptor input, AutoDescriptor output)
00233 {
00234 #ifdef BLOCXX_WIN32
00235 return WinUnnamedPipe::createUnnamedPipeFromDescriptor(input, output);
00236 #else
00237 return UnnamedPipeRef(new PosixUnnamedPipe(input, output));
00238 #endif
00239 }
00240
00242
00243 void
00244 UnnamedPipe::createConnectedPipes(UnnamedPipeRef& first, UnnamedPipeRef& second)
00245 {
00246 #ifdef BLOCXX_WIN32
00247 return WinUnnamedPipe::createConnectedPipes(first, second);
00248 #else
00249 int fds[2];
00250 if (::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
00251 {
00252 BLOCXX_THROW_ERRNO_MSG(UnnamedPipeException, "PosixUnamedPipe::open(): soketpair()");
00253 }
00254 first = createUnnamedPipeFromDescriptor(AutoDescriptor(fds[0]));
00255 second = createUnnamedPipeFromDescriptor(AutoDescriptor(fds[1]));
00256 #endif
00257 }
00258
00259 }
00260