mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 07:23:20 +00:00

Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016. The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021: Number of commits on the main branch: 2930 Number of contributors: 31 Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
656 lines
18 KiB
C
656 lines
18 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
splice.c
|
|
|
|
Abstract:
|
|
|
|
This file contains tests for the splice syscall.
|
|
|
|
--*/
|
|
|
|
#include "lxtcommon.h"
|
|
#include "unittests.h"
|
|
#include <unistd.h>
|
|
#include <sys/syscall.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <fcntl.h>
|
|
|
|
#define LXT_NAME "Splice"
|
|
|
|
#define SPLICE_SYSCALL(_Fdin, _Offin, _Fdout, _Offout, _Size, _Flags) \
|
|
syscall(SYS_splice, _Fdin, _Offin, _Fdout, _Offout, _Size, _Flags)
|
|
|
|
#define TEE_SYSCALL(_Fdin, _Fdout, _Size, _Flags) syscall(SYS_tee, _Fdin, _Fdout, _Size, _Flags)
|
|
|
|
#ifndef SPLICE_F_NONBLOCK
|
|
#define SPLICE_F_NONBLOCK 0x02
|
|
#endif
|
|
|
|
#define SPLICE_READ_PIPE_INDEX 0
|
|
#define SPLICE_WRITE_PIPE_INDEX 1
|
|
|
|
//
|
|
// The following defines a standardized file path and content for a file that
|
|
// can be used for splicing.
|
|
//
|
|
|
|
#define SPLICE_STD_FILE "/data/test/splice_test_std_file_1.txt"
|
|
#define SPLICE_STD_FILE_CONTENT "123456789Test"
|
|
#define SPLICE_STD_FILE_SIZE (unsigned long)(strlen(SPLICE_STD_FILE_CONTENT))
|
|
|
|
int SpliceOpenStandardFile(void);
|
|
|
|
int SpliceVariationBasicTests(PLXT_ARGS Args);
|
|
|
|
int SpliceVariationBlocking(PLXT_ARGS Args);
|
|
|
|
int SpliceVariationInvalidParameters(PLXT_ARGS Args);
|
|
|
|
int TeeVariationBasicTests(PLXT_ARGS Args);
|
|
|
|
int TeeVariationInvalidParameters(PLXT_ARGS Args);
|
|
|
|
//
|
|
// Globals.
|
|
//
|
|
|
|
static const LXT_VARIATION g_LxtVariations[] = {
|
|
{"Splice - Invalid Parameter Test ", SpliceVariationInvalidParameters},
|
|
{"Splice - Blocking Tests", SpliceVariationBlocking},
|
|
{"Splice - Basic Usage Tests", SpliceVariationBasicTests},
|
|
{"Tee - Invalid Parameter Test ", TeeVariationInvalidParameters},
|
|
{"Tee - Basic Usage Test", TeeVariationBasicTests}};
|
|
|
|
int SpliceTestEntry(int Argc, char* Argv[])
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the main entry point for the procfs tests.
|
|
|
|
Arguments:
|
|
|
|
Argc - Supplies the number of command line arguments.
|
|
|
|
Argv - Supplies the command line arguments.
|
|
|
|
Return Value:
|
|
|
|
Returns 0 on success, -1 on failure.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
LXT_ARGS Args;
|
|
int Result;
|
|
|
|
LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
|
|
LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
|
|
|
|
ErrorExit:
|
|
LxtUninitialize();
|
|
return !LXT_SUCCESS(Result);
|
|
}
|
|
|
|
int SpliceOpenStandardFile(void)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns the file descriptor for the standard file which
|
|
include uniform data for splicing.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
On success, returns open file descriptor; otherwise, -1.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
int Fd;
|
|
off_t Offset;
|
|
int Result;
|
|
|
|
LxtCheckErrno(Fd = open(SPLICE_STD_FILE, (O_CREAT | O_RDWR), (S_IRUSR | S_IWUSR)));
|
|
|
|
LxtCheckErrno(write(Fd, SPLICE_STD_FILE_CONTENT, SPLICE_STD_FILE_SIZE));
|
|
|
|
//
|
|
// Set the offset back to zero.
|
|
//
|
|
|
|
LxtCheckErrno(Offset = lseek(Fd, 0, SEEK_SET));
|
|
|
|
//
|
|
// Set the result.
|
|
//
|
|
|
|
Result = Fd;
|
|
Fd = 0;
|
|
|
|
ErrorExit:
|
|
if (Fd > 0)
|
|
{
|
|
close(Fd);
|
|
unlink(SPLICE_STD_FILE);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SpliceVariationBasicTests(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine runs basic usage tests for splice, including splicing between
|
|
two pipes and a pipe and a regular file, and tests the results for
|
|
accurate splice sizes, content, and file offsets.
|
|
|
|
Arguments:
|
|
|
|
Args - Supplies a pointer to variation arguments.
|
|
|
|
Return Value:
|
|
|
|
On success, returns open file descriptor; otherwise, -1.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
char Buffer[4];
|
|
LXT_PIPE DestinationPipe = {-1, -1};
|
|
loff_t InitialOffset;
|
|
loff_t Offset;
|
|
char* PipeData;
|
|
ssize_t PipeDataSize;
|
|
int RegularFd;
|
|
int Result;
|
|
ssize_t SpliceSize;
|
|
LXT_PIPE SourcePipe = {-1, -1};
|
|
|
|
RegularFd = -1;
|
|
PipeData = "1234";
|
|
PipeDataSize = strlen(PipeData);
|
|
LxtCheckResult(LxtCreatePipe(&DestinationPipe));
|
|
LxtCheckResult(LxtCreatePipe(&SourcePipe));
|
|
LxtCheckResult(RegularFd = SpliceOpenStandardFile());
|
|
|
|
//
|
|
// Set up read-end of pipes as non-blocking for empty tests.
|
|
//
|
|
|
|
LxtCheckErrno(fcntl(SourcePipe.Read, F_SETFL, O_NONBLOCK));
|
|
LxtCheckErrno(fcntl(DestinationPipe.Read, F_SETFL, O_NONBLOCK));
|
|
|
|
//
|
|
// Perform basic tests between pipes.
|
|
//
|
|
|
|
LxtLogInfo("Basic Usage - Splicing between two pipes");
|
|
LxtCheckErrno(write(SourcePipe.Write, PipeData, PipeDataSize));
|
|
LxtCheckErrno(SpliceSize = SPLICE_SYSCALL(SourcePipe.Read, NULL, DestinationPipe.Write, NULL, PipeDataSize, SPLICE_F_NONBLOCK));
|
|
|
|
LxtCheckEqual(SpliceSize, PipeDataSize, "%d");
|
|
|
|
//
|
|
// Check that the read pipe is now empty by attempting to read a single
|
|
// byte.
|
|
//
|
|
|
|
LxtCheckErrnoFailure(read(SourcePipe.Read, Buffer, 1), EAGAIN);
|
|
LxtCheckErrno(SpliceSize = read(DestinationPipe.Read, Buffer, PipeDataSize));
|
|
|
|
LxtCheckEqual(SpliceSize, PipeDataSize, "%d");
|
|
|
|
//
|
|
// LX_TODO: Enable the following additional basic tests once splicing is
|
|
// available for VolFs file types.
|
|
//
|
|
|
|
/*
|
|
//
|
|
// Perform test from a regular file to a pipe.
|
|
//
|
|
|
|
InitialOffset = 4;
|
|
Offset = InitialOffset;
|
|
LxtLogInfo("Basic Usage - Splicing from a regular file to a pipe");
|
|
LxtCheckErrno(SpliceSize = SPLICE_SYSCALL(RegularFd,
|
|
&Offset,
|
|
DestinationPipe.Write,
|
|
NULL,
|
|
4,
|
|
SPLICE_F_NONBLOCK));
|
|
|
|
LxtCheckEqual(SpliceSize, 4, "%d");
|
|
LxtCheckErrno(SpliceSize = read(DestinationPipe.Read, Buffer, 4));
|
|
LxtCheckEqual(SpliceSize, 4, "%d");
|
|
LxtCheckEqual(Offset - InitialOffset, 4, "%d");
|
|
LxtCheckEqual(Buffer[0],
|
|
SPLICE_STD_FILE_CONTENT[InitialOffset],
|
|
"%c");
|
|
|
|
//
|
|
// Ensure that offset remains unchanged on the file.
|
|
//
|
|
|
|
LxtCheckErrno(SpliceSize = read(RegularFd, Buffer, 4));
|
|
LxtCheckEqual(SpliceSize, 4, "%d");
|
|
LxtCheckEqual(Buffer[0],
|
|
SPLICE_STD_FILE_CONTENT[0],
|
|
"%c");
|
|
|
|
//
|
|
// Reset the file's offset for the next test.
|
|
//
|
|
|
|
LxtCheckErrno(lseek(RegularFd, 0, SEEK_SET));
|
|
|
|
//
|
|
// Perform test from a pipe to a regular file.
|
|
//
|
|
|
|
InitialOffset = 1;
|
|
Offset = InitialOffset;
|
|
LxtLogInfo("Basic Usage - Splicing from a pipe to a regular file");
|
|
LxtCheckErrno(write(SourcePipe.Write, PipeData, PipeDataSize));
|
|
LxtCheckErrno(SpliceSize = SPLICE_SYSCALL(SourcePipe.Read,
|
|
NULL,
|
|
RegularFd,
|
|
&Offset,
|
|
PipeDataSize,
|
|
SPLICE_F_NONBLOCK));
|
|
|
|
LxtCheckEqual(SpliceSize, PipeDataSize, "%d");
|
|
LxtCheckEqual(Offset - InitialOffset, PipeDataSize, "%d");
|
|
|
|
//
|
|
// Ensure that the regular file's internal offset is unchanged and that the
|
|
// the pipe data was properly splice into the file with the offset.
|
|
//
|
|
|
|
LxtCheckErrno(SpliceSize = read(RegularFd, Buffer, 2));
|
|
LxtCheckEqual(SpliceSize, 2, "%d");
|
|
LxtCheckEqual(Buffer[0],
|
|
SPLICE_STD_FILE_CONTENT[0],
|
|
"%c");
|
|
|
|
LxtCheckEqual(Buffer[1], PipeData[0], "%c");
|
|
*/
|
|
|
|
ErrorExit:
|
|
LxtClosePipe(&DestinationPipe);
|
|
LxtClosePipe(&SourcePipe);
|
|
if (RegularFd > 0)
|
|
{
|
|
close(RegularFd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SpliceVariationBlocking(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine tests the splice syscall with the splice-specific non-blocking
|
|
flag with pipes that have opposite internal blocking settings and checks for
|
|
proper behavior.
|
|
|
|
Arguments:
|
|
|
|
Args - Supplies a pointer to variation arguments.
|
|
|
|
Return Value:
|
|
|
|
On success, returns open file descriptor; otherwise, -1.
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
pid_t ChildPid;
|
|
LXT_PIPE DestinationPipe = {-1, -1};
|
|
int Result;
|
|
LXT_PIPE SourcePipe = {-1, -1};
|
|
int WaitPidResult;
|
|
int WaitPidStatus;
|
|
|
|
LxtCheckResult(LxtCreatePipe(&DestinationPipe));
|
|
LxtCheckResult(LxtCreatePipe(&SourcePipe));
|
|
|
|
//
|
|
// Verify that a pipe which is automatically set to have blocking I/O
|
|
// semantics, does not block when the splice call is supplied with the
|
|
// splice-specific non-blocking flag.
|
|
//
|
|
|
|
LxtLogInfo("Blocking - Non-blocking splice with blocking pipes");
|
|
LxtCheckResult(ChildPid = fork());
|
|
if (ChildPid == 0)
|
|
{
|
|
|
|
//
|
|
// By default, the created pipes are blocking. The splice non-blocking
|
|
// flag should override this behavior.
|
|
//
|
|
|
|
Result = SPLICE_SYSCALL(SourcePipe.Read, NULL, DestinationPipe.Write, NULL, 1, SPLICE_F_NONBLOCK);
|
|
|
|
if (Result >= 0)
|
|
{
|
|
LxtLogError("Non-blocking splice syscall succeeded");
|
|
_exit(1);
|
|
}
|
|
|
|
if (errno != EAGAIN)
|
|
{
|
|
LxtLogError("Non-blocking splice syscall returned with error %s", strerror(errno));
|
|
|
|
_exit(1);
|
|
}
|
|
|
|
_exit(0);
|
|
}
|
|
|
|
LxtCheckResult(WaitPidStatus = LxtWaitPidPollOptions(ChildPid, 0, 0, 2));
|
|
|
|
//
|
|
// Verify that a pipe that is set to non-blocking will block when the
|
|
// splice-specific non-blocking flag is not passed to splice.
|
|
//
|
|
|
|
LxtLogInfo("Blocking - Blocking splice with non-blocking pipe");
|
|
LxtCheckErrno(fcntl(SourcePipe.Read, F_SETFL, O_NONBLOCK));
|
|
LxtCheckResult(ChildPid = fork());
|
|
if (ChildPid == 0)
|
|
{
|
|
Result = SPLICE_SYSCALL(SourcePipe.Read, NULL, DestinationPipe.Write, NULL, 1, 0);
|
|
|
|
_exit(0);
|
|
}
|
|
|
|
sleep(2);
|
|
LxtCheckErrno(WaitPidResult = waitpid(ChildPid, &WaitPidStatus, WNOHANG));
|
|
|
|
//
|
|
// If the child is not alive, it did not block as expected.
|
|
//
|
|
|
|
LxtCheckEqual(WaitPidResult, 0, "%d");
|
|
kill(ChildPid, SIGKILL);
|
|
Result = 0;
|
|
ErrorExit:
|
|
LxtClosePipe(&DestinationPipe);
|
|
LxtClosePipe(&SourcePipe);
|
|
return Result;
|
|
}
|
|
|
|
int SpliceVariationInvalidParameters(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine tests the splice syscall errors are properly set when invalid
|
|
parameters are passed to it.
|
|
|
|
Arguments:
|
|
|
|
Args - Supplies a pointer to variation arguments.
|
|
|
|
Return Value:
|
|
|
|
On success, returns open file descriptor; otherwise, -1.
|
|
|
|
--*/
|
|
{
|
|
|
|
LXT_PIPE DestinationPipe = {-1, -1};
|
|
loff_t ReadOffset;
|
|
int Result;
|
|
LXT_PIPE SourcePipe = {-1, -1};
|
|
int StandardFd;
|
|
|
|
StandardFd = 0;
|
|
LxtCheckErrno(LxtCreatePipe(&SourcePipe));
|
|
LxtCheckErrno(LxtCreatePipe(&DestinationPipe));
|
|
LxtCheckResult(StandardFd = SpliceOpenStandardFile());
|
|
|
|
//
|
|
// Put some random data into the source pipe and set the offset.
|
|
//
|
|
|
|
LxtCheckErrno(write(SourcePipe.Write, "1234", 4));
|
|
ReadOffset = 2;
|
|
|
|
//
|
|
// Check that a call with invalid parameters, but a splice size of zero will
|
|
// succeed.
|
|
//
|
|
|
|
LxtLogInfo("Invalid Params - Passing invalid parameters with splice size of zero");
|
|
|
|
LxtCheckErrno(SPLICE_SYSCALL(SourcePipe.Read, &ReadOffset, DestinationPipe.Write, NULL, 0, 0));
|
|
|
|
LxtCheckErrno(SPLICE_SYSCALL(StandardFd, NULL, StandardFd, NULL, 0, 0));
|
|
LxtCheckErrno(SPLICE_SYSCALL(-1, NULL, -1, NULL, 0, 0));
|
|
|
|
//
|
|
// Check that invalid flags do not cause any errors.
|
|
//
|
|
|
|
LxtCheckErrno(SPLICE_SYSCALL(SourcePipe.Read, NULL, DestinationPipe.Write, NULL, 4, 0xF0));
|
|
|
|
//
|
|
// Check the error result when a pipe is given a non-null offset.
|
|
//
|
|
|
|
LxtLogInfo("Invalid Params - Passing non-null offset with pipe fd");
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(SourcePipe.Read, &ReadOffset, DestinationPipe.Write, NULL, 1, 0), ESPIPE);
|
|
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(SourcePipe.Read, NULL, DestinationPipe.Write, &ReadOffset, 1, 0), ESPIPE);
|
|
|
|
//
|
|
// Ensure that the correct error is returned when splice takes two
|
|
// parameters that are not pipes.
|
|
//
|
|
|
|
LxtLogInfo("Invalid Params - Passing two non-pipe fd's to splice");
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(StandardFd, NULL, StandardFd, NULL, 1, 0), EINVAL);
|
|
|
|
//
|
|
// Validate errors returned wrong read\write pipe
|
|
//
|
|
|
|
//
|
|
// LX_TODO: Here and in the tee syscall variation, the atomic property of
|
|
// tee/splice must be implemented before these tests are enabled.
|
|
//
|
|
|
|
/*
|
|
LxtLogInfo("Invalid Params - Invalid splice read\write pipe 1");
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(SourcePipe.Read,
|
|
NULL,
|
|
SourcePipe.Read,
|
|
NULL,
|
|
200,
|
|
0),
|
|
EBADF);
|
|
|
|
LxtLogInfo("Invalid Params - Invalid splice read\write pipe 2");
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(SourcePipe.Write,
|
|
NULL,
|
|
SourcePipe.Read,
|
|
NULL,
|
|
200,
|
|
0),
|
|
EBADF);
|
|
|
|
LxtLogInfo("Invalid Params - Invalid splice read\write pipe 3");
|
|
LxtCheckErrnoFailure(SPLICE_SYSCALL(SourcePipe.Read,
|
|
NULL,
|
|
DestinationPipe.Read,
|
|
NULL,
|
|
200,
|
|
0),
|
|
EBADF);
|
|
*/
|
|
|
|
ErrorExit:
|
|
LxtClosePipe(&SourcePipe);
|
|
LxtClosePipe(&DestinationPipe);
|
|
if (StandardFd > 0)
|
|
{
|
|
close(StandardFd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int TeeVariationBasicTests(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
char Buffer[16];
|
|
LXT_PIPE DestinationPipe = {-1, -1};
|
|
char* PipeData;
|
|
ssize_t PipeDataSize;
|
|
ssize_t ReadSize;
|
|
int Result;
|
|
ssize_t SpliceSize;
|
|
LXT_PIPE SourcePipe = {-1, -1};
|
|
|
|
PipeData = "1234";
|
|
PipeDataSize = strlen(PipeData);
|
|
LxtCheckResult(LxtCreatePipe(&DestinationPipe));
|
|
LxtCheckResult(LxtCreatePipe(&SourcePipe));
|
|
|
|
//
|
|
// Set up read-end of pipes as non-blocking for empty tests.
|
|
//
|
|
|
|
LxtCheckErrno(fcntl(SourcePipe.Read, F_SETFL, O_NONBLOCK));
|
|
LxtCheckErrno(fcntl(DestinationPipe.Read, F_SETFL, O_NONBLOCK));
|
|
|
|
//
|
|
// Perform basic tests between pipes.
|
|
//
|
|
|
|
LxtLogInfo("Basic Usage - Tee");
|
|
LxtCheckErrno(write(SourcePipe.Write, PipeData, PipeDataSize));
|
|
LxtCheckErrno(SpliceSize = TEE_SYSCALL(SourcePipe.Read, DestinationPipe.Write, PipeDataSize, SPLICE_F_NONBLOCK));
|
|
|
|
LxtCheckEqual(SpliceSize, PipeDataSize, "%d");
|
|
|
|
//
|
|
// Check that the read pipe still has the same data as before.
|
|
//
|
|
|
|
LxtCheckErrno(ReadSize = read(SourcePipe.Read, Buffer, PipeDataSize));
|
|
LxtCheckEqual(ReadSize, PipeDataSize, "%d");
|
|
Buffer[ReadSize] = '\0';
|
|
LxtCheckStringEqual(Buffer, PipeData);
|
|
|
|
//
|
|
// Check that the destination pipe has the correct data after the tee.
|
|
//
|
|
|
|
LxtCheckErrno(ReadSize = read(DestinationPipe.Read, Buffer, PipeDataSize));
|
|
LxtCheckEqual(ReadSize, PipeDataSize, "%d");
|
|
Buffer[ReadSize] = '\0';
|
|
LxtCheckStringEqual(Buffer, PipeData);
|
|
|
|
ErrorExit:
|
|
LxtClosePipe(&SourcePipe);
|
|
LxtClosePipe(&DestinationPipe);
|
|
return Result;
|
|
}
|
|
|
|
int TeeVariationInvalidParameters(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
LXT_PIPE DestinationPipe = {-1, -1};
|
|
int Result;
|
|
LXT_PIPE SourcePipe = {-1, -1};
|
|
int StandardFd;
|
|
|
|
StandardFd = 0;
|
|
LxtCheckErrno(LxtCreatePipe(&SourcePipe));
|
|
LxtCheckErrno(LxtCreatePipe(&DestinationPipe));
|
|
LxtCheckResult(StandardFd = SpliceOpenStandardFile());
|
|
|
|
//
|
|
// Put some random data into the source pipe and set the offset.
|
|
//
|
|
|
|
LxtCheckErrno(write(SourcePipe.Write, "1234", 4));
|
|
|
|
//
|
|
// Check that a call with invalid parameters, but a size of zero will
|
|
// succeed.
|
|
//
|
|
|
|
LxtLogInfo("Invalid Params - Passing invalid parameters to tee with size of zero");
|
|
|
|
LxtCheckErrno(TEE_SYSCALL(StandardFd, DestinationPipe.Write, 0, 0));
|
|
LxtCheckErrno(TEE_SYSCALL(SourcePipe.Read, StandardFd, 0, 0));
|
|
LxtCheckErrno(TEE_SYSCALL(StandardFd, StandardFd, 0, 0));
|
|
|
|
//
|
|
// Check that invalid flags do not cause any errors.
|
|
//
|
|
|
|
LxtCheckErrno(TEE_SYSCALL(SourcePipe.Read, DestinationPipe.Write, 4, 0xF0));
|
|
//
|
|
// Validate the errors returned with invalid parameters and non-zero splice
|
|
// sizes.
|
|
//
|
|
|
|
LxtLogInfo("Invalid Params - Passing a non-pipe to a tee syscall");
|
|
LxtCheckErrnoFailure(TEE_SYSCALL(StandardFd, DestinationPipe.Write, 1, 0), EINVAL);
|
|
|
|
LxtCheckErrnoFailure(TEE_SYSCALL(SourcePipe.Read, StandardFd, 1, 0), EINVAL);
|
|
|
|
//
|
|
// Validate errors returned sending to the wrong read\write pipe
|
|
//
|
|
|
|
ErrorExit:
|
|
LxtClosePipe(&SourcePipe);
|
|
LxtClosePipe(&DestinationPipe);
|
|
if (StandardFd > 0)
|
|
{
|
|
close(StandardFd);
|
|
}
|
|
|
|
return Result;
|
|
}
|