blocxx
Main Page
Namespaces
Classes
Files
File List
File Members
src
blocxx
UnnamedPipe.cpp
Go to the documentation of this file.
1
/*******************************************************************************
2
* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3
* Copyright (C) 2006, Novell, Inc. All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
*
8
* * Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* * Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* * Neither the name of
14
* Vintela, Inc.,
15
* nor Novell, Inc.,
16
* nor the names of its contributors or employees may be used to
17
* endorse or promote products derived from this software without
18
* specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
* POSSIBILITY OF SUCH DAMAGE.
31
*******************************************************************************/
32
33
39
#include "blocxx/BLOCXX_config.h"
40
#include "
blocxx/UnnamedPipe.hpp
"
41
#include "
blocxx/AutoPtr.hpp
"
42
#include "
blocxx/String.hpp
"
43
#include "
blocxx/StringBuffer.hpp
"
44
#include "
blocxx/ExceptionIds.hpp
"
45
46
#ifdef BLOCXX_HAVE_UNISTD_H
47
#include <unistd.h>
// for dup()
48
#endif
49
50
#include <sys/types.h>
51
#ifdef BLOCXX_WIN32
52
#include "blocxx/WinUnnamedPipe.hpp"
53
#else
54
#include "
blocxx/PosixUnnamedPipe.hpp
"
55
#include <sys/socket.h>
// for socketpair()
56
#endif
57
58
59
namespace
BLOCXX_NAMESPACE
60
{
61
62
BLOCXX_DEFINE_EXCEPTION_WITH_ID
(
UnnamedPipe
);
63
65
UnnamedPipe::~UnnamedPipe
()
66
{
67
}
69
int
70
UnnamedPipe::writeInt
(
int
value)
71
{
72
return
this->
write
(&value,
sizeof
(
int
));
73
}
75
int
76
UnnamedPipe::writeString
(
const
String
& strData)
77
{
78
int
rc;
79
int
len =
static_cast<
int
>
(strData.
length
()+1);
80
if
((rc = this->
writeInt
(len)) != -1)
81
{
82
rc = this->
write
(strData.
c_str
(), len);
83
}
84
return
rc;
85
}
87
int
88
UnnamedPipe::readInt
(
int
* value)
89
{
90
return
this->
read
(value,
sizeof
(
int
));
91
}
93
int
94
UnnamedPipe::readString
(
String
& strData)
95
{
96
int
len;
97
int
rc;
98
99
if
((rc = this->
readInt
(&len)) != -1)
100
{
101
AutoPtrVec<char>
p(
new
char
[len+1]);
102
103
// writeString() writes the '\0' terminator, so we don't worry about it here.
104
if
((rc = this->
read
(p.
get
(), len)) != -1)
105
{
106
strData =
String
(
String::E_TAKE_OWNERSHIP
, p.
release
(), len);
107
}
108
}
109
return
rc;
110
}
112
String
113
UnnamedPipe::readAll
()
114
{
115
char
buf[1024];
116
int
readbytes;
117
StringBuffer
retval;
118
do
119
{
120
readbytes = this->
read
(buf,
sizeof
(buf)-1,
E_THROW_ON_ERROR
);
121
buf[readbytes] = 0;
// null-terminate the buffer
122
retval += buf;
123
}
while
(readbytes > 0);
// keep going until we don't fill up the buffer.
124
return
retval.
releaseString
();
125
}
126
128
// STATIC
129
UnnamedPipeRef
130
UnnamedPipe::createUnnamedPipe
(
EOpen
doOpen)
131
{
132
#ifdef BLOCXX_WIN32
133
return
WinUnnamedPipe::createUnnamedPipe
(doOpen);
134
#else
135
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(doOpen));
136
#endif
137
}
138
140
// STATIC
141
UnnamedPipeRef
142
UnnamedPipe::createStdin
()
143
{
144
#ifdef BLOCXX_WIN32
145
return
WinUnnamedPipe::createStdin
();
146
#else
147
AutoDescriptor
duped(::dup(0));
148
if
(duped.
get
() ==
BLOCXX_INVALID_HANDLE
)
149
{
150
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createStdin(): dup():"
);
151
}
152
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(duped,
AutoDescriptor
()));
153
#endif
154
}
155
157
// STATIC
158
UnnamedPipeRef
159
UnnamedPipe::createStdout
()
160
{
161
#ifdef BLOCXX_WIN32
162
return
WinUnnamedPipe::createStdout
();
163
#else
164
AutoDescriptor
duped(::dup(1));
165
if
(duped.
get
() ==
BLOCXX_INVALID_HANDLE
)
166
{
167
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createStdout(): dup():"
);
168
}
169
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(
AutoDescriptor
(), duped));
170
#endif
171
}
172
174
// STATIC
175
UnnamedPipeRef
176
UnnamedPipe::createStdinStdout
()
177
{
178
#ifdef BLOCXX_WIN32
179
return
WinUnnamedPipe::createStdinStdout
();
180
#else
181
AutoDescriptor
dupedIn(::dup(0));
182
if
(dupedIn.
get
() ==
BLOCXX_INVALID_HANDLE
)
183
{
184
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createStdout(): dup():"
);
185
}
186
AutoDescriptor
dupedOut(::dup(1));
187
if
(dupedOut.
get
() ==
BLOCXX_INVALID_HANDLE
)
188
{
189
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createStdout(): dup():"
);
190
}
191
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(dupedIn, dupedOut));
192
#endif
193
}
194
196
// STATIC
197
UnnamedPipeRef
198
UnnamedPipe::createStderr
()
199
{
200
#ifdef BLOCXX_WIN32
201
return
WinUnnamedPipe::createStderr
();
202
#else
203
AutoDescriptor
duped(::dup(2));
204
if
(duped.
get
() ==
BLOCXX_INVALID_HANDLE
)
205
{
206
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createStderr(): dup():"
);
207
}
208
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(
AutoDescriptor
(), duped));
209
#endif
210
}
211
213
// static
214
UnnamedPipeRef
215
UnnamedPipe::createUnnamedPipeFromDescriptor
(
AutoDescriptor
inputAndOutput)
216
{
217
#ifdef BLOCXX_WIN32
218
return
WinUnnamedPipe::createUnnamedPipeFromDescriptor
(inputAndOutput);
219
#else
220
AutoDescriptor
duped(::dup(inputAndOutput.
get
()));
221
if
(duped.
get
() ==
BLOCXX_INVALID_HANDLE
)
222
{
223
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"UnnamedPipe::createUnnamedPipeFromDescriptor(): dup():"
);
224
}
225
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(inputAndOutput, duped));
226
#endif
227
}
228
230
// static
231
UnnamedPipeRef
232
UnnamedPipe::createUnnamedPipeFromDescriptor
(
AutoDescriptor
input,
AutoDescriptor
output)
233
{
234
#ifdef BLOCXX_WIN32
235
return
WinUnnamedPipe::createUnnamedPipeFromDescriptor
(input, output);
236
#else
237
return
UnnamedPipeRef
(
new
PosixUnnamedPipe
(input, output));
238
#endif
239
}
240
242
// static
243
void
244
UnnamedPipe::createConnectedPipes
(
UnnamedPipeRef
& first,
UnnamedPipeRef
& second)
245
{
246
#ifdef BLOCXX_WIN32
247
return
WinUnnamedPipe::createConnectedPipes
(first, second);
248
#else
249
int
fds[2];
250
if
(::socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1)
251
{
252
BLOCXX_THROW_ERRNO_MSG
(
UnnamedPipeException
,
"PosixUnamedPipe::open(): soketpair()"
);
253
}
254
first =
createUnnamedPipeFromDescriptor
(
AutoDescriptor
(fds[0]));
255
second =
createUnnamedPipeFromDescriptor
(
AutoDescriptor
(fds[1]));
256
#endif
257
}
258
259
}
// end namespace BLOCXX_NAMESPACE
260
Generated by
1.8.1