VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTPipe.cpp@ 106579

Last change on this file since 106579 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.1 KB
Line 
1/* $Id: tstRTPipe.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTPipe.
4 */
5
6/*
7 * Copyright (C) 2010-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/pipe.h>
42
43#include <iprt/env.h>
44#include <iprt/err.h>
45#include <iprt/initterm.h>
46#include <iprt/mem.h>
47#include <iprt/message.h>
48#include <iprt/param.h>
49#include <iprt/process.h>
50#include <iprt/string.h>
51#ifdef RT_OS_WINDOWS
52# include <iprt/system.h>
53#endif
54#include <iprt/test.h>
55
56
57/*********************************************************************************************************************************
58* Global Variables *
59*********************************************************************************************************************************/
60static RTTEST g_hTest = NIL_RTTEST;
61static const char g_szTest4Message[] = "This is test #4, everything is working fine.\n\r";
62static const char g_szTest5Message[] = "This is test #5, everything is working fine.\n\r";
63
64
65static RTEXITCODE tstRTPipe5Child(const char *pszPipe)
66{
67 int rc = RTR3InitExeNoArguments(0);
68 if (RT_FAILURE(rc))
69 return RTMsgInitFailure(rc);
70
71 int64_t iNative;
72 rc = RTStrToInt64Full(pszPipe, 10, &iNative);
73 if (RT_FAILURE(rc))
74 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);
75
76 RTPIPE hPipe;
77 rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_READ);
78 if (RT_FAILURE(rc))
79 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,READ) -> %Rrc\n", pszPipe, rc);
80
81 ///
82 char szTmp[1024];
83 size_t cbRead = 0;
84 rc = RTPipeReadBlocking(hPipe, szTmp, sizeof(szTmp) - 1, &cbRead);
85 if (RT_FAILURE(rc))
86 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc\n", rc);
87 szTmp[cbRead] = '\0';
88
89 size_t cbRead2;
90 char szTmp2[4];
91 rc = RTPipeReadBlocking(hPipe, szTmp2, sizeof(szTmp2), &cbRead2);
92 if (rc != VERR_BROKEN_PIPE)
93 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeReadBlocking() -> %Rrc instead of VERR_BROKEN_PIPE\n", rc);
94
95 rc = RTPipeClose(hPipe);
96 if (RT_FAILURE(rc))
97 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);
98
99 if (memcmp(szTmp, g_szTest5Message, sizeof(g_szTest5Message)))
100 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Message mismatch.\n:Expected '%s'\nGot '%s'\n", g_szTest5Message, szTmp);
101
102 return RTEXITCODE_SUCCESS;
103}
104
105static void tstRTPipe5(void)
106{
107 RTTestISub("Inherit non-standard pipe handle, read end");
108
109 char szPathSelf[RTPATH_MAX];
110 RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf);
111
112 RTPIPE hPipeR;
113 RTPIPE hPipeW;
114 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);
115
116 RTHCINTPTR hNative = RTPipeToNative(hPipeR);
117 RTTESTI_CHECK_RETV(hNative != -1);
118
119 char szNative[64];
120 RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
121 const char *papszArgs[4] = { szPathSelf, "--child-5", szNative, NULL };
122
123 RTPROCESS hChild;
124 RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
125 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
126
127 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeW, g_szTest5Message, sizeof(g_szTest5Message) - 1, NULL), VINF_SUCCESS);
128 int rc;
129 RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeW), VINF_SUCCESS);
130 if (RT_FAILURE(rc))
131 RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);
132
133 RTPROCSTATUS ProcStatus;
134 RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
135 if (RT_FAILURE(rc))
136 return;
137 RTTESTI_CHECK( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
138 && ProcStatus.iStatus == 0);
139}
140
141
142static RTEXITCODE tstRTPipe4Child(const char *pszPipe)
143{
144 int rc = RTR3InitExeNoArguments(0);
145 if (RT_FAILURE(rc))
146 return RTMsgInitFailure(rc);
147
148 int64_t iNative;
149 rc = RTStrToInt64Full(pszPipe, 10, &iNative);
150 if (RT_FAILURE(rc))
151 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTStrToUInt64Full(%s) -> %Rrc\n", pszPipe, rc);
152
153 RTPIPE hPipe;
154 rc = RTPipeFromNative(&hPipe, (RTHCINTPTR)iNative, RTPIPE_N_WRITE);
155 if (RT_FAILURE(rc))
156 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeFromNative(,%s,WRITE) -> %Rrc\n", pszPipe, rc);
157
158 rc = RTPipeWriteBlocking(hPipe, g_szTest4Message, sizeof(g_szTest4Message) - 1, NULL);
159 if (RT_FAILURE(rc))
160 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeWriteBlocking() -> %Rrc\n", rc);
161
162 rc = RTPipeClose(hPipe);
163 if (RT_FAILURE(rc))
164 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPipeClose() -> %Rrc\n", rc);
165 return RTEXITCODE_SUCCESS;
166}
167
168static void tstRTPipe4(void)
169{
170 RTTestISub("Inherit non-standard pipe handle, write end");
171
172 char szPathSelf[RTPATH_MAX];
173 RTTESTI_CHECK_RETV(RTProcGetExecutablePath(szPathSelf, sizeof(szPathSelf)) == szPathSelf);
174
175 RTPIPE hPipeR;
176 RTPIPE hPipeW;
177 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
178
179 RTHCINTPTR hNative = RTPipeToNative(hPipeW);
180 RTTESTI_CHECK_RETV(hNative != -1);
181
182 char szNative[64];
183 RTStrPrintf(szNative, sizeof(szNative), "%RHi", hNative);
184 const char *papszArgs[4] = { szPathSelf, "--child-4", szNative, NULL };
185
186 RTPROCESS hChild;
187 RTTESTI_CHECK_RC_RETV(RTProcCreate(szPathSelf, papszArgs, RTENV_DEFAULT, 0 /*fFlags*/, &hChild), VINF_SUCCESS);
188 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
189
190 char szTmp[1024];
191 size_t cbRead = 0;
192 int rc;
193 RTTESTI_CHECK_RC(rc = RTPipeReadBlocking(hPipeR, szTmp, sizeof(szTmp) - 1, &cbRead), VINF_SUCCESS);
194 if (RT_FAILURE(rc))
195 cbRead = 0;
196 RTTESTI_CHECK_RETV(cbRead < sizeof(szTmp));
197 szTmp[cbRead] = '\0';
198
199 size_t cbRead2;
200 char szTmp2[4];
201 RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeR, szTmp2, sizeof(szTmp2), &cbRead2), VERR_BROKEN_PIPE);
202 RTTESTI_CHECK_RC(rc = RTPipeClose(hPipeR), VINF_SUCCESS);
203 if (RT_FAILURE(rc))
204 RTTESTI_CHECK_RC(RTProcTerminate(hChild), VINF_SUCCESS);
205
206 RTPROCSTATUS ProcStatus;
207 RTTESTI_CHECK_RC(rc = RTProcWait(hChild, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
208 if (RT_FAILURE(rc))
209 return;
210 RTTESTI_CHECK( ProcStatus.enmReason == RTPROCEXITREASON_NORMAL
211 && ProcStatus.iStatus == 0);
212 if (memcmp(szTmp, g_szTest4Message, sizeof(g_szTest4Message)))
213 RTTestIFailed("Message mismatch.\n:Expected '%s'\nGot '%s'\n", g_szTest4Message, szTmp);
214}
215
216
217static void tstRTPipe3(void)
218{
219 RTTestISub("Full write buffer");
220#ifdef RT_OS_WINDOWS
221 /* Kludge! The RTPipeWrite+RTPipeWriteBlocking code is able to write twice the size
222 of the pipe buffer, so the testcase won't behave right if we go lower
223 than 50% on the readback. */
224 for (unsigned uPct = 50; uPct < 100; uPct += 12)
225#else
226 for (unsigned uPct = 25; uPct < 100; uPct += 12)
227#endif
228 {
229 RTPIPE hPipeR = (RTPIPE)999999;
230 RTPIPE hPipeW = (RTPIPE)999999;
231 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
232 RTTestIErrContext("uPct=%d", uPct);
233
234 static char s_abBuf[_256K];
235 int rc = VINF_SUCCESS;
236 size_t cbTotal = 0;
237 memset(s_abBuf, 0xff, sizeof(s_abBuf));
238 for (;;)
239 {
240 RTTESTI_CHECK(cbTotal < _1G);
241 if (cbTotal > _1G)
242 break;
243
244 size_t cbWritten = _1G;
245 rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten);
246 RTTESTI_CHECK_MSG(rc == VINF_SUCCESS || rc == VINF_TRY_AGAIN, ("rc=%Rrc\n", rc));
247 if (rc != VINF_SUCCESS)
248 break;
249 cbTotal += cbWritten;
250 }
251
252 if (rc == VINF_TRY_AGAIN)
253 {
254 size_t const cbToRead = RT_MIN(sizeof(s_abBuf), cbTotal * uPct / 100);
255 RTTestIPrintf(RTTESTLVL_ALWAYS, "cbTotal=%zu (%#zx) cbToRead=%zu (%#zx)\n", cbTotal, cbTotal, cbToRead, cbToRead);
256 RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VERR_TIMEOUT);
257 RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VERR_TIMEOUT);
258 size_t cbRead;
259 RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeR, s_abBuf, cbToRead, &cbRead), VINF_SUCCESS);
260
261#ifdef RT_OS_WINDOWS
262 /* Kludge! Older Windows NT versions does not complete a pending write till
263 all the pending data has been read and the pipe buffer is
264 completely empty. Applies to NT4, W2K, and XP. Though on XP the
265 test works at 50% for some reason and we can write double the
266 amount, so possibly a different issue there, so we'l
267
268 This does not seem to be a bug in pipe-win.cpp. */
269 if (RTSystemGetNtVersion() < (uPct == 50 ? RTSYSTEM_MAKE_NT_VERSION(5,2,0) : RTSYSTEM_MAKE_NT_VERSION(6,0,0)))
270 RTTestIPrintf(RTTESTLVL_ALWAYS, "old buggy windows - skipping 2nd part (0: %Rrc, 1: %Rrc)\n",
271 RTPipeSelectOne(hPipeW, 0), RTPipeSelectOne(hPipeW, 1));
272 else
273#endif
274 {
275 RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 0), VINF_SUCCESS);
276 RTTESTI_CHECK_RC(RTPipeSelectOne(hPipeW, 1), VINF_SUCCESS);
277
278 size_t cbWritten = _1G;
279 rc = RTPipeWrite(hPipeW, s_abBuf, sizeof(s_abBuf), &cbWritten);
280 RTTESTI_CHECK(rc == VINF_SUCCESS);
281 }
282 }
283
284 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
285 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
286 }
287}
288
289static void tstRTPipe2(void)
290{
291 RTTestISub("Negative");
292
293 RTPIPE hPipeR = (RTPIPE)1;
294 RTPIPE hPipeW = (RTPIPE)1;
295 RTTESTI_CHECK_RC(RTPipeCreate(&hPipeR, &hPipeW, UINT32_MAX), VERR_INVALID_PARAMETER);
296 RTTESTI_CHECK_RC(RTPipeCreate(NULL, &hPipeW, 0), VERR_INVALID_POINTER);
297 RTTESTI_CHECK_RC(RTPipeCreate(&hPipeR, NULL, 0), VERR_INVALID_POINTER);
298 RTTESTI_CHECK(hPipeR == (RTPIPE)1);
299 RTTESTI_CHECK(hPipeW == (RTPIPE)1);
300
301
302 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
303
304 char abBuf[_4K];
305 size_t cbRead = ~(size_t)3;
306 RTTESTI_CHECK_RC(RTPipeRead(hPipeW, abBuf, 0, &cbRead), VERR_ACCESS_DENIED);
307 RTTESTI_CHECK_RC(RTPipeRead(hPipeW, abBuf, 1, &cbRead), VERR_ACCESS_DENIED);
308 RTTESTI_CHECK(cbRead == ~(size_t)3);
309 RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeW, abBuf, 0, NULL), VERR_ACCESS_DENIED);
310 RTTESTI_CHECK_RC(RTPipeReadBlocking(hPipeW, abBuf, 1, NULL), VERR_ACCESS_DENIED);
311
312 size_t cbWrite = ~(size_t)5;
313 RTTESTI_CHECK_RC(RTPipeWrite(hPipeR, "asdf", 0, &cbWrite), VERR_ACCESS_DENIED);
314 RTTESTI_CHECK_RC(RTPipeWrite(hPipeR, "asdf", 4, &cbWrite), VERR_ACCESS_DENIED);
315 RTTESTI_CHECK(cbWrite == ~(size_t)5);
316 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeR, "asdf", 0, NULL), VERR_ACCESS_DENIED);
317 RTTESTI_CHECK_RC(RTPipeWriteBlocking(hPipeR, "asdf", 4, NULL), VERR_ACCESS_DENIED);
318
319 RTTESTI_CHECK_RC(RTPipeFlush(hPipeR), VERR_ACCESS_DENIED);
320
321 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
322 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
323}
324
325
326static void tstRTPipe1(void)
327{
328 RTTestISub("Basics");
329
330 RTPIPE hPipeR = NIL_RTPIPE;
331 RTPIPE hPipeW = NIL_RTPIPE;
332 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
333 RTTESTI_CHECK_RETV(hPipeR != NIL_RTPIPE);
334 RTTESTI_CHECK_RETV(hPipeW != NIL_RTPIPE);
335 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
336 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
337 RTTESTI_CHECK_RC_RETV(RTPipeClose(NIL_RTPIPE), VINF_SUCCESS);
338
339 hPipeR = NIL_RTPIPE;
340 hPipeW = NIL_RTPIPE;
341 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ | RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
342 int rc = RTPipeFlush(hPipeW);
343 RTTESTI_CHECK_MSG(rc == VERR_NOT_SUPPORTED || rc == VINF_SUCCESS, ("%Rrc\n", rc));
344 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
345 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
346
347 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);
348 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 0), VERR_TIMEOUT);
349 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 1), VERR_TIMEOUT);
350 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeW, 0), VINF_SUCCESS);
351 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeW, 1), VINF_SUCCESS);
352 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
353 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
354
355 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_WRITE), VINF_SUCCESS);
356 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
357 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
358
359 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, RTPIPE_C_INHERIT_READ), VINF_SUCCESS);
360
361 size_t cbRead = ~(size_t)0;
362 char abBuf[_64K + _4K];
363 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VINF_TRY_AGAIN);
364 RTTESTI_CHECK_RETV(cbRead == 0);
365
366 cbRead = ~(size_t)0;
367 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 1, &cbRead), VINF_TRY_AGAIN);
368 RTTESTI_CHECK_RETV(cbRead == 0);
369
370 cbRead = ~(size_t)0;
371 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
372 RTTESTI_CHECK_RETV(cbRead == 0);
373
374 size_t cbWritten = ~(size_t)2;
375 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, abBuf, 0, &cbWritten), VINF_SUCCESS);
376 RTTESTI_CHECK_RETV(cbWritten == 0);
377
378 /* We can write a number of bytes without blocking (see PIPE_BUF on
379 POSIX systems). */
380 cbWritten = ~(size_t)2;
381 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "42", 2, &cbWritten), VINF_SUCCESS);
382 RTTESTI_CHECK_MSG_RETV(cbWritten == 2, ("cbWritten=%zu\n", cbWritten));
383 cbWritten = ~(size_t)2;
384 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "!", 1, &cbWritten), VINF_SUCCESS);
385 RTTESTI_CHECK_RETV(cbWritten == 1);
386 cbRead = ~(size_t)0;
387 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 3, &cbRead), VINF_SUCCESS);
388 RTTESTI_CHECK_RETV(cbRead == 3);
389 RTTESTI_CHECK_RETV(!memcmp(abBuf, "42!", 3));
390
391 cbWritten = ~(size_t)2;
392 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "BigQ", 4, &cbWritten), VINF_SUCCESS);
393 RTTESTI_CHECK_RETV(cbWritten == 4);
394 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 0), VINF_SUCCESS);
395 RTTESTI_CHECK_RC_RETV(RTPipeSelectOne(hPipeR, 1), VINF_SUCCESS);
396 cbRead = ~(size_t)0;
397 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
398 RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
399 cbRead = ~(size_t)0;
400 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VINF_SUCCESS);
401 RTTESTI_CHECK_RETV(cbRead == 4);
402 RTTESTI_CHECK_RETV(!memcmp(abBuf, "BigQ", 4));
403
404 cbWritten = ~(size_t)2;
405 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "H2G2", 4, &cbWritten), VINF_SUCCESS);
406 RTTESTI_CHECK_RETV(cbWritten == 4);
407 cbRead = ~(size_t)0;
408 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
409 RTTESTI_CHECK_MSG(cbRead == cbWritten, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
410 cbRead = ~(size_t)0;
411 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
412 RTTESTI_CHECK_RETV(cbRead == 1);
413 cbRead = ~(size_t)0;
414 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
415 RTTESTI_CHECK_MSG(cbRead == cbWritten - 1, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
416 cbRead = ~(size_t)0;
417 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[1], 1, &cbRead), VINF_SUCCESS);
418 RTTESTI_CHECK_RETV(cbRead == 1);
419 cbRead = ~(size_t)0;
420 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
421 RTTESTI_CHECK_MSG(cbRead == cbWritten - 2, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
422 cbRead = ~(size_t)0;
423 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[2], 1, &cbRead), VINF_SUCCESS);
424 RTTESTI_CHECK_RETV(cbRead == 1);
425 cbRead = ~(size_t)0;
426 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
427 RTTESTI_CHECK_MSG(cbRead == cbWritten - 3, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
428 cbRead = ~(size_t)0;
429 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[3], 1, &cbRead), VINF_SUCCESS);
430 RTTESTI_CHECK_RETV(cbRead == 1);
431 RTTESTI_CHECK_RETV(!memcmp(abBuf, "H2G2", 4));
432 cbRead = ~(size_t)0;
433 RTTESTI_CHECK_RC_RETV(RTPipeQueryReadable(hPipeR, &cbRead), VINF_SUCCESS);
434 RTTESTI_CHECK_MSG(cbRead == cbWritten - 4, ("cbRead=%zu cbWritten=%zu\n", cbRead, cbWritten));
435
436 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
437 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
438
439
440 RTTestISub("VERR_BROKEN_PIPE");
441 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
442 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeR), VINF_SUCCESS);
443 cbWritten = ~(size_t)2;
444 RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "", 0, &cbWritten), VINF_SUCCESS);
445 RTTESTI_CHECK(cbWritten == 0);
446 cbWritten = ~(size_t)2;
447 RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "4", 1, &cbWritten), VERR_BROKEN_PIPE);
448 RTTESTI_CHECK(cbWritten == ~(size_t)2);
449 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
450
451 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
452 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
453 cbRead = ~(size_t)0;
454 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
455 RTTESTI_CHECK(cbRead == 0);
456 cbRead = ~(size_t)3;
457 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
458 RTTESTI_CHECK(cbRead == ~(size_t)3);
459 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
460
461 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
462 cbWritten = ~(size_t)2;
463 RTTESTI_CHECK_RC(RTPipeWrite(hPipeW, "42", 2, &cbWritten), VINF_SUCCESS);
464 RTTESTI_CHECK(cbWritten == 2);
465 RTTESTI_CHECK_RC_RETV(RTPipeClose(hPipeW), VINF_SUCCESS);
466 cbRead = ~(size_t)0;
467 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
468 RTTESTI_CHECK(cbRead == 0);
469 cbRead = ~(size_t)0;
470 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
471 RTTESTI_CHECK(cbRead == 1);
472 cbRead = ~(size_t)0;
473 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, &abBuf[1], 1, &cbRead), VINF_SUCCESS);
474 RTTESTI_CHECK(cbRead == 1);
475 RTTESTI_CHECK(!memcmp(abBuf, "42", 2));
476 cbRead = ~(size_t)0;
477 RTTESTI_CHECK_RC(RTPipeRead(hPipeR, abBuf, 0, &cbRead), VINF_SUCCESS);
478 RTTESTI_CHECK(cbRead == 0);
479 cbRead = ~(size_t)3;
480 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
481 RTTESTI_CHECK(cbRead == ~(size_t)3);
482 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
483
484 RTTestISub("Blocking");
485 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
486 RTTESTI_CHECK_RC_RETV(RTPipeWrite(hPipeW, "42!", 3, &cbWritten), VINF_SUCCESS);
487 RTTESTI_CHECK(cbWritten == 3);
488 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, abBuf, 3, NULL), VINF_SUCCESS);
489 RTTESTI_CHECK(!memcmp(abBuf, "42!", 3));
490 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
491 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 0, NULL), VINF_SUCCESS);
492 cbRead = ~(size_t)42;
493 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 0, &cbRead), VINF_SUCCESS);
494 RTTESTI_CHECK(cbRead == 0);
495 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 1, NULL), VERR_BROKEN_PIPE);
496 cbRead = ~(size_t)42;
497 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[0], 1, &cbRead), VERR_BROKEN_PIPE);
498 RTTESTI_CHECK(cbRead == 0);
499 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
500
501 RTTESTI_CHECK_RC_RETV(RTPipeCreate(&hPipeR, &hPipeW, 0), VINF_SUCCESS);
502 RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42!", 3, NULL), VINF_SUCCESS);
503 RTTESTI_CHECK(cbWritten == 3);
504 cbRead = ~(size_t)0;
505 RTTESTI_CHECK_RC_RETV(RTPipeRead(hPipeR, &abBuf[0], 1, &cbRead), VINF_SUCCESS);
506 RTTESTI_CHECK(cbRead == 1);
507 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[1], 1, NULL), VINF_SUCCESS);
508 RTTESTI_CHECK_RC_RETV(RTPipeReadBlocking(hPipeR, &abBuf[2], 1, NULL), VINF_SUCCESS);
509 RTTESTI_CHECK(!memcmp(abBuf, "42!", 3));
510 RTTESTI_CHECK_RC(RTPipeClose(hPipeR), VINF_SUCCESS);
511 RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "", 0, NULL), VINF_SUCCESS);
512 cbWritten = ~(size_t)9;
513 RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "", 0, &cbWritten), VINF_SUCCESS);
514 RTTESTI_CHECK(cbWritten == 0);
515 RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42", 2, NULL), VERR_BROKEN_PIPE);
516 cbWritten = ~(size_t)9;
517 RTTESTI_CHECK_RC_RETV(RTPipeWriteBlocking(hPipeW, "42", 2, &cbWritten), VERR_BROKEN_PIPE);
518 RTTESTI_CHECK(cbWritten == 0);
519 RTTESTI_CHECK_RC(RTPipeClose(hPipeW), VINF_SUCCESS);
520}
521
522int main(int argc, char **argv)
523{
524 if (argc == 3 && !strcmp(argv[1], "--child-4"))
525 return tstRTPipe4Child(argv[2]);
526 if (argc == 3 && !strcmp(argv[1], "--child-5"))
527 return tstRTPipe5Child(argv[2]);
528
529 int rc = RTTestInitAndCreate("tstRTPipe", &g_hTest);
530 if (rc)
531 return rc;
532 RTTestBanner(g_hTest);
533
534 /*
535 * The tests.
536 */
537 tstRTPipe1();
538 if (RTTestErrorCount(g_hTest) == 0)
539 {
540 bool fMayPanic = RTAssertMayPanic();
541 bool fQuiet = RTAssertAreQuiet();
542 RTAssertSetMayPanic(false);
543 RTAssertSetQuiet(true);
544 tstRTPipe2();
545 RTAssertSetQuiet(fQuiet);
546 RTAssertSetMayPanic(fMayPanic);
547
548 tstRTPipe3();
549 tstRTPipe4();
550 tstRTPipe5();
551 }
552
553 /*
554 * Summary.
555 */
556 return RTTestSummaryAndDestroy(g_hTest);
557}
558
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette